/* See fget.h */ /* Last edited on 2005-01-16 15:05:06 by stolfi */ /* Copyright © 2005 Jorge Stolfi, UNICAMP. See note at end of file. */ #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. */ /* COPYRIGHT AND AUTHORSHIP NOTICE Copyright © 2005 Jorge Stolfi, Universidade Estadual de Campinas (UNICAMP). Created by Jorge Stolfi in 1992--2005. This source file can be freely distributed, used, and modified, provided that this copyright and authorship notice is preserved in all copies, and that any modified versions of this file are clearly marked as such. This software has NO WARRANTY of correctness or applicability for any purpose. Neither the author nor his employers shall be held responsible for any losses or damages that may result from its use. END OF NOTICE */