📄 ckclib.c
字号:
#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 floating point number; 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(1); /* Succeed */}#endif /* CKFLOAT *//* Sorting routines... */#ifdef USE_QSORT/* Quicksort works but it's not measurably faster than shell sort, probably because it makes a lot more comparisons, since it was originally designed for sorting an array of integers. It would need more thorough testing and debugging before production use.*/static int /* Internal comparison routine for ckqsort() */compare(s1,s2,k,r,c) char *s1, *s2; int k, r, c; { int x; char *t, *t1, *t2;#ifdef CKFLOAT CKFLOAT f1, f2;#else long n1, n2;#endif /* CKFLOAT */ t = t2 = s1; /* String 1 */ if (!t) /* If it's NULL */ t2 = ""; /* make it the empty string */ if (k > 0 && *t2) { if ((int)strlen(t2) < k) /* If key too big */ t2 = ""; /* make key the empty string */ else /* Key is in string */ t2 += k; /* so point to key position */ } t1 = s2; if (!t1) /* Same deal for s2 */ t1 = ""; if (k > 0 && *t1) { if ((int)strlen(t1) < k) t1 = ""; else t1 += k; } if (c == 2) { /* Numeric comparison */ x = 0;#ifdef CKFLOAT f2 = 0.0; f1 = 0.0; if (isfloat(t1,1)) { f1 = floatval; if (isfloat(t2,1)) f2 = floatval; else f1 = 0.0; } if (f2 < f1) x = 1; else x = -1;#else n2 = 0L; n1 = 0L; if (rdigits(t1)) { n1 = atol(t1); if (rdigits(t2)) n2 = atol(t2); else n1 = 0L; } if (n2 < n1) x = 1; else x = -1;#endif /* CKFLOAT */ } else { x = ckstrcmp(t1,t2,-1,c); } return(x);}/* It's called sh_sort() but it's really quicksort... */VOIDsh_sort(s,s2,n,k,r,how) char **s, **s2; int n, k, r, how; { int x, lp, up, p, lv[16], uv[16], m, c; char * y, * y2; if (!s) return; if (n < 2) return; if (k < 0) k = 0; lv[0] = 0; uv[0] = n-1; p = 0;stb: /* Hmmm, looks like Fortran... */ if (p < 0) return;stc: lp = lv[p]; up = uv[p]; m = up - lp + 1; if (m < 2) { p--; goto stb; } if (m == 2) { x = compare(s[lp],s[up],k,r,how); if (x > 0) { y = s[lp]; s[lp] = s[up]; s[up] = y; if (s2) { y2 = s2[lp]; s2[lp] = s2[up]; s2[up] = y2; } } p--; goto stb; } c = (lp+up) / 2; if (m < 10) goto std; x = compare(s[lp],s[c],k,r,how); if (x < 1) { if (s[c] <= s[up]) { goto std; } else { x = compare(s[lp],s[up],k,r,how); if (x < 1) c = up; else c = lp; goto std; } } else { x = compare(s[up],s[c],k,r,how); if (x < 1) { goto std; } else { x = compare(s[lp],s[up],k,r,how); if (x < 1) c = lp; else c = up; goto std; } }std: y = s[c]; s[c] = s[up]; if (s2) { y2 = s2[c]; s2[c] = s2[up]; } lp--;stf: if ((up - lp) < 2) goto stk; lp++; x = compare(s[lp],y,k,r,how); if (x < 1) goto stf; s[up] = s[lp];sth: if ((up - lp) < 2) goto stj; up--; x = compare(s[up],y,k,r,how); if (x > 0) goto sth; s[lp] = s[up]; goto stf;stj: up--;stk: if (up == uv[p]) { lp = lv[p] - 1;stl: if ((up - lp) < 2) goto stq; lp++; x = compare(s[lp],y,k,r,how); if (x < 0) goto stl; s[up] = s[lp];stn: if ((up - lp) < 2) goto stp; up--; x = compare(s[up],y,k,r,how); if (x >= 0) goto stn; s[lp] = s[up]; goto stl;stp: up--;stq: s[up] = y; if (s2) s2[up] = y2; if (up == lv[p]) { p--; goto stb; } uv[p] = up - 1; goto stc; } s[up] = y; if (s2) s2[up] = y2; if ((up - lv[p]) < (uv[p] - up)) { lv[p+1] = lv[p]; uv[p+1] = up - 1; lv[p] = up + 1; } else { lv[p+1] = up + 1; uv[p+1] = uv[p]; uv[p] = up - 1; } p++; goto stc;}#else /* !USE_QSORT *//* 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 */ if (!s) return; /* Nothing to sort? */ if (n < 2) return; /* Not enough elements to sort? */ if (k < 0) k = 0; /* Key */ m = n; /* Initial group size is whole array */ while (1) { m = m / 2; /* Divide group size in half */ if (m < 1) /* Small as can be, so done */ break; for (j = 0; j < n-m; j++) { /* Sort each group */ t = t2 = s[j+m]; /* Compare this one... */ if (!t) /* But if it's NULL */ t2 = ""; /* make it the empty string */ if (p) /* Handle parallel array, if any */ u = p[j+m]; if (k > 0 && *t2) { if ((int)strlen(t2) < k) /* If key too big */ t2 = ""; /* make key the empty string */ else /* Key is in string */ t2 = t + k; /* so point to key position */ } for (i = j; i >= 0; i -= m) { /* Loop thru comparands s[i..]*/ t1 = s[i]; if (!t1) /* Same deal */ t1 = ""; if (k > 0 && *t1) { if ((int)strlen(t1) < k) t1 = ""; else t1 = s[i]+k; } if (c == 2) { /* Numeric comparison */ x = 0;#ifdef CKFLOAT f2 = 0.0; f1 = 0.0; if (isfloat(t1,1)) { f1 = floatval; if (isfloat(t2,1)) f2 = floatval; else f1 = 0.0; } if (f2 < f1) x = 1; else x = -1;#else n2 = 0L; n1 = 0L; if (rdigits(t1)) { n1 = atol(t1); if (rdigits(t2)) n2 = atol(t2); else n1 = 0L; } if (n2 < n1) x = 1; else x = -1;#endif /* CKFLOAT */ } else { x = ckstrcmp(t1,t2,-1,c); /* Compare */ } if (r == 0 && x < 0) break; if (r != 0 && x > 0) break; s[i+m] = s[i]; if (p) p[i+m] = p[i]; } s[i+m] = t; if (p) p[i+m] = u; } }}#endif /* COMMENT *//* F I L E S E L E C T -- Select this file for sending */intfileselect(f,sa,sb,sna,snb,minsiz,maxsiz,nbu,nxlist,xlist) char *f,*sa,*sb,*sna,*snb; long minsiz,maxsiz; int nbu,nxlist; char ** xlist;/* fileselect */ { char *fdate; int n; long z; if (!sa) sa = ""; if (!sb) sb = ""; if (!sna) sna = ""; if (!snb) snb = ""; debug(F110,"fileselect",f,0); if (*sa || *sb || *sna || *snb) { fdate = zfcdat(f); /* Date/time of this file */ if (!fdate) fdate = ""; n = strlen(fdate); debug(F111,"fileselect fdate",fdate,n); if (n != 17) /* Failed to get it */ return(1); /* /AFTER: */ if (sa[0] && (strcmp(fdate,(char *)sa) <= 0)) { debug(F110,"fileselect sa",sa,0); /* tlog(F110,"Skipping (too old)",f,0); */ return(0); } /* /BEFORE: */ if (sb[0] && (strcmp(fdate,(char *)sb) >= 0)) { debug(F110,"fileselect sb",sb,0); /* tlog(F110,"Skipping (too new)",f,0); */ return(0); } /* /NOT-AFTER: */ if (sna[0] && (strcmp(fdate,(char *)sna) > 0)) { debug(F110,"fileselect sna",sna,0); /* tlog(F110,"Skipping (too new)",f,0); */ return(0); } /* /NOT-BEFORE: */ if (snb[0] && (strcmp(fdate,(char *)snb) < 0)) { debug(F110,"fileselect snb",snb,0); /* tlog(F110,"Skipping (too old)",f,0); */ return(0); } } if (minsiz > -1L || maxsiz > -1L) { /* Smaller or larger */ z = zchki(f); /* Get size */ debug(F101,"fileselect filesize","",z); if (z < 0) return(1); if ((minsiz > -1L) && (z >= minsiz)) { debug(F111,"fileselect minsiz skipping",f,minsiz); /* tlog(F111,"Skipping (too big)",f,z); */ return(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -