/* build_active_list: add line matching a pattern to the global-active list */ int build_active_list(int isgcmd) { regex_t *pat; line_t *lp; int n; char *s; char delimiter; if ((delimiter = *ibufp) == ' ' || delimiter == '\n') { seterrmsg("invalid pattern delimiter"); return ERR; } else if ((pat = get_compiled_pattern()) == NULL) return ERR; else if (*ibufp == delimiter) ibufp++; clear_active_list(); lp = get_addressed_line_node(first_addr); for (n = first_addr; n <= second_addr; n++, lp = lp->q_forw) { if ((s = get_sbuf_line(lp)) == NULL) return ERR; if (isbinary) NUL_TO_NEWLINE(s, lp->len); if (!regexec(pat, s, 0, NULL, 0) == isgcmd && set_active_node(lp) < 0) return ERR; } return 0; }
/* extract_pattern: copy a pattern string from the command buffer; return pointer to the copy */ char * extract_pattern(int delimiter) { static char *lhbuf = NULL; /* buffer */ static int lhbufsz = 0; /* buffer size */ char *nd; int len; for (nd = ibufp; *nd != delimiter && *nd != '\n'; nd++) switch (*nd) { default: break; case '[': if ((nd = parse_char_class(++nd)) == NULL) { errmsg = "unbalanced brackets ([])"; return NULL; } break; case '\\': if (*++nd == '\n') { errmsg = "trailing backslash (\\)"; return NULL; } break; } len = nd - ibufp; REALLOC(lhbuf, lhbufsz, len + 1, NULL); memcpy(lhbuf, ibufp, len); lhbuf[len] = '\0'; ibufp = nd; return (isbinary) ? NUL_TO_NEWLINE(lhbuf, len) : lhbuf; }
/* get_matching_node_addr: Return the address of the next line matching a pattern in a given direction. Wrap around begin/end of editor buffer if necessary. */ int get_matching_node_address (const regex_t *re, int dir, off_t *addr, ed_buffer_t *ed) { regmatch_t rm[1]; ed_line_node_t *lp; char *s; *addr = ed->state->dot; if (!re) return ERR; do { if ((*addr = (dir ? INC_MOD (*addr, ed->state->lines) : DEC_MOD (*addr, ed->state->lines)))) { lp = get_line_node (*addr, ed); if (!(s = get_buffer_line (lp, ed))) return ERR; #ifdef REG_STARTEND rm->rm_so = 0; rm->rm_eo = lp->len; if (!regexec (re, s, 0, rm, REG_STARTEND)) #else if (ed->state->is_binary) NUL_TO_NEWLINE (s, lp->len); if (!regexec (re, s, 0, NULL, 0)) #endif /* !defined (REG_STARTEND) */ return 0; } } while (*addr != ed->state->dot); ed->exec->err = _("No match"); return ERR; }
/* substitute_matching_text: replace text matched by a pattern according to a substitution template; return pointer to the modified text */ int substitute_matching_text(pattern_t *pat, line_t *lp, int gflag, int kth) { int off = 0; int changed = 0; int matchno = 0; int i = 0; regmatch_t rm[SE_MAX]; char *txt; char *eot; if ((txt = get_sbuf_line(lp)) == NULL) return ERR; if (isbinary) NUL_TO_NEWLINE(txt, lp->len); eot = txt + lp->len; if (!regexec(pat, txt, SE_MAX, rm, 0)) { do { if (!kth || kth == ++matchno) { changed++; i = rm[0].rm_so; REALLOC(rbuf, rbufsz, off + i, ERR); if (isbinary) NEWLINE_TO_NUL(txt, rm[0].rm_eo); memcpy(rbuf + off, txt, i); off += i; if ((off = apply_subst_template(txt, rm, off, pat->re_nsub)) < 0) return ERR; } else { i = rm[0].rm_eo; REALLOC(rbuf, rbufsz, off + i, ERR); if (isbinary) NEWLINE_TO_NUL(txt, i); memcpy(rbuf + off, txt, i); off += i; } txt += rm[0].rm_eo; } while (*txt && (!changed || ((gflag & GSG) && rm[0].rm_eo)) && !regexec(pat, txt, SE_MAX, rm, REG_NOTBOL)); i = eot - txt; REALLOC(rbuf, rbufsz, off + i + 2, ERR); if (i > 0 && !rm[0].rm_eo && (gflag & GSG)) { errmsg = "infinite substitution loop"; return ERR; } if (isbinary) NEWLINE_TO_NUL(txt, i); memcpy(rbuf + off, txt, i); memcpy(rbuf + off + i, "\n", 2); } return changed ? off + i + 1 : 0; }
/* mark_global_nodes: Add lines matching a pattern to global queue. */ int mark_global_nodes (int want_match, ed_buffer_t *ed) { regmatch_t rm[1]; regex_t *re; ed_line_node_t *lp; off_t from = ed->exec->region->start; off_t to = ed->exec->region->end; off_t n = from ? to - from + 1 : 0; char dc = *ed->input; /* pattern delimiting char */ char *s; spl1 (); if (!(re = get_compiled_regex (dc, RE_SEARCH, ed))) { spl0 (); return ERR; } if (*ed->input == dc && *ed->input != '\n') ++ed->input; reset_global_queue (ed); spl0 (); lp = get_line_node (from, ed); for (; n; --n, lp = lp->q_forw) { if (!(s = get_buffer_line (lp, ed))) return ERR; #ifdef REG_STARTEND rm->rm_so = 0; rm->rm_eo = lp->len; if ((!regexec (re, s, 0, rm, REG_STARTEND)) == want_match && !append_global_node (lp, ed)) #else if (ed->state->is_binary) NUL_TO_NEWLINE (s, lp->len); if (!regexec (re, s, 0, NULL, 0) == want_match && !append_global_node (lp, ed)) #endif /* !REG_STARTEND */ return ERR; } return 0; }