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_lib.h" 23 0 jyri #include "libsed.h" 24 0 jyri #include "sed.h" 25 0 jyri #include "apr_strings.h" 26 0 jyri #include "regexp.h" 27 0 jyri 28 0 jyri char *trans[040] = { 29 0 jyri "\\01", 30 0 jyri "\\02", 31 0 jyri "\\03", 32 0 jyri "\\04", 33 0 jyri "\\05", 34 0 jyri "\\06", 35 0 jyri "\\07", 36 0 jyri "-<", 37 0 jyri "->", 38 0 jyri "\n", 39 0 jyri "\\13", 40 0 jyri "\\14", 41 0 jyri "\\15", 42 0 jyri "\\16", 43 0 jyri "\\17", 44 0 jyri "\\20", 45 0 jyri "\\21", 46 0 jyri "\\22", 47 0 jyri "\\23", 48 0 jyri "\\24", 49 0 jyri "\\25", 50 0 jyri "\\26", 51 0 jyri "\\27", 52 0 jyri "\\30", 53 0 jyri "\\31", 54 0 jyri "\\32", 55 0 jyri "\\33", 56 0 jyri "\\34", 57 0 jyri "\\35", 58 0 jyri "\\36", 59 0 jyri "\\37" 60 0 jyri }; 61 0 jyri char rub[] = {"\\177"}; 62 0 jyri 63 0 jyri extern int sed_step(char *p1, char *p2, int circf, step_vars_storage *vars); 64 0 jyri static int substitute(sed_eval_t *eval, sed_reptr_t *ipc, 65 0 jyri step_vars_storage *step_vars); 66 0 jyri static apr_status_t execute(sed_eval_t *eval); 67 0 jyri static int match(sed_eval_t *eval, char *expbuf, int gf, 68 0 jyri step_vars_storage *step_vars); 69 0 jyri static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n, 70 0 jyri step_vars_storage *step_vars); 71 0 jyri static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2); 72 0 jyri static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, 73 0 jyri step_vars_storage *step_vars); 74 0 jyri static void wline(sed_eval_t *eval, char *buf, int sz); 75 0 jyri static void arout(sed_eval_t *eval); 76 0 jyri 77 0 jyri static void eval_errf(sed_eval_t *eval, const char *fmt, ...) 78 0 jyri { 79 0 jyri if (eval->errfn && eval->pool) { 80 0 jyri va_list args; 81 0 jyri const char* error; 82 0 jyri va_start(args, fmt); 83 0 jyri error = apr_pvsprintf(eval->pool, fmt, args); 84 0 jyri eval->errfn(eval->data, error); 85 0 jyri va_end(args); 86 0 jyri } 87 0 jyri } 88 0 jyri 89 6 bk139067 #define INIT_BUF_SIZE 1024 90 6 bk139067 91 6 bk139067 /* 92 6 bk139067 * grow_buffer 93 6 bk139067 */ 94 6 bk139067 static void grow_buffer(apr_pool_t *pool, char **buffer, 95 6 bk139067 char **spend, unsigned int *cursize, 96 6 bk139067 unsigned int newsize) 97 6 bk139067 { 98 6 bk139067 char* newbuffer = NULL; 99 6 bk139067 int spendsize = 0; 100 6 bk139067 if (*cursize >= newsize) 101 6 bk139067 return; 102 6 bk139067 /* Align it to 4 KB boundary */ 103 6 bk139067 newsize = (newsize + ((1 << 12) - 1)) & ~((1 << 12) -1); 104 6 bk139067 newbuffer = apr_pcalloc(pool, newsize); 105 6 bk139067 if (*spend && *buffer && (*cursize > 0)) { 106 6 bk139067 spendsize = *spend - *buffer; 107 6 bk139067 } 108 6 bk139067 if ((*cursize > 0) && *buffer) { 109 6 bk139067 memcpy(newbuffer, *buffer, *cursize); 110 6 bk139067 } 111 6 bk139067 *buffer = newbuffer; 112 6 bk139067 *cursize = newsize; 113 6 bk139067 if (spend != buffer) { 114 6 bk139067 *spend = *buffer + spendsize; 115 6 bk139067 } 116 6 bk139067 } 117 6 bk139067 118 6 bk139067 /* 119 6 bk139067 * grow_line_buffer 120 6 bk139067 */ 121 6 bk139067 static void grow_line_buffer(sed_eval_t *eval, int newsize) 122 6 bk139067 { 123 6 bk139067 grow_buffer(eval->pool, &eval->linebuf, &eval->lspend, 124 6 bk139067 &eval->lsize, newsize); 125 6 bk139067 } 126 6 bk139067 127 6 bk139067 /* 128 6 bk139067 * grow_hold_buffer 129 6 bk139067 */ 130 6 bk139067 static void grow_hold_buffer(sed_eval_t *eval, int newsize) 131 6 bk139067 { 132 6 bk139067 grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend, 133 6 bk139067 &eval->hsize, newsize); 134 6 bk139067 } 135 6 bk139067 136 6 bk139067 /* 137 6 bk139067 * grow_gen_buffer 138 6 bk139067 */ 139 6 bk139067 static void grow_gen_buffer(sed_eval_t *eval, int newsize, 140 6 bk139067 char **gspend) 141 6 bk139067 { 142 6 bk139067 if (gspend == NULL) { 143 6 bk139067 gspend = &eval->genbuf; 144 6 bk139067 } 145 6 bk139067 grow_buffer(eval->pool, &eval->genbuf, gspend, 146 6 bk139067 &eval->gsize, newsize); 147 6 bk139067 eval->lcomend = &eval->genbuf[71]; 148 6 bk139067 } 149 6 bk139067 150 6 bk139067 /* 151 6 bk139067 * appendmem_to_linebuf 152 6 bk139067 */ 153 6 bk139067 static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, int len) 154 6 bk139067 { 155 8 basantk unsigned int reqsize = (eval->lspend - eval->linebuf) + len; 156 6 bk139067 if (eval->lsize < reqsize) { 157 6 bk139067 grow_line_buffer(eval, reqsize); 158 6 bk139067 } 159 6 bk139067 memcpy(eval->lspend, sz, len); 160 6 bk139067 eval->lspend += len; 161 6 bk139067 } 162 6 bk139067 163 6 bk139067 /* 164 6 bk139067 * append_to_linebuf 165 6 bk139067 */ 166 6 bk139067 static void append_to_linebuf(sed_eval_t *eval, const char* sz) 167 6 bk139067 { 168 6 bk139067 int len = strlen(sz); 169 6 bk139067 /* Copy string including null character */ 170 6 bk139067 appendmem_to_linebuf(eval, sz, len + 1); 171 6 bk139067 --eval->lspend; /* lspend will now point to NULL character */ 172 6 bk139067 } 173 6 bk139067 174 6 bk139067 /* 175 6 bk139067 * copy_to_linebuf 176 6 bk139067 */ 177 6 bk139067 static void copy_to_linebuf(sed_eval_t *eval, const char* sz) 178 6 bk139067 { 179 6 bk139067 eval->lspend = eval->linebuf; 180 6 bk139067 append_to_linebuf(eval, sz); 181 6 bk139067 } 182 6 bk139067 183 6 bk139067 /* 184 6 bk139067 * append_to_holdbuf 185 6 bk139067 */ 186 6 bk139067 static void append_to_holdbuf(sed_eval_t *eval, const char* sz) 187 6 bk139067 { 188 6 bk139067 int len = strlen(sz); 189 8 basantk unsigned int reqsize = (eval->hspend - eval->holdbuf) + len + 1; 190 6 bk139067 if (eval->hsize <= reqsize) { 191 6 bk139067 grow_hold_buffer(eval, reqsize); 192 6 bk139067 } 193 6 bk139067 strcpy(eval->hspend, sz); 194 6 bk139067 /* hspend will now point to NULL character */ 195 6 bk139067 eval->hspend += len; 196 6 bk139067 } 197 6 bk139067 198 6 bk139067 /* 199 6 bk139067 * copy_to_holdbuf 200 6 bk139067 */ 201 6 bk139067 static void copy_to_holdbuf(sed_eval_t *eval, const char* sz) 202 6 bk139067 { 203 6 bk139067 eval->hspend = eval->holdbuf; 204 6 bk139067 append_to_holdbuf(eval, sz); 205 6 bk139067 } 206 6 bk139067 207 6 bk139067 /* 208 6 bk139067 * append_to_genbuf 209 6 bk139067 */ 210 6 bk139067 static void append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend) 211 6 bk139067 { 212 6 bk139067 int len = strlen(sz); 213 8 basantk unsigned int reqsize = (*gspend - eval->genbuf) + len + 1; 214 6 bk139067 if (eval->gsize < reqsize) { 215 6 bk139067 grow_gen_buffer(eval, reqsize, gspend); 216 6 bk139067 } 217 6 bk139067 strcpy(*gspend, sz); 218 6 bk139067 /* *gspend will now point to NULL character */ 219 6 bk139067 *gspend += len; 220 6 bk139067 } 221 6 bk139067 222 6 bk139067 /* 223 6 bk139067 * copy_to_genbuf 224 6 bk139067 */ 225 6 bk139067 static void copy_to_genbuf(sed_eval_t *eval, const char* sz) 226 6 bk139067 { 227 6 bk139067 int len = strlen(sz); 228 8 basantk unsigned int reqsize = len + 1; 229 6 bk139067 if (eval->gsize < reqsize) { 230 6 bk139067 grow_gen_buffer(eval, reqsize, NULL); 231 6 bk139067 } 232 6 bk139067 } 233 6 bk139067 234 0 jyri /* 235 0 jyri * sed_init_eval 236 0 jyri */ 237 0 jyri 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) 238 0 jyri { 239 0 jyri memset(eval, 0, sizeof(*eval)); 240 0 jyri eval->pool = p; 241 0 jyri eval->writefn = writefn; 242 0 jyri return sed_reset_eval(eval, commands, errfn, data); 243 0 jyri } 244 0 jyri 245 0 jyri /* 246 0 jyri * sed_reset_eval 247 0 jyri */ 248 0 jyri apr_status_t sed_reset_eval(sed_eval_t *eval, sed_commands_t *commands, sed_err_fn_t *errfn, void *data) 249 0 jyri { 250 0 jyri int i; 251 0 jyri 252 0 jyri eval->errfn = errfn; 253 0 jyri eval->data = data; 254 0 jyri 255 0 jyri eval->commands = commands; 256 0 jyri 257 0 jyri eval->lnum = 0; 258 0 jyri eval->fout = NULL; 259 0 jyri 260 0 jyri if (eval->linebuf == NULL) { 261 6 bk139067 eval->lsize = INIT_BUF_SIZE; 262 6 bk139067 eval->linebuf = apr_pcalloc(eval->pool, eval->lsize); 263 0 jyri } 264 0 jyri if (eval->holdbuf == NULL) { 265 6 bk139067 eval->hsize = INIT_BUF_SIZE; 266 6 bk139067 eval->holdbuf = apr_pcalloc(eval->pool, eval->hsize); 267 0 jyri } 268 0 jyri if (eval->genbuf == NULL) { 269 6 bk139067 eval->gsize = INIT_BUF_SIZE; 270 6 bk139067 eval->genbuf = apr_pcalloc(eval->pool, eval->gsize); 271 0 jyri } 272 0 jyri eval->lspend = eval->linebuf; 273 0 jyri eval->hspend = eval->holdbuf; 274 0 jyri eval->lcomend = &eval->genbuf[71]; 275 0 jyri 276 0 jyri for (i = 0; i < sizeof(eval->abuf) / sizeof(eval->abuf[0]); i++) 277 0 jyri eval->abuf[i] = NULL; 278 0 jyri eval->aptr = eval->abuf; 279 0 jyri eval->pending = NULL; 280 0 jyri eval->inar = apr_pcalloc(eval->pool, commands->nrep * sizeof(unsigned char)); 281 0 jyri eval->nrep = commands->nrep; 282 0 jyri 283 0 jyri eval->dolflag = 0; 284 0 jyri eval->sflag = 0; 285 0 jyri eval->jflag = 0; 286 0 jyri eval->delflag = 0; 287 0 jyri eval->lreadyflag = 0; 288 0 jyri eval->quitflag = 0; 289 0 jyri eval->finalflag = 1; /* assume we're evaluating only one file/stream */ 290 0 jyri eval->numpass = 0; 291 0 jyri eval->nullmatch = 0; 292 0 jyri eval->col = 0; 293 0 jyri 294 0 jyri for (i = 0; i < commands->nfiles; i++) { 295 0 jyri const char* filename = commands->fname[i]; 296 0 jyri if (apr_file_open(&eval->fcode[i], filename, 297 0 jyri APR_WRITE | APR_CREATE, APR_OS_DEFAULT, 298 0 jyri eval->pool) != APR_SUCCESS) { 299 0 jyri eval_errf(eval, SEDERR_COMES, filename); 300 0 jyri return APR_EGENERAL; 301 0 jyri } 302 0 jyri } 303 0 jyri 304 0 jyri return APR_SUCCESS; 305 0 jyri } 306 0 jyri 307 0 jyri /* 308 0 jyri * sed_destroy_eval 309 0 jyri */ 310 0 jyri void sed_destroy_eval(sed_eval_t *eval) 311 0 jyri { 312 0 jyri int i; 313 0 jyri /* eval->linebuf, eval->holdbuf, eval->genbuf and eval->inar are allocated 314 0 jyri * on pool. It will be freed when pool will be freed */ 315 0 jyri for (i = 0; i < eval->commands->nfiles; i++) { 316 0 jyri if (eval->fcode[i] != NULL) { 317 0 jyri apr_file_close(eval->fcode[i]); 318 0 jyri eval->fcode[i] = NULL; 319 0 jyri } 320 0 jyri } 321 0 jyri } 322 0 jyri 323 0 jyri /* 324 0 jyri * sed_eval_file 325 0 jyri */ 326 0 jyri apr_status_t sed_eval_file(sed_eval_t *eval, apr_file_t *fin, void *fout) 327 0 jyri { 328 0 jyri for (;;) { 329 0 jyri char buf[1024]; 330 0 jyri apr_size_t read_bytes = 0; 331 0 jyri 332 0 jyri read_bytes = sizeof(buf); 333 0 jyri if (apr_file_read(fin, buf, &read_bytes) != APR_SUCCESS) 334 0 jyri break; 335 0 jyri 336 0 jyri if (sed_eval_buffer(eval, buf, read_bytes, fout) != APR_SUCCESS) 337 0 jyri return APR_EGENERAL; 338 0 jyri 339 0 jyri if (eval->quitflag) 340 0 jyri return APR_SUCCESS; 341 0 jyri } 342 0 jyri 343 0 jyri return sed_finalize_eval(eval, fout); 344 0 jyri } 345 0 jyri 346 0 jyri /* 347 0 jyri * sed_eval_buffer 348 0 jyri */ 349 0 jyri apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, int bufsz, void *fout) 350 0 jyri { 351 0 jyri apr_status_t rv; 352 0 jyri 353 0 jyri if (eval->quitflag) 354 0 jyri return APR_SUCCESS; 355 4 basantk 356 4 basantk if (!sed_canbe_finalized(eval->commands)) { 357 4 basantk /* Commands were not finalized properly. */ 358 4 basantk const char* error = sed_get_finalize_error(eval->commands, eval->pool); 359 4 basantk if (error) { 360 4 basantk eval_errf(eval, error); 361 4 basantk return APR_EGENERAL; 362 4 basantk } 363 4 basantk } 364 0 jyri 365 0 jyri eval->fout = fout; 366 0 jyri 367 0 jyri /* Process leftovers */ 368 0 jyri if (bufsz && eval->lreadyflag) { 369 0 jyri eval->lreadyflag = 0; 370 0 jyri eval->lspend--; 371 0 jyri *eval->lspend = '\0'; 372 0 jyri rv = execute(eval); 373 0 jyri if (rv != 0) 374 0 jyri return APR_EGENERAL; 375 0 jyri } 376 0 jyri 377 0 jyri while (bufsz) { 378 0 jyri char *n; 379 0 jyri int llen; 380 0 jyri 381 0 jyri n = memchr(buf, '\n', bufsz); 382 0 jyri if (n == NULL) 383 0 jyri break; 384 0 jyri 385 0 jyri llen = n - buf; 386 0 jyri if (llen == bufsz - 1) { 387 0 jyri /* This might be the last line; delay its processing */ 388 0 jyri eval->lreadyflag = 1; 389 0 jyri break; 390 0 jyri } 391 6 bk139067 392 6 bk139067 appendmem_to_linebuf(eval, buf, llen + 1); 393 6 bk139067 --eval->lspend; 394 6 bk139067 /* replace new line character with NULL */ 395 6 bk139067 *eval->lspend = '\0'; 396 0 jyri buf += (llen + 1); 397 0 jyri bufsz -= (llen + 1); 398 0 jyri rv = execute(eval); 399 0 jyri if (rv != 0) 400 0 jyri return APR_EGENERAL; 401 0 jyri if (eval->quitflag) 402 0 jyri break; 403 0 jyri } 404 0 jyri 405 0 jyri /* Save the leftovers for later */ 406 0 jyri if (bufsz) { 407 6 bk139067 appendmem_to_linebuf(eval, buf, bufsz); 408 0 jyri } 409 0 jyri 410 0 jyri return APR_SUCCESS; 411 0 jyri } 412 0 jyri 413 0 jyri /* 414 0 jyri * sed_finalize_eval 415 0 jyri */ 416 0 jyri apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout) 417 0 jyri { 418 0 jyri if (eval->quitflag) 419 0 jyri return APR_SUCCESS; 420 0 jyri 421 0 jyri if (eval->finalflag) 422 0 jyri eval->dolflag = 1; 423 0 jyri 424 0 jyri eval->fout = fout; 425 0 jyri 426 0 jyri /* Process leftovers */ 427 0 jyri if (eval->lspend > eval->linebuf) { 428 0 jyri apr_status_t rv; 429 0 jyri 430 0 jyri if (eval->lreadyflag) { 431 0 jyri eval->lreadyflag = 0; 432 0 jyri eval->lspend--; 433 0 jyri } else { 434 6 bk139067 /* Code can probably reach here when last character in output 435 7 basantk * buffer is not a newline. 436 6 bk139067 */ 437 6 bk139067 /* Assure space for NULL */ 438 6 bk139067 append_to_linebuf(eval, ""); 439 0 jyri } 440 0 jyri 441 0 jyri *eval->lspend = '\0'; 442 0 jyri rv = execute(eval); 443 0 jyri if (rv != 0) 444 0 jyri return APR_EGENERAL; 445 0 jyri } 446 0 jyri 447 0 jyri eval->quitflag = 1; 448 0 jyri 449 0 jyri return APR_SUCCESS; 450 0 jyri } 451 0 jyri 452 0 jyri /* 453 0 jyri * execute 454 0 jyri */ 455 0 jyri static apr_status_t execute(sed_eval_t *eval) 456 0 jyri { 457 0 jyri sed_reptr_t *ipc = eval->commands->ptrspace; 458 0 jyri step_vars_storage step_vars; 459 0 jyri 460 0 jyri eval->lnum++; 461 0 jyri 462 0 jyri eval->sflag = 0; 463 0 jyri 464 0 jyri if (eval->pending) { 465 0 jyri ipc = eval->pending; 466 0 jyri eval->pending = NULL; 467 0 jyri } 468 0 jyri 469 0 jyri memset(&step_vars, 0, sizeof(step_vars)); 470 0 jyri 471 0 jyri while (ipc->command) { 472 0 jyri char *p1; 473 0 jyri char *p2; 474 0 jyri apr_status_t rv; 475 0 jyri int c; 476 0 jyri 477 0 jyri p1 = ipc->ad1; 478 0 jyri p2 = ipc->ad2; 479 0 jyri 480 0 jyri if (p1) { 481 0 jyri 482 0 jyri if (eval->inar[ipc->nrep]) { 483 0 jyri if (*p2 == CEND) { 484 0 jyri p1 = 0; 485 0 jyri } else if (*p2 == CLNUM) { 486 0 jyri c = (unsigned char)p2[1]; 487 0 jyri if (eval->lnum > eval->commands->tlno[c]) { 488 0 jyri eval->inar[ipc->nrep] = 0; 489 0 jyri if (ipc->negfl) 490 0 jyri goto yes; 491 0 jyri ipc = ipc->next; 492 0 jyri continue; 493 0 jyri } 494 0 jyri if (eval->lnum == eval->commands->tlno[c]) { 495 0 jyri eval->inar[ipc->nrep] = 0; 496 0 jyri } 497 0 jyri } else if (match(eval, p2, 0, &step_vars)) { 498 0 jyri eval->inar[ipc->nrep] = 0; 499 0 jyri } 500 0 jyri } else if (*p1 == CEND) { 501 0 jyri if (!eval->dolflag) { 502 0 jyri if (ipc->negfl) 503 0 jyri goto yes; 504 0 jyri ipc = ipc->next; 505 0 jyri continue; 506 0 jyri } 507 0 jyri } else if (*p1 == CLNUM) { 508 0 jyri c = (unsigned char)p1[1]; 509 0 jyri if (eval->lnum != eval->commands->tlno[c]) { 510 0 jyri if (ipc->negfl) 511 0 jyri goto yes; 512 0 jyri ipc = ipc->next; 513 0 jyri continue; 514 0 jyri } 515 0 jyri if (p2) 516 0 jyri eval->inar[ipc->nrep] = 1; 517 0 jyri } else if (match(eval, p1, 0, &step_vars)) { 518 0 jyri if (p2) 519 0 jyri eval->inar[ipc->nrep] = 1; 520 0 jyri } else { 521 0 jyri if (ipc->negfl) 522 0 jyri goto yes; 523 0 jyri ipc = ipc->next; 524 0 jyri continue; 525 0 jyri } 526 0 jyri } 527 0 jyri 528 0 jyri if (ipc->negfl) { 529 0 jyri ipc = ipc->next; 530 0 jyri continue; 531 0 jyri } 532 0 jyri 533 0 jyri yes: 534 0 jyri rv = command(eval, ipc, &step_vars); 535 0 jyri if (rv != APR_SUCCESS) 536 0 jyri return rv; 537 0 jyri 538 0 jyri if (eval->quitflag) 539 0 jyri return APR_SUCCESS; 540 0 jyri 541 0 jyri if (eval->pending) 542 0 jyri return APR_SUCCESS; 543 0 jyri 544 0 jyri if (eval->delflag) 545 0 jyri break; 546 0 jyri 547 0 jyri if (eval->jflag) { 548 0 jyri eval->jflag = 0; 549 0 jyri if ((ipc = ipc->lb1) == 0) { 550 0 jyri ipc = eval->commands->ptrspace; 551 0 jyri break; 552 0 jyri } 553 0 jyri } else 554 0 jyri ipc = ipc->next; 555 0 jyri } 556 0 jyri 557 0 jyri if (!eval->commands->nflag && !eval->delflag) 558 0 jyri wline(eval, eval->linebuf, eval->lspend - eval->linebuf); 559 0 jyri 560 0 jyri if (eval->aptr > eval->abuf) 561 0 jyri arout(eval); 562 0 jyri 563 0 jyri eval->delflag = 0; 564 0 jyri 565 0 jyri eval->lspend = eval->linebuf; 566 0 jyri 567 0 jyri return APR_SUCCESS; 568 0 jyri } 569 0 jyri 570 0 jyri /* 571 0 jyri * match 572 0 jyri */ 573 0 jyri static int match(sed_eval_t *eval, char *expbuf, int gf, 574 0 jyri step_vars_storage *step_vars) 575 0 jyri { 576 0 jyri char *p1; 577 0 jyri int circf; 578 0 jyri 579 0 jyri if(gf) { 580 0 jyri if(*expbuf) return(0); 581 0 jyri step_vars->locs = p1 = step_vars->loc2; 582 0 jyri } else { 583 0 jyri p1 = eval->linebuf; 584 0 jyri step_vars->locs = 0; 585 0 jyri } 586 0 jyri 587 0 jyri circf = *expbuf++; 588 0 jyri return(sed_step(p1, expbuf, circf, step_vars)); 589 0 jyri } 590 0 jyri 591 0 jyri /* 592 0 jyri * substitute 593 0 jyri */ 594 0 jyri static int substitute(sed_eval_t *eval, sed_reptr_t *ipc, 595 0 jyri step_vars_storage *step_vars) 596 0 jyri { 597 0 jyri if(match(eval, ipc->re1, 0, step_vars) == 0) return(0); 598 0 jyri 599 0 jyri eval->numpass = 0; 600 0 jyri eval->sflag = 0; /* Flags if any substitution was made */ 601 0 jyri if (dosub(eval, ipc->rhs, ipc->gfl, step_vars) != APR_SUCCESS) 602 0 jyri return -1; 603 0 jyri 604 0 jyri if(ipc->gfl) { 605 0 jyri while(*step_vars->loc2) { 606 0 jyri if(match(eval, ipc->re1, 1, step_vars) == 0) break; 607 0 jyri if (dosub(eval, ipc->rhs, ipc->gfl, step_vars) != APR_SUCCESS) 608 0 jyri return -1; 609 0 jyri } 610 0 jyri } 611 0 jyri return(eval->sflag); 612 0 jyri } 613 0 jyri 614 0 jyri /* 615 0 jyri * dosub 616 0 jyri */ 617 0 jyri static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n, 618 0 jyri step_vars_storage *step_vars) 619 0 jyri { 620 0 jyri char *lp, *sp, *rp; 621 0 jyri int c; 622 0 jyri apr_status_t rv = APR_SUCCESS; 623 0 jyri 624 0 jyri if(n > 0 && n < 999) { 625 0 jyri eval->numpass++; 626 0 jyri if(n != eval->numpass) return APR_SUCCESS; 627 0 jyri } 628 0 jyri eval->sflag = 1; 629 0 jyri lp = eval->linebuf; 630 0 jyri sp = eval->genbuf; 631 0 jyri rp = rhsbuf; 632 6 bk139067 sp = place(eval, sp, lp, step_vars->loc1); 633 8 basantk while ((c = *rp++) != 0) { 634 0 jyri if (c == '&') { 635 0 jyri sp = place(eval, sp, step_vars->loc1, step_vars->loc2); 636 0 jyri if (sp == NULL) 637 0 jyri return APR_EGENERAL; 638 0 jyri } 639 0 jyri else if (c == '\\') { 640 0 jyri c = *rp++; 641 0 jyri if (c >= '1' && c < NBRA+'1') { 642 0 jyri sp = place(eval, sp, step_vars->braslist[c-'1'], 643 0 jyri step_vars->braelist[c-'1']); 644 0 jyri if (sp == NULL) 645 0 jyri return APR_EGENERAL; 646 0 jyri } 647 0 jyri else 648 0 jyri *sp++ = c; 649 0 jyri } else 650 0 jyri *sp++ = c; 651 6 bk139067 if (sp >= eval->genbuf + eval->gsize) { 652 6 bk139067 /* expand genbuf and set the sp appropriately */ 653 6 bk139067 grow_gen_buffer(eval, eval->gsize + 1024, &sp); 654 0 jyri } 655 0 jyri } 656 0 jyri lp = step_vars->loc2; 657 0 jyri step_vars->loc2 = sp - eval->genbuf + eval->linebuf; 658 6 bk139067 append_to_genbuf(eval, lp, &sp); 659 6 bk139067 copy_to_linebuf(eval, eval->genbuf); 660 0 jyri return rv; 661 0 jyri } 662 0 jyri 663 0 jyri /* 664 0 jyri * place 665 0 jyri */ 666 0 jyri static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2) 667 0 jyri { 668 6 bk139067 char *sp = asp; 669 6 bk139067 int n = al2 - al1; 670 8 basantk unsigned int reqsize = (sp - eval->genbuf) + n + 1; 671 0 jyri 672 6 bk139067 if (eval->gsize < reqsize) { 673 6 bk139067 grow_gen_buffer(eval, reqsize, &sp); 674 0 jyri } 675 6 bk139067 memcpy(sp, al1, n); 676 6 bk139067 return sp + n; 677 0 jyri } 678 0 jyri 679 0 jyri /* 680 0 jyri * command 681 0 jyri */ 682 0 jyri static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, 683 0 jyri step_vars_storage *step_vars) 684 0 jyri { 685 0 jyri int i; 686 0 jyri char *p1, *p2, *p3; 687 0 jyri int length; 688 0 jyri char sz[32]; /* 32 bytes enough to store 64 bit integer in decimal */ 689 0 jyri 690 0 jyri 691 0 jyri switch(ipc->command) { 692 0 jyri 693 0 jyri case ACOM: 694 0 jyri if(eval->aptr >= &eval->abuf[SED_ABUFSIZE]) { 695 0 jyri eval_errf(eval, SEDERR_TMAMES, eval->lnum); 696 0 jyri } else { 697 0 jyri *eval->aptr++ = ipc; 698 0 jyri *eval->aptr = NULL; 699 0 jyri } 700 0 jyri break; 701 0 jyri 702 0 jyri case CCOM: 703 0 jyri eval->delflag = 1; 704 0 jyri if(!eval->inar[ipc->nrep] || eval->dolflag) { 705 0 jyri for (p1 = ipc->re1; *p1; p1++) 706 0 jyri ; 707 0 jyri wline(eval, ipc->re1, p1 - ipc->re1); 708 0 jyri } 709 0 jyri break; 710 0 jyri case DCOM: 711 0 jyri eval->delflag++; 712 0 jyri break; 713 0 jyri case CDCOM: 714 0 jyri p1 = eval->linebuf; 715 0 jyri 716 0 jyri while(*p1 != '\n') { 717 0 jyri if(*p1++ == 0) { 718 0 jyri eval->delflag++; 719 0 jyri return APR_SUCCESS; 720 0 jyri } 721 0 jyri } 722 0 jyri 723 0 jyri p1++; 724 6 bk139067 copy_to_linebuf(eval, p1); 725 0 jyri eval->jflag++; 726 0 jyri break; 727 0 jyri 728 0 jyri case EQCOM: 729 8 basantk length = apr_snprintf(sz, sizeof(sz), "%d", (int) eval->lnum); 730 0 jyri wline(eval, sz, length); 731 0 jyri break; 732 0 jyri 733 0 jyri case GCOM: 734 6 bk139067 copy_to_linebuf(eval, eval->holdbuf); 735 0 jyri break; 736 0 jyri 737 0 jyri case CGCOM: 738 6 bk139067 append_to_linebuf(eval, "\n"); 739 6 bk139067 append_to_linebuf(eval, eval->holdbuf); 740 0 jyri break; 741 0 jyri 742 0 jyri case HCOM: 743 6 bk139067 copy_to_holdbuf(eval, eval->linebuf); 744 0 jyri break; 745 0 jyri 746 0 jyri case CHCOM: 747 6 bk139067 append_to_holdbuf(eval, "\n"); 748 6 bk139067 append_to_holdbuf(eval, eval->linebuf); 749 0 jyri break; 750 0 jyri 751 0 jyri case ICOM: 752 0 jyri for (p1 = ipc->re1; *p1; p1++); 753 0 jyri wline(eval, ipc->re1, p1 - ipc->re1); 754 0 jyri break; 755 0 jyri 756 0 jyri case BCOM: 757 0 jyri eval->jflag = 1; 758 0 jyri break; 759 0 jyri 760 0 jyri 761 0 jyri case LCOM: 762 0 jyri p1 = eval->linebuf; 763 0 jyri p2 = eval->genbuf; 764 0 jyri eval->genbuf[72] = 0; 765 0 jyri while(*p1) 766 0 jyri if((unsigned char)*p1 >= 040) { 767 0 jyri if(*p1 == 0177) { 768 0 jyri p3 = rub; 769 8 basantk while ((*p2++ = *p3++) != 0) 770 0 jyri if(p2 >= eval->lcomend) { 771 0 jyri *p2 = '\\'; 772 0 jyri wline(eval, eval->genbuf, 773 0 jyri strlen(eval->genbuf)); 774 0 jyri p2 = eval->genbuf; 775 0 jyri } 776 0 jyri p2--; 777 0 jyri p1++; 778 0 jyri continue; 779 0 jyri } 780 0 jyri if(!isprint(*p1 & 0377)) { 781 0 jyri *p2++ = '\\'; 782 0 jyri if(p2 >= eval->lcomend) { 783 0 jyri *p2 = '\\'; 784 0 jyri wline(eval, eval->genbuf, strlen(eval->genbuf)); 785 0 jyri p2 = eval->genbuf; 786 0 jyri } 787 0 jyri *p2++ = (*p1 >> 6) + '0'; 788 0 jyri if(p2 >= eval->lcomend) { 789 0 jyri *p2 = '\\'; 790 0 jyri wline(eval, eval->genbuf, strlen(eval->genbuf)); 791 0 jyri p2 = eval->genbuf; 792 0 jyri } 793 0 jyri *p2++ = ((*p1 >> 3) & 07) + '0'; 794 0 jyri if(p2 >= eval->lcomend) { 795 0 jyri *p2 = '\\'; 796 0 jyri wline(eval, eval->genbuf, strlen(eval->genbuf)); 797 0 jyri p2 = eval->genbuf; 798 0 jyri } 799 0 jyri *p2++ = (*p1++ & 07) + '0'; 800 0 jyri if(p2 >= eval->lcomend) { 801 0 jyri *p2 = '\\'; 802 0 jyri wline(eval, eval->genbuf, strlen(eval->genbuf)); 803 0 jyri p2 = eval->genbuf; 804 0 jyri } 805 0 jyri } else { 806 0 jyri *p2++ = *p1++; 807 0 jyri if(p2 >= eval->lcomend) { 808 0 jyri *p2 = '\\'; 809 0 jyri wline(eval, eval->genbuf, strlen(eval->genbuf)); 810 0 jyri p2 = eval->genbuf; 811 0 jyri } 812 0 jyri } 813 0 jyri } else { 814 0 jyri p3 = trans[(unsigned char)*p1-1]; 815 8 basantk while ((*p2++ = *p3++) != 0) 816 0 jyri if(p2 >= eval->lcomend) { 817 0 jyri *p2 = '\\'; 818 0 jyri wline(eval, eval->genbuf, strlen(eval->genbuf)); 819 0 jyri p2 = eval->genbuf; 820 0 jyri } 821 0 jyri p2--; 822 0 jyri p1++; 823 0 jyri } 824 0 jyri *p2 = 0; 825 0 jyri wline(eval, eval->genbuf, strlen(eval->genbuf)); 826 0 jyri break; 827 0 jyri 828 0 jyri case NCOM: 829 0 jyri if(!eval->commands->nflag) { 830 0 jyri wline(eval, eval->linebuf, eval->lspend - eval->linebuf); 831 0 jyri } 832 0 jyri 833 0 jyri if(eval->aptr > eval->abuf) 834 0 jyri arout(eval); 835 0 jyri eval->lspend = eval->linebuf; 836 0 jyri eval->pending = ipc->next; 837 0 jyri 838 0 jyri break; 839 0 jyri case CNCOM: 840 0 jyri if(eval->aptr > eval->abuf) 841 0 jyri arout(eval); 842 6 bk139067 append_to_linebuf(eval, "\n"); 843 0 jyri eval->pending = ipc->next; 844 0 jyri break; 845 0 jyri 846 0 jyri case PCOM: 847 0 jyri wline(eval, eval->linebuf, eval->lspend - eval->linebuf); 848 0 jyri break; 849 0 jyri case CPCOM: 850 0 jyri for (p1 = eval->linebuf; *p1 != '\n' && *p1 != '\0'; p1++); 851 0 jyri wline(eval, eval->linebuf, p1 - eval->linebuf); 852 0 jyri break; 853 0 jyri 854 0 jyri case QCOM: 855 0 jyri if (!eval->commands->nflag) 856 0 jyri wline(eval, eval->linebuf, eval->lspend - eval->linebuf); 857 0 jyri 858 0 jyri if(eval->aptr > eval->abuf) 859 0 jyri arout(eval); 860 0 jyri 861 0 jyri eval->quitflag = 1; 862 0 jyri break; 863 0 jyri case RCOM: 864 0 jyri if(eval->aptr >= &eval->abuf[SED_ABUFSIZE]) { 865 0 jyri eval_errf(eval, SEDERR_TMRMES, eval->lnum); 866 0 jyri } else { 867 0 jyri *eval->aptr++ = ipc; 868 0 jyri *eval->aptr = NULL; 869 0 jyri } 870 0 jyri break; 871 0 jyri 872 0 jyri case SCOM: 873 0 jyri i = substitute(eval, ipc, step_vars); 874 0 jyri if (i == -1) { 875 0 jyri return APR_EGENERAL; 876 0 jyri } 877 0 jyri if(ipc->pfl && eval->commands->nflag && i) { 878 0 jyri if(ipc->pfl == 1) { 879 0 jyri wline(eval, eval->linebuf, eval->lspend - eval->linebuf); 880 0 jyri } else { 881 0 jyri for (p1 = eval->linebuf; *p1 != '\n' && *p1 != '\0'; p1++); 882 0 jyri wline(eval, eval->linebuf, p1 - eval->linebuf); 883 0 jyri } 884 0 jyri } 885 0 jyri if (i && (ipc->findex >= 0) && eval->fcode[ipc->findex]) 886 0 jyri apr_file_printf(eval->fcode[ipc->findex], "%s\n", 887 0 jyri eval->linebuf); 888 0 jyri break; 889 0 jyri 890 0 jyri case TCOM: 891 0 jyri if(eval->sflag == 0) break; 892 0 jyri eval->sflag = 0; 893 0 jyri eval->jflag = 1; 894 0 jyri break; 895 0 jyri 896 0 jyri case WCOM: 897 0 jyri if (ipc->findex >= 0) 898 0 jyri apr_file_printf(eval->fcode[ipc->findex], "%s\n", 899 0 jyri eval->linebuf); 900 0 jyri break; 901 0 jyri case XCOM: 902 6 bk139067 copy_to_genbuf(eval, eval->linebuf); 903 6 bk139067 copy_to_linebuf(eval, eval->holdbuf); 904 6 bk139067 copy_to_holdbuf(eval, eval->genbuf); 905 0 jyri break; 906 0 jyri 907 0 jyri case YCOM: 908 0 jyri p1 = eval->linebuf; 909 0 jyri p2 = ipc->re1; 910 8 basantk while((*p1 = p2[(unsigned char)*p1]) != 0) p1++; 911 0 jyri break; 912 0 jyri } 913 0 jyri return APR_SUCCESS; 914 0 jyri } 915 0 jyri 916 0 jyri /* 917 0 jyri * arout 918 0 jyri */ 919 0 jyri static void arout(sed_eval_t *eval) 920 0 jyri { 921 0 jyri eval->aptr = eval->abuf - 1; 922 0 jyri while (*++eval->aptr) { 923 0 jyri if ((*eval->aptr)->command == ACOM) { 924 0 jyri char *p1; 925 0 jyri 926 0 jyri for (p1 = (*eval->aptr)->re1; *p1; p1++); 927 0 jyri wline(eval, (*eval->aptr)->re1, p1 - (*eval->aptr)->re1); 928 0 jyri } else { 929 0 jyri apr_file_t *fi = NULL; 930 0 jyri char buf[512]; 931 0 jyri apr_size_t n = sizeof(buf); 932 0 jyri 933 0 jyri if (apr_file_open(&fi, (*eval->aptr)->re1, APR_READ, 0, eval->pool) 934 0 jyri != APR_SUCCESS) 935 0 jyri continue; 936 0 jyri while ((apr_file_read(fi, buf, &n)) == APR_SUCCESS) { 937 0 jyri if (n == 0) 938 0 jyri break; 939 3 basantk eval->writefn(eval->fout, buf, n); 940 0 jyri n = sizeof(buf); 941 0 jyri } 942 0 jyri apr_file_close(fi); 943 0 jyri } 944 0 jyri } 945 0 jyri eval->aptr = eval->abuf; 946 0 jyri *eval->aptr = NULL; 947 0 jyri } 948 0 jyri 949 0 jyri /* 950 0 jyri * wline 951 0 jyri */ 952 0 jyri static void wline(sed_eval_t *eval, char *buf, int sz) 953 0 jyri { 954 3 basantk eval->writefn(eval->fout, buf, sz); 955 3 basantk eval->writefn(eval->fout, "\n", 1); 956 0 jyri } 957 0 jyri 958