📄 ckclib.c
字号:
for (flag = 0; !flag; pattern++) { /* Loop thru pattern */ c = (CHAR)*pattern; /* Current char */ if (q) { /* Quote within brackets */ q = 0; clist[c] = 1; continue; } if (!icase) /* Case conversion */ if (isupper(c)) c = tolower(c); switch (c) { /* Handle unquoted character */ case NUL: /* End of string */ MATCHRETURN(4,0); /* No matching ']' so fail */ case CMDQ: /* Next char is quoted */ q = 1; /* Set flag */ continue; /* and continue. */ case '-': /* A range is specified */ c1 = (pattern > psave) ? (CHAR)*(pattern-1) : NUL; c2 = (CHAR)*(pattern+1); /* IGNORE OUT-OF-BOUNDS WARNING */ if (c2 == ']') c2 = NUL; /* (it can't happen) */ if (c1 == NUL) c1 = c2; for (c = c1; c <= c2; c++) { clist[c] = 1; if (!icase) { if (islower(c)) { clist[toupper(c)] = 1; } else if (isupper(c)) { clist[tolower(c)] = 1; } } } continue; case ']': /* End of bracketed sequence */ flag = 1; /* Done with FOR loop */ break; /* Compare what we have */ default: /* Just a char */ clist[c] = 1; /* Record it */ if (!icase) { if (islower(c)) { clist[toupper(c)] = 1; } else if (isupper(c)) { clist[tolower(c)] = 1; } } continue; } } if (!clist[(unsigned)cs]) { /* Match? */ MATCHRETURN(5,0); /* Nope, done. */ } if (!matchpos) { matchpos = stringpos; debug(F111,"CKMATCH [] match",string, matchpos); } string++; /* Yes, advance string pointer */ stringpos++; continue; /* and go on. */ } else if (cp == '{') { /* Braces enclosing list of strings */ char * p, * s, * s2, * buf = NULL; int n, bc = 0; int len = 0; debug(F111,"CKMATCH {} ",string, matchpos); for (p = pattern++; *p; p++) { if (*p == '{') bc++; if (*p == '}') bc--; if (bc < 1) break; } if (bc != 0) { /* Braces don't match */ MATCHRETURN(6,0); /* Fail */ } else { /* Braces do match */ int q = 0, done = 0; len = *p ? strlen(p+1) : 0; /* Length of rest of pattern */ if (len) bronly = 0; if (bronly && (matchdepth != 1)) bronly = 0; n = p - pattern; /* Size of list in braces */ if ((buf = (char *)malloc(n+1))) { /* Copy so we can poke it */ char * tp = NULL; int k, sofar; ckstrncpy(buf,pattern,n+1); sofar = string - ostring - matchpos + 1; if (sofar < 0) sofar = 0; debug(F111,"CKMATCH .. string",string,sofar); debug(F111,"CKMATCH .. ostring",ostring,sofar); n = 0; for (s = s2 = buf; 1; s++) { /* Loop through segments */ n++; if (q) { /* This char is quoted */ q = 0; if (!*s) done = 1; continue; } if (*s == CMDQ && !q) { /* Quote next char */ q = 1; continue; } if (!*s || *s == ',') { /* End of this segment */ int tplen = 0; if (!*s) /* If end of buffer */ done = 1; /* then end of last segment */ *s = NUL; /* Overwrite comma with NUL */ debug(F111,"CKMATCH {} segment",s2,done); tplen = n + len + sofar + 2; if (!*s2) { /* Empty segment, no advancement */ k = 0; } else if ((tp = (char *)malloc(tplen))) { int savpos, opts2; char * pp; pp = matchpos > 0 ? &ostring[matchpos-1] : ostring; if (bronly) { if (matchpos > 0) ckstrncpy(tp,pp,sofar+1); else ckstrncpy(tp,pp,sofar); } else { tp[0] = '*'; tp[1] = NUL; if (matchpos > 0) ckstrncpy(&tp[1],pp,sofar+1); else ckstrncpy(&tp[1],pp,sofar); } ckstrncat(tp,s2,tplen); /* Current segment */ ckstrncat(tp,p+1,tplen); /* rest of pattern */ debug(F101,"CKMATCH {} matchpos","",matchpos); savpos = matchpos; matchpos = 0;#ifdef DEBUG if (deblog) { debug(F111,"CKMATCH {} tp",tp,matchpos); debug(F111,"CKMATCH {} string", string,matchpos); debug(F111,"CKMATCH {} ostring", ostring,savpos); }#endif /* DEBUG */ /* If segment starts with dot */ /* then set matchdot option.. */ opts2 = opts; if (*s2 == '.') opts2 |= 1; debug(F111,"CKMATCH {} recursing",s2,opts2); k = ckmatch(tp, (string > ostring) ? &ostring[savpos-1] : string, icase,opts2);#ifdef DEBUG if (deblog) { debug(F101,"CKMATCH {} k","",k); debug(F101,"CKMATCH {} savpos","",savpos); }#endif /* DEBUG */ free(tp); tp = NULL; if (k == 0) { matchpos = savpos; } if (k > 0) { /* If it matched we're done */ MATCHRETURN(7,k); } } else { /* Malloc failure */ MATCHRETURN(14,0); } if (k) { /* Successful comparison */ if (!matchpos) { matchpos = stringpos; debug(F111,"CKMATCH {} match", string, matchpos); } string += n-1; /* Advance pointers */ pattern = p+1; break; } if (done) /* If no more segments */ break; /* break out of segment loop. */ s2 = s+1; /* Otherwise, on to next segment */ n = 0; } } free(buf); } }#endif /* CKREGEX */ } else if (cp == '*') { /* Pattern char is asterisk */ char * psave; char * p, * s = NULL; /* meaning match anything */ int k, n, q = 0; while (*pattern == '*') /* Collapse successive asterisks */ pattern++; psave = pattern; /* First non-asterisk after asterisk */ lastpat = pattern - 1; /* Ditto, global */ debug(F111,"CKMATCH * ",string,matchpos); for (n = 0, p = psave; *p; p++,n++) { /* Find next meta char */ if (!q) { if (*p == '?' || *p == '*' || *p == CMDQ#ifdef CKREGEX || *p == '[' || *p == '{'#endif /* CKREGEX */ ) break;#ifdef GLOBBING if (globbing#ifdef UNIXOROSK && *p == '/'#else#ifdef VMS && (*p == '.' || *p == ']' || *p == '<' || *p == '>' || *p == ':' || *p == ';')#else#ifdef datageneral && *p == ':'#else#ifdef STRATUS && *p == '>'#endif /* STRATUS */#endif /* datageneral */#endif /* VMS */#endif /* UNIXOROSK */ ) break;#endif /* GLOBBING */ } } debug(F111,"CKMATCH * n string",string,n); debug(F111,"CKMATCH * n pattrn",pattern,n); debug(F111,"CKMATCH * n p",p,n); if (n > 0) { /* Literal string to match */ s = (char *)malloc(n+1); if (s) { ckstrncpy(s,psave,n+1); /* Copy cuz no poking original */ if (*p) { k = ckindex(s,string,0,0,icase); /* 1-based index() */ debug(F110,"CKMATCH * Index() string",string,0); debug(F110,"CKMATCH * Index() pattrn",s,0); debug(F101,"CKMATCH * Index() result","",k); } else { /* String is right-anchored */ k = ckindex(s,string,-1,1,icase); /* rindex() */ debug(F111,"CKMATCH * Rindex()",string,k); debug(F110,"CKMATCH * Rindex() pattrn",s,0); debug(F101,"CKMATCH * Rindex() result","",k); } free(s); if (k < 1) { MATCHRETURN(8,0); } debug(F111,"CKMATCH * stringpos matchpos", ckitoa(stringpos), matchpos); if (!matchpos) { matchpos = string - ostring + k; debug(F111,"CKMATCH * new match ", string, matchpos); } string += k + n - 1; stringpos += k + n - 1; pattern += n; debug(F111,"CKMATCH * new string", string, stringpos); debug(F110,"CKMATCH * new pattrn", pattern, 0); continue; } } else if (!*p) { /* Asterisk at end matches the rest */ if (!globbing) { /* (if not filename globbing) */ if (!matchpos) { matchpos = stringpos; debug(F111,"CKMATCH *$ ",string, matchpos); } matchend = stringpos; MATCHRETURN(9,matchpos); }#ifdef GLOBBING while (*string) { if (globbing /* Filespec so don't cross fields */#ifdef OS2 && *string == '/' || *string == '\\' || *string == ':'#else#ifdef UNIXOROSK && *string == '/'#else#ifdef VMS && (*string == '.' || *string == ']' || *string == '<' || *string == '>' || *string == ':' || *string == ';')#else#ifdef datageneral && *string == ':'#else#ifdef STRATUS && *string == '>'#else && *string == '/' /* (catch-all) */#endif /* STRATUS */#endif /* datageneral */#endif /* VMS */#endif /* UNIXOROSK */#endif /* OS2 */ ) { matchend = stringpos; MATCHRETURN(10,0); } if (!matchpos) { matchpos = stringpos; debug(F111,"CKMATCH *$ match",string, matchpos); } string++; stringpos++; }#endif /* GLOBBING */ if (!matchpos) { matchpos = stringpos; debug(F111,"CKMATCH ** match",string, matchpos); } matchend = stringpos; MATCHRETURN(11,matchpos); } else { /* A meta char follows asterisk */ if (!*string) MATCHRETURN(17, matchpos = 0); while (*string && (k = ckmatch(p,string,icase,opts) < 1)) { string++; stringpos++; } debug(F111,"CKMATCH *<meta> k",string, k); if (!matchpos && k > 0) { matchpos = stringpos; debug(F111,"CKMATCH *<meta>",string, matchpos); } MATCHRETURN(12, (*string) ? matchpos : 0); } } else if (cs == cp) { pattern++, string++; stringpos++; if (!matchpos) { matchpos = stringpos; debug(F111,"CKMATCH cs=cp",string, matchpos); } continue; } else { MATCHRETURN(13,0); } } xckmatch: {#ifdef DEBUG char msgbuf[96];#endif /* DEBUG */ if (matchdepth > 0) matchdepth--; matchpos = rc;#ifdef DEBUG ckmakxmsg(msgbuf,96, "CKMATCH RETURN[", ckitoa(where), "] matchpos=", ckitoa(matchpos), " matchdepth=", ckitoa(matchdepth), " string=",NULL,NULL,NULL,NULL,NULL ); debug(F110,msgbuf,string,0);#endif /* DEBUG */ return(rc); }}#ifdef CKFLOAT/* I S F L O A T -- Verify that arg represents a floating-point number *//* Portable replacement for atof(), strtod(), scanf(), etc. Call with: s = pointer to string flag == 0 means entire string must be a (floating-pointing) number. flag != 0 means to terminate scan on first character that is not legal. Returns: 1 if result is a legal number; 2 if result has a fractional part; 0 if not or if string empty. Side effect: Sets global floatval to floating-point value if successful. Number need not contain a decimal point -- integer is subcase of float. Scientific notation not supported.*/CKFLOAT floatval = 0.0; /* For returning value */intisfloat(s,flag) char *s; int flag; { int state = 0; int sign = 0; char c; CKFLOAT d = 0.0, f = 0.0; if (!s) return(0); if (!*s) return(0); while (isspace(*s)) s++; if (*s == '-') { /* Handle optional sign */ sign = 1; s++; } else if (*s == '+') s++; while ((c = *s++)) { /* Handle numeric part */ switch (state) { case 0: /* Mantissa... */ if (isdigit(c)) { f = f * 10.0 + (CKFLOAT)(c - '0'); continue; } else if (c == '.') { state = 1; d = 1.0; continue; } if (flag) /* Not digit or period */ goto done; /* break if flag != 0 */ return(0); /* otherwise fail. */ case 1: /* Fraction... */ if (isdigit(c)) { d *= 10.0; f += (CKFLOAT)(c - '0') / d; continue; } default: if (flag) /* Illegal character */ goto done; /* Break */ return(0); /* or fail, depending on flag */ } } done: if (sign) f = 0.0 - f; /* Apply sign to result */ floatval = f; /* Set result */ return(d ? 2 : 1); /* Succeed */}#endif /* CKFLOAT *//* Sorting routines... *//* S H _ S O R T -- Shell sort -- sorts string array s in place. *//* Highly defensive and relatively quick. Uses shell sort algorithm. Args: s = pointer to array of strings. p = pointer to a second array to sort in parallel s, or NULL for none. n = number of elements in s. k = position of key. r = ascending lexical order if zero, reverse lexical order if nonzero. c = 0 for case independence, 1 for case matters, 2 for numeric. If k is past the right end of a string, the string is considered empty for comparison purposes. Hint: To sort a piece of an array, call with s pointing to the first element and n the number of elements to sort. Return value: None. Always succeeds, unless any of s[0]..s[n-1] are bad pointers, in which case memory violations are possible, but C offers no defense against this, so no way to gracefully return an error code.*/VOIDsh_sort(s,p,n,k,r,c) char **s, **p; int n, k, r, c; { int m, i, j, x; char *t, *t1, *t2, *u = NULL;#ifdef CKFLOAT CKFLOAT f1, f2;#else long n1, n2;#endif /* CKFLOAT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -