Annotation of 43BSD/usr.lib/libpc/READ8.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: 
                      3: static char sccsid[] = "@(#)READ8.c 1.9 11/6/83";
                      4: 
                      5: #include "h00vars.h"
                      6: #include <errno.h>
                      7: extern int errno;
                      8: 
                      9: double
                     10: READ8(curfile)
                     11:        register struct iorec   *curfile;
                     12: {
                     13:        double                  data;
                     14:        int                     retval;
                     15: 
                     16:        if (curfile->funit & FWRITE) {
                     17:                ERROR("%s: Attempt to read, but open for writing\n",
                     18:                        curfile->pfname);
                     19:                return;
                     20:        }
                     21:        UNSYNC(curfile);
                     22:        errno = 0;
                     23:        retval = readreal(curfile, &data);
                     24:        if (retval == EOF) {
                     25:                ERROR("%s: Tried to read past end of file\n", curfile->pfname);
                     26:                return;
                     27:        }
                     28:        if (retval == 0) {
                     29:                ERROR("%s: Bad data found on real read\n", curfile->pfname);
                     30:                return;
                     31:        }
                     32:        if (errno == ERANGE) {
                     33:                if (data == 0.0)
                     34:                        ERROR("%s: Underflow on real read\n", curfile->pfname);
                     35:                else
                     36:                        ERROR("%s: Overflow on real read\n", curfile->pfname);
                     37:                return;
                     38:        }
                     39:        if (errno != 0) {
                     40:                PERROR("Error encountered on real read ", curfile->pfname);
                     41:                return;
                     42:        }
                     43:        return (data);
                     44: }
                     45: 
                     46: /*
                     47:  *     given a file pointer, read a sequence of characters of the
                     48:  *     syntax of section 6.1.5 and form them into a double.
                     49:  *
                     50:  *     the syntax of a signed-real is:
                     51:  *         [-|+] digit {digit} [ . digit {digit} ] [ e [+|-] digit {digit} ]
                     52:  *
                     53:  *     returns:
                     54:  *             1       for success (with value in *doublep)
                     55:  *             0       on error (with *doublep unchanged)
                     56:  *            -1       on end-of-file during read (with *doublep unchanged)
                     57:  *     side effects:
                     58:  *           errno     may be set to ERANGE if atof() sets it.
                     59:  */
                     60: readreal(curfile, doublep)
                     61:        struct iorec    *curfile;
                     62:        double          *doublep;
                     63: {
                     64:        FILE    *filep = curfile->fbuf; /* current file variable */
                     65:        char    *sequencep;             /* a pointer into sequence */
                     66:        int     read;                   /* return value from fscanf() */
                     67:        char    sequence[BUFSIZ];       /* the character sequence */
                     68:        double  atof();
                     69: 
                     70: #define PUSHBACK(curfile, sequencep) \
                     71:        if (ungetc(*--(sequencep), (curfile)->fbuf) != EOF) { \
                     72:                *(sequencep) = '\0'; \
                     73:        } else if ((curfile)->funit & SYNC) { \
                     74:                (curfile)->funit &= ~SYNC; \
                     75:                *(curfile)->fileptr = *(sequencep); \
                     76:                *(sequencep) = '\0'; \
                     77:        } else { \
                     78:                return (0); \
                     79:        }
                     80: 
                     81: #define        RETURN_ON_EOF(read) \
                     82:        if (read == EOF) \
                     83:                return (EOF); \
                     84:        else \
                     85:                /* void */;
                     86: 
                     87: #define        PUSH_TO_NULL(sequencep) \
                     88:        while (*sequencep) \
                     89:                sequencep++;
                     90: 
                     91:        /* general reader of the next character */
                     92: #define        NEXT_CHAR(read, filep, format, sequencep) \
                     93:        read = fscanf(filep, "%c", sequencep); \
                     94:        RETURN_ON_EOF(read); \
                     95:        *++sequencep = '\0';
                     96: 
                     97:        /* e.g. use %[0123456789] for {digit}, and check read */
                     98: #define        SOME(read, filep, format, sequencep) \
                     99:        read = fscanf(filep, format, sequencep); \
                    100:        RETURN_ON_EOF(read); \
                    101:        PUSH_TO_NULL(sequencep);
                    102: 
                    103:        /* e.g. use %[0123456789] for digit {digit} */
                    104: #define        AT_LEAST_ONE(read, filep, format, sequencep) \
                    105:        read = fscanf(filep, format, sequencep); \
                    106:        RETURN_ON_EOF(read); \
                    107:        if (strlen(sequencep) < 1) \
                    108:                return (0); \
                    109:        PUSH_TO_NULL(sequencep);
                    110: 
                    111: #define        ANY_ONE_OF(read, filep, format, sequencep) \
                    112:        read = fscanf(filep, format, sequencep); \
                    113:        RETURN_ON_EOF(read); \
                    114:        if (strlen(sequencep) != 1) \
                    115:                return (0); \
                    116:        PUSH_TO_NULL(sequencep);
                    117: 
                    118: #define        AT_MOST_ONE(read, filep, format, sequencep) \
                    119:        read = fscanf(filep, format, sequencep); \
                    120:        RETURN_ON_EOF(read); \
                    121:        if (strlen(sequencep) > 1) \
                    122:                return (0); \
                    123:        PUSH_TO_NULL(sequencep);
                    124:                
                    125:        sequencep = &sequence[0];
                    126:        *sequencep = '\0';
                    127:        /*
                    128:         *      skip leading whitespace
                    129:         */
                    130:        SOME(read, filep, "%*[ \t\n]", sequencep);
                    131:        /*
                    132:         *      this much is required:
                    133:         *      [ "+" | "-" ] digit {digits}
                    134:         */
                    135:        AT_MOST_ONE(read, filep, "%[+-]", sequencep);
                    136:        AT_LEAST_ONE(read, filep, "%[0123456789]", sequencep);
                    137:        /*
                    138:         *      any of this is optional:
                    139:         *      [ `.' digit {digit} ] [ `e' [ `+' | `-' ] digit {digits} ]
                    140:         */
                    141:        NEXT_CHAR(read, filep, "%c", sequencep);
                    142:        switch (sequencep[-1]) {
                    143:        default:
                    144:                PUSHBACK(curfile, sequencep);
                    145:                goto convert;
                    146:        case '.':
                    147:                SOME(read, filep, "%[0123456789]", sequencep);
                    148:                if (!read) {
                    149:                        PUSHBACK(curfile, sequencep);
                    150:                        goto convert;
                    151:                }
                    152:                NEXT_CHAR(read, filep, "%c", sequencep);
                    153:                if (sequencep[-1] != 'e') {
                    154:                        PUSHBACK(curfile, sequencep);
                    155:                        goto convert;
                    156:                }
                    157:                /* fall through */
                    158:        case 'e':
                    159:                NEXT_CHAR(read, filep, "%c", sequencep);
                    160:                if (sequencep[-1] != '+' && sequencep[-1] != '-') {
                    161:                        PUSHBACK(curfile, sequencep);
                    162:                        SOME(read, filep, "%[0123456789]", sequencep);
                    163:                        if (!read)
                    164:                                PUSHBACK(curfile, sequencep);
                    165:                        goto convert;
                    166:                }
                    167:                SOME(read, filep, "%[0123456789]", sequencep);
                    168:                if (!read) {
                    169:                        PUSHBACK(curfile, sequencep);
                    170:                        PUSHBACK(curfile, sequencep);
                    171:                }
                    172:        }
                    173: 
                    174: convert:
                    175:        /*
                    176:         * convert sequence to double
                    177:         */
                    178:        *doublep = atof(&sequence[0]);
                    179:        return (1);
                    180: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.