📄 file.c
字号:
if (comp) scannum = -scannum; chnum = 0; for (;;) { len = 0; b = buf; for(;;) { c = fgetc(fp); if (c == EOF || c == '\0') break; chnum++; if(scannum && (!isspace(c) ^ comp)) break; if (!skip) { *b++ = c; len++; if (len >= READSIZE) break; } if (chnum == width) break; } if (!skip) { if (totlen) str = (char *) realloc(str, totlen + len + 1); else str = (char *) malloc(len + 1); if (str == NULL) { math_error("Out of memory for scanning"); /*NOTREACHED*/ } if (len) memcpy(&str[totlen], buf, len); totlen += len; } if (len < READSIZE) break; } if (!(width && chnum == width) && c != '\0') ungetc(c, fp); if (!skip) { str[totlen] = '\0'; *strptr = str; }}static intfscanfile(FILE *fp, char *fmt, int count, VALUE **vals){ int assnum; /* Number of assignments made */ int c; /* Character read from file */ char f; /* Character read from format string */ int scannum; /* Number of characters in scanlist */ char *scanptr; /* Start of scanlist */ char *str; BOOL comp; /* True scanset is complementary */ BOOL skip; /* True if string to be skipped rather than read */ int width; VALUE *var; /* lvalue to be assigned to */ unsigned short subtype; /* for var->v_subtype */ FILEPOS cur; /* current location */ if (feof(fp)) return EOF; assnum = 0; for (;;) { for (;;) { f = *fmt++; if (isspace((int)f)) { getscanwhite(fp,1,0,6,NULL); do { f = *fmt++; } while (isspace((int)f)); } c = fgetc(fp); if (c == EOF) return assnum; if (f == '%') { f = *fmt++; if (f != '%' && f != '\0') break; } if (f != c || f == '\0') { ungetc(c, fp); return assnum; } } ungetc(c, fp); skip = (f == '*'); if (!skip && count == 0) { return assnum; } if (skip) f = *fmt++; width = 0; while (f >= '0' && f <= '9') { width = 10 * width + f - '0'; f = *fmt++; } switch (f) { case 'c': if (width == 0) width = 1; getscanfield(fp,skip,width,0,NULL,&str); break; case 's': getscanwhite(fp,1,0,6,NULL); if (feof(fp)) return assnum; getscanwhite(fp,skip,width,-6,&str); break; case '[': f = *fmt; comp = (f == '^'); if (comp) f = *++fmt; scanptr = fmt; if (f == '\0') return assnum; fmt = strchr((f == ']' ? fmt + 1 : fmt), ']'); if (fmt == NULL) return assnum; scannum = fmt - scanptr; if (comp) scannum = -scannum; fmt++; getscanfield(fp,skip, width,scannum,scanptr,&str); break; case 'f': case 'e': case 'r': case 'i': getscanwhite(fp,1,0,6, NULL); if (feof(fp)) return assnum; if (skip) { fskipnum(fp); continue; } assnum++; var = *vals++; if (var->v_type != V_ADDR) math_error("This should not happen!!"); var = var->v_addr; subtype = var->v_subtype; freevalue(var); count--; freadsum(fp, var); var->v_subtype = subtype; continue; case 'n': assnum++; var = *vals++; count--; if (var->v_type != V_ADDR) math_error("This should not happen!!"); var = var->v_addr; subtype = var->v_subtype; freevalue(var); var->v_type = V_NUM; var->v_num = qalloc(); f_tell(fp, &cur); var->v_num->num = filepos2z(cur); var->v_subtype = subtype; continue; default: fprintf(stderr, "Unsupported scan specifier"); return assnum; } if (!skip) { assnum++; var = *vals++; count--; if (var->v_type != V_ADDR) math_error("Assigning to nonvariable"); var = var->v_addr; subtype = var->v_subtype; freevalue(var); var->v_type = V_STR; var->v_str = makestring(str); } }}intfscanfid(FILEID id, char *fmt, int count, VALUE **vals){ FILEIO *fiop; FILE *fp; FILEPOS fpos; fiop = findid(id, FALSE); if (fiop == NULL) return -2; fp = fiop->fp; if (fiop->action == 'w') { f_tell(fp, &fpos); fflush(fp); if (f_seek_set(fp, &fpos) < 0) return -4; } fiop->action = 'r'; return fscanfile(fp, fmt, count, vals);}intscanfstr(char *str, char *fmt, int count, VALUE **vals){ FILE *fp; int i; fp = tmpfile(); if (fp == NULL) return EOF; fputs(str, fp); rewind(fp); i = fscanfile(fp, fmt, count, vals); fclose(fp); return i;}/* * Read a number in floating-point format from a file. The first dot, * if any, is considered as the decimal point; later dots are ignored. * For example, -23.45..67. is interpreted as -23.4567 * An optional 'e' or 'E' indicates multiplication by a power or 10, * e.g. -23.45e-6 has the effect of -23.45 * 10^-6. The reading * ceases when a character other than a digit, a leading sign, * a sign immediately following 'e' or 'E', or a dot is encountered. * Absence of digits is interpreted as zero. */static voidfreadnum(FILE *fp, VALUE *valptr){ ZVALUE num, zden, newnum, newden, div, tmp; NUMBER *q; COMPLEX *c; VALUE val; char ch; LEN i; HALF *a; FULL f; long decimals, exp; BOOL sign, negexp, havedp, imag, exptoobig; decimals = 0; exp = 0; sign = FALSE; negexp = FALSE; havedp = FALSE; imag = FALSE; exptoobig = FALSE; ch = fgetc(fp); if (ch == '+' || ch == '-') { if (ch == '-') sign = TRUE; ch = fgetc(fp); } num.v = alloc(1); *num.v = 0; num.len = 1; num.sign = sign; for (;;) { if (ch >= '0' && ch <= '9') { f = (FULL) (ch - '0'); a = num.v; i = num.len; while (i-- > 0) { f = 10 * (FULL) *a + f; *a++ = (HALF) f; f >>= BASEB; } if (f) { a = alloc(num.len + 1); memcpy(a, num.v, num.len * sizeof(HALF)); a[num.len] = (HALF) f; num.len++; freeh(num.v); num.v = a; } if (havedp) decimals++; } else if (ch == '.') havedp = TRUE; else break; ch = fgetc(fp); } if (ch == 'e' || ch == 'E') { ch = fgetc(fp); if (ch == '+' || ch == '-') { if (ch == '-') negexp = TRUE; ch = fgetc(fp); } while (ch >= '0' && ch <= '9') { if (!exptoobig) { exp = (exp * 10) + ch - '0'; if (exp > 1000000) exptoobig = TRUE; } ch = fgetc(fp); } } if (ch == 'i' || ch == 'I') { imag = TRUE; } else { ungetc(ch, fp); } if (ziszero(num)) { zfree(num); val.v_type = V_NUM; val.v_subtype = V_NOSUBTYPE; val.v_num = qlink(&_qzero_); *valptr = val; return; } if (exptoobig) { zfree(num); *valptr = error_value(E_BIGEXP); return; } ztenpow(decimals, &zden); if (exp) { ztenpow(exp, &tmp); if (negexp) { zmul(zden, tmp, &newden); zfree(zden); zden = newden; } else { zmul(num, tmp, &newnum); zfree(num); num = newnum; } zfree(tmp); } if (!zisunit(num) && !zisunit(zden)) { zgcd(num, zden, &div); if (!zisunit(div)) { zequo(num, div, &newnum); zfree(num); zequo(zden, div, &newden); zfree(zden); num = newnum; zden = newden; } zfree(div); } q = qalloc(); q->num = num; q->den = zden; if (imag) { c = comalloc(); qfree(c->imag); c->imag = q; val.v_type = V_COM; val.v_com = c; } else { val.v_type = V_NUM; val.v_num = q; } val.v_subtype = V_NOSUBTYPE; *valptr = val;}static voidfreadsum(FILE *fp, VALUE *valptr){ VALUE v1, v2, v3; char ch; freadprod(fp, &v1); ch = fgetc(fp); while (ch == '+' || ch == '-') { freadprod(fp, &v2); if (ch == '+') addvalue(&v1, &v2, &v3); else subvalue(&v1, &v2, &v3); freevalue(&v1); freevalue(&v2); v1 = v3; ch = fgetc(fp); } ungetc(ch, fp); *valptr = v1;}static voidfreadprod(FILE *fp, VALUE *valptr){ VALUE v1, v2, v3; char ch; freadnum(fp, &v1); ch = fgetc(fp); while (ch == '*' || ch == '/') { freadnum(fp, &v2); if (ch == '*') mulvalue(&v1, &v2, &v3); else divvalue(&v1, &v2, &v3); freevalue(&v1); freevalue(&v2); v1 = v3; ch = fgetc(fp); } ungetc(ch, fp); *valptr = v1;}static voidfskipnum(FILE *fp){ char ch; do { ch = fgetc(fp); if (ch == '+' || ch == '-') ch = fgetc(fp); while ((ch >= '0' && ch <= '9') || ch == '.') ch = fgetc(fp); if (ch == 'e' || ch == 'E') { ch = fgetc(fp); if (ch == '+' || ch == '-') ch = fgetc(fp); while (ch >= '0' && ch <= '9') ch = fgetc(fp); } if (ch == 'i' || ch == 'I') ch = fgetc(fp); } while (ch == '/' || ch == '*' || ch == '+' || ch == '-'); ungetc(ch, fp);}intisattyid(FILEID id){ FILEIO *fiop; fiop = findid(id, -1); if (fiop == NULL) return -2; return isatty(fileno(fiop->fp));}/* * fsearch - search for a string in a file * * given: * id FILEID to search * str string to look for * pos file postion to start at (NULL => current position) * * returns: * EOF if system error * other negative integer if file not open, etc. * positive integer if string not found * zero if string found, position stored at res * * XXX - This search is a translation of the original search that did not * work with large files. The search algorithm used is slow and * should be spead up much more. */intfsearch(FILEID id, char *str, ZVALUE start, ZVALUE end, ZVALUE *res){ FILEIO *fiop; /* FILEIO of file id */ FILEPOS cur; /* current file position */ ZVALUE tmp, tmp2; /* temporary ZVALUEs */ char c; /* str comparison character */ int r; /* character read from file */ char *s; /* str comparison pointer */ long k = 0; /* get FILEIO */ fiop = findid(id, FALSE); if (fiop == NULL) return -2; /* * file setup */ if (fiop->action == 'w') fflush(fiop->fp); zsub(end, start, &tmp2); if (zisneg(tmp2)) { zfree(tmp2); return 1; } tmp.sign = 0; tmp.len = tmp2.len; tmp.v = alloc(tmp.len); zcopyval(tmp2, tmp); zfree(tmp2); cur = z2filepos(start); if (f_seek_set(fiop->fp, &cur) < 0) { zfree(tmp); return EOF; } /* * search setup */ /* note the first str search character */ c = *str++; if (c == '\0') { zfree(tmp); return 2; } clearerr(fiop->fp); while ((r = fgetc(fiop->fp)) != EOF) { if ((char)r == c) { (void) f_tell(fiop->fp, &cur); s = str; while (*s) { r = fgetc(fiop->fp); if ((char)r != *s) break; s++; } if (r == EOF) break; if (*s == '\0') { zfree(tmp); tmp = filepos2z(cur); zsub(tmp, _one_, res); zfree(tmp); return 0; } (void) f_seek_set(fiop->fp, &cur); } if (*tmp.v) { (*tmp.v)--; } else { if (tmp.len == 1) break; k = 0; do { tmp.v[k++] = BASE1; } while (k < tmp.len && tmp.v[k] == 0); if (k == tmp.len) { math_error("This should not happen"); /*NOTREACHED*/ } tmp.v[k]--; if (tmp.v[tmp.len - 1] == 0) tmp.len--; } } zfree(tmp); if (ferror(fiop->fp)) return EOF; return 1;}/* * frsearch - reverse search for a string in a file * * given: * id FILEID to search * str string to look for * search starts at pos = first and continues for decreasing * pos >= last * * returns: * EOF if system error * other negative integer if file not open, etc. * positive integer if string not found * zero if string found, position stored at res * * XXX - This search is a translation of the original search that did not * work with large files. The search algorithm used is so slow * as to be painful to the user and needs to be sped up much more. */intfrsearch(FILEID id, char *str, ZVALUE first, ZVALUE last, ZVALUE *res){ FILEIO *fiop; /* FILEIO of file id */ FILEPOS cur; /* current file position */ ZVALUE pos; /* current file position as ZVALUE */ ZVALUE tmp; /* temporary ZVALUEs */ char c; /* str comparison character */ int r; /* character read from file */ char *s; /* str comparison pointer */ /* get FILEIO */ fiop = findid(id, FALSE); if (fiop == NULL) return -2; /* * file setup */ if (fiop->action == 'w') fflush(fiop->fp); zcopy(first, &pos); /* * search setup */ /* note the first str search character */ c = *str++; if (c == '\0') { cur = z2filepos(pos); if (f_seek_set(fiop->fp, &cur) < 0) { zfree(pos); return EOF; } *res = pos; return 0; } clearerr(fiop->fp); while(zrel(pos, last) >= 0) { cur = z2filepos(pos); if (f_seek_set(fiop->fp, &cur) < 0) { zfree(pos); return EOF; } r = fgetc(fiop->fp); if (r == EOF) { zfree(pos); return EOF; } if ((char) r == c) { s = str; while (*s) { r = fgetc(fiop->fp); if ((char)r != *s) break; s++; } if (r == EOF) { zfree(pos); return EOF; } if (*s == '\0') { *res = pos; ungetc(r, fiop->fp); return 0; } } zsub(pos, _one_, &tmp); zfree(pos); pos = tmp; } cur = z2filepos(last); f_seek_set(fiop->fp, &cur); zfree(pos); if (ferror(fiop->fp)) return EOF; return 1;}char *findfname(FILEID id){ FILEIO *fiop; fiop = findid(id, -1); if (fiop == NULL) return NULL; return fiop->name;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -