5 #define MAX_NL_CACHE 3 /* maximum number of namelist hash tables to cache */
6 #define MAXDIM 20 /* maximum number of subscripts */
8 extern char *malloc(), *memset();
16 typedef struct dimen dimen;
19 struct hashentry *next;
23 typedef struct hashentry hashentry;
31 typedef struct hashtab hashtab;
33 static hashtab *nl_cache;
35 static hashentry **zot;
36 extern ftnlen typesize[];
40 extern int (*l_getc)(), (*l_ungetc)(), t_getc(), ungetc();
48 register hashentry *h;
51 for(x = 0; c = *s++; x = x & 0x4000 ? ((x << 1) & 0x7fff) + 1 : x << 1)
53 for(h = *(zot = ht->tab + x % ht->htsize); h; h = h->next)
54 if (!strcmp(s0, h->name))
65 Vardesc *v, **vd, **vde;
68 hashtab **x, **x0, *y;
69 for(x = &nl_cache; y = *x; x0 = x, x = &y->next)
72 if (n_nlcache >= MAX_NL_CACHE) {
73 /* discard least recently used namelist hash table */
75 free((char *)y->next);
84 for(nht = 1; nht < nv; nht <<= 1);
87 ht = (hashtab *)malloc(sizeof(hashtab) + (nht-1)*sizeof(hashentry *)
88 + nv*sizeof(hashentry));
91 he = (hashentry *)&ht->tab[nht];
96 memset((char *)ht->tab, 0, nht*sizeof(hashentry *));
101 if (!hash(ht, v->name)) {
112 static char Alpha[256], Alphanum[256];
121 for(s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; c = *s++; )
124 = Alpha[c + 'a' - 'A']
125 = Alphanum[c + 'a' - 'A']
127 for(s = "0123456789_"; c = *s++; )
131 #define GETC(x) (x=(*l_getc)())
132 #define Ungetc(x,y) (*l_ungetc)(x,y)
139 register char *se = s + slen - 1;
143 if (!(*s++ = Alpha[ch & 0xff])) {
146 err(elist->cierr, ch, "namelist read");
148 while(*s = Alphanum[GETC(ch) & 0xff])
152 err(elist->cierr, ch == EOF ? -1 : 115, "namelist read");
163 register int ch, sign;
166 while(GETC(ch) <= ' ' && ch >= 0);
179 while(GETC(ch) >= '0' && ch <= '9')
181 while(ch <= ' ' && ch >= 0)
185 *val = sign ? -x : x;
191 getdimen(chp, d, delta, extent, x1)
194 ftnlen delta, extent, *x1;
199 if (k = getnum(chp, x1))
203 if (k = getnum(chp, &x2))
207 if (k = getnum(chp, &x3))
213 if (x2 < 0 || x2 >= extent)
225 static char where0[] = "namelist read start ";
230 int ch, got1, k, n, nd;
232 static char where[] = "namelist read";
236 dimen *dn, *dn0, *dn1;
237 ftnlen *dims, *dims1;
238 ftnlen b, b0, b1, ex, no, no1, nomax, size, span;
242 dimen dimens[MAXDIM], substr;
251 for(;;) switch(GETC(ch)) {
253 err(a->ciend,(EOF),where0);
258 if (ch <= ' ' && ch >= 0)
260 err(a->cierr, 115, where0);
263 if (ch = getname(buf,sizeof(buf)))
265 nl = (Namelist *)a->cifmt;
266 if (strcmp(buf, nl->name))
267 err(a->cierr, 118, where0);
270 err(elist->cierr, 113, where0);
272 for(;;) switch(GETC(ch)) {
276 err(a->ciend,(EOF),where0);
281 if (ch <= ' ' && ch >= 0 || ch == ',')
284 if (ch = getname(buf,sizeof(buf)))
291 err(a->cierr, 119, where);
292 while(GETC(ch) <= ' ' && ch >= 0);
300 size = typesize[type];
303 if (ch == '(' /*)*/ ) {
305 if (!(dims = v->dims)) {
307 err(a->cierr, 122, where);
308 if (k = getdimen(&ch, dn, (ftnlen)size,
310 err(a->cierr, k, where);
312 err(a->cierr, 115, where);
314 if (--b < 0 || b + b1 > size)
318 while(GETC(ch) <= ' ' && ch >= 0);
322 nomax = span = dims[1];
323 ivae = iva + size*nomax;
324 if (k = getdimen(&ch, dn, size, nomax, &b))
325 err(a->cierr, k, where);
330 for(n = 1; n++ < nd; dims++) {
332 err(a->cierr, 115, where);
335 if (k = getdimen(&ch, dn1, dn->delta**dims,
337 err(a->cierr, k, where);
344 err(a->cierr, 115, where);
346 if (b < 0 || b >= nomax)
347 err(a->cierr, 125, where);
350 while(GETC(ch) <= ' ' && ch >= 0);
353 if (type == TYCHAR && ch == '(' /*)*/) {
354 if (k = getdimen(&ch, &substr, size, size, &b))
355 err(a->cierr, k, where);
357 err(a->cierr, 115, where);
359 if (--b < 0 || b + b1 > size)
364 while(GETC(ch) <= ' ' && ch >= 0);
368 for(; dn0 < dn; dn0++) {
369 if (dn0->extent != *dims++ || dn0->stride != 1)
373 if (dn0 == dimens && dimens[0].stride == 1) {
374 no1 = dimens[0].extent;
379 for(dn1 = dn0; dn1 <= dn; dn1++)
380 ex += (dn1->extent-1)
381 * (dn1->delta *= dn1->stride);
382 for(dn1 = dn; dn1 > dn0; dn1--) {
383 ex -= (dn1->extent - 1) * dn1->delta;
387 else if (dims = v->dims) {
389 ivae = iva + no*size;
395 err(a->cierr, 115, where);
399 if (iva >= ivae || iva < 0)
401 else if (iva + no1*size > ivae) {
402 no1 = (ivae - iva)/size;
403 l_read(&no1, vaddr + iva, size, type);
405 if (GETC(ch) == '/' || ch == '$')
408 err(a->cierr, 125, where);
411 l_read(&no1, vaddr + iva, size, type);
414 if ((no -= no1) <= 0)
416 for(dn1 = dn0; dn1 <= dn; dn1++) {
417 if (++dn1->curval < dn1->extent) {
433 extern integer e_rsle();
437 if(curunit->uwrt && nowreading(curunit))
438 err(a->cierr,errno,where0);