|
|
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: err(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: static char where0[] = "namelist read start ";
263:
264: #ifdef KR_headers
265: x_rsne(a) cilist *a;
266: #else
267: x_rsne(cilist *a)
268: #endif
269: {
270: int ch, got1, k, n, nd;
271: Namelist *nl;
272: static char where[] = "namelist read";
273: char buf[64];
274: hashtab *ht;
275: Vardesc *v;
276: dimen *dn, *dn0, *dn1;
277: ftnlen *dims, *dims1;
278: ftnlen b, b0, b1, ex, no, no1, nomax, size, span;
279: ftnint type;
280: char *vaddr;
281: long iva, ivae;
282: dimen dimens[MAXDIM], substr;
283:
284: if (!Alpha['a'])
285: nl_init();
286: f__reading=1;
287: f__formatted=1;
288: got1 = 0;
289: for(;;) switch(GETC(ch)) {
290: case EOF:
291: err(a->ciend,(EOF),where0);
292: case '&':
293: case '$':
294: goto have_amp;
295: default:
296: if (ch <= ' ' && ch >= 0)
297: continue;
298: err(a->cierr, 115, where0);
299: }
300: have_amp:
301: if (ch = getname(buf,sizeof(buf)))
302: return ch;
303: nl = (Namelist *)a->cifmt;
304: if (strcmp(buf, nl->name))
305: err(a->cierr, 118, where0);
306: ht = mk_hashtab(nl);
307: if (!ht)
308: err(f__elist->cierr, 113, where0);
309: for(;;) {
310: for(;;) switch(GETC(ch)) {
311: case EOF:
312: if (got1)
313: return 0;
314: err(a->ciend,(EOF),where0);
315: case '/':
316: case '$':
317: case '&':
318: return 0;
319: default:
320: if (ch <= ' ' && ch >= 0 || ch == ',')
321: continue;
322: Ungetc(ch,f__cf);
323: if (ch = getname(buf,sizeof(buf)))
324: return ch;
325: goto havename;
326: }
327: havename:
328: v = hash(ht,buf);
329: if (!v)
330: err(a->cierr, 119, where);
331: while(GETC(ch) <= ' ' && ch >= 0);
332: vaddr = v->addr;
333: type = v->type;
334: if (type < 0) {
335: size = -type;
336: type = TYCHAR;
337: }
338: else
339: size = f__typesize[type];
340: ivae = size;
341: iva = 0;
342: if (ch == '(' /*)*/ ) {
343: dn = dimens;
344: if (!(dims = v->dims)) {
345: if (type != TYCHAR)
346: err(a->cierr, 122, where);
347: if (k = getdimen(&ch, dn, (ftnlen)size,
348: (ftnlen)size, &b))
349: err(a->cierr, k, where);
350: if (ch != ')')
351: err(a->cierr, 115, where);
352: b1 = dn->extent;
353: if (--b < 0 || b + b1 > size)
354: return 124;
355: iva += b;
356: size = b1;
357: while(GETC(ch) <= ' ' && ch >= 0);
358: goto scalar;
359: }
360: nd = dims[0];
361: nomax = span = dims[1];
362: ivae = iva + size*nomax;
363: if (k = getdimen(&ch, dn, size, nomax, &b))
364: err(a->cierr, k, where);
365: no = dn->extent;
366: b0 = dims[2];
367: dims1 = dims += 3;
368: ex = 1;
369: for(n = 1; n++ < nd; dims++) {
370: if (ch != ',')
371: err(a->cierr, 115, where);
372: dn1 = dn + 1;
373: span /= *dims;
374: if (k = getdimen(&ch, dn1, dn->delta**dims,
375: span, &b1))
376: err(a->cierr, k, where);
377: ex *= *dims;
378: b += b1*ex;
379: no *= dn1->extent;
380: dn = dn1;
381: }
382: if (ch != ')')
383: err(a->cierr, 115, where);
384: b -= b0;
385: if (b < 0 || b >= nomax)
386: err(a->cierr, 125, where);
387: iva += size * b;
388: dims = dims1;
389: while(GETC(ch) <= ' ' && ch >= 0);
390: no1 = 1;
391: dn0 = dimens;
392: if (type == TYCHAR && ch == '(' /*)*/) {
393: if (k = getdimen(&ch, &substr, size, size, &b))
394: err(a->cierr, k, where);
395: if (ch != ')')
396: err(a->cierr, 115, where);
397: b1 = substr.extent;
398: if (--b < 0 || b + b1 > size)
399: return 124;
400: iva += b;
401: b0 = size;
402: size = b1;
403: while(GETC(ch) <= ' ' && ch >= 0);
404: if (b1 < b0)
405: goto delta_adj;
406: }
407: for(; dn0 < dn; dn0++) {
408: if (dn0->extent != *dims++ || dn0->stride != 1)
409: break;
410: no1 *= dn0->extent;
411: }
412: if (dn0 == dimens && dimens[0].stride == 1) {
413: no1 = dimens[0].extent;
414: dn0++;
415: }
416: delta_adj:
417: ex = 0;
418: for(dn1 = dn0; dn1 <= dn; dn1++)
419: ex += (dn1->extent-1)
420: * (dn1->delta *= dn1->stride);
421: for(dn1 = dn; dn1 > dn0; dn1--) {
422: ex -= (dn1->extent - 1) * dn1->delta;
423: dn1->delta -= ex;
424: }
425: }
426: else if (dims = v->dims) {
427: no = no1 = dims[1];
428: ivae = iva + no*size;
429: }
430: else
431: scalar:
432: no = no1 = 1;
433: if (ch != '=')
434: err(a->cierr, 115, where);
435: got1 = nml_read = 1;
436: f__lcount = 0;
437: readloop:
438: for(;;) {
439: if (iva >= ivae || iva < 0) {
440: f__lquit = 1;
441: goto mustend;
442: }
443: else if (iva + no1*size > ivae)
444: no1 = (ivae - iva)/size;
445: f__lquit = 0;
446: l_read(&no1, vaddr + iva, size, type);
447: if (f__lquit == 1)
448: return 0;
449: mustend:
450: if (GETC(ch) == '/' || ch == '$' || ch == '&') {
451: f__lquit = 1;
452: return 0;
453: }
454: else if (f__lquit) {
455: while(ch <= ' ' && ch >= 0)
456: GETC(ch);
457: Ungetc(ch,f__cf);
458: if (!Alpha[ch & 0xff] && ch >= 0)
459: err(a->cierr, 125, where);
460: break;
461: }
462: Ungetc(ch,f__cf);
463: if ((no -= no1) <= 0)
464: break;
465: for(dn1 = dn0; dn1 <= dn; dn1++) {
466: if (++dn1->curval < dn1->extent) {
467: iva += dn1->delta;
468: goto readloop;
469: }
470: dn1->curval = 0;
471: }
472: break;
473: }
474: }
475: }
476:
477: integer
478: #ifdef KR_headers
479: s_rsne(a) cilist *a;
480: #else
481: s_rsne(cilist *a)
482: #endif
483: {
484: extern int l_eof;
485: int n;
486:
487: f__external=1;
488: l_eof = 0;
489: if(n = c_le(a))
490: return n;
491: if(f__curunit->uwrt && f__nowreading(f__curunit))
492: err(a->cierr,errno,where0);
493: l_getc = t_getc;
494: l_ungetc = un_getc;
495: if (n = x_rsne(a))
496: return n;
497: return e_rsle();
498: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.