static int getto(char *flds[]) { char *dev[D_MAX+2], devbuf[BUFSIZ]; int status; int dcf = -1; int reread = 0; int tries = 0; /* count of call attempts - for limit purposes */ CDEBUG(1, "Device Type %s wanted\n", flds[F_TYPE]); Uerror = 0; while (tries < TRYCALLS) { if ((status = rddev(flds[F_TYPE], dev, devbuf, D_MAX)) == FAIL) { if (tries == 0 || ++reread >= TRYCALLS) break; devreset(); continue; } /* check class, check (and possibly set) speed */ if (classmatch(flds, dev) != SUCCESS) { DEBUG(7, "Skipping entry in '%s'", currdev()); DEBUG(7, " - class (%s) not wanted.\n", dev[D_CLASS]); continue; } DEBUG(5, "Trying device entry from '%s'.\n", currdev()); if ((dcf = processdev(flds, dev)) >= 0) break; switch (Uerror) { case SS_CANT_ACCESS_DEVICE: case SS_DEVICE_FAILED: case SS_LOCKED_DEVICE: break; default: tries++; break; } } devreset(); /* reset devices file(s) */ if (status == FAIL && !Uerror) { CDEBUG(1, "Requested Device Type Not Found\n%s", ""); Uerror = SS_NO_DEVICE; } return (dcf); }
parse() {int i,j,found,current, someread; char c; hash_init(); routinit(); line_init(); someread = 0; /* indicates haven't read part of a routine */ empseek(0); endbuf = getline(&endline, &endchar, &endcom, & comchar); if (progress && endbuf != -1) fprintf(stderr,"parsing\n"); while(endbuf != -1) /* getline returns -1 when no more input */ { someread = 1; if (progress > 0) { for (i = begline; i <= endline; i++) if (!(i % progress)) fprintf(stderr,"parsing line %d\n",i); } current = 0; for (i = 0; i < endbuf; i++) { c = buffer[i]; if(c != '~') { found = 0; if ( (current < 0 || current >= snum) && current != ABORT) { strerr("in parsing:","",""); fprintf(stderr,"line %d of file, parser in invalid state", begline,current); fprintf(stderr,"treating it as straight line code\n"); current = ABORT; } else for (j = match[current]; j < match[current + 1]; j++) { if ((symclass[j] == 0 && c == symbol[j]) || (symclass[j] != 0 && classmatch(c,symclass[j]) )) {found = 1; break; } } if (!found) { error("in syntax:","",""); fprintf(stderr,"between lines %d and %d of file\n",begline, endline); if (debug) fprintf(stderr,"symbol '%c' does not match entries for state %d\n",c,current); fprintf(stderr,"treating it as straight line code\n"); current = ABORT; } else if (!action[j]) current = newstate[j]; else { current = act(action[j],c,i); if (current == nulls) current = newstate[j]; } if (current == ABORT) break; if (current == endrt) { return(1); } } } line_init(); endbuf = getline(&endline, &endchar, &endcom,&comchar); } if (someread) return(1); else return(0); }
static int rangematch(const char *pattern, char test, int flags, char **newp) { int negate, ok, rv; char c, c2; /* * A bracket expression starting with an unquoted circumflex * character produces unspecified results (IEEE 1003.2-1992, * 3.13.2). This implementation treats it like '!', for * consistency with the regular expression syntax. * J.T. Conklin ([email protected]) */ if ((negate = (*pattern == '!' || *pattern == '^'))) ++pattern; if (flags & FNM_CASEFOLD) test = (char)tolower((unsigned char)test); /* * A right bracket shall lose its special meaning and represent * itself in a bracket expression if it occurs first in the list. * -- POSIX.2 2.8.3.2 */ ok = 0; c = *pattern++; do { if (c == '[' && *pattern == ':') { do { rv = classmatch(pattern + 1, test, (flags & FNM_CASEFOLD), &pattern); if (rv == RANGE_MATCH) ok = 1; c = *pattern++; } while (rv != RANGE_ERROR && c == '[' && *pattern == ':'); if (c == ']') break; } if (c == '\\' && !(flags & FNM_NOESCAPE)) c = *pattern++; if (c == EOS) return (RANGE_ERROR); if (c == '/' && (flags & FNM_PATHNAME)) return (RANGE_NOMATCH); if ((flags & FNM_CASEFOLD)) c = (char)tolower((unsigned char)c); if (*pattern == '-' && (c2 = *(pattern+1)) != EOS && c2 != ']') { pattern += 2; if (c2 == '\\' && !(flags & FNM_NOESCAPE)) c2 = *pattern++; if (c2 == EOS) return (RANGE_ERROR); if (flags & FNM_CASEFOLD) c2 = (char)tolower((unsigned char)c2); if (c <= test && test <= c2) ok = 1; } else if (c == test) ok = 1; } while ((c = *pattern++) != ']'); *newp = (char *)pattern; return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); }
/* Most MBCS/collation/case issues handled here. Wildcard '*' is not handled. * EOS '\0' and the FNM_PATHNAME '/' delimiters are not advanced over, * however the "\/" sequence is advanced to '/'. * * Both pattern and string are **char to support pointer increment of arbitrary * multibyte characters for the given locale, in a later iteration of this code */ static int fnmatch_ch(const char **pattern, const char **string, int flags) { const char * const mismatch = *pattern; const int nocase = !!(flags & FNM_CASEFOLD); const int escape = !(flags & FNM_NOESCAPE); const int slash = !!(flags & FNM_PATHNAME); int result = FNM_NOMATCH; const char *startch; int negate; if (**pattern == '[') { ++*pattern; /* Handle negation, either leading ! or ^ operators (never both) */ negate = ((**pattern == '!') || (**pattern == '^')); if (negate) ++*pattern; /* ']' is an ordinary character at the start of the range pattern */ if (**pattern == ']') goto leadingclosebrace; while (**pattern) { if (**pattern == ']') { ++*pattern; /* XXX: Fix for MBCS character width */ ++*string; return (result ^ negate); } if (escape && (**pattern == '\\')) { ++*pattern; /* Patterns must be terminated with ']', not EOS */ if (!**pattern) break; } /* Patterns must be terminated with ']' not '/' */ if (slash && (**pattern == '/')) break; /* Match character classes. */ if (classmatch(*pattern, **string, nocase, pattern) == RANGE_MATCH) { result = 0; continue; } if (!**pattern) break; leadingclosebrace: /* Look at only well-formed range patterns; * "x-]" is not allowed unless escaped ("x-\]") * XXX: Fix for locale/MBCS character width */ if (((*pattern)[1] == '-') && ((*pattern)[2] != ']')) { startch = *pattern; *pattern += (escape && ((*pattern)[2] == '\\')) ? 3 : 2; /* NOT a properly balanced [expr] pattern, EOS terminated * or ranges containing a slash in FNM_PATHNAME mode pattern * fall out to to the rewind and test '[' literal code path */ if (!**pattern || (slash && (**pattern == '/'))) break; /* XXX: handle locale/MBCS comparison, advance by MBCS char width */ if ((**string >= *startch) && (**string <= **pattern)) result = 0; else if (nocase && (isupper((unsigned char)**string) || isupper((unsigned char)*startch) || isupper((unsigned char)**pattern)) && (tolower((unsigned char)**string) >= tolower((unsigned char)*startch)) && (tolower((unsigned char)**string) <= tolower((unsigned char)**pattern))) result = 0; ++*pattern; continue; } /* XXX: handle locale/MBCS comparison, advance by MBCS char width */ if ((**string == **pattern)) result = 0; else if (nocase && (isupper((unsigned char)**string) || isupper((unsigned char)**pattern)) && (tolower((unsigned char)**string) == tolower((unsigned char)**pattern))) result = 0; ++*pattern; } /* NOT a properly balanced [expr] pattern; Rewind * and reset result to test '[' literal */ *pattern = mismatch; result = FNM_NOMATCH; } else if (**pattern == '?') { /* Optimize '?' match before unescaping **pattern */ if (!**string || (slash && (**string == '/'))) return FNM_NOMATCH; result = 0; goto fnmatch_ch_success; } else if (escape && (**pattern == '\\') && (*pattern)[1]) { ++*pattern; } /* XXX: handle locale/MBCS comparison, advance by the MBCS char width */ if (**string == **pattern) result = 0; else if (nocase && (isupper((unsigned char)**string) || isupper((unsigned char)**pattern)) && (tolower((unsigned char)**string) == tolower((unsigned char)**pattern))) result = 0; /* Refuse to advance over trailing slash or nulls */ if (!**string || !**pattern || (slash && ((**string == '/') || (**pattern == '/')))) return result; fnmatch_ch_success: ++*pattern; ++*string; return result; }