/* See fget.h */ /* Last edited on 2003-01-14 13:24:45 by stolfi */ #include #include #include #include #include void fget_skip_to_non_blank(FILE *f); /* Skips spaces and requires that the next character is not a line or page break, or end-of-file. */ void fget_skip_formatting_chars(FILE *f) { int c; do { c = fgetc(f); if (c == EOF) { return; } } while ((c=='\000')||(c==' ')||((c>='\011')&&(c<='\015'))); ungetc(c, f); return; } void fget_skip_spaces(FILE *f) { int c; do { c = fgetc(f); if (c == EOF) { return; } } while ((c=='\000')||(c==' ')||(c=='\011')); ungetc(c, f); return; } void fget_match(FILE *f, char *t) { while ((*t) != '\000') { int c = fgetc(f); if (c != (*t)) { fprintf(stderr, "next char = '%c'\n", c); affirm(FALSE, txtcat("cannot find \"", txtcat(t, "\""))); } t++; } } void fget_eol(FILE *f) { int c; fget_skip_spaces(f); c = fgetc(f); affirm(c == '\n', "extraneous data on input line"); } void fget_skip_to_non_blank(FILE *f) { int c; fget_skip_spaces(f); c = fgetc(f); affirm((c!=EOF)&&((c<'\012')||(c>'\015')), "item not found"); ungetc(c, f); } char fget_char(FILE *f) { int c; fget_skip_to_non_blank(f); c = fgetc(f); affirm(c != EOF, "expecting nonblank char, found end of file"); return c; } bool fget_bool(FILE *f) { int c; fget_skip_to_non_blank(f); c = fgetc(f); if ((c == 't') || (c == 'T') || (c == '1' )) { return TRUE; } else if ((c == 'f') || (c == 'F') || (c == '0' )) { return FALSE; } else { ungetc(c, f); affirm(FALSE, "missing or invalid bool value"); return FALSE; } } #define INITEXTLENGTH 1024 char *fget_string(FILE *f) { char buf[INITEXTLENGTH+1]; char *pbuf = &(buf[0]); int bufsz = INITEXTLENGTH+1; int i = 0, c; fget_skip_to_non_blank(f); c = fgetc(f); while ((c!=EOF)&&(c!='\000')&&(c!=' ')&&(c!='\011')&&((c<'\012')||(c>'\015'))) { if (i >= bufsz-1) { int tmpsz = 2*bufsz; char *tmp = (char *)notnull(malloc(tmpsz), "out of mem for buf"); pbuf[i] = '\000'; strcpy(tmp, pbuf); if (pbuf != &(buf[0])) { free(pbuf); } pbuf = tmp; bufsz = tmpsz; } pbuf[i] = c; i++; c = fgetc(f); } if (c != EOF) { ungetc(c, f); } pbuf[i] = '\000'; i++; if ((i < bufsz) || (pbuf == &(buf[0]))) { char *tmp = (char *)notnull(malloc(i), "out of mem for result"); strcpy(tmp, pbuf); if (pbuf != &(buf[0])) { free(pbuf); } pbuf = tmp; } return pbuf; } #define MAXNUMLENGTH 1024 /* Maximum length of an "int" or "double" item. */ int fget_int(FILE *f) { char buf[MAXNUMLENGTH+1]; int i, c; long x; char *rest; fget_skip_to_non_blank(f); i = 0; c = fgetc(f); if ((c == '+') || (c == '-')) { buf[i] = c; i++; c = fgetc(f); } while ((i < MAXNUMLENGTH) && (c >= '0') && (c <= '9')) { buf[i] = c; i++; c = fgetc(f); } if (c != EOF) { ungetc(c, f); } buf[i] = '\000'; x = strtol(&(buf[0]), &rest, 10); affirm((*rest) == '\000', txtcat("invalid integer", &(buf[0]))); return x; } double fget_double(FILE *f) { char buf[MAXNUMLENGTH+1]; int i, c; double x; char *rest; fget_skip_to_non_blank(f); i = 0; c = fgetc(f); if ((c == '+') || (c == '-')) { buf[i] = c; i++; c = fgetc(f); } while ((i < MAXNUMLENGTH) && (c != EOF) && (c >= '0') && (c <= '9')) { buf[i] = c; i++; c = fgetc(f); } if ((i < MAXNUMLENGTH) && (c == '.')) { buf[i] = c; i++; c = fgetc(f); } while ((i < MAXNUMLENGTH) && (c >= '0') && (c <= '9')) { buf[i] = c; i++; c = fgetc(f); } if ((i < MAXNUMLENGTH) && ((c == 'e') || (c == 'E') || (c == 'd') || (c == 'D'))) { buf[i] = c; i++; c = fgetc(f); if ((i < MAXNUMLENGTH) && ((c == '+') || (c == '-'))) { buf[i] = c; i++; c = fgetc(f); } while ((i < MAXNUMLENGTH) && (c >= '0') && (c <= '9')) { buf[i] = c; i++; c = fgetc(f); } } if (c != EOF) { ungetc(c, f); } buf[i] = '\000'; x = strtod(&(buf[0]), &rest); affirm((*rest) == '\000', txtcat("invalid number", &(buf[0]))); return x; } bool fget_skip_and_test_char(FILE *f, char c) { fget_skip_spaces(f); return fget_test_char(f, c); } bool fget_test_char(FILE *f, char c) { int r; fget_skip_spaces(f); r = fgetc(f); if (r == c) { return TRUE; } else if (r == EOF) { return FALSE; } else { ungetc(r, f); return FALSE; } } /* Created by J. Stolfi, Unicamp, Dec/2002. */