rsne.c 11 KB

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