Lines 71-77
Link Here
|
71 |
static void do_tr(struct s_tr *); |
71 |
static void do_tr(struct s_tr *); |
72 |
static void flush_appends(void); |
72 |
static void flush_appends(void); |
73 |
static void lputs(char *, size_t); |
73 |
static void lputs(char *, size_t); |
74 |
static int regexec_e(regex_t *, const char *, int, int, size_t); |
74 |
static int regexec_e(regex_t *, const char *, int, int, size_t, |
|
|
75 |
size_t); |
75 |
static void regsub(SPACE *, char *, char *); |
76 |
static void regsub(SPACE *, char *, char *); |
76 |
static int substitute(struct s_command *); |
77 |
static int substitute(struct s_command *); |
77 |
|
78 |
|
Lines 281-287
Link Here
|
281 |
* (lastline, linenumber, ps). |
282 |
* (lastline, linenumber, ps). |
282 |
*/ |
283 |
*/ |
283 |
#define MATCH(a) \ |
284 |
#define MATCH(a) \ |
284 |
((a)->type == AT_RE ? regexec_e((a)->u.r, ps, 0, 1, psl) : \ |
285 |
((a)->type == AT_RE ? regexec_e((a)->u.r, ps, 0, 1, 0, psl) : \ |
285 |
(a)->type == AT_LINE ? linenum == (a)->u.l : lastline()) |
286 |
(a)->type == AT_LINE ? linenum == (a)->u.l : lastline()) |
286 |
|
287 |
|
287 |
/* |
288 |
/* |
Lines 381-386
Link Here
|
381 |
regex_t *re; |
382 |
regex_t *re; |
382 |
regoff_t slen; |
383 |
regoff_t slen; |
383 |
int lastempty, n; |
384 |
int lastempty, n; |
|
|
385 |
size_t le = 0; |
384 |
char *s; |
386 |
char *s; |
385 |
|
387 |
|
386 |
s = ps; |
388 |
s = ps; |
Lines 392-398
Link Here
|
392 |
linenum, fname, cp->u.s->maxbref); |
394 |
linenum, fname, cp->u.s->maxbref); |
393 |
} |
395 |
} |
394 |
} |
396 |
} |
395 |
if (!regexec_e(re, s, 0, 0, psl)) |
397 |
if (!regexec_e(re, s, 0, 0, 0, psl)) |
396 |
return (0); |
398 |
return (0); |
397 |
|
399 |
|
398 |
SS.len = 0; /* Clean substitute space. */ |
400 |
SS.len = 0; /* Clean substitute space. */ |
Lines 402-429
Link Here
|
402 |
|
404 |
|
403 |
do { |
405 |
do { |
404 |
/* Copy the leading retained string. */ |
406 |
/* Copy the leading retained string. */ |
405 |
if (n <= 1 && match[0].rm_so) |
407 |
if (n <= 1 && match[0].rm_so - le) |
406 |
cspace(&SS, s, match[0].rm_so, APPEND); |
408 |
cspace(&SS, s, match[0].rm_so - le, APPEND); |
407 |
|
409 |
|
408 |
/* Skip zero-length matches right after other matches. */ |
410 |
/* Skip zero-length matches right after other matches. */ |
409 |
if (lastempty || match[0].rm_so || |
411 |
if (lastempty || (match[0].rm_so - le) || |
410 |
match[0].rm_so != match[0].rm_eo) { |
412 |
match[0].rm_so != match[0].rm_eo) { |
411 |
if (n <= 1) { |
413 |
if (n <= 1) { |
412 |
/* Want this match: append replacement. */ |
414 |
/* Want this match: append replacement. */ |
413 |
regsub(&SS, s, cp->u.s->new); |
415 |
regsub(&SS, ps, cp->u.s->new); |
414 |
if (n == 1) |
416 |
if (n == 1) |
415 |
n = -1; |
417 |
n = -1; |
416 |
} else { |
418 |
} else { |
417 |
/* Want a later match: append original. */ |
419 |
/* Want a later match: append original. */ |
418 |
if (match[0].rm_eo) |
420 |
if (match[0].rm_eo - le) |
419 |
cspace(&SS, s, match[0].rm_eo, APPEND); |
421 |
cspace(&SS, s, match[0].rm_eo - le, |
|
|
422 |
APPEND); |
420 |
n--; |
423 |
n--; |
421 |
} |
424 |
} |
422 |
} |
425 |
} |
423 |
|
426 |
|
424 |
/* Move past this match. */ |
427 |
/* Move past this match. */ |
425 |
s += match[0].rm_eo; |
428 |
s += (match[0].rm_eo - le); |
426 |
slen -= match[0].rm_eo; |
429 |
slen -= (match[0].rm_eo - le); |
|
|
430 |
le = match[0].rm_eo; |
427 |
|
431 |
|
428 |
/* |
432 |
/* |
429 |
* After a zero-length match, advance one byte, |
433 |
* After a zero-length match, advance one byte, |
Lines 434-446
Link Here
|
434 |
slen = -1; |
438 |
slen = -1; |
435 |
else |
439 |
else |
436 |
slen--; |
440 |
slen--; |
437 |
if (*s != '\0') |
441 |
if (*s != '\0') { |
438 |
cspace(&SS, s++, 1, APPEND); |
442 |
cspace(&SS, s++, 1, APPEND); |
|
|
443 |
le++; |
444 |
} |
439 |
lastempty = 1; |
445 |
lastempty = 1; |
440 |
} else |
446 |
} else |
441 |
lastempty = 0; |
447 |
lastempty = 0; |
442 |
|
448 |
|
443 |
} while (n >= 0 && slen >= 0 && regexec_e(re, s, REG_NOTBOL, 0, slen)); |
449 |
} while (n >= 0 && slen >= 0 && regexec_e(re, ps, 0, 0, le, psl)); |
444 |
|
450 |
|
445 |
/* Did not find the requested number of matches. */ |
451 |
/* Did not find the requested number of matches. */ |
446 |
if (n > 1) |
452 |
if (n > 1) |
Lines 652-658
Link Here
|
652 |
|
658 |
|
653 |
static int |
659 |
static int |
654 |
regexec_e(regex_t *preg, const char *string, int eflags, int nomatch, |
660 |
regexec_e(regex_t *preg, const char *string, int eflags, int nomatch, |
655 |
size_t slen) |
661 |
size_t start, size_t stop) |
656 |
{ |
662 |
{ |
657 |
int eval; |
663 |
int eval; |
658 |
|
664 |
|
Lines 663-670
Link Here
|
663 |
defpreg = preg; |
669 |
defpreg = preg; |
664 |
|
670 |
|
665 |
/* Set anchors */ |
671 |
/* Set anchors */ |
666 |
match[0].rm_so = 0; |
672 |
match[0].rm_so = start; |
667 |
match[0].rm_eo = slen; |
673 |
match[0].rm_eo = stop; |
668 |
|
674 |
|
669 |
eval = regexec(defpreg, string, |
675 |
eval = regexec(defpreg, string, |
670 |
nomatch ? 0 : maxnsub + 1, match, eflags | REG_STARTEND); |
676 |
nomatch ? 0 : maxnsub + 1, match, eflags | REG_STARTEND); |