summaryrefslogtreecommitdiffstats
path: root/usr.bin/sed/process.c
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2009-05-25 06:45:33 +0000
committerbrian <brian@FreeBSD.org>2009-05-25 06:45:33 +0000
commitd2e1d02aee4f88f94d6a339f0bea9c50a8021d9d (patch)
tree58c15e354139e133c3610f654c7ea9a645df5a89 /usr.bin/sed/process.c
parent94f304cdb00fc25cb6b7e8d5b0d6e292aae7e244 (diff)
downloadFreeBSD-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.c33
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.
OpenPOWER on IntegriCloud