Apache HTTPD
sed1.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
3 * Use is subject to license terms.
4 *
5 * Copyright (c) 1984 AT&T
6 * All Rights Reserved
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0.
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
16 * or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#include "apr.h"
22#include "apr_lib.h"
23#include "libsed.h"
24#include "sed.h"
25#include "apr_strings.h"
26#include "regexp.h"
27
28static const char *const trans[040] = {
29 "\\01",
30 "\\02",
31 "\\03",
32 "\\04",
33 "\\05",
34 "\\06",
35 "\\07",
36 "\\10",
37 "\\11",
38 "\n",
39 "\\13",
40 "\\14",
41 "\\15",
42 "\\16",
43 "\\17",
44 "\\20",
45 "\\21",
46 "\\22",
47 "\\23",
48 "\\24",
49 "\\25",
50 "\\26",
51 "\\27",
52 "\\30",
53 "\\31",
54 "\\32",
55 "\\33",
56 "\\34",
57 "\\35",
58 "\\36",
59 "\\37"
60};
61static const char rub[] = {"\\177"};
62
63extern int sed_step(char *p1, char *p2, int circf, step_vars_storage *vars);
64static int substitute(sed_eval_t *eval, sed_reptr_t *ipc,
66static apr_status_t execute(sed_eval_t *eval);
67static int match(sed_eval_t *eval, char *expbuf, int gf,
69static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
71static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2);
74static apr_status_t wline(sed_eval_t *eval, char *buf, apr_size_t sz);
75static apr_status_t arout(sed_eval_t *eval);
76
77static void eval_errf(sed_eval_t *eval, const char *fmt, ...)
78{
79 if (eval->errfn && eval->pool) {
81 const char* error;
83 error = apr_pvsprintf(eval->pool, fmt, args);
84 eval->errfn(eval->data, error);
85 va_end(args);
86 }
87}
88
89#define INIT_BUF_SIZE 1024
90#define MAX_BUF_SIZE 1024*8192
91
92/*
93 * grow_buffer
94 */
96 char **spend, apr_size_t *cursize,
98{
99 char* newbuffer = NULL;
101 if (*cursize >= newsize) {
102 return APR_SUCCESS;
103 }
104 /* Avoid number of times realloc is called. It could cause huge memory
105 * requirement if line size is huge e.g 2 MB */
106 if (newsize < *cursize * 2) {
107 newsize = *cursize * 2;
108 }
109
110 /* Align it to 4 KB boundary */
111 newsize = (newsize + ((1 << 12) - 1)) & ~((1 << 12) - 1);
112 if (newsize > MAX_BUF_SIZE) {
113 return APR_ENOMEM;
114 }
116 if (*spend && *buffer && (*cursize > 0)) {
117 spendsize = *spend - *buffer;
118 }
119 if ((*cursize > 0) && *buffer) {
121 }
122 *buffer = newbuffer;
123 *cursize = newsize;
124 if (spend != buffer) {
125 *spend = *buffer + spendsize;
126 }
127 return APR_SUCCESS;
128}
129
130/*
131 * grow_line_buffer
132 */
134{
135 return grow_buffer(eval->pool, &eval->linebuf, &eval->lspend,
136 &eval->lsize, newsize);
137}
138
139/*
140 * grow_hold_buffer
141 */
143{
144 return grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend,
145 &eval->hsize, newsize);
146}
147
148/*
149 * grow_gen_buffer
150 */
152 char **gspend)
153{
154 apr_status_t rc = 0;
155 if (gspend == NULL) {
156 gspend = &eval->genbuf;
157 }
158 rc = grow_buffer(eval->pool, &eval->genbuf, gspend,
159 &eval->gsize, newsize);
160 if (rc == APR_SUCCESS) {
161 eval->lcomend = &eval->genbuf[71];
162 }
163 return rc;
164}
165
166/*
167 * appendmem_to_linebuf
168 */
170{
171 apr_status_t rc = 0;
172 apr_size_t reqsize = (eval->lspend - eval->linebuf) + len;
173 if (eval->lsize < reqsize) {
174 rc = grow_line_buffer(eval, reqsize);
175 if (rc != APR_SUCCESS) {
176 return rc;
177 }
178 }
179 memcpy(eval->lspend, sz, len);
180 eval->lspend += len;
181 return APR_SUCCESS;
182}
183
184/*
185 * append_to_linebuf
186 */
187static apr_status_t append_to_linebuf(sed_eval_t *eval, const char* sz,
189{
190 apr_size_t len = strlen(sz);
191 char *old_linebuf = eval->linebuf;
192 apr_status_t rc = 0;
193 /* Copy string including null character */
194 rc = appendmem_to_linebuf(eval, sz, len + 1);
195 if (rc != APR_SUCCESS) {
196 return rc;
197 }
198 --eval->lspend; /* lspend will now point to NULL character */
199 /* Sync step_vars after a possible linebuf expansion */
200 if (step_vars && old_linebuf != eval->linebuf) {
201 if (step_vars->loc1) {
202 step_vars->loc1 = step_vars->loc1 - old_linebuf + eval->linebuf;
203 }
204 if (step_vars->loc2) {
205 step_vars->loc2 = step_vars->loc2 - old_linebuf + eval->linebuf;
206 }
207 if (step_vars->locs) {
208 step_vars->locs = step_vars->locs - old_linebuf + eval->linebuf;
209 }
210 }
211 return APR_SUCCESS;
212}
213
214/*
215 * copy_to_linebuf
216 */
217static apr_status_t copy_to_linebuf(sed_eval_t *eval, const char* sz,
219{
220 eval->lspend = eval->linebuf;
221 return append_to_linebuf(eval, sz, step_vars);
222}
223
224/*
225 * append_to_holdbuf
226 */
227static apr_status_t append_to_holdbuf(sed_eval_t *eval, const char* sz)
228{
229 apr_size_t len = strlen(sz);
230 apr_size_t reqsize = (eval->hspend - eval->holdbuf) + len + 1;
231 apr_status_t rc = 0;
232 if (eval->hsize <= reqsize) {
233 rc = grow_hold_buffer(eval, reqsize);
234 if (rc != APR_SUCCESS) {
235 return rc;
236 }
237 }
238 memcpy(eval->hspend, sz, len + 1);
239 /* hspend will now point to NULL character */
240 eval->hspend += len;
241 return APR_SUCCESS;
242}
243
244/*
245 * copy_to_holdbuf
246 */
247static apr_status_t copy_to_holdbuf(sed_eval_t *eval, const char* sz)
248{
249 eval->hspend = eval->holdbuf;
250 return append_to_holdbuf(eval, sz);
251}
252
253/*
254 * append_to_genbuf
255 */
256static apr_status_t append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend)
257{
258 apr_size_t len = strlen(sz);
259 apr_size_t reqsize = (*gspend - eval->genbuf) + len + 1;
260 apr_status_t rc = 0;
261 if (eval->gsize < reqsize) {
263 if (rc != APR_SUCCESS) {
264 return rc;
265 }
266 }
267 memcpy(*gspend, sz, len + 1);
268 /* *gspend will now point to NULL character */
269 *gspend += len;
270 return APR_SUCCESS;
271}
272
273/*
274 * copy_to_genbuf
275 */
276static apr_status_t copy_to_genbuf(sed_eval_t *eval, const char* sz)
277{
278 apr_size_t len = strlen(sz);
279 apr_size_t reqsize = len + 1;
281 if (eval->gsize < reqsize) {
282 rc = grow_gen_buffer(eval, reqsize, NULL);
283 if (rc != APR_SUCCESS) {
284 return rc;
285 }
286 }
287 memcpy(eval->genbuf, sz, len + 1);
288 return rc;
289}
290
291/*
292 * sed_init_eval
293 */
295{
296 memset(eval, 0, sizeof(*eval));
297 eval->pool = p;
298 eval->writefn = writefn;
299 return sed_reset_eval(eval, commands, errfn, data);
300}
301
302/*
303 * sed_reset_eval
304 */
306{
307 int i;
308
309 eval->errfn = errfn;
310 eval->data = data;
311
312 eval->commands = commands;
313
314 eval->lnum = 0;
315 eval->fout = NULL;
316
317 if (eval->linebuf == NULL) {
318 eval->lsize = INIT_BUF_SIZE;
319 eval->linebuf = apr_pcalloc(eval->pool, eval->lsize);
320 }
321 if (eval->holdbuf == NULL) {
322 eval->hsize = INIT_BUF_SIZE;
323 eval->holdbuf = apr_pcalloc(eval->pool, eval->hsize);
324 }
325 if (eval->genbuf == NULL) {
326 eval->gsize = INIT_BUF_SIZE;
327 eval->genbuf = apr_pcalloc(eval->pool, eval->gsize);
328 }
329 eval->lspend = eval->linebuf;
330 eval->hspend = eval->holdbuf;
331 eval->lcomend = &eval->genbuf[71];
332
333 for (i = 0; i < sizeof(eval->abuf) / sizeof(eval->abuf[0]); i++)
334 eval->abuf[i] = NULL;
335 eval->aptr = eval->abuf;
336 eval->pending = NULL;
337 eval->inar = apr_pcalloc(eval->pool, commands->nrep * sizeof(unsigned char));
338 eval->nrep = commands->nrep;
339
340 eval->dolflag = 0;
341 eval->sflag = 0;
342 eval->jflag = 0;
343 eval->delflag = 0;
344 eval->lreadyflag = 0;
345 eval->quitflag = 0;
346 eval->finalflag = 1; /* assume we're evaluating only one file/stream */
347 eval->numpass = 0;
348 eval->nullmatch = 0;
349 eval->col = 0;
350
351 for (i = 0; i < commands->nfiles; i++) {
352 const char* filename = commands->fname[i];
353 if (apr_file_open(&eval->fcode[i], filename,
355 eval->pool) != APR_SUCCESS) {
357 return APR_EGENERAL;
358 }
359 }
360
361 return APR_SUCCESS;
362}
363
364/*
365 * sed_destroy_eval
366 */
368{
369 int i;
370 /* eval->linebuf, eval->holdbuf, eval->genbuf and eval->inar are allocated
371 * on pool. It will be freed when pool will be freed */
372 for (i = 0; i < eval->commands->nfiles; i++) {
373 if (eval->fcode[i] != NULL) {
374 apr_file_close(eval->fcode[i]);
375 eval->fcode[i] = NULL;
376 }
377 }
378}
379
380/*
381 * sed_eval_file
382 */
384{
385 for (;;) {
386 char buf[1024];
388
389 read_bytes = sizeof(buf);
391 break;
392
393 if (sed_eval_buffer(eval, buf, read_bytes, fout) != APR_SUCCESS)
394 return APR_EGENERAL;
395
396 if (eval->quitflag)
397 return APR_SUCCESS;
398 }
399
400 return sed_finalize_eval(eval, fout);
401}
402
403/*
404 * sed_eval_buffer
405 */
406apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz, void *fout)
407{
408 apr_status_t rv;
409
410 if (eval->quitflag)
411 return APR_SUCCESS;
412
413 if (!sed_canbe_finalized(eval->commands)) {
414 /* Commands were not finalized properly. */
415 const char* error = sed_get_finalize_error(eval->commands, eval->pool);
416 if (error) {
417 eval_errf(eval, error);
418 return APR_EGENERAL;
419 }
420 }
421
422 eval->fout = fout;
423
424 /* Process leftovers */
425 if (bufsz && eval->lreadyflag) {
426 eval->lreadyflag = 0;
427 eval->lspend--;
428 *eval->lspend = '\0';
429 rv = execute(eval);
430 if (rv != APR_SUCCESS)
431 return rv;
432 }
433
434 while (bufsz) {
435 apr_status_t rc = 0;
436 char *n;
438
439 n = memchr(buf, '\n', bufsz);
440 if (n == NULL)
441 break;
442
443 llen = n - buf;
444 if (llen == bufsz - 1) {
445 /* This might be the last line; delay its processing */
446 eval->lreadyflag = 1;
447 break;
448 }
449
450 rc = appendmem_to_linebuf(eval, buf, llen + 1);
451 if (rc != APR_SUCCESS) {
452 return rc;
453 }
454 --eval->lspend;
455 /* replace new line character with NULL */
456 *eval->lspend = '\0';
457 buf += (llen + 1);
458 bufsz -= (llen + 1);
459 rv = execute(eval);
460 if (rv != APR_SUCCESS)
461 return rv;
462 if (eval->quitflag)
463 break;
464 }
465
466 /* Save the leftovers for later */
467 if (bufsz) {
468 apr_status_t rc = appendmem_to_linebuf(eval, buf, bufsz);
469 if (rc != APR_SUCCESS) {
470 return rc;
471 }
472 }
473
474 return APR_SUCCESS;
475}
476
477/*
478 * sed_finalize_eval
479 */
481{
482 if (eval->quitflag)
483 return APR_SUCCESS;
484
485 if (eval->finalflag)
486 eval->dolflag = 1;
487
488 eval->fout = fout;
489
490 /* Process leftovers */
491 if (eval->lspend > eval->linebuf) {
492 apr_status_t rv;
493 apr_status_t rc = 0;
494
495 if (eval->lreadyflag) {
496 eval->lreadyflag = 0;
497 eval->lspend--;
498 } else {
499 /* Code can probably reach here when last character in output
500 * buffer is not a newline.
501 */
502 /* Assure space for NULL */
503 rc = append_to_linebuf(eval, "", NULL);
504 if (rc != APR_SUCCESS) {
505 return rc;
506 }
507 }
508
509 *eval->lspend = '\0';
510 rv = execute(eval);
511 if (rv != APR_SUCCESS)
512 return rv;
513 }
514
515 eval->quitflag = 1;
516
517 return APR_SUCCESS;
518}
519
520/*
521 * execute
522 */
524{
528
529 eval->lnum++;
530
531 eval->sflag = 0;
532
533 if (eval->pending) {
534 ipc = eval->pending;
535 eval->pending = NULL;
536 }
537
538 memset(&step_vars, 0, sizeof(step_vars));
539
540 while (ipc->command) {
541 char *p1;
542 char *p2;
543 int c;
544
545 p1 = ipc->ad1;
546 p2 = ipc->ad2;
547
548 if (p1) {
549
550 if (eval->inar[ipc->nrep]) {
551 if (*p2 == CEND) {
552 p1 = 0;
553 } else if (*p2 == CLNUM) {
554 c = (unsigned char)p2[1];
555 if (eval->lnum > eval->commands->tlno[c]) {
556 eval->inar[ipc->nrep] = 0;
557 if (ipc->negfl)
558 goto yes;
559 ipc = ipc->next;
560 continue;
561 }
562 if (eval->lnum == eval->commands->tlno[c]) {
563 eval->inar[ipc->nrep] = 0;
564 }
565 } else if (match(eval, p2, 0, &step_vars)) {
566 eval->inar[ipc->nrep] = 0;
567 }
568 } else if (*p1 == CEND) {
569 if (!eval->dolflag) {
570 if (ipc->negfl)
571 goto yes;
572 ipc = ipc->next;
573 continue;
574 }
575 } else if (*p1 == CLNUM) {
576 c = (unsigned char)p1[1];
577 if (eval->lnum != eval->commands->tlno[c]) {
578 if (ipc->negfl)
579 goto yes;
580 ipc = ipc->next;
581 continue;
582 }
583 if (p2)
584 eval->inar[ipc->nrep] = 1;
585 } else if (match(eval, p1, 0, &step_vars)) {
586 if (p2)
587 eval->inar[ipc->nrep] = 1;
588 } else {
589 if (ipc->negfl)
590 goto yes;
591 ipc = ipc->next;
592 continue;
593 }
594 }
595
596 if (ipc->negfl) {
597 ipc = ipc->next;
598 continue;
599 }
600
601yes:
602 rv = command(eval, ipc, &step_vars);
603 if (rv != APR_SUCCESS)
604 return rv;
605
606 if (eval->quitflag)
607 return APR_SUCCESS;
608
609 if (eval->pending)
610 return APR_SUCCESS;
611
612 if (eval->delflag)
613 break;
614
615 if (eval->jflag) {
616 eval->jflag = 0;
617 if ((ipc = ipc->lb1) == 0) {
618 ipc = eval->commands->ptrspace;
619 break;
620 }
621 } else
622 ipc = ipc->next;
623 }
624
625 if (!eval->commands->nflag && !eval->delflag) {
626 rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
627 if (rv != APR_SUCCESS)
628 return rv;
629 }
630
631 if (eval->aptr > eval->abuf)
632 rv = arout(eval);
633
634 eval->delflag = 0;
635
636 eval->lspend = eval->linebuf;
637
638 return rv;
639}
640
641/*
642 * match
643 */
644static int match(sed_eval_t *eval, char *expbuf, int gf,
646{
647 char *p1;
648 int circf;
649
650 if (gf) {
651 if (*expbuf) return(0);
652 step_vars->locs = p1 = step_vars->loc2;
653 } else {
654 p1 = eval->linebuf;
655 step_vars->locs = 0;
656 }
657
658 circf = *expbuf++;
659 return(sed_step(p1, expbuf, circf, step_vars));
660}
661
662/*
663 * substitute
664 */
667{
668 if (match(eval, ipc->re1, 0, step_vars) == 0) return(0);
669
670 eval->numpass = 0;
671 eval->sflag = 0; /* Flags if any substitution was made */
672 if (dosub(eval, ipc->rhs, ipc->gfl, step_vars) != APR_SUCCESS)
673 return -1;
674
675 if (ipc->gfl) {
676 while (*step_vars->loc2) {
677 if (match(eval, ipc->re1, 1, step_vars) == 0) break;
678 if (dosub(eval, ipc->rhs, ipc->gfl, step_vars) != APR_SUCCESS)
679 return -1;
680 }
681 }
682 return(eval->sflag);
683}
684
685/*
686 * dosub
687 */
688static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
690{
691 char *lp, *sp, *rp;
692 int c;
694
695 if (n > 0 && n < 999) {
696 eval->numpass++;
697 if (n != eval->numpass) return APR_SUCCESS;
698 }
699 eval->sflag = 1;
700 lp = eval->linebuf;
701 sp = eval->genbuf;
702 rp = rhsbuf;
703 sp = place(eval, sp, lp, step_vars->loc1);
704 if (sp == NULL) {
705 return APR_EGENERAL;
706 }
707 while ((c = *rp++) != 0) {
708 if (c == '&') {
709 sp = place(eval, sp, step_vars->loc1, step_vars->loc2);
710 if (sp == NULL) {
711 return APR_EGENERAL;
712 }
713 }
714 else if (c == '\\') {
715 c = *rp++;
716 if (c >= '1' && c < NBRA+'1') {
717 sp = place(eval, sp, step_vars->braslist[c-'1'],
718 step_vars->braelist[c-'1']);
719 if (sp == NULL)
720 return APR_EGENERAL;
721 }
722 else
723 *sp++ = c;
724 } else
725 *sp++ = c;
726 if (sp >= eval->genbuf + eval->gsize) {
727 /* expand genbuf and set the sp appropriately */
728 rv = grow_gen_buffer(eval, eval->gsize + 1024, &sp);
729 if (rv != APR_SUCCESS) {
730 return rv;
731 }
732 }
733 }
734 lp = step_vars->loc2;
735 step_vars->loc2 = sp - eval->genbuf + eval->linebuf;
736 rv = append_to_genbuf(eval, lp, &sp);
737 if (rv != APR_SUCCESS) {
738 return rv;
739 }
740 rv = copy_to_linebuf(eval, eval->genbuf, step_vars);
741 return rv;
742}
743
744/*
745 * place
746 */
747static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2)
748{
749 char *sp = asp;
750 apr_size_t n = al2 - al1;
751 apr_size_t reqsize = (sp - eval->genbuf) + n + 1;
752
753 if (eval->gsize < reqsize) {
755 if (rc != APR_SUCCESS) {
756 return NULL;
757 }
758 }
759 memcpy(sp, al1, n);
760 return sp + n;
761}
762
763/*
764 * command
765 */
768{
769 int i;
770 char *p1, *p2;
771 const char *p3;
772 int length;
773 char sz[32]; /* 32 bytes enough to store 64 bit integer in decimal */
775
776
777 switch(ipc->command) {
778
779 case ACOM:
780 if (eval->aptr >= &eval->abuf[SED_ABUFSIZE]) {
781 eval_errf(eval, SEDERR_TMAMES, eval->lnum);
782 } else {
783 *eval->aptr++ = ipc;
784 *eval->aptr = NULL;
785 }
786 break;
787
788 case CCOM:
789 eval->delflag = 1;
790 if (!eval->inar[ipc->nrep] || eval->dolflag) {
791 for (p1 = ipc->re1; *p1; p1++)
792 ;
793 rv = wline(eval, ipc->re1, p1 - ipc->re1);
794 }
795 break;
796
797 case DCOM:
798 eval->delflag++;
799 break;
800
801 case CDCOM:
802 p1 = eval->linebuf;
803
804 while (*p1 != '\n') {
805 if (*p1++ == 0) {
806 eval->delflag++;
807 return APR_SUCCESS;
808 }
809 }
810
811 p1++;
812 rv = copy_to_linebuf(eval, p1, step_vars);
813 if (rv != APR_SUCCESS) return rv;
814 eval->jflag++;
815 break;
816
817 case EQCOM:
818 length = apr_snprintf(sz, sizeof(sz), "%d", (int) eval->lnum);
819 rv = wline(eval, sz, length);
820 break;
821
822 case GCOM:
823 rv = copy_to_linebuf(eval, eval->holdbuf, step_vars);
824 if (rv != APR_SUCCESS) return rv;
825 break;
826
827 case CGCOM:
828 rv = append_to_linebuf(eval, "\n", step_vars);
829 if (rv != APR_SUCCESS) return rv;
830 rv = append_to_linebuf(eval, eval->holdbuf, step_vars);
831 if (rv != APR_SUCCESS) return rv;
832 break;
833
834 case HCOM:
835 rv = copy_to_holdbuf(eval, eval->linebuf);
836 if (rv != APR_SUCCESS) return rv;
837 break;
838
839 case CHCOM:
840 rv = append_to_holdbuf(eval, "\n");
841 if (rv != APR_SUCCESS) return rv;
842 rv = append_to_holdbuf(eval, eval->linebuf);
843 if (rv != APR_SUCCESS) return rv;
844 break;
845
846 case ICOM:
847 for (p1 = ipc->re1; *p1; p1++);
848 rv = wline(eval, ipc->re1, p1 - ipc->re1);
849 break;
850
851 case BCOM:
852 eval->jflag = 1;
853 break;
854
855 case LCOM:
856 p1 = eval->linebuf;
857 p2 = eval->genbuf;
858 eval->genbuf[72] = 0;
859 while (*p1) {
860 if ((unsigned char)*p1 >= 040) {
861 if (*p1 == 0177) {
862 p3 = rub;
863 while ((*p2++ = *p3++) != 0)
864 if (p2 >= eval->lcomend) {
865 *p2 = '\\';
866 rv = wline(eval, eval->genbuf,
867 strlen(eval->genbuf));
868 if (rv != APR_SUCCESS)
869 return rv;
870 p2 = eval->genbuf;
871 }
872 p2--;
873 p1++;
874 continue;
875 }
876 if (!isprint(*p1 & 0377)) {
877 *p2++ = '\\';
878 if (p2 >= eval->lcomend) {
879 *p2 = '\\';
880 rv = wline(eval, eval->genbuf,
881 strlen(eval->genbuf));
882 if (rv != APR_SUCCESS)
883 return rv;
884 p2 = eval->genbuf;
885 }
886 *p2++ = (*p1 >> 6) + '0';
887 if (p2 >= eval->lcomend) {
888 *p2 = '\\';
889 rv = wline(eval, eval->genbuf,
890 strlen(eval->genbuf));
891 if (rv != APR_SUCCESS)
892 return rv;
893 p2 = eval->genbuf;
894 }
895 *p2++ = ((*p1 >> 3) & 07) + '0';
896 if (p2 >= eval->lcomend) {
897 *p2 = '\\';
898 rv = wline(eval, eval->genbuf,
899 strlen(eval->genbuf));
900 if (rv != APR_SUCCESS)
901 return rv;
902 p2 = eval->genbuf;
903 }
904 *p2++ = (*p1++ & 07) + '0';
905 if (p2 >= eval->lcomend) {
906 *p2 = '\\';
907 rv = wline(eval, eval->genbuf,
908 strlen(eval->genbuf));
909 if (rv != APR_SUCCESS)
910 return rv;
911 p2 = eval->genbuf;
912 }
913 } else {
914 *p2++ = *p1++;
915 if (p2 >= eval->lcomend) {
916 *p2 = '\\';
917 rv = wline(eval, eval->genbuf,
918 strlen(eval->genbuf));
919 if (rv != APR_SUCCESS)
920 return rv;
921 p2 = eval->genbuf;
922 }
923 }
924 } else {
925 p3 = trans[(unsigned char)*p1-1];
926 while ((*p2++ = *p3++) != 0)
927 if (p2 >= eval->lcomend) {
928 *p2 = '\\';
929 rv = wline(eval, eval->genbuf,
930 strlen(eval->genbuf));
931 if (rv != APR_SUCCESS)
932 return rv;
933 p2 = eval->genbuf;
934 }
935 p2--;
936 p1++;
937 }
938 }
939 *p2 = 0;
940 rv = wline(eval, eval->genbuf, strlen(eval->genbuf));
941 break;
942
943 case NCOM:
944 if (!eval->commands->nflag) {
945 rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
946 if (rv != APR_SUCCESS)
947 return rv;
948 }
949
950 if (eval->aptr > eval->abuf) {
951 rv = arout(eval);
952 if (rv != APR_SUCCESS)
953 return rv;
954 }
955 eval->lspend = eval->linebuf;
956 eval->pending = ipc->next;
957 break;
958
959 case CNCOM:
960 if (eval->aptr > eval->abuf) {
961 rv = arout(eval);
962 if (rv != APR_SUCCESS)
963 return rv;
964 }
965 rv = append_to_linebuf(eval, "\n", step_vars);
966 if (rv != APR_SUCCESS) return rv;
967 eval->pending = ipc->next;
968 break;
969
970 case PCOM:
971 rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
972 break;
973
974 case CPCOM:
975 for (p1 = eval->linebuf; *p1 != '\n' && *p1 != '\0'; p1++);
976 rv = wline(eval, eval->linebuf, p1 - eval->linebuf);
977 break;
978
979 case QCOM:
980 if (!eval->commands->nflag) {
981 rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
982 if (rv != APR_SUCCESS)
983 break;
984 }
985
986 if (eval->aptr > eval->abuf) {
987 rv = arout(eval);
988 if (rv != APR_SUCCESS)
989 return rv;
990 }
991
992 eval->quitflag = 1;
993 break;
994
995 case RCOM:
996 if (eval->aptr >= &eval->abuf[SED_ABUFSIZE]) {
997 eval_errf(eval, SEDERR_TMRMES, eval->lnum);
998 } else {
999 *eval->aptr++ = ipc;
1000 *eval->aptr = NULL;
1001 }
1002 break;
1003
1004 case SCOM:
1005 i = substitute(eval, ipc, step_vars);
1006 if (i == -1) {
1007 return APR_EGENERAL;
1008 }
1009 if (ipc->pfl && eval->commands->nflag && i) {
1010 if (ipc->pfl == 1) {
1011 rv = wline(eval, eval->linebuf, eval->lspend -
1012 eval->linebuf);
1013 if (rv != APR_SUCCESS)
1014 return rv;
1015 } else {
1016 for (p1 = eval->linebuf; *p1 != '\n' && *p1 != '\0'; p1++);
1017 rv = wline(eval, eval->linebuf, p1 - eval->linebuf);
1018 if (rv != APR_SUCCESS)
1019 return rv;
1020 }
1021 }
1022 if (i && (ipc->findex >= 0) && eval->fcode[ipc->findex])
1023 apr_file_printf(eval->fcode[ipc->findex], "%s\n",
1024 eval->linebuf);
1025 break;
1026
1027 case TCOM:
1028 if (eval->sflag == 0) break;
1029 eval->sflag = 0;
1030 eval->jflag = 1;
1031 break;
1032
1033 case WCOM:
1034 if (ipc->findex >= 0)
1035 apr_file_printf(eval->fcode[ipc->findex], "%s\n",
1036 eval->linebuf);
1037 break;
1038
1039 case XCOM:
1040 rv = copy_to_genbuf(eval, eval->linebuf);
1041 if (rv != APR_SUCCESS) return rv;
1042 rv = copy_to_linebuf(eval, eval->holdbuf, step_vars);
1043 if (rv != APR_SUCCESS) return rv;
1044 rv = copy_to_holdbuf(eval, eval->genbuf);
1045 if (rv != APR_SUCCESS) return rv;
1046 break;
1047
1048 case YCOM:
1049 p1 = eval->linebuf;
1050 p2 = ipc->re1;
1051 while ((*p1 = p2[(unsigned char)*p1]) != 0) p1++;
1052 break;
1053 }
1054 return rv;
1055}
1056
1057/*
1058 * arout
1059 */
1061{
1063 eval->aptr = eval->abuf - 1;
1064 while (*++eval->aptr) {
1065 if ((*eval->aptr)->command == ACOM) {
1066 char *p1;
1067
1068 for (p1 = (*eval->aptr)->re1; *p1; p1++);
1069 rv = wline(eval, (*eval->aptr)->re1, p1 - (*eval->aptr)->re1);
1070 if (rv != APR_SUCCESS)
1071 return rv;
1072 } else {
1073 apr_file_t *fi = NULL;
1074 char buf[512];
1075 apr_size_t n = sizeof(buf);
1076
1077 if (apr_file_open(&fi, (*eval->aptr)->re1, APR_READ, 0, eval->pool)
1078 != APR_SUCCESS)
1079 continue;
1080 while ((apr_file_read(fi, buf, &n)) == APR_SUCCESS) {
1081 if (n == 0)
1082 break;
1083 rv = eval->writefn(eval->fout, buf, n);
1084 if (rv != APR_SUCCESS) {
1086 return rv;
1087 }
1088 n = sizeof(buf);
1089 }
1091 }
1092 }
1093 eval->aptr = eval->abuf;
1094 *eval->aptr = NULL;
1095 return rv;
1096}
1097
1098/*
1099 * wline
1100 */
1102{
1104 rv = eval->writefn(eval->fout, buf, sz);
1105 if (rv != APR_SUCCESS)
1106 return rv;
1107 rv = eval->writefn(eval->fout, "\n", 1);
1108 return rv;
1109}
1110
int n
Definition ap_regex.h:278
int int const char ** match
Definition ap_regex.h:279
const char apr_size_t len
Definition ap_regex.h:187
APR general purpose library routines.
APR Strings library.
const unsigned char * buf
Definition util_md5.h:50
#define APR_EGENERAL
Definition apr_errno.h:313
#define APR_ENOMEM
Definition apr_errno.h:683
int apr_off_t * length
apr_pool_t const char apr_dbd_t const char ** error
Definition apr_dbd.h:143
apr_redis_t * rc
Definition apr_redis.h:173
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
char * buffer
#define APR_READ
Definition apr_file_io.h:93
#define APR_WRITE
Definition apr_file_io.h:94
#define APR_CREATE
Definition apr_file_io.h:95
#define APR_OS_DEFAULT
void * memchr(const void *s, int c, size_t n)
apr_vformatter_buff_t const char * fmt
Definition apr_lib.h:175
apr_vformatter_buff_t * c
Definition apr_lib.h:175
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
apr_size_t const char * filename
Definition apr_shm.h:72
apr_size_t reqsize
Definition apr_shm.h:71
apr_child_errfn_t * errfn
const char const char *const * args
apr_status_t() sed_err_fn_t(void *data, const char *error)
Definition libsed.h:62
char * sed_get_finalize_error(const sed_commands_t *commands, apr_pool_t *pool)
Definition sed0.c:127
int sed_canbe_finalized(const sed_commands_t *commands)
Definition sed0.c:152
#define SED_ABUFSIZE
Definition libsed.h:35
apr_status_t() sed_write_fn_t(void *ctx, char *buf, apr_size_t sz)
Definition libsed.h:63
apr_pool_t * p
Definition md_event.c:32
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
#define NBRA
Definition regexp.h:52
#define SEDERR_TMRMES
Definition regexp.h:97
#define SEDERR_TMAMES
Definition regexp.h:96
#define SEDERR_COMES
Definition regexp.h:93
static const char *const trans[040]
Definition sed1.c:28
static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n, step_vars_storage *step_vars)
Definition sed1.c:688
static apr_status_t wline(sed_eval_t *eval, char *buf, apr_size_t sz)
Definition sed1.c:1101
apr_status_t sed_init_eval(sed_eval_t *eval, sed_commands_t *commands, sed_err_fn_t *errfn, void *data, sed_write_fn_t *writefn, apr_pool_t *p)
Definition sed1.c:294
void sed_destroy_eval(sed_eval_t *eval)
Definition sed1.c:367
static int substitute(sed_eval_t *eval, sed_reptr_t *ipc, step_vars_storage *step_vars)
Definition sed1.c:665
static apr_status_t append_to_holdbuf(sed_eval_t *eval, const char *sz)
Definition sed1.c:227
static apr_status_t append_to_linebuf(sed_eval_t *eval, const char *sz, step_vars_storage *step_vars)
Definition sed1.c:187
static apr_status_t append_to_genbuf(sed_eval_t *eval, const char *sz, char **gspend)
Definition sed1.c:256
static apr_status_t appendmem_to_linebuf(sed_eval_t *eval, const char *sz, apr_size_t len)
Definition sed1.c:169
static const char rub[]
Definition sed1.c:61
#define INIT_BUF_SIZE
Definition sed1.c:89
#define MAX_BUF_SIZE
Definition sed1.c:90
static apr_status_t grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize, char **gspend)
Definition sed1.c:151
apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout)
Definition sed1.c:480
static apr_status_t grow_line_buffer(sed_eval_t *eval, apr_size_t newsize)
Definition sed1.c:133
apr_status_t sed_reset_eval(sed_eval_t *eval, sed_commands_t *commands, sed_err_fn_t *errfn, void *data)
Definition sed1.c:305
apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz, void *fout)
Definition sed1.c:406
static apr_status_t copy_to_genbuf(sed_eval_t *eval, const char *sz)
Definition sed1.c:276
int sed_step(char *p1, char *p2, int circf, step_vars_storage *vars)
Definition regexp.c:358
static apr_status_t grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize)
Definition sed1.c:142
static char * place(sed_eval_t *eval, char *asp, char *al1, char *al2)
Definition sed1.c:747
static apr_status_t copy_to_holdbuf(sed_eval_t *eval, const char *sz)
Definition sed1.c:247
static apr_status_t grow_buffer(apr_pool_t *pool, char **buffer, char **spend, apr_size_t *cursize, apr_size_t newsize)
Definition sed1.c:95
static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, step_vars_storage *step_vars)
Definition sed1.c:766
static apr_status_t copy_to_linebuf(sed_eval_t *eval, const char *sz, step_vars_storage *step_vars)
Definition sed1.c:217
static apr_status_t execute(sed_eval_t *eval)
Definition sed1.c:523
static apr_status_t arout(sed_eval_t *eval)
Definition sed1.c:1060
static void eval_errf(sed_eval_t *eval, const char *fmt,...)
Definition sed1.c:77
apr_status_t sed_eval_file(sed_eval_t *eval, apr_file_t *fin, void *fout)
Definition sed1.c:383
#define CLNUM
Definition sed.h:28
#define YCOM
Definition sed.h:58
#define CNCOM
Definition sed.h:37
#define QCOM
Definition sed.h:52
#define CEND
Definition sed.h:27
#define WCOM
Definition sed.h:56
#define RCOM
Definition sed.h:53
#define HCOM
Definition sed.h:46
#define CDCOM
Definition sed.h:36
#define BCOM
Definition sed.h:34
#define CPCOM
Definition sed.h:39
#define TCOM
Definition sed.h:55
#define SCOM
Definition sed.h:54
#define EQCOM
Definition sed.h:42
#define CHCOM
Definition sed.h:47
#define NCOM
Definition sed.h:50
#define XCOM
Definition sed.h:59
#define LCOM
Definition sed.h:49
#define CCOM
Definition sed.h:35
#define DCOM
Definition sed.h:40
#define CGCOM
Definition sed.h:45
#define PCOM
Definition sed.h:51
#define ICOM
Definition sed.h:48
#define GCOM
Definition sed.h:44
#define ACOM
Definition sed.h:33
apr_int64_t tlno[256]
Definition libsed.h:86
char * fname[11]
Definition libsed.h:90
sed_reptr_t * ptrspace
Definition libsed.h:99
apr_pool_t * pool
Definition libsed.h:148
sed_reptr_t * abuf[20]
Definition libsed.h:132
apr_size_t lsize
Definition libsed.h:119
sed_write_fn_t * writefn
Definition libsed.h:111
char * linebuf
Definition libsed.h:120
int nullmatch
Definition libsed.h:146
void * fout
Definition libsed.h:117
int numpass
Definition libsed.h:145
apr_int64_t lnum
Definition libsed.h:116
unsigned char * inar
Definition libsed.h:135
int jflag
Definition libsed.h:140
int dolflag
Definition libsed.h:138
sed_reptr_t * pending
Definition libsed.h:134
void * data
Definition libsed.h:112
int lreadyflag
Definition libsed.h:142
int nrep
Definition libsed.h:136
sed_commands_t * commands
Definition libsed.h:114
int delflag
Definition libsed.h:141
char * lcomend
Definition libsed.h:129
sed_reptr_t ** aptr
Definition libsed.h:133
sed_err_fn_t * errfn
Definition libsed.h:110
int col
Definition libsed.h:147
char * holdbuf
Definition libsed.h:124
apr_size_t hsize
Definition libsed.h:123
char * genbuf
Definition libsed.h:128
char * lspend
Definition libsed.h:121
int quitflag
Definition libsed.h:143
int finalflag
Definition libsed.h:144
int sflag
Definition libsed.h:139
apr_size_t gsize
Definition libsed.h:127
char * hspend
Definition libsed.h:125
apr_file_t * fcode[11]
Definition libsed.h:131
sed_reptr_t * next
Definition libsed.h:40