/* 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; }
/* replace text matched by a pattern according to a substitution template; return pointer to the modified text */ static int replace_matching_text( const line_t *lp, const int gflags, const int snum ) { const int se_max = 30; /* max subexpressions in a regular expression */ regmatch_t rm[se_max]; char *txt = get_sbuf_line( lp ); char *eot; int i = 0, off = 0; char changed = 0; if( !txt ) return -1; if( isbinary() ) nul_to_newline( txt, lp->len ); eot = txt + lp->len; if( !regexec( global_pat, txt, se_max, rm, 0 ) ) { int matchno = 0; do { if( !snum || snum == ++matchno ) { changed = 1; i = rm[0].rm_so; if( !resize_buffer( &rbuf, &rbufsz, off + i ) ) return -1; if( isbinary() ) newline_to_nul( txt, rm[0].rm_eo ); memcpy( rbuf + off, txt, i ); off += i; off = apply_subst_template( txt, rm, off, global_pat->re_nsub ); if( off < 0 ) return -1; } else { i = rm[0].rm_eo; if( !resize_buffer( &rbuf, &rbufsz, off + i ) ) return -1; if( isbinary() ) newline_to_nul( txt, i ); memcpy( rbuf + off, txt, i ); off += i; } txt += rm[0].rm_eo; } while( *txt && ( !changed || ( ( gflags & GSG ) && rm[0].rm_eo ) ) && !regexec( global_pat, txt, se_max, rm, REG_NOTBOL ) ); i = eot - txt; if( !resize_buffer( &rbuf, &rbufsz, off + i + 2 ) ) return -1; if( i > 0 && !rm[0].rm_eo && ( gflags & GSG ) ) { set_error_msg( "Infinite substitution loop" ); return -1; } if( isbinary() ) newline_to_nul( txt, i ); memcpy( rbuf + off, txt, i ); memcpy( rbuf + off + i, "\n", 2 ); } return ( changed ? off + i + 1 : 0 ); }