[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #25805] fgrep or "grep -F" fails to match patterns on Windows/DOS

From: Harold Bamford
Subject: [bug #25805] fgrep or "grep -F" fails to match patterns on Windows/DOS
Date: Tue, 10 Mar 2009 00:57:09 +0000
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/2009011913 Firefox/3.0.6 (.NET CLR 3.5.30729)


                 Summary: fgrep or "grep -F"  fails to match patterns on
                 Project: grep
            Submitted by: hbamford
            Submitted on: Tue 10 Mar 2009 12:57:06 AM GMT
                Category: None
                Severity: 3 - Normal
              Item Group: None
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any



On a Windows/DOS box, the newline is actually \r\n rather than the normal
Unix \n. The function Fcompile() (in src/search.c around line 500) doesn't
account for this and so the \r is treated as part of the pattern. This is
almost never what was intended. I checked the latest version, 2.5.4

As a temporary kludgey patch, I have this alternate version of that

  char const *beg, *lim, *err;

  kwsinit ();
  beg = pattern;
    for (lim = beg; lim < pattern + size && *lim != '\n'; ++lim)

#if HAVE_DOS_FILE_CONTENTS      /* heb */
    // Try to handle Windows/DOS \r\n pairs as just a \n.
    // This function (Fcompile) is called as:
    //          compile(keys, keycc);
    // which becomes:
    //          Fcompile(pattern,size);
    // if the -F option was given or if the program is called 'fgrep' rather
than 'grep'.
    // This means that the patterns are in a file, seperated by newlines. And
that is
    // the problem; newlines are different on different machines (like
Windows and Mac).
    // This "fix" only addresses the case of Windows/DOS machines using ASCII
    // files.
    // This is a ghastly kludge, but for straight ASCII input on a Windows
    // it seems to work.  The idea is that if we have just encountered a '\n'
    // (as the above for() loop has terminated), then see if it was preceded
by a '\r'
    // char. If so, tell kwsincr() that the string is shorter by 1 than
actually found.
    // This won't work for multibyte chars and it probably doesn't handle
lots of other
    // cases, but it lets me get by on my Windows box running Cygwin.
    if(((lim - beg) >= 1) &&    /* must have at least 2 chars to look at */
        (*lim == '\n')    &&    /* last one is a normal Unix-style newline char
        (*(lim - 1) == '\r'))   /* next-to-last one is a carriage-return char
      // Indicate string is shorter by 1
      if ((err = kwsincr (kwset, beg, (lim - beg) - 1)) != 0)
        error (2, 0, err);
      // Normal, non-Windows operation
      if ((err = kwsincr (kwset, beg, lim - beg)) != 0)
        error (2, 0, err);
    // This does not handle Windows/DOS newlines (\r\n instead of \n)
    if ((err = kwsincr (kwset, beg, lim - beg)) != 0)
      error (2, 0, err);

    if (lim < pattern + size)
    beg = lim;
  while (beg < pattern + size);

  if ((err = kwsprep (kwset)) != 0)
    error (2, 0, err);


Reply to this item at:


  Message sent via/by Savannah

reply via email to

[Prev in Thread] Current Thread [Next in Thread]