From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from proxy4.ba.best.com ([206.184.139.15]) by hawkwind.utcs.toronto.edu with SMTP id <25609>; Tue, 18 Apr 2000 17:12:02 -0400 Received: from peanut.rakitzis.com (dynamic13.pm01.san-mateo.best.com [205.149.174.13]) by proxy4.ba.best.com (8.9.3/8.9.2/best.out) with ESMTP id XAA28895; Mon, 17 Apr 2000 23:31:38 -0700 (PDT) Received: (from byron@localhost) by peanut.rakitzis.com (8.8.7/8.8.7) id XAA05903; Mon, 17 Apr 2000 23:30:00 -0700 Date: Tue, 18 Apr 2000 02:30:00 -0400 From: Byron Rakitzis Message-Id: <200004180630.XAA05903@peanut.rakitzis.com> To: fosterd@hartwick.edu, tjg@star.le.ac.uk Subject: Re: Bug#62339: rc bug Cc: rc@hawkwind.utcs.toronto.edu Thanks for tracking this down. I'm the original miscreant as far as the documentation style of rc is concerned. Much of this code was written roughly 10 years ago, I'd certainly write it differently now. The metacharacter array is properly an array of booleans. Hence the explicit checks against 0 and 1, which should be cleaned up somehow to reflect their function. A macro "ismeta(p, i)", perhaps. I don't know where the tests against '\001' snuck in. I think it's a mistake. > Now in lmatch() when we go through looking for '*'s, we have this > loop: > > for (i = 0; p->w[i] != '\0'; i++) > if (p->w[i] != '*' || p->m[i] != 1) { > > Which assumes that m is as big as w (i.e, not NULL). I came up with > this replacement, which works for all the test cases I can think of: > > if (s == NULL) { > if (p == NULL) /* null matches null */ > return TRUE; > for (; p != NULL; p = p->n) /* one or more stars match null */ > if (p->w && strspn(p->w, "*") == strlen(p->w) && > p->m && strspn(p->m, "\001") == strlen(p->m)) > return TRUE; > return FALSE; > } > > I was also able to get rid of 'okay', which i found hard to follow. > The comment about the null string is gone too, because IMO the null > string fails for the same reason 'foo' fails. There's really no need > for an explicit check. This is good. I'm picking nits here, but since I obsessed over this code a while ago, I might suggest two small changes to your fix: > if (p->w && strspn(p->w, "*") == strlen(p->w) && > p->m && strspn(p->m, "\001") == strlen(p->m)) to: if (p->m != NULL && strspn(p->w, "*") == strlen(p->w) && strlen(p->m) == strlen(p->w)) Firstly, p->w can not be NULL here; there can be no null words in a word list, only empty strings which are represented as "". As long as you are getting sneaky about using the string library to find zeroes in a character array, you may also rephrase the metacharacter test as two calls to strlen. Byron.