/* * regsub */ #include #include #include #include #include #include "regmagic.h" /* - regsub - perform substitutions after a regexp match */ void regsub(rp, source, dest) const regexp *rp; const char *source; char *dest; { regnsub(rp, source, dest, BUFSIZ); } /* - regnsub - perform bounds-checked substitutions after a regexp match */ void regnsub(rp, source, dest, destlen) const regexp *rp; const char *source; char *dest; size_t destlen; { register regexp * const prog = (regexp *)rp; register const char *src = (char *)source; register char *dst = dest; char *dstend = dest + destlen; char *odst; register char c; register int no; register size_t len; if (prog == NULL || source == NULL || dest == NULL) { regerror("NULL parameter to regsub"); return; } if ((unsigned char)*(prog->program) != MAGIC) { regerror("damaged regexp"); return; } while ((c = *src++) != '\0') { if (c == '&') no = 0; else if (c == '\\' && isdigit(*src)) no = *src++ - '0'; else no = -1; if (no < 0) { /* Ordinary character. */ if (c == '\\' && (*src == '\\' || *src == '&')) c = *src++; *dst++ = c; if (dst >= dstend) { regerror("output buffer too small"); return; } } else if (prog->startp[no] != NULL && prog->endp[no] != NULL && prog->endp[no] > prog->startp[no]) { len = prog->endp[no] - prog->startp[no]; odst = dst; dst += len; if (dst >= dstend) { regerror("output buffer too small"); return; } (void) strncpy(odst, prog->startp[no], len); if (*(dst-1) == '\0') { /* strncpy hit NUL. */ regerror("damaged match string"); return; } } } *dst++ = '\0'; } size_t regsublen(rp, source) const regexp *rp; const char *source; { register regexp * const prog = (regexp *)rp; register char *src = (char *)source; register char c; register int no; register int len = 0; if (prog == NULL || source == NULL) { regerror("NULL parameter to regsublen"); return -1; } if ((unsigned char)*(prog->program) != MAGIC) { regerror("damaged regexp"); return -1; } while ((c = *src++) != '\0') { if (c == '&') no = 0; else if (c == '\\' && isdigit(*src)) no = *src++ - '0'; else no = -1; if (no < 0) { /* Ordinary character. */ if (c == '\\' && (*src == '\\' || *src == '&')) src++; len++; } else { const char *s = prog->startp[no]; const char *e = prog->endp[no]; if ((s != NULL) && (e != NULL) && (e > s)) { len += e-s; } } } return len+1; }