f82568a780e35e8786958c49a1259434e2088b9cniq * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
f82568a780e35e8786958c49a1259434e2088b9cniq * Use is subject to license terms.
11e076839c8d5a82d55e710194d0daac51390dbdsf * Copyright (c) 1984 AT&T
11e076839c8d5a82d55e710194d0daac51390dbdsf * All Rights Reserved
f82568a780e35e8786958c49a1259434e2088b9cniq * Licensed under the Apache License, Version 2.0 (the "License");
f82568a780e35e8786958c49a1259434e2088b9cniq * you may not use this file except in compliance with the License.
f82568a780e35e8786958c49a1259434e2088b9cniq * You may obtain a copy of the License at
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * Unless required by applicable law or agreed to in writing, software
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * distributed under the License is distributed on an "AS IS" BASIS,
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * or implied.
f82568a780e35e8786958c49a1259434e2088b9cniq * See the License for the specific language governing permissions and
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * limitations under the License.
f82568a780e35e8786958c49a1259434e2088b9cniqextern int sed_step(char *p1, char *p2, int circf, step_vars_storage *vars);
f82568a780e35e8786958c49a1259434e2088b9cniqstatic int substitute(sed_eval_t *eval, sed_reptr_t *ipc,
f82568a780e35e8786958c49a1259434e2088b9cniqstatic apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
f82568a780e35e8786958c49a1259434e2088b9cniqstatic char *place(sed_eval_t *eval, char *asp, char *al1, char *al2);
f82568a780e35e8786958c49a1259434e2088b9cniqstatic apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
0134ffd85f3bcfd84cf0bea0f4b797a885eb78adniqstatic apr_status_t wline(sed_eval_t *eval, char *buf, int sz);
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void eval_errf(sed_eval_t *eval, const char *fmt, ...)
f82568a780e35e8786958c49a1259434e2088b9cniq * grow_buffer
f82568a780e35e8786958c49a1259434e2088b9cniq unsigned int newsize)
ab2b977442827214b1d884decf3e3f1579fd45e1rpluem /* Avoid number of times realloc is called. It could cause huge memory
ab2b977442827214b1d884decf3e3f1579fd45e1rpluem * requirement if line size is huge e.g 2 MB */
f82568a780e35e8786958c49a1259434e2088b9cniq /* Align it to 4 KB boundary */
f82568a780e35e8786958c49a1259434e2088b9cniq newsize = (newsize + ((1 << 12) - 1)) & ~((1 << 12) -1);
f82568a780e35e8786958c49a1259434e2088b9cniq * grow_line_buffer
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void grow_line_buffer(sed_eval_t *eval, int newsize)
f82568a780e35e8786958c49a1259434e2088b9cniq * grow_hold_buffer
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void grow_hold_buffer(sed_eval_t *eval, int newsize)
f82568a780e35e8786958c49a1259434e2088b9cniq * grow_gen_buffer
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void grow_gen_buffer(sed_eval_t *eval, int newsize,
f82568a780e35e8786958c49a1259434e2088b9cniq * appendmem_to_linebuf
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, int len)
f82568a780e35e8786958c49a1259434e2088b9cniq unsigned int reqsize = (eval->lspend - eval->linebuf) + len;
f82568a780e35e8786958c49a1259434e2088b9cniq * append_to_linebuf
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void append_to_linebuf(sed_eval_t *eval, const char* sz)
f82568a780e35e8786958c49a1259434e2088b9cniq /* Copy string including null character */
f82568a780e35e8786958c49a1259434e2088b9cniq --eval->lspend; /* lspend will now point to NULL character */
f82568a780e35e8786958c49a1259434e2088b9cniq * copy_to_linebuf
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void copy_to_linebuf(sed_eval_t *eval, const char* sz)
f82568a780e35e8786958c49a1259434e2088b9cniq * append_to_holdbuf
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void append_to_holdbuf(sed_eval_t *eval, const char* sz)
f82568a780e35e8786958c49a1259434e2088b9cniq unsigned int reqsize = (eval->hspend - eval->holdbuf) + len + 1;
f82568a780e35e8786958c49a1259434e2088b9cniq /* hspend will now point to NULL character */
f82568a780e35e8786958c49a1259434e2088b9cniq * copy_to_holdbuf
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void copy_to_holdbuf(sed_eval_t *eval, const char* sz)
f82568a780e35e8786958c49a1259434e2088b9cniq * append_to_genbuf
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend)
f82568a780e35e8786958c49a1259434e2088b9cniq unsigned int reqsize = (*gspend - eval->genbuf) + len + 1;
f82568a780e35e8786958c49a1259434e2088b9cniq /* *gspend will now point to NULL character */
f82568a780e35e8786958c49a1259434e2088b9cniq * copy_to_genbuf
f82568a780e35e8786958c49a1259434e2088b9cniqstatic void copy_to_genbuf(sed_eval_t *eval, const char* sz)
f82568a780e35e8786958c49a1259434e2088b9cniq * sed_init_eval
f82568a780e35e8786958c49a1259434e2088b9cniqapr_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)
f82568a780e35e8786958c49a1259434e2088b9cniq * sed_reset_eval
f82568a780e35e8786958c49a1259434e2088b9cniqapr_status_t sed_reset_eval(sed_eval_t *eval, sed_commands_t *commands, sed_err_fn_t *errfn, void *data)
f82568a780e35e8786958c49a1259434e2088b9cniq for (i = 0; i < sizeof(eval->abuf) / sizeof(eval->abuf[0]); i++)
f82568a780e35e8786958c49a1259434e2088b9cniq eval->inar = apr_pcalloc(eval->pool, commands->nrep * sizeof(unsigned char));
f82568a780e35e8786958c49a1259434e2088b9cniq eval->finalflag = 1; /* assume we're evaluating only one file/stream */
f82568a780e35e8786958c49a1259434e2088b9cniq * sed_destroy_eval
f82568a780e35e8786958c49a1259434e2088b9cniq /* eval->linebuf, eval->holdbuf, eval->genbuf and eval->inar are allocated
f82568a780e35e8786958c49a1259434e2088b9cniq * on pool. It will be freed when pool will be freed */
f82568a780e35e8786958c49a1259434e2088b9cniq * sed_eval_file
f82568a780e35e8786958c49a1259434e2088b9cniqapr_status_t sed_eval_file(sed_eval_t *eval, apr_file_t *fin, void *fout)
f82568a780e35e8786958c49a1259434e2088b9cniq for (;;) {
f82568a780e35e8786958c49a1259434e2088b9cniq if (apr_file_read(fin, buf, &read_bytes) != APR_SUCCESS)
f82568a780e35e8786958c49a1259434e2088b9cniq if (sed_eval_buffer(eval, buf, read_bytes, fout) != APR_SUCCESS)
f82568a780e35e8786958c49a1259434e2088b9cniq * sed_eval_buffer
f82568a780e35e8786958c49a1259434e2088b9cniqapr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, int bufsz, void *fout)
f82568a780e35e8786958c49a1259434e2088b9cniq /* Commands were not finalized properly. */
f82568a780e35e8786958c49a1259434e2088b9cniq const char* error = sed_get_finalize_error(eval->commands, eval->pool);
f82568a780e35e8786958c49a1259434e2088b9cniq /* Process leftovers */
f82568a780e35e8786958c49a1259434e2088b9cniq /* This might be the last line; delay its processing */
f82568a780e35e8786958c49a1259434e2088b9cniq /* replace new line character with NULL */
f82568a780e35e8786958c49a1259434e2088b9cniq /* Save the leftovers for later */
f82568a780e35e8786958c49a1259434e2088b9cniq * sed_finalize_eval
f82568a780e35e8786958c49a1259434e2088b9cniqapr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout)
f82568a780e35e8786958c49a1259434e2088b9cniq /* Process leftovers */
f82568a780e35e8786958c49a1259434e2088b9cniq /* Code can probably reach here when last character in output
f82568a780e35e8786958c49a1259434e2088b9cniq * buffer is not a newline.
f82568a780e35e8786958c49a1259434e2088b9cniq /* Assure space for NULL */
0134ffd85f3bcfd84cf0bea0f4b797a885eb78adniq rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
f82568a780e35e8786958c49a1259434e2088b9cniq if(*expbuf) return(0);
f82568a780e35e8786958c49a1259434e2088b9cniq * substitute
f82568a780e35e8786958c49a1259434e2088b9cniqstatic int substitute(sed_eval_t *eval, sed_reptr_t *ipc,
f82568a780e35e8786958c49a1259434e2088b9cniq eval->sflag = 0; /* Flags if any substitution was made */
f82568a780e35e8786958c49a1259434e2088b9cniq if (dosub(eval, ipc->rhs, ipc->gfl, step_vars) != APR_SUCCESS)
f82568a780e35e8786958c49a1259434e2088b9cniq return -1;
f82568a780e35e8786958c49a1259434e2088b9cniq if (dosub(eval, ipc->rhs, ipc->gfl, step_vars) != APR_SUCCESS)
f82568a780e35e8786958c49a1259434e2088b9cniq return -1;
f82568a780e35e8786958c49a1259434e2088b9cniqstatic apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
f82568a780e35e8786958c49a1259434e2088b9cniq if(n > 0 && n < 999) {
f82568a780e35e8786958c49a1259434e2088b9cniq while ((c = *rp++) != 0) {
f82568a780e35e8786958c49a1259434e2088b9cniq if (c == '&') {
f82568a780e35e8786958c49a1259434e2088b9cniq else if (c == '\\') {
f82568a780e35e8786958c49a1259434e2088b9cniq /* expand genbuf and set the sp appropriately */
f82568a780e35e8786958c49a1259434e2088b9cniqstatic char *place(sed_eval_t *eval, char *asp, char *al1, char *al2)
f82568a780e35e8786958c49a1259434e2088b9cniq return sp + n;
f82568a780e35e8786958c49a1259434e2088b9cniqstatic apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
f82568a780e35e8786958c49a1259434e2088b9cniq char sz[32]; /* 32 bytes enough to store 64 bit integer in decimal */
f82568a780e35e8786958c49a1259434e2088b9cniq if(*p1++ == 0) {
f82568a780e35e8786958c49a1259434e2088b9cniq length = apr_snprintf(sz, sizeof(sz), "%d", (int) eval->lnum);
0134ffd85f3bcfd84cf0bea0f4b797a885eb78adniq rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
0134ffd85f3bcfd84cf0bea0f4b797a885eb78adniq rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
f82568a780e35e8786958c49a1259434e2088b9cniq for (p1 = eval->linebuf; *p1 != '\n' && *p1 != '\0'; p1++);
0134ffd85f3bcfd84cf0bea0f4b797a885eb78adniq rv = wline(eval, eval->linebuf, eval->lspend - eval->linebuf);
f82568a780e35e8786958c49a1259434e2088b9cniq if (i == -1) {
f82568a780e35e8786958c49a1259434e2088b9cniq for (p1 = eval->linebuf; *p1 != '\n' && *p1 != '\0'; p1++);
f82568a780e35e8786958c49a1259434e2088b9cniq if (i && (ipc->findex >= 0) && eval->fcode[ipc->findex])
0134ffd85f3bcfd84cf0bea0f4b797a885eb78adniq rv = wline(eval, (*eval->aptr)->re1, p1 - (*eval->aptr)->re1);
f82568a780e35e8786958c49a1259434e2088b9cniq if (apr_file_open(&fi, (*eval->aptr)->re1, APR_READ, 0, eval->pool)
f82568a780e35e8786958c49a1259434e2088b9cniq if (n == 0)
f82568a780e35e8786958c49a1259434e2088b9cniq n = sizeof(buf);
0134ffd85f3bcfd84cf0bea0f4b797a885eb78adniqstatic apr_status_t wline(sed_eval_t *eval, char *buf, int sz)