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