|
|
1.1 ! root 1: #include "f2c.h" ! 2: #include "fio.h" ! 3: #include "lio.h" ! 4: ! 5: #define MAX_NL_CACHE 3 /* maximum number of namelist hash tables to cache */ ! 6: #define MAXDIM 20 /* maximum number of subscripts */ ! 7: ! 8: struct dimen { ! 9: ftnlen extent; ! 10: ftnlen curval; ! 11: ftnlen delta; ! 12: ftnlen stride; ! 13: }; ! 14: typedef struct dimen dimen; ! 15: ! 16: struct hashentry { ! 17: struct hashentry *next; ! 18: char *name; ! 19: Vardesc *vd; ! 20: }; ! 21: typedef struct hashentry hashentry; ! 22: ! 23: struct hashtab { ! 24: struct hashtab *next; ! 25: Namelist *nl; ! 26: int htsize; ! 27: hashentry *tab[1]; ! 28: }; ! 29: typedef struct hashtab hashtab; ! 30: ! 31: static hashtab *nl_cache; ! 32: static n_nlcache; ! 33: static hashentry **zot; ! 34: extern ftnlen f__typesize[]; ! 35: ! 36: extern flag f__lquit; ! 37: extern int f__lcount, nml_read; ! 38: extern t_getc(Void); ! 39: ! 40: #ifdef KR_headers ! 41: extern char *malloc(), *memset(); ! 42: ! 43: #ifdef ungetc ! 44: static int ! 45: un_getc(x,f__cf) int x; FILE *f__cf; ! 46: { return ungetc(x,f__cf); } ! 47: #else ! 48: #define un_getc ungetc ! 49: extern int ungetc(); ! 50: #endif ! 51: ! 52: #else ! 53: #undef abs ! 54: #undef min ! 55: #undef max ! 56: #include "stdlib.h" ! 57: #include "string.h" ! 58: ! 59: #ifdef ungetc ! 60: static int ! 61: un_getc(int x, FILE *f__cf) ! 62: { return ungetc(x,f__cf); } ! 63: #else ! 64: #define un_getc ungetc ! 65: #endif ! 66: #endif ! 67: ! 68: static Vardesc * ! 69: #ifdef KR_headers ! 70: hash(ht, s) hashtab *ht; register char *s; ! 71: #else ! 72: hash(hashtab *ht, register char *s) ! 73: #endif ! 74: { ! 75: register int c, x; ! 76: register hashentry *h; ! 77: char *s0 = s; ! 78: ! 79: for(x = 0; c = *s++; x = x & 0x4000 ? ((x << 1) & 0x7fff) + 1 : x << 1) ! 80: x += c; ! 81: for(h = *(zot = ht->tab + x % ht->htsize); h; h = h->next) ! 82: if (!strcmp(s0, h->name)) ! 83: return h->vd; ! 84: return 0; ! 85: } ! 86: ! 87: hashtab * ! 88: #ifdef KR_headers ! 89: mk_hashtab(nl) Namelist *nl; ! 90: #else ! 91: mk_hashtab(Namelist *nl) ! 92: #endif ! 93: { ! 94: int nht, nv; ! 95: hashtab *ht; ! 96: Vardesc *v, **vd, **vde; ! 97: hashentry *he; ! 98: ! 99: hashtab **x, **x0, *y; ! 100: for(x = &nl_cache; y = *x; x0 = x, x = &y->next) ! 101: if (nl == y->nl) ! 102: return y; ! 103: if (n_nlcache >= MAX_NL_CACHE) { ! 104: /* discard least recently used namelist hash table */ ! 105: y = *x0; ! 106: free((char *)y->next); ! 107: y->next = 0; ! 108: } ! 109: else ! 110: n_nlcache++; ! 111: nv = nl->nvars; ! 112: if (nv >= 0x4000) ! 113: nht = 0x7fff; ! 114: else { ! 115: for(nht = 1; nht < nv; nht <<= 1); ! 116: nht += nht - 1; ! 117: } ! 118: ht = (hashtab *)malloc(sizeof(hashtab) + (nht-1)*sizeof(hashentry *) ! 119: + nv*sizeof(hashentry)); ! 120: if (!ht) ! 121: return 0; ! 122: he = (hashentry *)&ht->tab[nht]; ! 123: ht->nl = nl; ! 124: ht->htsize = nht; ! 125: ht->next = nl_cache; ! 126: nl_cache = ht; ! 127: memset((char *)ht->tab, 0, nht*sizeof(hashentry *)); ! 128: vd = nl->vars; ! 129: vde = vd + nv; ! 130: while(vd < vde) { ! 131: v = *vd++; ! 132: if (!hash(ht, v->name)) { ! 133: he->next = *zot; ! 134: *zot = he; ! 135: he->name = v->name; ! 136: he->vd = v; ! 137: he++; ! 138: } ! 139: } ! 140: return ht; ! 141: } ! 142: ! 143: static char Alpha[256], Alphanum[256]; ! 144: ! 145: static VOID ! 146: nl_init(Void) { ! 147: register char *s; ! 148: register int c; ! 149: ! 150: if(!f__init) ! 151: f_init(); ! 152: for(s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; c = *s++; ) ! 153: Alpha[c] ! 154: = Alphanum[c] ! 155: = Alpha[c + 'a' - 'A'] ! 156: = Alphanum[c + 'a' - 'A'] ! 157: = c; ! 158: for(s = "0123456789_"; c = *s++; ) ! 159: Alphanum[c] = c; ! 160: } ! 161: ! 162: #define GETC(x) (x=(*l_getc)()) ! 163: #define Ungetc(x,y) (*l_ungetc)(x,y) ! 164: ! 165: static int ! 166: #ifdef KR_headers ! 167: getname(s, slen) register char *s; int slen; ! 168: #else ! 169: getname(register char *s, int slen) ! 170: #endif ! 171: { ! 172: register char *se = s + slen - 1; ! 173: register int ch; ! 174: ! 175: GETC(ch); ! 176: if (!(*s++ = Alpha[ch & 0xff])) { ! 177: if (ch != EOF) ! 178: ch = 115; ! 179: errfl(f__elist->cierr, ch, "namelist read"); ! 180: } ! 181: while(*s = Alphanum[GETC(ch) & 0xff]) ! 182: if (s < se) ! 183: s++; ! 184: if (ch == EOF) ! 185: err(f__elist->cierr, EOF, "namelist read"); ! 186: if (ch > ' ') ! 187: Ungetc(ch,f__cf); ! 188: return *s = 0; ! 189: } ! 190: ! 191: static int ! 192: #ifdef KR_headers ! 193: getnum(chp, val) int *chp; ftnlen *val; ! 194: #else ! 195: getnum(int *chp, ftnlen *val) ! 196: #endif ! 197: { ! 198: register int ch, sign; ! 199: register ftnlen x; ! 200: ! 201: while(GETC(ch) <= ' ' && ch >= 0); ! 202: if (ch == '-') { ! 203: sign = 1; ! 204: GETC(ch); ! 205: } ! 206: else { ! 207: sign = 0; ! 208: if (ch == '+') ! 209: GETC(ch); ! 210: } ! 211: x = ch - '0'; ! 212: if (x < 0 || x > 9) ! 213: return 115; ! 214: while(GETC(ch) >= '0' && ch <= '9') ! 215: x = 10*x + ch - '0'; ! 216: while(ch <= ' ' && ch >= 0) ! 217: GETC(ch); ! 218: if (ch == EOF) ! 219: return EOF; ! 220: *val = sign ? -x : x; ! 221: *chp = ch; ! 222: return 0; ! 223: } ! 224: ! 225: static int ! 226: #ifdef KR_headers ! 227: getdimen(chp, d, delta, extent, x1) ! 228: int *chp; dimen *d; ftnlen delta, extent, *x1; ! 229: #else ! 230: getdimen(int *chp, dimen *d, ftnlen delta, ftnlen extent, ftnlen *x1) ! 231: #endif ! 232: { ! 233: register int k; ! 234: ftnlen x2, x3; ! 235: ! 236: if (k = getnum(chp, x1)) ! 237: return k; ! 238: x3 = 1; ! 239: if (*chp == ':') { ! 240: if (k = getnum(chp, &x2)) ! 241: return k; ! 242: x2 -= *x1; ! 243: if (*chp == ':') { ! 244: if (k = getnum(chp, &x3)) ! 245: return k; ! 246: if (!x3) ! 247: return 123; ! 248: x2 /= x3; ! 249: } ! 250: if (x2 < 0 || x2 >= extent) ! 251: return 123; ! 252: d->extent = x2 + 1; ! 253: } ! 254: else ! 255: d->extent = 1; ! 256: d->curval = 0; ! 257: d->delta = delta; ! 258: d->stride = x3; ! 259: return 0; ! 260: } ! 261: ! 262: #ifndef No_Namelist_Questions ! 263: static Void ! 264: #ifdef KR_headers ! 265: print_ne(a) cilist *a; ! 266: #else ! 267: print_ne(cilist *a) ! 268: #endif ! 269: { ! 270: flag intext = f__external; ! 271: int rpsave = f__recpos; ! 272: FILE *cfsave = f__cf; ! 273: unit *usave = f__curunit; ! 274: cilist t; ! 275: t = *a; ! 276: t.ciunit = 6; ! 277: s_wsne(&t); ! 278: fflush(f__cf); ! 279: f__external = intext; ! 280: f__reading = 1; ! 281: f__recpos = rpsave; ! 282: f__cf = cfsave; ! 283: f__curunit = usave; ! 284: f__elist = a; ! 285: } ! 286: #endif ! 287: ! 288: static char where0[] = "namelist read start "; ! 289: ! 290: #ifdef KR_headers ! 291: x_rsne(a) cilist *a; ! 292: #else ! 293: x_rsne(cilist *a) ! 294: #endif ! 295: { ! 296: int ch, got1, k, n, nd, quote; ! 297: Namelist *nl; ! 298: static char where[] = "namelist read"; ! 299: char buf[64]; ! 300: hashtab *ht; ! 301: Vardesc *v; ! 302: dimen *dn, *dn0, *dn1; ! 303: ftnlen *dims, *dims1; ! 304: ftnlen b, b0, b1, ex, no, no1, nomax, size, span; ! 305: ftnint type; ! 306: char *vaddr; ! 307: long iva, ivae; ! 308: dimen dimens[MAXDIM], substr; ! 309: ! 310: if (!Alpha['a']) ! 311: nl_init(); ! 312: f__reading=1; ! 313: f__formatted=1; ! 314: got1 = 0; ! 315: top: ! 316: for(;;) switch(GETC(ch)) { ! 317: case EOF: ! 318: err(a->ciend,(EOF),where0); ! 319: case '&': ! 320: case '$': ! 321: goto have_amp; ! 322: #ifndef No_Namelist_Questions ! 323: case '?': ! 324: print_ne(a); ! 325: continue; ! 326: #endif ! 327: default: ! 328: if (ch <= ' ' && ch >= 0) ! 329: continue; ! 330: errfl(a->cierr, 115, where0); ! 331: } ! 332: have_amp: ! 333: if (ch = getname(buf,sizeof(buf))) ! 334: return ch; ! 335: nl = (Namelist *)a->cifmt; ! 336: if (strcmp(buf, nl->name)) ! 337: #ifdef No_Bad_Namelist_Skip ! 338: errfl(a->cierr, 118, where0); ! 339: #else ! 340: { ! 341: fprintf(stderr, ! 342: "Skipping namelist \"%s\": seeking namelist \"%s\".\n", ! 343: buf, nl->name); ! 344: fflush(stderr); ! 345: for(;;) switch(GETC(ch)) { ! 346: case EOF: ! 347: err(a->ciend, EOF, where0); ! 348: case '/': ! 349: case '&': ! 350: case '$': ! 351: if (f__external) ! 352: e_rsle(); ! 353: else ! 354: z_rnew(); ! 355: goto top; ! 356: case '"': ! 357: case '\'': ! 358: quote = ch; ! 359: more_quoted: ! 360: while(GETC(ch) != quote) ! 361: if (ch == EOF) ! 362: err(a->ciend, EOF, where0); ! 363: if (GETC(ch) == quote) ! 364: goto more_quoted; ! 365: Ungetc(ch,f__cf); ! 366: default: ! 367: continue; ! 368: } ! 369: } ! 370: #endif ! 371: ht = mk_hashtab(nl); ! 372: if (!ht) ! 373: errfl(f__elist->cierr, 113, where0); ! 374: for(;;) { ! 375: for(;;) switch(GETC(ch)) { ! 376: case EOF: ! 377: if (got1) ! 378: return 0; ! 379: err(a->ciend, EOF, where0); ! 380: case '/': ! 381: case '$': ! 382: case '&': ! 383: return 0; ! 384: default: ! 385: if (ch <= ' ' && ch >= 0 || ch == ',') ! 386: continue; ! 387: Ungetc(ch,f__cf); ! 388: if (ch = getname(buf,sizeof(buf))) ! 389: return ch; ! 390: goto havename; ! 391: } ! 392: havename: ! 393: v = hash(ht,buf); ! 394: if (!v) ! 395: errfl(a->cierr, 119, where); ! 396: while(GETC(ch) <= ' ' && ch >= 0); ! 397: vaddr = v->addr; ! 398: type = v->type; ! 399: if (type < 0) { ! 400: size = -type; ! 401: type = TYCHAR; ! 402: } ! 403: else ! 404: size = f__typesize[type]; ! 405: ivae = size; ! 406: iva = 0; ! 407: if (ch == '(' /*)*/ ) { ! 408: dn = dimens; ! 409: if (!(dims = v->dims)) { ! 410: if (type != TYCHAR) ! 411: errfl(a->cierr, 122, where); ! 412: if (k = getdimen(&ch, dn, (ftnlen)size, ! 413: (ftnlen)size, &b)) ! 414: errfl(a->cierr, k, where); ! 415: if (ch != ')') ! 416: errfl(a->cierr, 115, where); ! 417: b1 = dn->extent; ! 418: if (--b < 0 || b + b1 > size) ! 419: return 124; ! 420: iva += b; ! 421: size = b1; ! 422: while(GETC(ch) <= ' ' && ch >= 0); ! 423: goto scalar; ! 424: } ! 425: nd = (int)dims[0]; ! 426: nomax = span = dims[1]; ! 427: ivae = iva + size*nomax; ! 428: if (k = getdimen(&ch, dn, size, nomax, &b)) ! 429: errfl(a->cierr, k, where); ! 430: no = dn->extent; ! 431: b0 = dims[2]; ! 432: dims1 = dims += 3; ! 433: ex = 1; ! 434: for(n = 1; n++ < nd; dims++) { ! 435: if (ch != ',') ! 436: errfl(a->cierr, 115, where); ! 437: dn1 = dn + 1; ! 438: span /= *dims; ! 439: if (k = getdimen(&ch, dn1, dn->delta**dims, ! 440: span, &b1)) ! 441: errfl(a->cierr, k, where); ! 442: ex *= *dims; ! 443: b += b1*ex; ! 444: no *= dn1->extent; ! 445: dn = dn1; ! 446: } ! 447: if (ch != ')') ! 448: errfl(a->cierr, 115, where); ! 449: b -= b0; ! 450: if (b < 0 || b >= nomax) ! 451: errfl(a->cierr, 125, where); ! 452: iva += size * b; ! 453: dims = dims1; ! 454: while(GETC(ch) <= ' ' && ch >= 0); ! 455: no1 = 1; ! 456: dn0 = dimens; ! 457: if (type == TYCHAR && ch == '(' /*)*/) { ! 458: if (k = getdimen(&ch, &substr, size, size, &b)) ! 459: errfl(a->cierr, k, where); ! 460: if (ch != ')') ! 461: errfl(a->cierr, 115, where); ! 462: b1 = substr.extent; ! 463: if (--b < 0 || b + b1 > size) ! 464: return 124; ! 465: iva += b; ! 466: b0 = size; ! 467: size = b1; ! 468: while(GETC(ch) <= ' ' && ch >= 0); ! 469: if (b1 < b0) ! 470: goto delta_adj; ! 471: } ! 472: for(; dn0 < dn; dn0++) { ! 473: if (dn0->extent != *dims++ || dn0->stride != 1) ! 474: break; ! 475: no1 *= dn0->extent; ! 476: } ! 477: if (dn0 == dimens && dimens[0].stride == 1) { ! 478: no1 = dimens[0].extent; ! 479: dn0++; ! 480: } ! 481: delta_adj: ! 482: ex = 0; ! 483: for(dn1 = dn0; dn1 <= dn; dn1++) ! 484: ex += (dn1->extent-1) ! 485: * (dn1->delta *= dn1->stride); ! 486: for(dn1 = dn; dn1 > dn0; dn1--) { ! 487: ex -= (dn1->extent - 1) * dn1->delta; ! 488: dn1->delta -= ex; ! 489: } ! 490: } ! 491: else if (dims = v->dims) { ! 492: no = no1 = dims[1]; ! 493: ivae = iva + no*size; ! 494: } ! 495: else ! 496: scalar: ! 497: no = no1 = 1; ! 498: if (ch != '=') ! 499: errfl(a->cierr, 115, where); ! 500: got1 = nml_read = 1; ! 501: f__lcount = 0; ! 502: readloop: ! 503: for(;;) { ! 504: if (iva >= ivae || iva < 0) { ! 505: f__lquit = 1; ! 506: goto mustend; ! 507: } ! 508: else if (iva + no1*size > ivae) ! 509: no1 = (ivae - iva)/size; ! 510: f__lquit = 0; ! 511: if (k = l_read(&no1, vaddr + iva, size, type)) ! 512: return k; ! 513: if (f__lquit == 1) ! 514: return 0; ! 515: mustend: ! 516: if (GETC(ch) == '/' || ch == '$' || ch == '&') { ! 517: f__lquit = 1; ! 518: return 0; ! 519: } ! 520: else if (f__lquit) { ! 521: while(ch <= ' ' && ch >= 0) ! 522: GETC(ch); ! 523: Ungetc(ch,f__cf); ! 524: if (!Alpha[ch & 0xff] && ch >= 0) ! 525: errfl(a->cierr, 125, where); ! 526: break; ! 527: } ! 528: Ungetc(ch,f__cf); ! 529: if ((no -= no1) <= 0) ! 530: break; ! 531: for(dn1 = dn0; dn1 <= dn; dn1++) { ! 532: if (++dn1->curval < dn1->extent) { ! 533: iva += dn1->delta; ! 534: goto readloop; ! 535: } ! 536: dn1->curval = 0; ! 537: } ! 538: break; ! 539: } ! 540: } ! 541: } ! 542: ! 543: integer ! 544: #ifdef KR_headers ! 545: s_rsne(a) cilist *a; ! 546: #else ! 547: s_rsne(cilist *a) ! 548: #endif ! 549: { ! 550: extern int l_eof; ! 551: int n; ! 552: ! 553: f__external=1; ! 554: l_eof = 0; ! 555: if(n = c_le(a)) ! 556: return n; ! 557: if(f__curunit->uwrt && f__nowreading(f__curunit)) ! 558: err(a->cierr,errno,where0); ! 559: l_getc = t_getc; ! 560: l_ungetc = un_getc; ! 561: f__doend = xrd_SL; ! 562: if (n = x_rsne(a)) ! 563: return n; ! 564: return e_rsle(); ! 565: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.