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