|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)lread.c 5.2 7/30/85 ! 7: */ ! 8: ! 9: /* ! 10: * list directed read ! 11: */ ! 12: ! 13: #include "fio.h" ! 14: #include "lio.h" ! 15: ! 16: #define SP 1 ! 17: #define B 2 ! 18: #define AP 4 ! 19: #define EX 8 ! 20: #define D 16 ! 21: #define EIN 32 ! 22: #define isblnk(x) (ltab[x+1]&B) /* space, tab, newline */ ! 23: #define issep(x) (ltab[x+1]&SP) /* space, tab, newline, comma */ ! 24: #define isapos(x) (ltab[x+1]&AP) /* apost., quote mark, \02 */ ! 25: #define isexp(x) (ltab[x+1]&EX) /* d, e, D, E */ ! 26: #define isdigit(x) (ltab[x+1]&D) ! 27: #define endlinp(x) (ltab[x+1]&EIN) /* EOF, newline, / */ ! 28: ! 29: #define GETC(x) (x=(*getn)()) ! 30: ! 31: LOCAL char lrd[] = "list read"; ! 32: LOCAL char *lchar; ! 33: LOCAL double lx,ly; ! 34: LOCAL int ltype; ! 35: int l_read(),t_getc(),ungetc(); ! 36: ! 37: LOCAL char ltab[128+1] = ! 38: { EIN, /* offset one for EOF */ ! 39: /* 0- 15 */ 0,0,AP,0,0,0,0,0,0,SP|B,SP|B|EIN,0,0,0,0,0, /* ^B,TAB,NEWLINE */ ! 40: /* 16- 31 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, ! 41: /* 32- 47 */ SP|B,0,AP,0,0,0,0,AP,0,0,0,0,SP,0,0,EIN, /* space,",',comma,/ */ ! 42: /* 48- 63 */ D,D,D,D,D,D,D,D,D,D,0,0,0,0,0,0, /* digits 0-9 */ ! 43: /* 64- 79 */ 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, /* D,E */ ! 44: /* 80- 95 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, ! 45: /* 96-111 */ 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, /* d,e */ ! 46: /* 112-127 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ! 47: }; ! 48: ! 49: s_rsle(a) cilist *a; /* start read sequential list external */ ! 50: { ! 51: int n; ! 52: reading = YES; ! 53: formatted = LISTDIRECTED; ! 54: fmtbuf = "ext list io"; ! 55: if(n=c_le(a,READ)) return(n); ! 56: l_first = YES; ! 57: lquit = NO; ! 58: lioproc = l_read; ! 59: getn = t_getc; ! 60: ungetn = ungetc; ! 61: leof = curunit->uend; ! 62: lcount = 0; ! 63: ltype = NULL; ! 64: if(curunit->uwrt && ! nowreading(curunit)) err(errflag, errno, lrd) ! 65: return(OK); ! 66: } ! 67: ! 68: LOCAL ! 69: t_getc() ! 70: { int ch; ! 71: if(curunit->uend) return(EOF); ! 72: if((ch=getc(cf))!=EOF) return(ch); ! 73: if(feof(cf)) ! 74: { curunit->uend = YES; ! 75: leof = EOF; ! 76: } ! 77: else clearerr(cf); ! 78: return(EOF); ! 79: } ! 80: ! 81: e_rsle() ! 82: { ! 83: int ch; ! 84: if(curunit->uend) return(EOF); ! 85: while(GETC(ch) != '\n' && ch != EOF); ! 86: return(ch==EOF?EOF:OK); ! 87: } ! 88: ! 89: l_read(number,ptr,len,type) ftnint *number,type; flex *ptr; ftnlen len; ! 90: { int i,n,ch; ! 91: double *yy; ! 92: float *xx; ! 93: for(i=0;i<*number;i++) ! 94: { ! 95: if(leof) err(endflag, EOF, lrd) ! 96: if(l_first) ! 97: { l_first = NO; ! 98: while(isblnk(GETC(ch))); /* skip blanks */ ! 99: (*ungetn)(ch,cf); ! 100: } ! 101: else if(lcount==0) /* repeat count == 0 ? */ ! 102: { ERR(t_sep()); /* look for non-blank, allow 1 comma */ ! 103: if(lquit) return(OK); /* slash found */ ! 104: } ! 105: switch((int)type) ! 106: { ! 107: case TYSHORT: ! 108: case TYLONG: ! 109: case TYREAL: ! 110: case TYDREAL: ! 111: ERR(l_R(1)); ! 112: break; ! 113: case TYCOMPLEX: ! 114: case TYDCOMPLEX: ! 115: ERR(l_C()); ! 116: break; ! 117: case TYLOGICAL: ! 118: ERR(l_L()); ! 119: break; ! 120: case TYCHAR: ! 121: ERR(l_CHAR()); ! 122: break; ! 123: } ! 124: ! 125: /* peek at next character; it should be separator or new line */ ! 126: GETC(ch); (*ungetn)(ch,cf); ! 127: if(!issep(ch) && !endlinp(ch)) { ! 128: while(GETC(ch)!= '\n' && ch != EOF); ! 129: err(errflag,F_ERLIO,lrd); ! 130: } ! 131: ! 132: if(lquit) return(OK); ! 133: if(leof) err(endflag,EOF,lrd) ! 134: else if(external && ferror(cf)) err(errflag,errno,lrd) ! 135: if(ltype) switch((int)type) ! 136: { ! 137: case TYSHORT: ! 138: ptr->flshort=lx; ! 139: break; ! 140: case TYLOGICAL: ! 141: if(len == sizeof(short)) ! 142: ptr->flshort = lx; ! 143: else ! 144: ptr->flint = lx; ! 145: break; ! 146: case TYLONG: ! 147: ptr->flint=lx; ! 148: break; ! 149: case TYREAL: ! 150: ptr->flreal=lx; ! 151: break; ! 152: case TYDREAL: ! 153: ptr->fldouble=lx; ! 154: break; ! 155: case TYCOMPLEX: ! 156: xx=(float *)ptr; ! 157: *xx++ = ly; ! 158: *xx = lx; ! 159: break; ! 160: case TYDCOMPLEX: ! 161: yy=(double *)ptr; ! 162: *yy++ = ly; ! 163: *yy = lx; ! 164: break; ! 165: case TYCHAR: ! 166: b_char(lchar,(char *)ptr,len); ! 167: break; ! 168: } ! 169: if(lcount>0) lcount--; ! 170: ptr = (flex *)((char *)ptr + len); ! 171: } ! 172: return(OK); ! 173: } ! 174: ! 175: LOCAL ! 176: lr_comm() ! 177: { int ch; ! 178: if(lcount) return(lcount); ! 179: ltype=NULL; ! 180: while(isblnk(GETC(ch))); ! 181: (*ungetn)(ch,cf); ! 182: if(ch==',') ! 183: { lcount=1; ! 184: return(lcount); ! 185: } ! 186: if(ch=='/') ! 187: { lquit = YES; ! 188: return(lquit); ! 189: } ! 190: else ! 191: return(OK); ! 192: } ! 193: ! 194: LOCAL ! 195: get_repet() ! 196: { char ch; ! 197: double lc; ! 198: if(isdigit(GETC(ch))) ! 199: { (*ungetn)(ch,cf); ! 200: rd_int(&lc); ! 201: lcount = (int)lc; ! 202: if(GETC(ch)!='*') ! 203: if(leof) return(EOF); ! 204: else return(F_ERREPT); ! 205: } ! 206: else ! 207: { lcount = 1; ! 208: (*ungetn)(ch,cf); ! 209: } ! 210: return(OK); ! 211: } ! 212: ! 213: LOCAL ! 214: l_R(flg) int flg; ! 215: { double a,b,c,d; ! 216: int da,db,dc,dd; ! 217: int i,ch,sign=0; ! 218: a=b=c=d=0; ! 219: da=db=dc=dd=0; ! 220: ! 221: if( flg ) /* real */ ! 222: { ! 223: if(lr_comm()) return(OK); ! 224: da=rd_int(&a); /* repeat count ? */ ! 225: if(GETC(ch)=='*') ! 226: { ! 227: if (a <= 0.) return(F_ERNREP); ! 228: lcount=(int)a; ! 229: if (nullfld()) return(OK); /* could be R* */ ! 230: db=rd_int(&b); /* whole part of number */ ! 231: } ! 232: else ! 233: { (*ungetn)(ch,cf); ! 234: db=da; ! 235: b=a; ! 236: lcount=1; ! 237: } ! 238: } ! 239: else /* complex */ ! 240: { ! 241: db=rd_int(&b); ! 242: } ! 243: ! 244: if(GETC(ch)=='.' && isdigit(GETC(ch))) ! 245: { (*ungetn)(ch,cf); ! 246: dc=rd_int(&c); /* fractional part of number */ ! 247: } ! 248: else ! 249: { (*ungetn)(ch,cf); ! 250: dc=0; ! 251: c=0.; ! 252: } ! 253: if(isexp(GETC(ch))) ! 254: dd=rd_int(&d); /* exponent */ ! 255: else if (ch == '+' || ch == '-') ! 256: { (*ungetn)(ch,cf); ! 257: dd=rd_int(&d); ! 258: } ! 259: else ! 260: { (*ungetn)(ch,cf); ! 261: dd=0; ! 262: } ! 263: if(db<0 || b<0) ! 264: { sign=1; ! 265: b = -b; ! 266: } ! 267: for(i=0;i<dc;i++) c/=10.; ! 268: b=b+c; ! 269: if (dd > 0) ! 270: { for(i=0;i<d;i++) b *= 10.; ! 271: for(i=0;i< -d;i++) b /= 10.; ! 272: } ! 273: lx=sign?-b:b; ! 274: ltype=TYLONG; ! 275: return(OK); ! 276: } ! 277: ! 278: LOCAL ! 279: rd_int(x) double *x; ! 280: { int ch,sign=0,i=0; ! 281: double y=0.0; ! 282: if(GETC(ch)=='-') sign = -1; ! 283: else if(ch=='+') sign=0; ! 284: else (*ungetn)(ch,cf); ! 285: while(isdigit(GETC(ch))) ! 286: { i++; ! 287: y=10*y + ch-'0'; ! 288: } ! 289: (*ungetn)(ch,cf); ! 290: if(sign) y = -y; ! 291: *x = y; ! 292: return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */ ! 293: } ! 294: ! 295: LOCAL ! 296: l_C() ! 297: { int ch,n; ! 298: if(lr_comm()) return(OK); ! 299: if(n=get_repet()) return(n); /* get repeat count */ ! 300: if (nullfld()) return(OK); /* could be R* */ ! 301: if(GETC(ch)!='(') err(errflag,F_ERLIO,"no (") ! 302: while(isblnk(GETC(ch))); ! 303: (*ungetn)(ch,cf); ! 304: l_R(0); /* get real part */ ! 305: ly = lx; ! 306: if(t_sep()) return(EOF); ! 307: l_R(0); /* get imag part */ ! 308: while(isblnk(GETC(ch))); ! 309: if(ch!=')') err(errflag,F_ERLIO,"no )") ! 310: ltype = TYCOMPLEX; ! 311: return(OK); ! 312: } ! 313: ! 314: LOCAL ! 315: l_L() ! 316: { ! 317: int ch,n; ! 318: if(lr_comm()) return(OK); ! 319: if(n=get_repet()) return(n); /* get repeat count */ ! 320: if (nullfld()) return(OK); /* could be R* */ ! 321: if(GETC(ch)=='.') GETC(ch); ! 322: switch(ch) ! 323: { ! 324: case 't': ! 325: case 'T': ! 326: lx=1; ! 327: break; ! 328: case 'f': ! 329: case 'F': ! 330: lx=0; ! 331: break; ! 332: default: ! 333: if(issep(ch)) ! 334: { (*ungetn)(ch,cf); ! 335: lx=0; ! 336: return(OK); ! 337: } ! 338: else if(ch==EOF) return(EOF); ! 339: else err(errflag,F_ERLIO,"logical not T or F"); ! 340: } ! 341: ltype=TYLOGICAL; ! 342: while(!issep(GETC(ch)) && !endlinp(ch)); ! 343: (*ungetn)(ch,cf); ! 344: return(OK); ! 345: } ! 346: ! 347: #define BUFSIZE 128 ! 348: LOCAL ! 349: l_CHAR() ! 350: { int ch,size,i,n; ! 351: char quote,*p; ! 352: if(lr_comm()) return(OK); ! 353: if(n=get_repet()) return(n); /* get repeat count */ ! 354: if (nullfld()) return(OK); /* could be R* */ ! 355: if(isapos(GETC(ch))) quote=ch; ! 356: else if(issep(ch) || ch==EOF || ch=='\n') ! 357: { if(ch==EOF) return(EOF); ! 358: (*ungetn)(ch,cf); ! 359: return(OK); ! 360: } ! 361: else ! 362: { quote = '\0'; /* to allow single word non-quoted */ ! 363: (*ungetn)(ch,cf); ! 364: } ! 365: ltype=TYCHAR; ! 366: if(lchar!=NULL) free(lchar); ! 367: size=BUFSIZE-1; ! 368: p=lchar=(char *)malloc(BUFSIZE); ! 369: if(lchar==NULL) err(errflag,F_ERSPACE,lrd) ! 370: for(i=0;;) ! 371: { while( ( (quote && GETC(ch)!=quote) || ! 372: (!quote && !issep(GETC(ch)) && !endlinp(ch)) ) ! 373: && ch!='\n' && ch!=EOF && ++i<size ) ! 374: *p++ = ch; ! 375: if(i==size) ! 376: { ! 377: newone: ! 378: size += BUFSIZE; ! 379: lchar=(char *)realloc(lchar, size+1); ! 380: if(lchar==NULL) err(errflag,F_ERSPACE,lrd) ! 381: p=lchar+i-1; ! 382: *p++ = ch; ! 383: } ! 384: else if(ch==EOF) return(EOF); ! 385: else if(ch=='\n') ! 386: { if(*(p-1) == '\\') *(p-1) = ch; ! 387: else if(!quote) ! 388: { *p = '\0'; ! 389: (*ungetn)(ch,cf); ! 390: return(OK); ! 391: } ! 392: } ! 393: else if(quote && GETC(ch)==quote) ! 394: { if(++i<size) *p++ = ch; ! 395: else goto newone; ! 396: } ! 397: else ! 398: { (*ungetn)(ch,cf); ! 399: *p = '\0'; ! 400: return(OK); ! 401: } ! 402: } ! 403: } ! 404: ! 405: LOCAL ! 406: t_sep() ! 407: { ! 408: int ch; ! 409: while(isblnk(GETC(ch))); ! 410: if(leof) return(EOF); ! 411: if(ch=='/') ! 412: { lquit = YES; ! 413: (*ungetn)(ch,cf); ! 414: return(OK); ! 415: } ! 416: if(issep(ch)) while(isblnk(GETC(ch))); ! 417: if(leof) return(EOF); ! 418: (*ungetn)(ch,cf); ! 419: return(OK); ! 420: } ! 421: ! 422: LOCAL ! 423: nullfld() /* look for null field following a repeat count */ ! 424: { ! 425: int ch; ! 426: ! 427: GETC(ch); ! 428: (*ungetn)(ch,cf); ! 429: if (issep(ch) || endlinp(ch)) ! 430: return(YES); ! 431: return(NO); ! 432: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.