From owner-freebsd-bugs@FreeBSD.ORG Fri May 22 11:50:02 2009 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C89C6106566B for ; Fri, 22 May 2009 11:50:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 99C688FC1E for ; Fri, 22 May 2009 11:50:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id n4MBo2pX046590 for ; Fri, 22 May 2009 11:50:02 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id n4MBo26u046589; Fri, 22 May 2009 11:50:02 GMT (envelope-from gnats) Resent-Date: Fri, 22 May 2009 11:50:02 GMT Resent-Message-Id: <200905221150.n4MBo26u046589@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Jeremie Le Hen Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BAE9310656AD for ; Fri, 22 May 2009 11:47:00 +0000 (UTC) (envelope-from tataz@obiwan.tataz.chchile.org) Received: from smtpfb2-g21.free.fr (smtpfb2-g21.free.fr [212.27.42.10]) by mx1.freebsd.org (Postfix) with ESMTP id 2D8938FC19 for ; Fri, 22 May 2009 11:46:58 +0000 (UTC) (envelope-from tataz@obiwan.tataz.chchile.org) Received: from smtp6-g21.free.fr (smtp6-g21.free.fr [212.27.42.6]) by smtpfb2-g21.free.fr (Postfix) with ESMTP id 14F13CB2D37 for ; Fri, 22 May 2009 13:31:28 +0200 (CEST) Received: from smtp6-g21.free.fr (localhost [127.0.0.1]) by smtp6-g21.free.fr (Postfix) with ESMTP id 99E04E08038; Fri, 22 May 2009 13:31:22 +0200 (CEST) Received: from endor.tataz.chchile.org (tataz.chchile.org [82.233.239.98]) by smtp6-g21.free.fr (Postfix) with ESMTP id A4D83E080A5; Fri, 22 May 2009 13:31:19 +0200 (CEST) Received: from obiwan.tataz.chchile.org (obiwan.tataz.chchile.org [192.168.1.222]) by endor.tataz.chchile.org (Postfix) with ESMTP id E362333E5F; Fri, 22 May 2009 11:30:42 +0000 (UTC) Received: by obiwan.tataz.chchile.org (Postfix, from userid 1000) id BA81D50835; Fri, 22 May 2009 13:30:42 +0200 (CEST) Message-Id: <20090522113042.BA81D50835@obiwan.tataz.chchile.org> Date: Fri, 22 May 2009 13:30:42 +0200 (CEST) From: Jeremie Le Hen To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: jeremie@le-hen.org Subject: bin/134856: [PATCH] [sed] Implementation of "addr1,+N" ranges X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Jeremie Le Hen List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 May 2009 11:50:03 -0000 >Number: 134856 >Category: bin >Synopsis: [PATCH] [sed] Implementation of "addr1,+N" ranges >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri May 22 11:50:01 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Jeremie Le Hen >Release: FreeBSD 7.2-STABLE i386 >Organization: N/A >Environment: System: FreeBSD 7.2-STABLE >Description: This patch implements the "addr1,+N" range in sed(1). It is stated in the manpage that this is a non-standard extension (although both GNU sed and vim supports this). --- sed_range.diff begins here --- Index: compile.c =================================================================== RCS file: /mnt/space/cvsroot/src/usr.bin/sed/compile.c,v retrieving revision 1.33 diff -u -p -r1.33 compile.c --- compile.c 11 Nov 2008 17:15:57 -0000 1.33 +++ compile.c 22 May 2009 11:26:38 -0000 @@ -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: Index: defs.h =================================================================== RCS file: /mnt/space/cvsroot/src/usr.bin/sed/defs.h,v retrieving revision 1.7 diff -u -p -r1.7 defs.h --- defs.h 9 Feb 2008 09:12:02 -0000 1.7 +++ defs.h 22 May 2009 11:26:19 -0000 @@ -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 */ }; /* Index: process.c =================================================================== RCS file: /mnt/space/cvsroot/src/usr.bin/sed/process.c,v retrieving revision 1.49 diff -u -p -r1.49 process.c --- process.c 9 Feb 2008 09:12:02 -0000 1.49 +++ process.c 22 May 2009 11:29:47 -0000 @@ -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. Index: sed.1 =================================================================== RCS file: /mnt/space/cvsroot/src/usr.bin/sed/sed.1,v retrieving revision 1.48 diff -u -p -r1.48 sed.1 --- sed.1 1 Sep 2008 17:48:40 -0000 1.48 +++ sed.1 22 May 2009 11:03:04 -0000 @@ -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 >How-To-Repeat: >Fix: >Release-Note: >Audit-Trail: >Unformatted: