Thread View: gnu.utils.bug
5 messages
5 total messages
Started by lang
Tue, 12 Sep 1989 18:17
Grep bug?
Author: lang
Date: Tue, 12 Sep 1989 18:17
Date: Tue, 12 Sep 1989 18:17
27 lines
1207 bytes
1207 bytes
This may not be a bug, but rather my misunderstanding the documentation, but this strikes me as odd.... % grep '\wx\w' foo finds all occurrences in foo of 'x' flanked by alphanumerics. % grep '\Wx\W' foo finds all occurrences in foo of 'x' flanked by non-alphanumerics. Fine. So far so good. Suppose now I want to find all occurrences of 'x' flanked by non-alphanumerics, but I want the match on 'x' not to be case-sensitive. Well, the -i flag makes grep ignore case difference when comparing strings, so I try % grep -i '\Wx\W' foo But the effect here is that the -i flag makes the '\W' meta-character non-case-sensitive as well, and I get all occurrences of x in foo, regardless of the case of x (which is fine) but also regardless of whether or not the x (or X) is flanked by non-alphanumerics! Is this a feature? --Francois Lang
Re: Grep bug?
Author: Tapani Tarvainen
Date: Sat, 16 Sep 1989 09:10
Date: Sat, 16 Sep 1989 09:10
75 lines
2759 bytes
2759 bytes
In article <8909121817.AA11159@gem> lang@PRC.UNISYS.COM writes:
...
>% grep -i '\Wx\W' foo
>
>But the effect here is that the -i flag makes the '\W'
>meta-character non-case-sensitive as well
I would call this a bug (and patched it).
I traced the problem to the following piece of code in dfa.c:
/* Parse and analyze a single string of the given length. */
void
regcompile(s, len, r, searchflag)
const char *s;
size_t len;
struct regexp *r;
int searchflag;
{
if (case_fold) /* dummy folding in service of regmust() */
{
static char *p;
case_fold = 0;
for (p = (char *)s; *p != 0; p++)
if (isupper((int)*p))
*p = tolower((int) *p);
...
I.e., when the -i flag is given, it folds the entire regexp to lower
case before doing anything else with it. I failed to find any reason
for this: the search routines handle case folding on their own anyway,
and removing the above loop didn't seem to have any other effect than
removing the undesired effect of -i flag on \W (and \B).
Does somebody know if the folding loop is necessary in some other
program using dfa.c (or do they maybe have the same bug)?
If yes, the following should work (avoids changing letters after a \):
for (p = (char *)s; *p != 0; p++)
if (isupper((int)*p))
*p = tolower((int) *p);
else if (*p == '\\' && *(p+1))
p++;
As far as e?grep is concerned, however, just removing the loop seems
to work just fine (the declaration of p can be removed as well).
Here's a context diff for just that (actually it #if's them
out rather than deletes them and adds a comment):
*** dfa.old Sat Sep 16 12:04:32 1989
--- dfa.c Sat Sep 16 12:04:34 1989
***************
*** 1668,1679 ****
--- 1668,1685 ----
{
if (case_fold) /* dummy folding in service of regmust() */
{
+ /* the following two #if 0's added by Tapani Tarvainen 16 Sep 89 */
+ /* to prevent -i flag from affecting \W and \B in e?grep */
+ #if 0
static char *p;
+ #endif
case_fold = 0;
+ #if 0
for (p = (char *)s; *p != 0; p++)
if (isupper((int)*p))
*p = tolower((int) *p);
+ #endif
reginit(r);
r->mustn = 0;
r->must[0] = '\0';
--
Tapani Tarvainen (tarvaine@tukki.jyu.fi, tarvainen@finjyu.bitnet)
SED bug
Author: Tapani Tarvainen
Date: Sun, 17 Sep 1989 19:21
Date: Sun, 17 Sep 1989 19:21
12 lines
871 bytes
871 bytes
The y-command doesn't seem to work with Gnu SED 1.02: e.g., echo a | sed 'y/a/A/' complains "extra characters after command". I tried it under SunOS 4.0 and MS-DOS with identical results. Is 1.02 the latest release, and if not, where could a newer one be found? (I just might try fixing this myself.) -- Tapani Tarvainen (tarvaine@tukki.jyu.fi, tarvainen@finjyu.bitnet)
Re: SED bug
Author: Tapani Tarvainen
Date: Sun, 17 Sep 1989 19:48
Date: Sun, 17 Sep 1989 19:48
28 lines
1280 bytes
1280 bytes
In article <1311@tukki.jyu.fi> tarvaine@tukki.jyu.fi I wrote: >The y-command doesn't seem to work with Gnu SED 1.02 The bug turned out to be that the program assumed that there is always '\n' at the end of a line, but it can be EOF as well. Here's my fix: *** sed.old Sun Sep 17 22:28:15 1989 --- sed.c Sun Sep 17 22:42:38 1989 *************** *** 704,710 **** cur_cmd->x.translate[*string++]=ch; } flush_buffer(b); ! if(inchar()!=slash || inchar()!='\n') bad_prog(LINE_JUNK); break; --- 704,710 ---- cur_cmd->x.translate[*string++]=ch; } flush_buffer(b); ! if(inchar()!=slash || ((ch=inchar())!='\n' && ch!=EOF) bad_prog(LINE_JUNK); break; -- Tapani Tarvainen (tarvaine@tukki.jyu.fi, tarvainen@finjyu.bitnet)
Re: SED bug
Author: Tapani Tarvainen
Date: Sun, 17 Sep 1989 23:20
Date: Sun, 17 Sep 1989 23:20
58 lines
2084 bytes
2084 bytes
I just found yet abother bug in the y-command of Gnu SED 1.02: characters >127 won't get translated properly. This depends on the compiler, though; the offending line is cur_cmd->x.translate[*string++]=ch; and the problem is that string is declared as char *, and if chars are signed and *string is negative, the ANSI promotion rules keep it negative when converted to an int. The easiest fix (or first that I could think of) is to declare string as unsigned char*; lint &c will complain about mixing pointers to signed and unsigned chars, but who cares (if you do, throw in a few casts or declare all chars as unsigned). At least it seems to work. Anyway, here's the diff (this includes the earlier patch): *** sed.old Sun Sep 17 22:28:15 1989 --- sed.c Mon Sep 18 01:58:58 1989 *************** *** 412,418 **** int ch; int slash; VOID *b; ! char *string; int num; FILE *compile_filename(); --- 412,418 ---- int ch; int slash; VOID *b; ! unsigned char *string; int num; FILE *compile_filename(); *************** *** 704,710 **** cur_cmd->x.translate[*string++]=ch; } flush_buffer(b); ! if(inchar()!=slash || inchar()!='\n') bad_prog(LINE_JUNK); break; --- 704,710 ---- cur_cmd->x.translate[*string++]=ch; } flush_buffer(b); ! if(inchar()!=slash || ((ch=inchar())!='\n' && ch!=EOF)) bad_prog(LINE_JUNK); break; -- Tapani Tarvainen (tarvaine@tukki.jyu.fi, tarvainen@finjyu.bitnet)
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads