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

1.1       root        1: /*-
                      2:  * Copyright (c) 1979 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that: (1) source distributions retain this entire copyright
                      7:  * notice and comment, and (2) distributions including binaries display
                      8:  * the following acknowledgement:  ``This product includes software
                      9:  * developed by the University of California, Berkeley and its contributors''
                     10:  * in the documentation or other materials provided with the distribution
                     11:  * and in all advertising materials mentioning features or use of this
                     12:  * software. Neither the name of the University nor the names of its
                     13:  * contributors may be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)READ8.c    1.11 (Berkeley) 4/9/90";
                     22: #endif /* not lint */
                     23: 
                     24: #include "h00vars.h"
                     25: #include <errno.h>
                     26: extern int errno;
                     27: 
                     28: double
                     29: READ8(curfile)
                     30:        register struct iorec   *curfile;
                     31: {
                     32:        double                  data;
                     33:        int                     retval;
                     34: 
                     35:        if (curfile->funit & FWRITE) {
                     36:                ERROR("%s: Attempt to read, but open for writing\n",
                     37:                        curfile->pfname);
                     38:        }
                     39:        UNSYNC(curfile);
                     40:        errno = 0;
                     41:        retval = readreal(curfile, &data);
                     42:        if (retval == EOF) {
                     43:                ERROR("%s: Tried to read past end of file\n", curfile->pfname);
                     44:        }
                     45:        if (retval == 0) {
                     46:                ERROR("%s: Bad data found on real read\n", curfile->pfname);
                     47:        }
                     48:        if (errno == ERANGE) {
                     49:                if (data == 0.0)
                     50:                        ERROR("%s: Underflow on real read\n", curfile->pfname);
                     51:                else
                     52:                        ERROR("%s: Overflow on real read\n", curfile->pfname);
                     53:        }
                     54:        if (errno != 0) {
                     55:                PERROR("Error encountered on real read ", curfile->pfname);
                     56:        }
                     57:        return (data);
                     58: }
                     59: 
                     60: /*
                     61:  *     given a file pointer, read a sequence of characters of the
                     62:  *     syntax of section 6.1.5 and form them into a double.
                     63:  *
                     64:  *     the syntax of a signed-real is:
                     65:  *         [-|+] digit {digit} [ . digit {digit} ] [ e [+|-] digit {digit} ]
                     66:  *
                     67:  *     returns:
                     68:  *             1       for success (with value in *doublep)
                     69:  *             0       on error (with *doublep unchanged)
                     70:  *            -1       on end-of-file during read (with *doublep unchanged)
                     71:  *     side effects:
                     72:  *           errno     may be set to ERANGE if atof() sets it.
                     73:  */
                     74: readreal(curfile, doublep)
                     75:        struct iorec    *curfile;
                     76:        double          *doublep;
                     77: {
                     78:        FILE    *filep = curfile->fbuf; /* current file variable */
                     79:        char    *sequencep;             /* a pointer into sequence */
                     80:        int     read;                   /* return value from fscanf() */
                     81:        char    sequence[BUFSIZ];       /* the character sequence */
                     82:        double  atof();
                     83: 
                     84: #define PUSHBACK(curfile, sequencep) \
                     85:        if (ungetc(*--(sequencep), (curfile)->fbuf) != EOF) { \
                     86:                *(sequencep) = '\0'; \
                     87:        } else if ((curfile)->funit & SYNC) { \
                     88:                (curfile)->funit &= ~SYNC; \
                     89:                *(curfile)->fileptr = *(sequencep); \
                     90:                *(sequencep) = '\0'; \
                     91:        } else { \
                     92:                return (0); \
                     93:        }
                     94: 
                     95: #define        RETURN_ON_EOF(read) \
                     96:        if (read == EOF) \
                     97:                return (EOF); \
                     98:        else \
                     99:                /* void */;
                    100: 
                    101: #define        PUSH_TO_NULL(sequencep) \
                    102:        while (*sequencep) \
                    103:                sequencep++;
                    104: 
                    105:        /* general reader of the next character */
                    106: #define        NEXT_CHAR(read, filep, format, sequencep) \
                    107:        read = fscanf(filep, "%c", sequencep); \
                    108:        RETURN_ON_EOF(read); \
                    109:        *++sequencep = '\0';
                    110: 
                    111:        /* e.g. use %[0123456789] for {digit}, and check read */
                    112: #define        SOME(read, filep, format, sequencep) \
                    113:        read = fscanf(filep, format, sequencep); \
                    114:        RETURN_ON_EOF(read); \
                    115:        PUSH_TO_NULL(sequencep);
                    116: 
                    117:        /* e.g. use %[0123456789] for digit {digit} */
                    118: #define        AT_LEAST_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: #define        ANY_ONE_OF(read, filep, format, sequencep) \
                    126:        read = fscanf(filep, format, sequencep); \
                    127:        RETURN_ON_EOF(read); \
                    128:        if (strlen(sequencep) != 1) \
                    129:                return (0); \
                    130:        PUSH_TO_NULL(sequencep);
                    131: 
                    132: #define        AT_MOST_ONE(read, filep, format, sequencep) \
                    133:        read = fscanf(filep, format, sequencep); \
                    134:        RETURN_ON_EOF(read); \
                    135:        if (strlen(sequencep) > 1) \
                    136:                return (0); \
                    137:        PUSH_TO_NULL(sequencep);
                    138:                
                    139:        sequencep = &sequence[0];
                    140:        *sequencep = '\0';
                    141:        /*
                    142:         *      skip leading whitespace
                    143:         */
                    144:        SOME(read, filep, "%*[ \t\n]", sequencep);
                    145:        /*
                    146:         *      this much is required:
                    147:         *      [ "+" | "-" ] digit {digits}
                    148:         */
                    149:        AT_MOST_ONE(read, filep, "%[+-]", sequencep);
                    150:        AT_LEAST_ONE(read, filep, "%[0123456789]", sequencep);
                    151:        /*
                    152:         *      any of this is optional:
                    153:         *      [ `.' digit {digit} ] [ `e' [ `+' | `-' ] digit {digits} ]
                    154:         */
                    155:        NEXT_CHAR(read, filep, "%c", sequencep);
                    156:        switch (sequencep[-1]) {
                    157:        default:
                    158:                PUSHBACK(curfile, sequencep);
                    159:                goto convert;
                    160:        case '.':
                    161:                SOME(read, filep, "%[0123456789]", sequencep);
                    162:                if (!read) {
                    163:                        PUSHBACK(curfile, sequencep);
                    164:                        goto convert;
                    165:                }
                    166:                NEXT_CHAR(read, filep, "%c", sequencep);
                    167:                if (sequencep[-1] != 'e') {
                    168:                        PUSHBACK(curfile, sequencep);
                    169:                        goto convert;
                    170:                }
                    171:                /* fall through */
                    172:        case 'e':
                    173:                NEXT_CHAR(read, filep, "%c", sequencep);
                    174:                if (sequencep[-1] != '+' && sequencep[-1] != '-') {
                    175:                        PUSHBACK(curfile, sequencep);
                    176:                        SOME(read, filep, "%[0123456789]", sequencep);
                    177:                        if (!read)
                    178:                                PUSHBACK(curfile, sequencep);
                    179:                        goto convert;
                    180:                }
                    181:                SOME(read, filep, "%[0123456789]", sequencep);
                    182:                if (!read) {
                    183:                        PUSHBACK(curfile, sequencep);
                    184:                        PUSHBACK(curfile, sequencep);
                    185:                }
                    186:        }
                    187: 
                    188: convert:
                    189:        /*
                    190:         * convert sequence to double
                    191:         */
                    192:        *doublep = atof(&sequence[0]);
                    193:        return (1);
                    194: }

unix.superglobalmegacorp.com

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