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_strings.h" 23#include "libsed.h" 24#include "sed.h" 25#include "regexp.h" 26 27#define CCEOF 22 28 29static int fcomp(sed_commands_t *commands, apr_file_t *fin); 30static char *compsub(sed_commands_t *commands, 31 sed_comp_args *compargs, char *rhsbuf); 32static int rline(sed_commands_t *commands, apr_file_t *fin, 33 char *lbuf, char *lbend); 34static char *address(sed_commands_t *commands, char *expbuf, 35 apr_status_t* status); 36static char *text(sed_commands_t *commands, char *textbuf, char *endbuf); 37static sed_label_t *search(sed_commands_t *commands); 38static char *ycomp(sed_commands_t *commands, char *expbuf); 39static char *comple(sed_commands_t *commands, sed_comp_args *compargs, 40 char *x1, char *ep, char *x3, char x4); 41static sed_reptr_t *alloc_reptr(sed_commands_t *commands); 42static int check_finalized(const sed_commands_t *commands); 43 44void command_errf(sed_commands_t *commands, const char *fmt, ...) 45{ 46 if (commands->errfn && commands->pool) { 47 va_list args; 48 const char* error; 49 va_start(args, fmt); 50 error = apr_pvsprintf(commands->pool, fmt, args); 51 commands->errfn(commands->data, error); 52 va_end(args); 53 } 54} 55 56/* 57 * sed_init_commands 58 */ 59apr_status_t sed_init_commands(sed_commands_t *commands, sed_err_fn_t *errfn, void *data, 60 apr_pool_t *p) 61{ 62 memset(commands, 0, sizeof(*commands)); 63 64 commands->errfn = errfn; 65 commands->data = data; 66 67 commands->labtab = commands->ltab; 68 commands->lab = commands->labtab + 1; 69 commands->pool = p; 70 71 commands->respace = apr_pcalloc(p, RESIZE); 72 if (commands->respace == NULL) { 73 command_errf(commands, SEDERR_OOMMES); 74 return APR_EGENERAL; 75 } 76 77 commands->rep = alloc_reptr(commands); 78 if (commands->rep == NULL) 79 return APR_EGENERAL; 80 81 commands->rep->ad1 = commands->respace; 82 commands->reend = &commands->respace[RESIZE - 1]; 83 commands->labend = &commands->labtab[SED_LABSIZE]; 84 commands->canbefinal = 1; 85 86 return APR_SUCCESS; 87} 88 89/* 90 * sed_destroy_commands 91 */ 92void sed_destroy_commands(sed_commands_t *commands) 93{ 94} 95 96/* 97 * sed_compile_string 98 */ 99apr_status_t sed_compile_string(sed_commands_t *commands, const char *s) 100{ 101 apr_status_t rv; 102 103 commands->earg = s; 104 commands->eflag = 1; 105 106 rv = fcomp(commands, NULL); 107 if (rv == APR_SUCCESS) 108 commands->canbefinal = check_finalized(commands); 109 110 commands->eflag = 0; 111 112 return (rv != 0 ? APR_EGENERAL : APR_SUCCESS); 113} 114 115/* 116 * sed_compile_file 117 */ 118apr_status_t sed_compile_file(sed_commands_t *commands, apr_file_t *fin) 119{ 120 apr_status_t rv = fcomp(commands, fin); 121 return (rv != 0 ? APR_EGENERAL : APR_SUCCESS); 122} 123 124/* 125 * sed_get_finalize_error 126 */ 127char* sed_get_finalize_error(const sed_commands_t *commands, apr_pool_t* pool) 128{ 129 const sed_label_t *lab; 130 if (commands->depth) { 131 return SEDERR_TMOMES; 132 } 133 134 /* Empty branch chain is not a issue */ 135 for (lab = commands->labtab + 1; lab < commands->lab; lab++) { 136 char *error; 137 if (lab->address == 0) { 138 error = apr_psprintf(pool, SEDERR_ULMES, lab->asc); 139 return error; 140 } 141 142 if (lab->chain) { 143 return SEDERR_INTERNAL; 144 } 145 } 146 return NULL; 147} 148 149/* 150 * sed_canbe_finalized 151 */ 152int sed_canbe_finalized(const sed_commands_t *commands) 153{ 154 return commands->canbefinal; 155} 156 157/* 158 * check_finalized 159 */ 160static int check_finalized(const sed_commands_t *commands) 161{ 162 const sed_label_t *lab; 163 if (commands->depth) { 164 return 0; 165 } 166 167 /* Empty branch chain is not a issue */ 168 for (lab = commands->labtab + 1; lab < commands->lab; lab++) { 169 if (lab->address == 0 || (lab->chain)) { 170 return 0; 171 } 172 } 173 return 1; 174} 175 176/* 177 * dechain 178 */ 179static void dechain(sed_label_t *lpt, sed_reptr_t *address) 180{ 181 sed_reptr_t *rep; 182 if ((lpt == NULL) || (lpt->chain == NULL) || (address == NULL)) 183 return; 184 rep = lpt->chain; 185 while (rep->lb1) { 186 sed_reptr_t *next; 187 188 next = rep->lb1; 189 rep->lb1 = address; 190 rep = next; 191 } 192 rep->lb1 = address; 193 lpt->chain = NULL; 194} 195 196/* 197 * fcomp 198 */ 199static int fcomp(sed_commands_t *commands, apr_file_t *fin) 200{ 201 char *p, *op, *tp; 202 sed_reptr_t *pt, *pt1; 203 int i, ii; 204 sed_label_t *lpt; 205 char fnamebuf[APR_PATH_MAX]; 206 apr_status_t status; 207 sed_comp_args compargs; 208 209 op = commands->lastre; 210 if (!commands->linebuf) { 211 commands->linebuf = apr_pcalloc(commands->pool, LBSIZE + 1); 212 } 213 214 if (rline(commands, fin, commands->linebuf, 215 (commands->linebuf + LBSIZE + 1)) < 0) 216 return 0; 217 if (*commands->linebuf == '#') { 218 if (commands->linebuf[1] == 'n') 219 commands->nflag = 1; 220 } 221 else { 222 commands->cp = commands->linebuf; 223 goto comploop; 224 } 225 226 for (;;) { 227 if (rline(commands, fin, commands->linebuf, 228 (commands->linebuf + LBSIZE + 1)) < 0) 229 break; 230 231 commands->cp = commands->linebuf; 232 233comploop: 234 while (*commands->cp == ' ' || *commands->cp == '\t') 235 commands->cp++; 236 if (*commands->cp == '\0' || *commands->cp == '#') 237 continue; 238 if (*commands->cp == ';') { 239 commands->cp++; 240 goto comploop; 241 } 242 243 p = address(commands, commands->rep->ad1, &status); 244 if (status != APR_SUCCESS) { 245 command_errf(commands, SEDERR_CGMES, commands->linebuf); 246 return -1; 247 } 248 249 if (p == commands->rep->ad1) { 250 if (op) 251 commands->rep->ad1 = op; 252 else { 253 command_errf(commands, SEDERR_NRMES); 254 return -1; 255 } 256 } else if (p == 0) { 257 p = commands->rep->ad1; 258 commands->rep->ad1 = 0; 259 } else { 260 op = commands->rep->ad1; 261 if (*commands->cp == ',' || *commands->cp == ';') { 262 commands->cp++; 263 commands->rep->ad2 = p; 264 p = address(commands, commands->rep->ad2, &status); 265 if ((status != APR_SUCCESS) || (p == 0)) { 266 command_errf(commands, SEDERR_CGMES, commands->linebuf); 267 return -1; 268 } 269 if (p == commands->rep->ad2) 270 commands->rep->ad2 = op; 271 else 272 op = commands->rep->ad2; 273 } else 274 commands->rep->ad2 = 0; 275 } 276 277 if(p > &commands->respace[RESIZE-1]) { 278 command_errf(commands, SEDERR_TMMES, commands->linebuf); 279 return -1; 280 } 281 282 while (*commands->cp == ' ' || *commands->cp == '\t') 283 commands->cp++; 284 285swit: 286 switch(*commands->cp++) { 287 default: 288 command_errf(commands, SEDERR_UCMES, commands->linebuf); 289 return -1; 290 291 case '!': 292 commands->rep->negfl = 1; 293 goto swit; 294 295 case '{': 296 commands->rep->command = BCOM; 297 commands->rep->negfl = !(commands->rep->negfl); 298 commands->cmpend[commands->depth++] = &commands->rep->lb1; 299 commands->rep = alloc_reptr(commands); 300 commands->rep->ad1 = p; 301 if (*commands->cp == '\0') 302 continue; 303 goto comploop; 304 305 case '}': 306 if (commands->rep->ad1) { 307 command_errf(commands, SEDERR_AD0MES, commands->linebuf); 308 return -1; 309 } 310 311 if (--commands->depth < 0) { 312 command_errf(commands, SEDERR_TMCMES); 313 return -1; 314 } 315 *commands->cmpend[commands->depth] = commands->rep; 316 317 commands->rep->ad1 = p; 318 continue; 319 320 case '=': 321 commands->rep->command = EQCOM; 322 if (commands->rep->ad2) { 323 command_errf(commands, SEDERR_AD1MES, commands->linebuf); 324 return -1; 325 } 326 break; 327 328 case ':': 329 if (commands->rep->ad1) { 330 command_errf(commands, SEDERR_AD0MES, commands->linebuf); 331 return -1; 332 } 333 334 while (*commands->cp++ == ' '); 335 commands->cp--; 336 337 tp = commands->lab->asc; 338 while ((*tp++ = *commands->cp++)) { 339 if (tp >= &(commands->lab->asc[8])) { 340 command_errf(commands, SEDERR_LTLMES, commands->linebuf); 341 return -1; 342 } 343 } 344 *--tp = '\0'; 345 346 if ((lpt = search(commands)) != NULL) { 347 if (lpt->address) { 348 command_errf(commands, SEDERR_DLMES, commands->linebuf); 349 return -1; 350 } 351 dechain(lpt, commands->rep); 352 } else { 353 commands->lab->chain = 0; 354 lpt = commands->lab; 355 if (++commands->lab >= commands->labend) { 356 command_errf(commands, SEDERR_TMLMES, commands->linebuf); 357 return -1; 358 } 359 } 360 lpt->address = commands->rep; 361 commands->rep->ad1 = p; 362 363 continue; 364 365 case 'a': 366 commands->rep->command = ACOM; 367 if (commands->rep->ad2) { 368 command_errf(commands, SEDERR_AD1MES, commands->linebuf); 369 return -1; 370 } 371 if (*commands->cp == '\\') 372 commands->cp++; 373 if (*commands->cp++ != '\n') { 374 command_errf(commands, SEDERR_CGMES, commands->linebuf); 375 return -1; 376 } 377 commands->rep->re1 = p; 378 p = text(commands, commands->rep->re1, commands->reend); 379 if (p == NULL) 380 return -1; 381 break; 382 383 case 'c': 384 commands->rep->command = CCOM; 385 if (*commands->cp == '\\') commands->cp++; 386 if (*commands->cp++ != ('\n')) { 387 command_errf(commands, SEDERR_CGMES, commands->linebuf); 388 return -1; 389 } 390 commands->rep->re1 = p; 391 p = text(commands, commands->rep->re1, commands->reend); 392 if (p == NULL) 393 return -1; 394 break; 395 396 case 'i': 397 commands->rep->command = ICOM; 398 if (commands->rep->ad2) { 399 command_errf(commands, SEDERR_AD1MES, commands->linebuf); 400 return -1; 401 } 402 if (*commands->cp == '\\') commands->cp++; 403 if (*commands->cp++ != ('\n')) { 404 command_errf(commands, SEDERR_CGMES, commands->linebuf); 405 return -1; 406 } 407 commands->rep->re1 = p; 408 p = text(commands, commands->rep->re1, commands->reend); 409 if (p == NULL) 410 return -1; 411 break; 412 413 case 'g': 414 commands->rep->command = GCOM; 415 break; 416 417 case 'G': 418 commands->rep->command = CGCOM; 419 break; 420 421 case 'h': 422 commands->rep->command = HCOM; 423 break; 424 425 case 'H': 426 commands->rep->command = CHCOM; 427 break; 428 429 case 't': 430 commands->rep->command = TCOM; 431 goto jtcommon; 432 433 case 'b': 434 commands->rep->command = BCOM; 435jtcommon: 436 while (*commands->cp++ == ' '); 437 commands->cp--; 438 439 if (*commands->cp == '\0') { 440 if ((pt = commands->labtab->chain) != NULL) { 441 while ((pt1 = pt->lb1) != NULL) 442 pt = pt1; 443 pt->lb1 = commands->rep; 444 } else 445 commands->labtab->chain = commands->rep; 446 break; 447 } 448 tp = commands->lab->asc; 449 while ((*tp++ = *commands->cp++)) 450 if (tp >= &(commands->lab->asc[8])) { 451 command_errf(commands, SEDERR_LTLMES, commands->linebuf); 452 return -1; 453 } 454 commands->cp--; 455 *--tp = '\0'; 456 457 if ((lpt = search(commands)) != NULL) { 458 if (lpt->address) { 459 commands->rep->lb1 = lpt->address; 460 } else { 461 pt = lpt->chain; 462 while ((pt1 = pt->lb1) != NULL) 463 pt = pt1; 464 pt->lb1 = commands->rep; 465 } 466 } else { 467 commands->lab->chain = commands->rep; 468 commands->lab->address = 0; 469 if (++commands->lab >= commands->labend) { 470 command_errf(commands, SEDERR_TMLMES, commands->linebuf); 471 return -1; 472 } 473 } 474 break; 475 476 case 'n': 477 commands->rep->command = NCOM; 478 break; 479 480 case 'N': 481 commands->rep->command = CNCOM; 482 break; 483 484 case 'p': 485 commands->rep->command = PCOM; 486 break; 487 488 case 'P': 489 commands->rep->command = CPCOM; 490 break; 491 492 case 'r': 493 commands->rep->command = RCOM; 494 if (commands->rep->ad2) { 495 command_errf(commands, SEDERR_AD1MES, commands->linebuf); 496 return -1; 497 } 498 if (*commands->cp++ != ' ') { 499 command_errf(commands, SEDERR_CGMES, commands->linebuf); 500 return -1; 501 } 502 commands->rep->re1 = p; 503 p = text(commands, commands->rep->re1, commands->reend); 504 if (p == NULL) 505 return -1; 506 break; 507 508 case 'd': 509 commands->rep->command = DCOM; 510 break; 511 512 case 'D': 513 commands->rep->command = CDCOM; 514 commands->rep->lb1 = commands->ptrspace; 515 break; 516 517 case 'q': 518 commands->rep->command = QCOM; 519 if (commands->rep->ad2) { 520 command_errf(commands, SEDERR_AD1MES, commands->linebuf); 521 return -1; 522 } 523 break; 524 525 case 'l': 526 commands->rep->command = LCOM; 527 break; 528 529 case 's': 530 commands->rep->command = SCOM; 531 commands->sseof = *commands->cp++; 532 commands->rep->re1 = p; 533 p = comple(commands, &compargs, (char *) 0, commands->rep->re1, 534 commands->reend, commands->sseof); 535 if (p == NULL) 536 return -1; 537 if (p == commands->rep->re1) { 538 if (op) 539 commands->rep->re1 = op; 540 else { 541 command_errf(commands, SEDERR_NRMES); 542 return -1; 543 } 544 } else 545 op = commands->rep->re1; 546 commands->rep->rhs = p; 547 548 p = compsub(commands, &compargs, commands->rep->rhs); 549 if ((p) == NULL) 550 return -1; 551 552 if (*commands->cp == 'g') { 553 commands->cp++; 554 commands->rep->gfl = 999; 555 } else if (commands->gflag) 556 commands->rep->gfl = 999; 557 558 if (*commands->cp >= '1' && *commands->cp <= '9') { 559 i = *commands->cp - '0'; 560 commands->cp++; 561 while (1) { 562 ii = *commands->cp; 563 if (ii < '0' || ii > '9') 564 break; 565 i = i*10 + ii - '0'; 566 if (i > 512) { 567 command_errf(commands, SEDERR_TOOBIG, commands->linebuf); 568 return -1; 569 } 570 commands->cp++; 571 } 572 commands->rep->gfl = i; 573 } 574 575 if (*commands->cp == 'p') { 576 commands->cp++; 577 commands->rep->pfl = 1; 578 } 579 580 if (*commands->cp == 'P') { 581 commands->cp++; 582 commands->rep->pfl = 2; 583 } 584 585 if (*commands->cp == 'w') { 586 commands->cp++; 587 if (*commands->cp++ != ' ') { 588 command_errf(commands, SEDERR_SMMES, commands->linebuf); 589 return -1; 590 } 591 if (text(commands, fnamebuf, &fnamebuf[APR_PATH_MAX]) == NULL) { 592 command_errf(commands, SEDERR_FNTL, commands->linebuf); 593 return -1; 594 } 595 for (i = commands->nfiles - 1; i >= 0; i--) 596 if (strcmp(fnamebuf,commands->fname[i]) == 0) { 597 commands->rep->findex = i; 598 goto done; 599 } 600 if (commands->nfiles >= NWFILES) { 601 command_errf(commands, SEDERR_TMWFMES); 602 return -1; 603 } 604 commands->fname[commands->nfiles] = 605 apr_pstrdup(commands->pool, fnamebuf); 606 if (commands->fname[commands->nfiles] == NULL) { 607 command_errf(commands, SEDERR_OOMMES); 608 return -1; 609 } 610 commands->rep->findex = commands->nfiles++; 611 } 612 break; 613 614 case 'w': 615 commands->rep->command = WCOM; 616 if (*commands->cp++ != ' ') { 617 command_errf(commands, SEDERR_SMMES, commands->linebuf); 618 return -1; 619 } 620 if (text(commands, fnamebuf, &fnamebuf[APR_PATH_MAX]) == NULL) { 621 command_errf(commands, SEDERR_FNTL, commands->linebuf); 622 return -1; 623 } 624 for (i = commands->nfiles - 1; i >= 0; i--) 625 if (strcmp(fnamebuf, commands->fname[i]) == 0) { 626 commands->rep->findex = i; 627 goto done; 628 } 629 if (commands->nfiles >= NWFILES) { 630 command_errf(commands, SEDERR_TMWFMES); 631 return -1; 632 } 633 if ((commands->fname[commands->nfiles] = 634 apr_pstrdup(commands->pool, fnamebuf)) == NULL) { 635 command_errf(commands, SEDERR_OOMMES); 636 return -1; 637 } 638 639 commands->rep->findex = commands->nfiles++; 640 break; 641 642 case 'x': 643 commands->rep->command = XCOM; 644 break; 645 646 case 'y': 647 commands->rep->command = YCOM; 648 commands->sseof = *commands->cp++; 649 commands->rep->re1 = p; 650 p = ycomp(commands, commands->rep->re1); 651 if (p == NULL) 652 return -1; 653 break; 654 } 655done: 656 commands->rep = alloc_reptr(commands); 657 658 commands->rep->ad1 = p; 659 660 if (*commands->cp++ != '\0') { 661 if (commands->cp[-1] == ';') 662 goto comploop; 663 command_errf(commands, SEDERR_CGMES, commands->linebuf); 664 return -1; 665 } 666 } 667 commands->rep->command = 0; 668 commands->lastre = op; 669 670 return 0; 671} 672 673static char *compsub(sed_commands_t *commands, 674 sed_comp_args *compargs, char *rhsbuf) 675{ 676 char *p, *q; 677 678 p = rhsbuf; 679 q = commands->cp; 680 for(;;) { 681 if(p > &commands->respace[RESIZE-1]) { 682 command_errf(commands, SEDERR_TMMES, commands->linebuf); 683 return NULL; 684 } 685 if((*p = *q++) == '\\') { 686 p++; 687 if(p > &commands->respace[RESIZE-1]) { 688 command_errf(commands, SEDERR_TMMES, commands->linebuf); 689 return NULL; 690 } 691 *p = *q++; 692 if(*p > compargs->nbra + '0' && *p <= '9') { 693 command_errf(commands, SEDERR_DOORNG, commands->linebuf); 694 return NULL; 695 } 696 p++; 697 continue; 698 } 699 if(*p == commands->sseof) { 700 *p++ = '\0'; 701 commands->cp = q; 702 return(p); 703 } 704 if(*p++ == '\0') { 705 command_errf(commands, SEDERR_EDMOSUB, commands->linebuf); 706 return NULL; 707 } 708 } 709} 710 711/* 712 * rline 713 */ 714static int rline(sed_commands_t *commands, apr_file_t *fin, 715 char *lbuf, char *lbend) 716{ 717 char *p; 718 const char *q; 719 int t; 720 apr_size_t bytes_read; 721 722 p = lbuf; 723 724 if(commands->eflag) { 725 if(commands->eflag > 0) { 726 commands->eflag = -1; 727 q = commands->earg; 728 while((t = *q++) != '\0') { 729 if(t == '\n') { 730 commands->saveq = q; 731 goto out1; 732 } 733 if (p < lbend) 734 *p++ = t; 735 if(t == '\\') { 736 if((t = *q++) == '\0') { 737 commands->saveq = NULL; 738 return(-1); 739 } 740 if (p < lbend) 741 *p++ = t; 742 } 743 } 744 commands->saveq = NULL; 745 746 out1: 747 if (p == lbend) { 748 command_errf(commands, SEDERR_CLTL); 749 return -1; 750 } 751 *p = '\0'; 752 return(1); 753 } 754 if((q = commands->saveq) == 0) return(-1); 755 756 while((t = *q++) != '\0') { 757 if(t == '\n') { 758 commands->saveq = q; 759 goto out2; 760 } 761 if(p < lbend) 762 *p++ = t; 763 if(t == '\\') { 764 if((t = *q++) == '\0') { 765 commands->saveq = NULL; 766 return(-1); 767 } 768 if (p < lbend) 769 *p++ = t; 770 } 771 } 772 commands->saveq = NULL; 773 774 out2: 775 if (p == lbend) { 776 command_errf(commands, SEDERR_CLTL); 777 return -1; 778 } 779 *p = '\0'; 780 return(1); 781 } 782 783 bytes_read = 1; 784 /* XXX extremely inefficient 1 byte reads */ 785 while (apr_file_read(fin, &t, &bytes_read) != APR_SUCCESS) { 786 if(t == '\n') { 787 if (p == lbend) { 788 command_errf(commands, SEDERR_CLTL); 789 return -1; 790 } 791 *p = '\0'; 792 return(1); 793 } 794 if (p < lbend) 795 *p++ = t; 796 if(t == '\\') { 797 bytes_read = 1; 798 if (apr_file_read(fin, &t, &bytes_read) != APR_SUCCESS) { 799 return -1; 800 } 801 if(p < lbend) 802 *p++ = t; 803 } 804 bytes_read = 1; 805 } 806 return(-1); 807} 808 809/* 810 * address 811 */ 812static char *address(sed_commands_t *commands, char *expbuf, 813 apr_status_t* status) 814{ 815 char *rcp; 816 apr_int64_t lno; 817 sed_comp_args compargs; 818 819 *status = APR_SUCCESS; 820 if(*commands->cp == '$') { 821 if (expbuf > &commands->respace[RESIZE-2]) { 822 command_errf(commands, SEDERR_TMMES, commands->linebuf); 823 *status = APR_EGENERAL; 824 return NULL; 825 } 826 commands->cp++; 827 *expbuf++ = CEND; 828 *expbuf++ = CCEOF; 829 return(expbuf); 830 } 831 if (*commands->cp == '/' || *commands->cp == '\\' ) { 832 if ( *commands->cp == '\\' ) 833 commands->cp++; 834 commands->sseof = *commands->cp++; 835 return(comple(commands, &compargs, (char *) 0, expbuf, commands->reend, 836 commands->sseof)); 837 } 838 839 rcp = commands->cp; 840 lno = 0; 841 842 while(*rcp >= '0' && *rcp <= '9') 843 lno = lno*10 + *rcp++ - '0'; 844 845 if(rcp > commands->cp) { 846 if (expbuf > &commands->respace[RESIZE-3]) { 847 command_errf(commands, SEDERR_TMMES, commands->linebuf); 848 *status = APR_EGENERAL; 849 return NULL; 850 } 851 *expbuf++ = CLNUM; 852 *expbuf++ = commands->nlno; 853 commands->tlno[commands->nlno++] = lno; 854 if(commands->nlno >= SED_NLINES) { 855 command_errf(commands, SEDERR_TMLNMES); 856 *status = APR_EGENERAL; 857 return NULL; 858 } 859 *expbuf++ = CCEOF; 860 commands->cp = rcp; 861 return(expbuf); 862 } 863 return(NULL); 864} 865 866/* 867 * text 868 */ 869static char *text(sed_commands_t *commands, char *textbuf, char *tbend) 870{ 871 char *p, *q; 872 873 p = textbuf; 874 q = commands->cp; 875#ifndef S5EMUL 876 /* 877 * Strip off indentation from text to be inserted. 878 */ 879 while(*q == '\t' || *q == ' ') q++; 880#endif 881 for(;;) { 882 883 if(p > tbend) 884 return(NULL); /* overflowed the buffer */ 885 if((*p = *q++) == '\\') 886 *p = *q++; 887 if(*p == '\0') { 888 commands->cp = --q; 889 return(++p); 890 } 891#ifndef S5EMUL 892 /* 893 * Strip off indentation from text to be inserted. 894 */ 895 if(*p == '\n') { 896 while(*q == '\t' || *q == ' ') q++; 897 } 898#endif 899 p++; 900 } 901} 902 903 904/* 905 * search 906 */ 907static sed_label_t *search(sed_commands_t *commands) 908{ 909 sed_label_t *rp; 910 sed_label_t *ptr; 911 912 rp = commands->labtab; 913 ptr = commands->lab; 914 while (rp < ptr) { 915 if (strcmp(rp->asc, ptr->asc) == 0) 916 return rp; 917 rp++; 918 } 919 920 return 0; 921} 922 923/* 924 * ycomp 925 */ 926static char *ycomp(sed_commands_t *commands, char *expbuf) 927{ 928 char c; 929 int cint; /* integer value of char c */ 930 char *ep, *tsp; 931 int i; 932 char *sp; 933 934 ep = expbuf; 935 if(ep + 0377 > &commands->respace[RESIZE-1]) { 936 command_errf(commands, SEDERR_TMMES, commands->linebuf); 937 return NULL; 938 } 939 sp = commands->cp; 940 for(tsp = commands->cp; (c = *tsp) != commands->sseof; tsp++) { 941 if(c == '\\') 942 tsp++; 943 if(c == '\0' || c == '\n') { 944 command_errf(commands, SEDERR_EDMOSTR, commands->linebuf); 945 return NULL; 946 } 947 } 948 tsp++; 949 memset(ep, 0, 0400); 950 951 while((c = *sp++) != commands->sseof) { 952 c &= 0377; 953 if(c == '\\' && *sp == 'n') { 954 sp++; 955 c = '\n'; 956 } 957 cint = (int) c; 958 if((ep[cint] = *tsp++) == '\\' && *tsp == 'n') { 959 ep[cint] = '\n'; 960 tsp++; 961 } 962 if(ep[cint] == commands->sseof || ep[cint] == '\0') { 963 command_errf(commands, SEDERR_TSNTSS, commands->linebuf); 964 } 965 } 966 if(*tsp != commands->sseof) { 967 if(*tsp == '\0') { 968 command_errf(commands, SEDERR_EDMOSTR, commands->linebuf); 969 } 970 else { 971 command_errf(commands, SEDERR_TSNTSS, commands->linebuf); 972 } 973 return NULL; 974 } 975 commands->cp = ++tsp; 976 977 for(i = 0; i < 0400; i++) 978 if(ep[i] == 0) 979 ep[i] = i; 980 981 return(ep + 0400); 982} 983 984/* 985 * comple 986 */ 987static char *comple(sed_commands_t *commands, sed_comp_args *compargs, 988 char *x1, char *ep, char *x3, char x4) 989{ 990 char *p; 991 992 p = sed_compile(commands, compargs, ep + 1, x3, x4); 993 if(p == ep + 1) 994 return(ep); 995 *ep = compargs->circf; 996 return(p); 997} 998 999/* 1000 * alloc_reptr 1001 */ 1002static sed_reptr_t *alloc_reptr(sed_commands_t *commands) 1003{ 1004 sed_reptr_t *var; 1005 1006 var = apr_pcalloc(commands->pool, sizeof(sed_reptr_t)); 1007 if (var == NULL) { 1008 command_errf(commands, SEDERR_OOMMES); 1009 return 0; 1010 } 1011 1012 var->nrep = commands->nrep; 1013 var->findex = -1; 1014 commands->nrep++; 1015 1016 if (commands->ptrspace == NULL) 1017 commands->ptrspace = var; 1018 else 1019 commands->ptrend->next = var; 1020 1021 commands->ptrend = var; 1022 commands->labtab->address = var; 1023 return var; 1024} 1025 1026 1027