int tfs_getfld (const TFSCAN *tfs, FILE *file, char *buf, int len, int *read) { /* --- read a table field */ int c; /* character read */ int d; /* delimiter type */ char *p; /* to traverse the buffer */ assert(tfs && file && buf && (len >= 0)); p = buf; *p = '\0'; /* clear read buffer */ do { /* --- skip leading blanks */ c = getc(file); /* get next character */ if (c == EOF) return (ferror(file)) ? -1 : TFS_EOF; } while (isblank(c)); /* while character is blank */ if (issep(c)) { /* check for field/record separator */ if (read) *read = 0; /* clear number of characters read */ return (isfldsep(c)) ? TFS_FLD : TFS_REC; } /* return delimiter type */ while (1) { /* --- read value */ if (len >= 0) { /* if buffer is not full, */ len--; *p++ = (char)c; } /* store character in buffer */ c = getc(file); /* get next character */ if (issep(c)) { d = (isfldsep(c)) ? TFS_FLD : TFS_REC; break; } if (c == EOF) { d = (ferror(file)) ? -1 : TFS_EOF; break; } } /* while character is no separator */ while (isblank(*--p)); /* --- remove trailing blanks */ *++p = '\0'; /* terminate string in buffer */ if (read) *read = (int)(p -buf); /* store number of characters read */ if (d != TFS_FLD) return d; /* if not at field separator, abort */ while (isblank(c)) { /* --- skip trailing blanks */ c = getc(file); /* get next character */ if (c == EOF) return (ferror(file)) ? -1 : TFS_EOF; } /* check for end of file */ if (isrecsep(c)) return TFS_REC; /* check for record separator */ if (!isfldsep(c)) ungetc(c, file); /* put back character */ return TFS_FLD; /* return delimiter type */ } /* tfs_getfld() */
int trd_read (TABREAD *trd) { /* --- read the next table field */ int c, d; /* character read, delimiter type */ char *p, *e; /* to traverse the field */ /* --- initialize --- */ assert(trd && trd->file); /* check the function arguments */ trd->pos = (trd->delim == TRD_FLD) ? trd->pos+1 : 1; trd->field[trd->len = 0] = 0; /* clear the current field */ GETC(trd, c, TRD_EOF); /* get the first character */ /* --- skip comment records --- */ if (trd->delim != TRD_FLD) { /* if at the start of a record */ while (iscomment(c)) { /* while the record is a comment */ while (!isrecsep(c)) /* while not at end of record, */ GETC(trd, c, TRD_EOF); /* get the next character */ trd->rec++; /* count the comment record */ GETC(trd, c, TRD_EOF); /* get the first character */ } /* after the comment record */ } /* (comment records are skipped) */ /* --- skip leading blanks --- */ while (isblank(c)) /* while the character is blank, */ GETC(trd, c, TRD_REC); /* get the next character */ if (issep(c)) { /* check for field/record separator */ trd->last = c; /* store the last character read */ if (isfldsep(c)) return trd->delim = TRD_FLD; trd->rec++; return trd->delim = TRD_REC; } /* if at end of record, count record */ /* Note that after at least one valid character was read, even */ /* if it is a blank, the end of file/input is translated into a */ /* record separator. EOF is returned only if no character could */ /* be read before the end of file/input is encountered. */ /* --- read the field --- */ p = trd->field; e = p +TRD_MAXLEN; while (1) { /* field read loop */ if (p < e) *p++ = (char)c; /* append the last character */ c = trd_getc(trd); /* and get the next character */ if (c < 0) { d = (c <= TRD_ERR) ? TRD_ERR : TRD_REC; break; } if (issep(c)) { d = (isfldsep(c)) ? TRD_FLD : TRD_REC; break; } } /* while character is no separator */ trd->last = c; /* store the last character read */ /* --- remove trailing blanks --- */ while (isblank(*--p)); /* skip blank characters at the end */ *++p = '\0'; /* and terminate the current field */ trd->len = (size_t)(p -trd->field); /* store number of characters */ /* --- check for a null value --- */ while (--p >= trd->field) /* check for only null value chars. */ if (!isnull((unsigned char)*p)) break; if (p < trd->field) /* clear field if null value */ trd->field[trd->len = 0] = 0; /* --- check for end of line --- */ if (d != TRD_FLD) { /* if not at a field separator */ if (d == TRD_REC) trd->rec++; return trd->delim = d; /* if at end of record, count record, */ } /* and then abort the function */ /* --- skip trailing blanks --- */ while (isblank(c)) { /* while character is blank, */ trd->last = c; /* note the last character */ GETC(trd, c, TRD_REC); /* and get the next character */ } if (isrecsep(c)) { /* check for a record separator */ trd->last = c; trd->rec++; return trd->delim = TRD_REC; } if (isfldsep(c)) /* note the field separator or */ trd->last = c; /* put back last character (may be */ else trd_ungetc(trd, c); /* necessary if blank = field sep.) */ return trd->delim = TRD_FLD; /* return the delimiter type */ } /* trd_read() */
int ts_next (TABSCAN *tsc, FILE *file, char *buf, int len) { /* --- read the next table field */ int c, d; /* character read, delimiter type */ char *p; /* to traverse the buffer */ assert(tsc && (!buf || (len >= 0))); /* check function argumens */ /* --- initialize --- */ if (!buf) { /* if no buffer given, use internal */ buf = tsc->buf; len = TS_SIZE; } p = buf; *p = '\0'; /* clear the read buffer and */ tsc->cnt = 0; /* the number of characters read */ GETC(c, TS_EOF, file); /* get the first character */ /* --- skip comment records --- */ if (tsc->delim != TS_FLD) { /* if at the start of a record */ while (iscomment(c)) { /* while the record is a comment */ tsc->reccnt++; /* count the record to be read */ while (!isrecsep(c)) /* while not at end of record, */ GETC(c, TS_EOF, file); /* get the next character */ GETC(c, TS_EOF, file); /* get the first character */ } /* after the comment record */ } /* (comment records are skipped) */ /* --- skip leading blanks --- */ while (isblank(c)) /* while character is blank, */ GETC(c, TS_REC, file); /* get the next character */ if (issep(c)) { /* check for field/record separator */ tsc->last = c; /* store the last character read */ if (isfldsep(c)) return tsc->delim = TS_FLD; tsc->reccnt++; return tsc->delim = TS_REC; } /* if at end of record, count reocrd */ /* Note that after at least one valid character was read, even */ /* if it is a blank, the end of file/input is translated into a */ /* record separator. -1 is returned only if no character could */ /* be read before the end of file/input is encountered. */ /* --- read the field --- */ while (1) { /* field read loop */ if (len > 0) { /* if the buffer is not full, */ len--; *p++ = (char)c; } /* store the character in the buffer */ c = getc(file); /* get the next character */ if (issep(c)) { d = (isfldsep(c)) ? TS_FLD : TS_REC; break; } if (c == EOF) { d = (ferror(file)) ? TS_ERR : TS_REC; break; } } /* while character is no separator */ tsc->last = c; /* store the last character read */ /* --- remove trailing blanks --- */ while (isblank(*--p)); /* while character is blank */ *++p = '\0'; /* terminate string in buffer */ tsc->cnt = (int)(p -buf); /* store number of characters read */ /* --- check for a null value --- */ while (--p >= buf) /* check for only null value chars. */ if (!isnull((unsigned char)*p)) break; if (p < buf) { /* clear buffer if null value */ buf[0] = '\0'; tsc->cnt = 0; } /* --- check for end of line --- */ if (d != TS_FLD) { /* if not at a field separator */ if (d == TS_REC) tsc->reccnt++; return tsc->delim = d; /* if at end of record, count record, */ } /* and then abort the function */ /* --- skip trailing blanks --- */ while (isblank(c)) { /* while character is blank, */ tsc->last = c; /* note the last character */ GETC(c, TS_REC, file); /* and get the next character */ } if (isrecsep(c)) { /* check for a record separator */ tsc->reccnt++; tsc->last = c; return tsc->delim = TS_REC; } if (isfldsep(c)) /* note the field separator or */ tsc->last = c; /* put back last character (may be */ else ungetc(c, file); /* necessary if blank = field sep.) */ return tsc->delim = TS_FLD; /* return the delimiter type */ } /* ts_next() */