static int expr_cond(State_t* state, Node_t *np) { register int tok = getnode(state, np); while (tok==':') { regex_t re; regmatch_t match[2]; int n; Node_t rp; char *cp; tok = getnode(state, &rp); if (np->type&T_STR) cp = np->str; else sfsprintf(cp=state->buf,sizeof(state->buf),"%d",np->num); np->num = 0; np->type = T_NUM; if (n = regcomp(&re, rp.str, REG_LEFT|REG_LENIENT)) regfatal(&re, ERROR_exit(2), n); if (!(n = regexec(&re, cp, elementsof(match), match, 0))) { if (re.re_nsub > 0) { np->type = T_STR; if (match[1].rm_so >= 0) { np->str = cp + match[1].rm_so; np->str[match[1].rm_eo - match[1].rm_so] = 0; np->num = strtol(np->str,&cp,10); if (cp!=np->str && *cp==0) np->type |= T_NUM; } else np->str = ""; } else np->num = match[0].rm_eo - match[0].rm_so; } else if (n != REG_NOMATCH) regfatal(&re, ERROR_exit(2), n); else if (re.re_nsub) { np->str = ""; np->type = T_STR; } regfree(&re); } return tok; }
static void compile(void) { register char* s; int c; s = input(0); if (*s) { if (*(s + 1)) { if (*s == *(s + 1)) input(2); else { if (ed.compiled) { ed.compiled = 0; regfree(&ed.re); } if (c = regcomp(&ed.re, s, ed.reflags)) { regfatal(&ed.re, 2, c); eat(); } else input(ed.re.re_npat); ed.compiled = 1; return; } } else input(1); } if (!ed.compiled) error(2, "no previous regular expression"); }
static void substitute(int inglob) { register Line_t* a1; char* s; char* e; int n; n = getnum(); compile(); splice(); if (n = regsubcomp(&ed.re, input(0), submap, n, 0)) regfatal(&ed.re, 2, n); else { if (!(ed.re.re_sub->re_flags & REG_SUB_FULL)) ed.re.re_sub->re_flags |= REG_SUB_PRINT; if ((n = *input(ed.re.re_npat)) && n != '\r' && n != '\n') error(2, "extra characters at end of command"); ed.print = ed.re.re_sub->re_flags; } eat(); for (a1 = ed.addr1; a1 <= ed.addr2; a1++) { if (execute(a1, 0)) { if (!regsubexec(&ed.re, CUR(), elementsof(ed.match), ed.match)) { inglob = 1; s = ed.re.re_sub->re_buf; SET(s, ed.re.re_sub->re_len); if (e = strchr(s, '\n')) *e++ = 0; replace(a1, s); if (e) { ed.linebreak = e; a1 = append(getbreak, a1, &ed.addr2); } } } } if (!inglob) error(2, "global pattern not found"); ed.dot = ed.addr2; }
static int execute(Line_t* addr, regflags_t flags) { register char* s; register int c; trap(); if (!addr) s = CUR(); else if (addr == ed.zero) return 0; else { s = lineget(addr->offset); SET(s, 0); } if (c = regexec(&ed.re, s, elementsof(ed.match), ed.match, ed.reflags|flags)) { if (c != REG_NOMATCH) regfatal(&ed.re, 2, c); return 0; } return 1; }
static int compare(char* pred, char* args, int match) { register int c; char* pptoken; long state; regex_t re; char tmp[MAXTOKEN + 1]; state = (pp.state & ~DISABLE); PUSH_STRING(args); pp.state |= PASSEOF; pptoken = pp.token; pp.token = tmp; if (!pplex()) goto bad; pp.token = pptoken; if (pplex() != ',' || !pplex()) goto bad; if (!match) c = strcmp(tmp, pp.token); else if ((c = regcomp(&re, pp.token, REG_AUGMENTED|REG_LENIENT|REG_NULL)) || (c = regexec(&re, tmp, NiL, 0, 0)) && c != REG_NOMATCH) regfatal(&re, 4, c); else { c = !c; regfree(&re); } if ((pp.state & PASSEOF) && pplex()) goto bad; pp.state = state; return c; bad: pp.token = pptoken; error(2, "%s: 2 arguments expected", pred); while (pplex()); pp.state = state; return 0; }