/* * NAME: find() * DESCRIPTION: scan a line for a pattern. If the pattern is found, longjump * out. */ static void find(const char *text) { if (rx_exec(ccb->regexp, text, 0, ccb->ignorecase) > 0) { throw "found"; } ccb->lineno++; }
static val_t Regex_exec(struct v7 *v7, val_t this_obj, val_t args) { if (v7_array_length(v7, args) > 0) { return rx_exec(v7, this_obj, v7_array_get(v7, args, 0), 0); } return v7_create_null(); }
/* * NAME: subst() * DESCRIPTION: do substitutions in a line. If something is substituted on line * N, and the next substitution happens on line N + 2, line N + 1 * is joined in the new block also. */ static void subst(const char *text) { char line[MAX_LINE_SIZE]; cmdbuf *cb; int idx, size; char *p; Int *k, *l; Int newlines; bool found; cb = ccb; found = FALSE; newlines = 0; idx = 0; /* * Because the write buffer might be flushed, and the text would * not remain in memory, use a local copy. */ text = strcpy(line, text); while (rx_exec(cb->regexp, text, idx, IGNORECASE(cb->vars)) > 0) { if (cb->flags & CB_SKIPPED) { /* * add the previous line, in which nothing was substituted, to * the block. Has to be done here, before the contents of the buffer * are changed. */ addblock(cb, cb->buffer); cb->flags &= ~CB_SKIPPED; /* * check if there were newlines in the last substitution. If there * are, marks on the previous line (without substitutions) will * also have to be changed. */ if (cb->offset > 0) { for (k = cb->mark, l = cb->moffset; k < &cb->mark[26]; k++, l++) { if (*k == cb->lineno - 1 && *l == 0) { *l = *k + cb->offset; } } } } found = TRUE; cb->flags &= ~(CB_UPPER | CB_LOWER | CB_TUPPER | CB_TLOWER); size = cb->regexp->start - text - idx; if (size > 0) { /* copy first unchanged part of line to buffer */ sub(cb, text + idx, size); } p = cb->replace; while (*p != '\0') { switch (*p) { case '&': /* insert matching string */ sub(cb, cb->regexp->start, cb->regexp->size); break; case '\\': /* special substitute characters */ switch (*++p) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* insert subexpression between \( \) */ if (cb->regexp->se[*p - '1'].start != (char*) NULL) { sub(cb, cb->regexp->se[*p - '1'].start, cb->regexp->se[*p - '1'].size); break; } /* if no subexpression, fall though */ default: sub(cb, p, 1); /* ignore preceding backslash */ break; case 'n': cb->buffer[cb->buflen++] = '\0'; newlines++; /* insert newline */ break; case 'U': /* convert string to uppercase */ cb->flags |= CB_UPPER; cb->flags &= ~(CB_LOWER | CB_TUPPER | CB_TLOWER); break; case 'L': /* convert string to lowercase */ cb->flags |= CB_LOWER; cb->flags &= ~(CB_UPPER | CB_TUPPER | CB_TLOWER); break; case 'e': case 'E': /* end case conversion */ cb->flags &= ~(CB_UPPER | CB_LOWER | CB_TUPPER | CB_TLOWER); break; case 'u': /* convert char to uppercase */ cb->flags |= CB_TUPPER; cb->flags &= ~CB_TLOWER; break; case 'l': /* convert char to lowercase */ cb->flags &= ~CB_TUPPER; cb->flags |= CB_TLOWER; break; case '\0': /* sigh */ continue; } break; default: /* normal char */ sub(cb, p, 1); break; } p++; } idx = cb->regexp->start + cb->regexp->size - text; if (!(cb->flags & CB_GLOBSUBST) || text[idx] == '\0' || (cb->regexp->size == 0 && text[++idx] == '\0')) { break; } } if (found) { if (text[idx] != '\0') { /* concatenate unchanged part of line after found pattern */ cb->flags &= ~(CB_UPPER | CB_LOWER | CB_TUPPER | CB_TLOWER); sub(cb, text + idx, strlen(text + idx)); } if (!(cb->flags & CB_CURRENTBLK)) { /* start a new block of lines with substitutions in them */ cb->flags |= CB_CHANGE; cb->first = cb->lineno; startblock(cb); cb->flags |= CB_CURRENTBLK; } /* add this changed line to block */ cb->buffer[cb->buflen] = '\0'; if (newlines == 0) { addblock(cb, cb->buffer); } else { /* * There were newlines in the substituted string. Add all * lines to the current block, and save the marks in range. */ p = cb->buffer; do { addblock(cb, p); p += strlen(p) + 1; } while (p <= cb->buffer + cb->buflen); for (k = cb->mark, l = cb->moffset; k < &cb->mark[26]; k++, l++) { if (*k == cb->lineno && *l == 0) { *l = *k + cb->offset; } } cb->offset += newlines; } cb->buflen = 0; cb->last = cb->lineno; } else { if (cb->flags & CB_SKIPPED) { /* two lines without substitutions now. Finish previous block. */ endblock(cb); cb->lineno += cb->offset; cb->offset = 0; cb->flags &= ~(CB_CURRENTBLK | CB_SKIPPED); } else if (cb->flags & CB_CURRENTBLK) { /* * no substitution on this line, but there was one on the previous * line. mark this line as skipped, so it can still be added to * the block of changed lines if the next line has substitutions. */ strcpy(cb->buffer, text); cb->flags |= CB_SKIPPED; } } cb->lineno++; }