rsne.c

Go to the documentation of this file.
00001 #include "f2c.h"
00002 #include "fio.h"
00003 #include "lio.h"
00004 
00005 #ifdef _MSC_VER
00006 #include <stdio.h>
00007 #endif
00008 
00009 #define MAX_NL_CACHE 3  /* maximum number of namelist hash tables to cache */
00010 #define MAXDIM 20       /* maximum number of subscripts */
00011 
00012  struct dimen {
00013         ftnlen extent;
00014         ftnlen curval;
00015         ftnlen delta;
00016         ftnlen stride;
00017         };
00018  typedef struct dimen dimen;
00019 
00020  struct hashentry {
00021         struct hashentry *next;
00022         char *name;
00023         Vardesc *vd;
00024         };
00025  typedef struct hashentry hashentry;
00026 
00027  struct hashtab {
00028         struct hashtab *next;
00029         Namelist *nl;
00030         int htsize;
00031         hashentry *tab[1];
00032         };
00033  typedef struct hashtab hashtab;
00034 
00035  static hashtab *nl_cache;
00036  static int n_nlcache;
00037  static hashentry **zot;
00038  static int colonseen;
00039  extern ftnlen f__typesize[];
00040 
00041  extern flag f__lquit;
00042  extern int f__lcount, nml_read;
00043  extern int t_getc(Void);
00044 
00045 #ifdef KR_headers
00046  extern char *malloc(), *memset();
00047 
00048 #ifdef ungetc
00049  static int
00050 un_getc(x,f__cf) int x; FILE *f__cf;
00051 { return ungetc(x,f__cf); }
00052 #else
00053 #define un_getc ungetc
00054  extern int ungetc();
00055 #endif
00056 
00057 #else
00058 #undef abs
00059 #undef min
00060 #undef max
00061 #include "stdlib.h"
00062 #include "string.h"
00063 #ifdef __cplusplus
00064 extern "C" {
00065 #endif
00066 
00067 #ifdef ungetc
00068  static int
00069 un_getc(int x, FILE *f__cf)
00070 { return ungetc(x,f__cf); }
00071 #else
00072 #ifndef _MSC_VER
00073         #define un_getc ungetc
00074         extern int ungetc(int, FILE*);  /* for systems with a buggy stdio.h */
00075         #endif
00076 #endif
00077 #endif
00078 
00079  static Vardesc *
00080 #ifdef KR_headers
00081 hash(ht, s) hashtab *ht; register char *s;
00082 #else
00083 hash(hashtab *ht, register char *s)
00084 #endif
00085 {
00086         register int c, x;
00087         register hashentry *h;
00088         char *s0 = s;
00089 
00090         for(x = 0; c = *s++; x = x & 0x4000 ? ((x << 1) & 0x7fff) + 1 : x << 1)
00091                 x += c;
00092         for(h = *(zot = ht->tab + x % ht->htsize); h; h = h->next)
00093                 if (!strcmp(s0, h->name))
00094                         return h->vd;
00095         return 0;
00096         }
00097 
00098  hashtab *
00099 #ifdef KR_headers
00100 mk_hashtab(nl) Namelist *nl;
00101 #else
00102 mk_hashtab(Namelist *nl)
00103 #endif
00104 {
00105         int nht, nv;
00106         hashtab *ht;
00107         Vardesc *v, **vd, **vde;
00108         hashentry *he;
00109 
00110         hashtab **x, **x0, *y;
00111         for(x = &nl_cache; y = *x; x0 = x, x = &y->next)
00112                 if (nl == y->nl)
00113                         return y;
00114         if (n_nlcache >= MAX_NL_CACHE) {
00115                 /* discard least recently used namelist hash table */
00116                 y = *x0;
00117                 free((char *)y->next);
00118                 y->next = 0;
00119                 }
00120         else
00121                 n_nlcache++;
00122         nv = nl->nvars;
00123         if (nv >= 0x4000)
00124                 nht = 0x7fff;
00125         else {
00126                 for(nht = 1; nht < nv; nht <<= 1);
00127                 nht += nht - 1;
00128                 }
00129         ht = (hashtab *)malloc(sizeof(hashtab) + (nht-1)*sizeof(hashentry *)
00130                                 + nv*sizeof(hashentry));
00131         if (!ht)
00132                 return 0;
00133         he = (hashentry *)&ht->tab[nht];
00134         ht->nl = nl;
00135         ht->htsize = nht;
00136         ht->next = nl_cache;
00137         nl_cache = ht;
00138         memset((char *)ht->tab, 0, nht*sizeof(hashentry *));
00139         vd = nl->vars;
00140         vde = vd + nv;
00141         while(vd < vde) {
00142                 v = *vd++;
00143                 if (!hash(ht, v->name)) {
00144                         he->next = *zot;
00145                         *zot = he;
00146                         he->name = v->name;
00147                         he->vd = v;
00148                         he++;
00149                         }
00150                 }
00151         return ht;
00152         }
00153 
00154 static char Alpha[256], Alphanum[256];
00155 
00156  static VOID
00157 nl_init(Void) {
00158         register char *s;
00159         register int c;
00160 
00161         if(!f__init)
00162                 f_init();
00163         for(s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; c = *s++; )
00164                 Alpha[c]
00165                 = Alphanum[c]
00166                 = Alpha[c + 'a' - 'A']
00167                 = Alphanum[c + 'a' - 'A']
00168                 = c;
00169         for(s = "0123456789_"; c = *s++; )
00170                 Alphanum[c] = c;
00171         }
00172 
00173 #define GETC(x) (x=(*l_getc)())
00174 #define Ungetc(x,y) (*l_ungetc)(x,y)
00175 
00176  static int
00177 #ifdef KR_headers
00178 getname(s, slen) register char *s; int slen;
00179 #else
00180 getname(register char *s, int slen)
00181 #endif
00182 {
00183         register char *se = s + slen - 1;
00184         register int ch;
00185 
00186         GETC(ch);
00187         if (!(*s++ = Alpha[ch & 0xff])) {
00188                 if (ch != EOF)
00189                         ch = 115;
00190                 errfl(f__elist->cierr, ch, "namelist read");
00191                 }
00192         while(*s = Alphanum[GETC(ch) & 0xff])
00193                 if (s < se)
00194                         s++;
00195         if (ch == EOF)
00196                 err(f__elist->cierr, EOF, "namelist read");
00197         if (ch > ' ')
00198                 Ungetc(ch,f__cf);
00199         return *s = 0;
00200         }
00201 
00202  static int
00203 #ifdef KR_headers
00204 getnum(chp, val) int *chp; ftnlen *val;
00205 #else
00206 getnum(int *chp, ftnlen *val)
00207 #endif
00208 {
00209         register int ch, sign;
00210         register ftnlen x;
00211 
00212         while(GETC(ch) <= ' ' && ch >= 0);
00213         if (ch == '-') {
00214                 sign = 1;
00215                 GETC(ch);
00216                 }
00217         else {
00218                 sign = 0;
00219                 if (ch == '+')
00220                         GETC(ch);
00221                 }
00222         x = ch - '0';
00223         if (x < 0 || x > 9)
00224                 return 115;
00225         while(GETC(ch) >= '0' && ch <= '9')
00226                 x = 10*x + ch - '0';
00227         while(ch <= ' ' && ch >= 0)
00228                 GETC(ch);
00229         if (ch == EOF)
00230                 return EOF;
00231         *val = sign ? -x : x;
00232         *chp = ch;
00233         return 0;
00234         }
00235 
00236  static int
00237 #ifdef KR_headers
00238 getdimen(chp, d, delta, extent, x1)
00239  int *chp; dimen *d; ftnlen delta, extent, *x1;
00240 #else
00241 getdimen(int *chp, dimen *d, ftnlen delta, ftnlen extent, ftnlen *x1)
00242 #endif
00243 {
00244         register int k;
00245         ftnlen x2, x3;
00246 
00247         if (k = getnum(chp, x1))
00248                 return k;
00249         x3 = 1;
00250         if (*chp == ':') {
00251                 if (k = getnum(chp, &x2))
00252                         return k;
00253                 x2 -= *x1;
00254                 if (*chp == ':') {
00255                         if (k = getnum(chp, &x3))
00256                                 return k;
00257                         if (!x3)
00258                                 return 123;
00259                         x2 /= x3;
00260                         colonseen = 1;
00261                         }
00262                 if (x2 < 0 || x2 >= extent)
00263                         return 123;
00264                 d->extent = x2 + 1;
00265                 }
00266         else
00267                 d->extent = 1;
00268         d->curval = 0;
00269         d->delta = delta;
00270         d->stride = x3;
00271         return 0;
00272         }
00273 
00274 #ifndef No_Namelist_Questions
00275  static Void
00276 #ifdef KR_headers
00277 print_ne(a) cilist *a;
00278 #else
00279 print_ne(cilist *a)
00280 #endif
00281 {
00282         flag intext = f__external;
00283         int rpsave = f__recpos;
00284         FILE *cfsave = f__cf;
00285         unit *usave = f__curunit;
00286         cilist t;
00287         t = *a;
00288         t.ciunit = 6;
00289         s_wsne(&t);
00290         fflush(f__cf);
00291         f__external = intext;
00292         f__reading = 1;
00293         f__recpos = rpsave;
00294         f__cf = cfsave;
00295         f__curunit = usave;
00296         f__elist = a;
00297         }
00298 #endif
00299 
00300  static char where0[] = "namelist read start ";
00301 
00302  int
00303 #ifdef KR_headers
00304 x_rsne(a) cilist *a;
00305 #else
00306 x_rsne(cilist *a)
00307 #endif
00308 {
00309         int ch, got1, k, n, nd, quote, readall;
00310         Namelist *nl;
00311         static char where[] = "namelist read";
00312         char buf[64];
00313         hashtab *ht;
00314         Vardesc *v;
00315         dimen *dn, *dn0, *dn1;
00316         ftnlen *dims, *dims1;
00317         ftnlen b, b0, b1, ex, no, nomax, size, span;
00318         ftnint no1, no2, type;
00319         char *vaddr;
00320         long iva, ivae;
00321         dimen dimens[MAXDIM], substr;
00322 
00323         if (!Alpha['a'])
00324                 nl_init();
00325         f__reading=1;
00326         f__formatted=1;
00327         got1 = 0;
00328  top:
00329         for(;;) switch(GETC(ch)) {
00330                 case EOF:
00331  eof:
00332                         err(a->ciend,(EOF),where0);
00333                 case '&':
00334                 case '$':
00335                         goto have_amp;
00336 #ifndef No_Namelist_Questions
00337                 case '?':
00338                         print_ne(a);
00339                         continue;
00340 #endif
00341                 default:
00342                         if (ch <= ' ' && ch >= 0)
00343                                 continue;
00344 #ifndef No_Namelist_Comments
00345                         while(GETC(ch) != '\n')
00346                                 if (ch == EOF)
00347                                         goto eof;
00348 #else
00349                         errfl(a->cierr, 115, where0);
00350 #endif
00351                 }
00352  have_amp:
00353         if (ch = getname(buf,sizeof(buf)))
00354                 return ch;
00355         nl = (Namelist *)a->cifmt;
00356         if (strcmp(buf, nl->name))
00357 #ifdef No_Bad_Namelist_Skip
00358                 errfl(a->cierr, 118, where0);
00359 #else
00360         {
00361                 fprintf(stderr,
00362                         "Skipping namelist \"%s\": seeking namelist \"%s\".\n",
00363                         buf, nl->name);
00364                 fflush(stderr);
00365                 for(;;) switch(GETC(ch)) {
00366                         case EOF:
00367                                 err(a->ciend, EOF, where0);
00368                         case '/':
00369                         case '&':
00370                         case '$':
00371                                 if (f__external)
00372                                         e_rsle();
00373                                 else
00374                                         z_rnew();
00375                                 goto top;
00376                         case '"':
00377                         case '\'':
00378                                 quote = ch;
00379  more_quoted:
00380                                 while(GETC(ch) != quote)
00381                                         if (ch == EOF)
00382                                                 err(a->ciend, EOF, where0);
00383                                 if (GETC(ch) == quote)
00384                                         goto more_quoted;
00385                                 Ungetc(ch,f__cf);
00386                         default:
00387                                 continue;
00388                         }
00389                 }
00390 #endif
00391         ht = mk_hashtab(nl);
00392         if (!ht)
00393                 errfl(f__elist->cierr, 113, where0);
00394         for(;;) {
00395                 for(;;) switch(GETC(ch)) {
00396                         case EOF:
00397                                 if (got1)
00398                                         return 0;
00399                                 err(a->ciend, EOF, where0);
00400                         case '/':
00401                         case '$':
00402                         case '&':
00403                                 return 0;
00404                         default:
00405                                 if (ch <= ' ' && ch >= 0 || ch == ',')
00406                                         continue;
00407                                 Ungetc(ch,f__cf);
00408                                 if (ch = getname(buf,sizeof(buf)))
00409                                         return ch;
00410                                 goto havename;
00411                         }
00412  havename:
00413                 v = hash(ht,buf);
00414                 if (!v)
00415                         errfl(a->cierr, 119, where);
00416                 while(GETC(ch) <= ' ' && ch >= 0);
00417                 vaddr = v->addr;
00418                 type = v->type;
00419                 if (type < 0) {
00420                         size = -type;
00421                         type = TYCHAR;
00422                         }
00423                 else
00424                         size = f__typesize[type];
00425                 ivae = size;
00426                 iva = readall = 0;
00427                 if (ch == '(' /*)*/ ) {
00428                         dn = dimens;
00429                         if (!(dims = v->dims)) {
00430                                 if (type != TYCHAR)
00431                                         errfl(a->cierr, 122, where);
00432                                 if (k = getdimen(&ch, dn, (ftnlen)size,
00433                                                 (ftnlen)size, &b))
00434                                         errfl(a->cierr, k, where);
00435                                 if (ch != ')')
00436                                         errfl(a->cierr, 115, where);
00437                                 b1 = dn->extent;
00438                                 if (--b < 0 || b + b1 > size)
00439                                         return 124;
00440                                 iva += b;
00441                                 size = b1;
00442                                 while(GETC(ch) <= ' ' && ch >= 0);
00443                                 goto scalar;
00444                                 }
00445                         nd = (int)dims[0];
00446                         nomax = span = dims[1];
00447                         ivae = iva + size*nomax;
00448                         colonseen = 0;
00449                         if (k = getdimen(&ch, dn, size, nomax, &b))
00450                                 errfl(a->cierr, k, where);
00451                         no = dn->extent;
00452                         b0 = dims[2];
00453                         dims1 = dims += 3;
00454                         ex = 1;
00455                         for(n = 1; n++ < nd; dims++) {
00456                                 if (ch != ',')
00457                                         errfl(a->cierr, 115, where);
00458                                 dn1 = dn + 1;
00459                                 span /= *dims;
00460                                 if (k = getdimen(&ch, dn1, dn->delta**dims,
00461                                                 span, &b1))
00462                                         errfl(a->cierr, k, where);
00463                                 ex *= *dims;
00464                                 b += b1*ex;
00465                                 no *= dn1->extent;
00466                                 dn = dn1;
00467                                 }
00468                         if (ch != ')')
00469                                 errfl(a->cierr, 115, where);
00470                         readall = 1 - colonseen;
00471                         b -= b0;
00472                         if (b < 0 || b >= nomax)
00473                                 errfl(a->cierr, 125, where);
00474                         iva += size * b;
00475                         dims = dims1;
00476                         while(GETC(ch) <= ' ' && ch >= 0);
00477                         no1 = 1;
00478                         dn0 = dimens;
00479                         if (type == TYCHAR && ch == '(' /*)*/) {
00480                                 if (k = getdimen(&ch, &substr, size, size, &b))
00481                                         errfl(a->cierr, k, where);
00482                                 if (ch != ')')
00483                                         errfl(a->cierr, 115, where);
00484                                 b1 = substr.extent;
00485                                 if (--b < 0 || b + b1 > size)
00486                                         return 124;
00487                                 iva += b;
00488                                 b0 = size;
00489                                 size = b1;
00490                                 while(GETC(ch) <= ' ' && ch >= 0);
00491                                 if (b1 < b0)
00492                                         goto delta_adj;
00493                                 }
00494                         if (readall)
00495                                 goto delta_adj;
00496                         for(; dn0 < dn; dn0++) {
00497                                 if (dn0->extent != *dims++ || dn0->stride != 1)
00498                                         break;
00499                                 no1 *= dn0->extent;
00500                                 }
00501                         if (dn0 == dimens && dimens[0].stride == 1) {
00502                                 no1 = dimens[0].extent;
00503                                 dn0++;
00504                                 }
00505  delta_adj:
00506                         ex = 0;
00507                         for(dn1 = dn0; dn1 <= dn; dn1++)
00508                                 ex += (dn1->extent-1)
00509                                         * (dn1->delta *= dn1->stride);
00510                         for(dn1 = dn; dn1 > dn0; dn1--) {
00511                                 ex -= (dn1->extent - 1) * dn1->delta;
00512                                 dn1->delta -= ex;
00513                                 }
00514                         }
00515                 else if (dims = v->dims) {
00516                         no = no1 = dims[1];
00517                         ivae = iva + no*size;
00518                         }
00519                 else
00520  scalar:
00521                         no = no1 = 1;
00522                 if (ch != '=')
00523                         errfl(a->cierr, 115, where);
00524                 got1 = nml_read = 1;
00525                 f__lcount = 0;
00526          readloop:
00527                 for(;;) {
00528                         if (iva >= ivae || iva < 0) {
00529                                 f__lquit = 1;
00530                                 goto mustend;
00531                                 }
00532                         else if (iva + no1*size > ivae)
00533                                 no1 = (ivae - iva)/size;
00534                         f__lquit = 0;
00535                         if (k = l_read(&no1, vaddr + iva, size, type))
00536                                 return k;
00537                         if (f__lquit == 1)
00538                                 return 0;
00539                         if (readall) {
00540                                 iva += dn0->delta;
00541                                 if (f__lcount > 0) {
00542                                         no2 = (ivae - iva)/size;
00543                                         if (no2 > f__lcount)
00544                                                 no2 = f__lcount;
00545                                         if (k = l_read(&no2, vaddr + iva,
00546                                                         size, type))
00547                                                 return k;
00548                                         iva += no2 * dn0->delta;
00549                                         }
00550                                 }
00551  mustend:
00552                         GETC(ch);
00553                         if (readall)
00554                                 if (iva >= ivae)
00555                                         readall = 0;
00556                                 else for(;;) {
00557                                         switch(ch) {
00558                                                 case ' ':
00559                                                 case '\t':
00560                                                 case '\n':
00561                                                         GETC(ch);
00562                                                         continue;
00563                                                 }
00564                                         break;
00565                                         }
00566                         if (ch == '/' || ch == '$' || ch == '&') {
00567                                 f__lquit = 1;
00568                                 return 0;
00569                                 }
00570                         else if (f__lquit) {
00571                                 while(ch <= ' ' && ch >= 0)
00572                                         GETC(ch);
00573                                 Ungetc(ch,f__cf);
00574                                 if (!Alpha[ch & 0xff] && ch >= 0)
00575                                         errfl(a->cierr, 125, where);
00576                                 break;
00577                                 }
00578                         Ungetc(ch,f__cf);
00579                         if (readall && !Alpha[ch & 0xff])
00580                                 goto readloop;
00581                         if ((no -= no1) <= 0)
00582                                 break;
00583                         for(dn1 = dn0; dn1 <= dn; dn1++) {
00584                                 if (++dn1->curval < dn1->extent) {
00585                                         iva += dn1->delta;
00586                                         goto readloop;
00587                                         }
00588                                 dn1->curval = 0;
00589                                 }
00590                         break;
00591                         }
00592                 }
00593         }
00594 
00595 #ifdef _MSC_VER
00596  #define un_getc ungetc
00597 #endif
00598 
00599  integer
00600 #ifdef KR_headers
00601 s_rsne(a) cilist *a;
00602 #else
00603 s_rsne(cilist *a)
00604 #endif
00605 {
00606         extern int l_eof;
00607         int n;
00608 
00609         f__external=1;
00610         l_eof = 0;
00611         if(n = c_le(a))
00612                 return n;
00613         if(f__curunit->uwrt && f__nowreading(f__curunit))
00614                 err(a->cierr,errno,where0);
00615         l_getc = t_getc;
00616         l_ungetc = un_getc;
00617         f__doend = xrd_SL;
00618         n = x_rsne(a);
00619         nml_read = 0;
00620         if (n)
00621                 return n;
00622         return e_rsle();
00623         }
00624 #ifdef __cplusplus
00625 }
00626 #endif

Generated on Sun Mar 4 15:03:43 2007 for Scilab [trunk] by  doxygen 1.5.1