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