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: }

Defined functions

READ8 defined in line 9; used 2 times
readreal defined in line 60; used 1 times
  • in line 23

Defined variables

sccsid defined in line 3; never used

Defined macros

ANY_ONE_OF defined in line 111; never used
AT_LEAST_ONE defined in line 104; used 1 times
AT_MOST_ONE defined in line 118; used 1 times
NEXT_CHAR defined in line 92; used 3 times
PUSHBACK defined in line 70; used 7 times
PUSH_TO_NULL defined in line 87; used 4 times
RETURN_ON_EOF defined in line 81; used 5 times
SOME defined in line 98; used 4 times
Last modified: 1983-11-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1298
Valid CSS Valid XHTML 1.0 Strict