bug in OpenBSD grep

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

bug in OpenBSD grep

Ralf Wildenhues
Hello there,

I think I found a bug in OpenBSD 3.8-current grep:

$ echo 'A
B
C' | grep -v 'A
B'

gives me:

| A
| B
| C

but I'd expect it to return C only.

More generally, multiple patterns separated by newlines seem completely
broken in OpenBSD grep.  This is very unfortunate, because on some older
unixy systems, multiple -e options are broken, too, leaving no really
portable way to specify them.

I think POSIX specifies this, as well as the manpage:
| Patterns may consist of one or more lines,
| allowing any of the pattern lines to match a portion of the input.

Cheers, and thanks,
Ralf

Reply | Threaded
Open this post in threaded view
|

Re: bug in OpenBSD grep

Ray Lai
On Mon, Mar 06, 2006 at 11:23:46PM +0100, Ralf Wildenhues wrote:

> Hello there,
>
> I think I found a bug in OpenBSD 3.8-current grep:
>
> $ echo 'A
> B
> C' | grep -v 'A
> B'
>
> gives me:
>
> | A
> | B
> | C
>
> but I'd expect it to return C only.
>
> More generally, multiple patterns separated by newlines seem completely
> broken in OpenBSD grep.  This is very unfortunate, because on some older
> unixy systems, multiple -e options are broken, too, leaving no really
> portable way to specify them.

In the meantime you can do this:

        ray@x[~] echo "A\nB\nC" | egrep -v 'A|B'
        C

-Ray-

Reply | Threaded
Open this post in threaded view
|

Re: bug in OpenBSD grep

Otto Moerbeek
In reply to this post by Ralf Wildenhues
On Mon, 6 Mar 2006, Ralf Wildenhues wrote:

> Hello there,
>
> I think I found a bug in OpenBSD 3.8-current grep:
>
> $ echo 'A
> B
> C' | grep -v 'A
> B'
>
> gives me:
>
> | A
> | B
> | C
>
> but I'd expect it to return C only.
>
> More generally, multiple patterns separated by newlines seem completely
> broken in OpenBSD grep.  This is very unfortunate, because on some older
> unixy systems, multiple -e options are broken, too, leaving no really
> portable way to specify them.
>
> I think POSIX specifies this, as well as the manpage:
> | Patterns may consist of one or more lines,
> | allowing any of the pattern lines to match a portion of the input.
>
> Cheers, and thanks,
> Ralf

Try this.

        -Otto

Index: grep.c
===================================================================
RCS file: /cvs/src/usr.bin/grep/grep.c,v
retrieving revision 1.34
diff -u -p -r1.34 grep.c
--- grep.c 9 Feb 2006 09:54:46 -0000 1.34
+++ grep.c 7 Mar 2006 08:41:23 -0000
@@ -204,6 +204,18 @@ add_pattern(char *pat, size_t len)
 }
 
 static void
+add_patterns(char *pats)
+{
+ char *nl;
+
+ while ((nl = strchr(pats, '\n')) != NULL) {
+ add_pattern(pats, nl - pats);
+ pats = nl + 1;
+ }
+ add_pattern(pats, strlen(pats));
+}
+
+static void
 read_patterns(const char *fn)
 {
  FILE *f;
@@ -359,7 +371,7 @@ main(int argc, char *argv[])
  cflag = 1;
  break;
  case 'e':
- add_pattern(optarg, strlen(optarg));
+ add_patterns(optarg);
  break;
  case 'f':
  patfile = grep_malloc(sizeof(*patfile));
@@ -440,7 +452,7 @@ main(int argc, char *argv[])
  usage();
 
  if (patterns == 0) {
- add_pattern(*argv, strlen(*argv));
+ add_patterns(*argv);
  --argc;
  ++argv;
  }

Reply | Threaded
Open this post in threaded view
|

Re: bug in OpenBSD grep

Ralf Wildenhues
In reply to this post by Ray Lai
Hi Ray,

* Ray Lai wrote on Tue, Mar 07, 2006 at 05:45:42AM CET:
> On Mon, Mar 06, 2006 at 11:23:46PM +0100, Ralf Wildenhues wrote:
> >
> > $ echo 'A
> > B
> > C' | grep -v 'A
> > B'

> In the meantime you can do this:
>
> ray@x[~] echo "A\nB\nC" | egrep -v 'A|B'
> C

Thanks for the reply.  I know this possibility, also there is 'grep -e
pattern1 -e pattern2 ...'.  But I found this originally while testing
Autoconf:
http://lists.gnu.org/archive/html/autoconf-patches/2006-03/msg00024.html
and would like to be able to use as portable expressions as possible
there, to avoid too much special-casing.  The expression in question
looks more or less as pasted at the end of this message.  It may get
even longer, so will raise line-length issues if joined with '|', and,
as already mentioned, the -e option is not portable either.

Cheers,
Ralf

egrep -v '^ac_cv_prog_(gcc|gxx|g77)$
^AC_ARG_VAR$
^AC_CANONICALIZE|AC_PREFIX_PROGRAM|AC_PREREQ$
^AC_CHECK_(ALIGNOF|DECL|FILE|FUNC|HEADER|LIB|MEMBER|PROG|SIZEOF|(TARGET_)?TOOL|TYPE)S?$
^AC_CONFIG
^AC_(F77|FC)_FUNC$
^AC_FC_(FUNC|FREEFORM|SRCEXT)$
^AC_FD_CC$
^AC_FUNC_(GETLOADAVG|FNMATCH_GNU|WAIT3)$
^AC_INIT
^AC_LANG
^AC_LINKER_OPTION$
^AC_LINK_FILES$
^AC_LIST_MEMBER_OF$
^AC_OUTPUT$
^AC_PATH_((TARGET_)?TOOL|PROG)S?$
^AC_REPLACE_(FNMATCH|FUNCS)$
^AC_SEARCH_LIBS$
^(AC_TRY.*|AC_RUN_LOG)$
^AC_.*_IFELSE$
^(AC_(PROG_CC|C_CONST|C_INLINE|C_RESTRICT|C_VOLATILE))$
^AC_(CYGWIN|CYGWIN32|EMXOS2|MING32|EXEEXT|OBJEXT)$
^AC_PATH_XTRA$
^AC_SYS_RESTARTABLE_SYSCALLS$
_AC_'

Reply | Threaded
Open this post in threaded view
|

Re: bug in OpenBSD grep

Ralf Wildenhues
In reply to this post by Otto Moerbeek
* Otto Moerbeek wrote on Tue, Mar 07, 2006 at 09:42:00AM CET:
> On Mon, 6 Mar 2006, Ralf Wildenhues wrote:
> >
> > More generally, multiple patterns separated by newlines seem completely
> > broken in OpenBSD grep.

> Try this.
>
> -Otto

Seems to work fine.  Thanks for the quick fix!

Cheers,
Ralf