Mail Archives: djgpp/2006/12/01/06:02:38
On Wed, 29 Nov 2006 22:31:24 -0800 in comp.os.msdos.djgpp, "Alexei A.
Frounze" <alexfru AT chat DOT ru> wrote:
>Brian Inglis wrote:
>> fOn Wed, 29 Nov 2006 11:34:38 -0500 in comp.os.msdos.djgpp, DJ Delorie
>> <dj AT delorie DOT com> wrote:
>>
>>>
>>>> This function indicates if STRING matches the PATTERN. ..."
>>>>
>>>> So DJGPP says that "\" doesn't match "\\" while Linux says it does.
>>>>
>>>> Well, I say DJGPP is right as the pattern says there should be two
>>>> backslashes and you only provide one.
>>>
>>> Except that PATTERN is a regex influenced by FNM_NOESCAPE and
>>> FNM_PATHNAME, and STRING isn't. So a pattern of "\\" is a single
>>> escaped backslash, whereas a string of "\" is a single backslash.
>>> They should match.
>>
>> switch ((c = *pattern++))
>> {
>> ...
>> ...
>> ...
>> case '\\':
>> /*+++ pattern already post-incremented to point to next char */
>> if (!(flags & FNM_NOESCAPE) && pattern[1] && strchr("*?[\\",
>> pattern[1]))
>> /*+++ should be:
>> if (!(flags & FNM_NOESCAPE) && strchr("*?[\\", *pattern))
>> *+++ as end of input pattern will match end char in escapes string */
>> {
>> /*+++ end of input pattern might be clearer with ! or == '\0' */
>> if ((c = *pattern++) == 0)
>> {
>> c = '\\';
>> --pattern;
>> }
>> if (c != *string++)
>> return FNM_NOMATCH;
>> break;
>> }
>
>I don't think the above is enough. There's another problem. With the above
>code you'd never see (c = *pattern++) == 0. My bet is that the intent was to
>treat the slash in the last character of pattern as an ordinary character.
AFAICS it does: strchr matches the nul pattern terminator with the nul
escapes constant terminator and returns a pointer to that character,
so the result is non-zero/true, as noted in the third +++ line.
If "&& *pattern &&" was included, and a nul pattern terminator was
encountered, that if statement would be false and fallthrough to the
following default case, which is clearly not intended by the
subsequent test for the nul pattern terminator, which fixes things up
to treat a terminal \ as an ordinary character.
>That would explain the {c = '\\'; --pattern;} thing along with the
>fallthrough behavior.
The break ensures that the fallthrough default case is skipped if an
escape is valid and there is a match, otherwise the previous return
happens.
>But the code is broken in this place. Dunno if it was
>tested against the single unix spec or just a little bit to see that it
>seems to work (in some basic cases).
Handling of non-special escape characters here is punted to the
fallthrough default case and treated the same as FNM_NOESCAPE!
Not sure if that is intentional or just inadequate.
If non-special escape characters should be treated as a literal
character, the strchr() should be eliminated and only the nul
terminator handled specially as it is.
The resulting code would look like:
case '\\': /* escape or directory */
if (!(flags & FNM_NOESCAPE)) /* if escapes allowed */
{
if ((c = *pattern++) == '\0') /* if next char end */
{
c = '\\'; /* trailing \ stays put */
--pattern; /* backup ptr to end */
}
if (c != *string++) /* mismatch */
return FNM_NOMATCH; /* quit */
break; /* done */
}
--
Thanks. Take care, Brian Inglis Calgary, Alberta, Canada
Brian DOT Inglis AT CSi DOT com (Brian[dot]Inglis{at}SystematicSW[dot]ab[dot]ca)
fake address use address above to reply
- Raw text -