From owner-svn-src-head@FreeBSD.ORG Mon May 25 06:45:34 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1F0D3106564A; Mon, 25 May 2009 06:45:34 +0000 (UTC) (envelope-from brian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0D29B8FC14; Mon, 25 May 2009 06:45:34 +0000 (UTC) (envelope-from brian@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n4P6jXJe013846; Mon, 25 May 2009 06:45:33 GMT (envelope-from brian@svn.freebsd.org) Received: (from brian@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n4P6jXIw013842; Mon, 25 May 2009 06:45:33 GMT (envelope-from brian@svn.freebsd.org) Message-Id: <200905250645.n4P6jXIw013842@svn.freebsd.org> From: Brian Somers Date: Mon, 25 May 2009 06:45:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r192732 - head/usr.bin/sed X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 May 2009 06:45:34 -0000 Author: brian Date: Mon May 25 06:45:33 2009 New Revision: 192732 URL: http://svn.freebsd.org/changeset/base/192732 Log: Implement "addr1,+N" ranges - not dissimilar to grep's -A switch. PR: 134856 Submitted by: Jeremie Le Hen - jeremie at le-hen dot org Modified: head/usr.bin/sed/compile.c head/usr.bin/sed/defs.h head/usr.bin/sed/process.c head/usr.bin/sed/sed.1 Modified: head/usr.bin/sed/compile.c ============================================================================== --- head/usr.bin/sed/compile.c Mon May 25 06:39:48 2009 (r192731) +++ head/usr.bin/sed/compile.c Mon May 25 06:45:33 2009 (r192732) @@ -181,7 +181,7 @@ semicolon: EATSPACE(); if ((*link = cmd = malloc(sizeof(struct s_command))) == NULL) err(1, "malloc"); link = &cmd->next; - cmd->nonsel = cmd->inrange = 0; + cmd->startline = cmd->nonsel = 0; /* First parse the addresses */ naddr = 0; @@ -775,6 +775,7 @@ compile_addr(char *p, struct s_addr *a) icase = 0; + a->type = 0; switch (*p) { case '\\': /* Context address */ ++p; @@ -798,10 +799,16 @@ compile_addr(char *p, struct s_addr *a) case '$': /* Last line */ a->type = AT_LAST; return (p + 1); + + case '+': /* Relative line number */ + a->type = AT_RELLINE; + p++; + /* FALLTHROUGH */ /* Line number */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - a->type = AT_LINE; + if (a->type == 0) + a->type = AT_LINE; a->u.l = strtol(p, &end, 10); return (end); default: Modified: head/usr.bin/sed/defs.h ============================================================================== --- head/usr.bin/sed/defs.h Mon May 25 06:39:48 2009 (r192731) +++ head/usr.bin/sed/defs.h Mon May 25 06:45:33 2009 (r192732) @@ -38,8 +38,9 @@ * Types of address specifications */ enum e_atype { - AT_RE, /* Line that match RE */ + AT_RE = 1, /* Line that match RE */ AT_LINE, /* Specific line */ + AT_RELLINE, /* Relative line */ AT_LAST, /* Last line */ }; @@ -91,6 +92,7 @@ struct s_tr { struct s_command { struct s_command *next; /* Pointer to next command */ struct s_addr *a1, *a2; /* Start and end address */ + u_long startline; /* Start line number or zero */ char *t; /* Text for : a c i r w */ union { struct s_command *c; /* Command(s) for b t { */ @@ -100,7 +102,6 @@ struct s_command { } u; char code; /* Command code */ u_int nonsel:1; /* True if ! */ - u_int inrange:1; /* True if in range */ }; /* Modified: head/usr.bin/sed/process.c ============================================================================== --- head/usr.bin/sed/process.c Mon May 25 06:39:48 2009 (r192731) +++ head/usr.bin/sed/process.c Mon May 25 06:45:33 2009 (r192732) @@ -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. Modified: head/usr.bin/sed/sed.1 ============================================================================== --- head/usr.bin/sed/sed.1 Mon May 25 06:39:48 2009 (r192731) +++ head/usr.bin/sed/sed.1 Mon May 25 06:45:33 2009 (r192732) @@ -211,6 +211,9 @@ that matches the second address. If the second address is a number less than or equal to the line number first selected, only that line is selected. +The number in the second address may be prefixed with a +.Pq Dq \&+ +to specify the number of lines to match after the first pattern. In the case when the second address is a context address, .Nm @@ -594,7 +597,10 @@ The .Fl E , I , a and .Fl i -options, as well as the +options, the prefixing +.Dq \&+ +in the second member of an address range, +as well as the .Dq I flag to the address regular expression and substitution command are non-standard