diff options
author | brian <brian@FreeBSD.org> | 2009-05-25 06:45:33 +0000 |
---|---|---|
committer | brian <brian@FreeBSD.org> | 2009-05-25 06:45:33 +0000 |
commit | d2e1d02aee4f88f94d6a339f0bea9c50a8021d9d (patch) | |
tree | 58c15e354139e133c3610f654c7ea9a645df5a89 /usr.bin/sed/process.c | |
parent | 94f304cdb00fc25cb6b7e8d5b0d6e292aae7e244 (diff) | |
download | FreeBSD-src-d2e1d02aee4f88f94d6a339f0bea9c50a8021d9d.zip FreeBSD-src-d2e1d02aee4f88f94d6a339f0bea9c50a8021d9d.tar.gz |
Implement "addr1,+N" ranges - not dissimilar to grep's -A switch.
PR: 134856
Submitted by: Jeremie Le Hen - jeremie at le-hen dot org
Diffstat (limited to 'usr.bin/sed/process.c')
-rw-r--r-- | usr.bin/sed/process.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/usr.bin/sed/process.c b/usr.bin/sed/process.c index a29fe0e..5e2618a 100644 --- a/usr.bin/sed/process.c +++ b/usr.bin/sed/process.c @@ -275,8 +275,8 @@ new: if (!nflag && !pd) (a)->type == AT_LINE ? linenum == (a)->u.l : lastline()) /* - * Return TRUE if the command applies to the current line. Sets the inrange - * flag to process ranges. Interprets the non-select (``!'') flag. + * Return TRUE if the command applies to the current line. Sets the start + * line for process ranges. Interprets the non-select (``!'') flag. */ static __inline int applies(struct s_command *cp) @@ -287,18 +287,22 @@ applies(struct s_command *cp) if (cp->a1 == NULL && cp->a2 == NULL) r = 1; else if (cp->a2) - if (cp->inrange) { + if (cp->startline > 0) { if (MATCH(cp->a2)) { - cp->inrange = 0; + cp->startline = 0; lastaddr = 1; r = 1; - } else if (cp->a2->type == AT_LINE && - linenum > cp->a2->u.l) { + } else if (linenum - cp->startline <= cp->a2->u.l) + r = 1; + else if ((cp->a2->type == AT_LINE && + linenum > cp->a2->u.l) || + (cp->a2->type == AT_RELLINE && + linenum - cp->startline > cp->a2->u.l)) { /* * We missed the 2nd address due to a branch, * so just close the range and return false. */ - cp->inrange = 0; + cp->startline = 0; r = 0; } else r = 1; @@ -308,12 +312,15 @@ applies(struct s_command *cp) * equal to the line number first selected, only * one line shall be selected. * -- POSIX 1003.2 + * Likewise if the relative second line address is zero. */ - if (cp->a2->type == AT_LINE && - linenum >= cp->a2->u.l) + if ((cp->a2->type == AT_LINE && + linenum >= cp->a2->u.l) || + (cp->a2->type == AT_RELLINE && cp->a2->u.l == 0)) lastaddr = 1; - else - cp->inrange = 1; + else { + cp->startline = linenum; + } r = 1; } else r = 0; @@ -331,11 +338,11 @@ resetstate(void) struct s_command *cp; /* - * Reset all inrange markers. + * Reset all in-range markers. */ for (cp = prog; cp; cp = cp->code == '{' ? cp->u.c : cp->next) if (cp->a2) - cp->inrange = 0; + cp->startline = 0; /* * Clear out the hold space. |