1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)rsnmle.c	5.3.1	1/1/94
   7:  */
   8: 
   9: /*
  10:  *		name-list read
  11:  */
  12: 
  13: #include "fio.h"
  14: #include "lio.h"
  15: #include "nmlio.h"
  16: #include <ctype.h>
  17: 
  18: LOCAL char *nml_rd;
  19: 
  20: static int ch;
  21: LOCAL nameflag;
  22: LOCAL   char var_name[VL+1];
  23: 
  24: #define SP 1
  25: #define B  2
  26: #define AP 4
  27: #define EX 8
  28: #define INTG 16
  29: #define RL 32
  30: #define LGC 64
  31: #define IRL         (INTG | RL | LGC )
  32: #define isblnk(x)   (ltab[x+1]&B)   /* space, tab, newline */
  33: #define issep(x)    (ltab[x+1]&SP)  /* space, tab, newline, comma */
  34: #define isapos(x)   (ltab[x+1]&AP)  /* apost., quote mark */
  35: #define isexp(x)    (ltab[x+1]&EX)  /* d, e, D, E */
  36: #define isint(x)    (ltab[x+1]&INTG)    /* 0-9, plus, minus */
  37: #define isrl(x)     (ltab[x+1]&RL)  /* 0-9, plus,  minus, period */
  38: #define islgc(x)    (ltab[x+1]&LGC) /* 0-9, period, t, f, T, F */
  39: 
  40: #define GETC (ch=t_getc())
  41: #define UNGETC() ungetc(ch,cf)
  42: 
  43: LOCAL char *lchar;
  44: LOCAL double lx,ly;
  45: LOCAL int ltype;
  46: int t_getc(), ungetc();
  47: 
  48: LOCAL char ltab[128+1] =
  49: {           0,      /* offset one for EOF */
  50: /*   0- 15 */ 0,0,0,0,0,0,0,0,0,SP|B,SP|B,0,0,0,0,0, /* TAB,NEWLINE */
  51: /*  16- 31 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  52: /*  32- 47 */ SP|B,0,AP,0,0,0,0,AP,0,0,0,RL|INTG,SP,RL|INTG,RL|LGC,0, /* space,",',comma,., */
  53: /*  48- 63 */ IRL,IRL,IRL,IRL,IRL,IRL,IRL,IRL,IRL,IRL,0,0,0,0,0,0, /* digits */
  54: /*  64- 79 */ 0,0,0,0,EX,EX,LGC,0,0,0,0,0,0,0,0,0,  /* D,E,F */
  55: /*  80- 95 */ 0,0,0,0,LGC,0,0,0,0,0,0,0,0,0,0,0,    /* T */
  56: /*  96-111 */ 0,0,0,0,EX,EX,LGC,0,0,0,0,0,0,0,0,0,  /* d,e,f */
  57: /* 112-127 */ 0,0,0,0,LGC,0,0,0,0,0,0,0,0,0,0,0     /* t */
  58: };
  59: 
  60: s_rsne(a) namelist_arglist *a;
  61: {
  62:     int n;
  63:     struct namelistentry *entry;
  64:     int nelem, vlen, vtype;
  65:     char *nmlist_nm, *addr;
  66: 
  67:     nml_rd = "namelist read";
  68:     reading = YES;
  69:     formatted = NAMELIST;
  70:     fmtbuf = "ext namelist io";
  71:     if(n=c_le(a,READ)) return(n);
  72:     getn = t_getc;
  73:     ungetn = ungetc;
  74:     leof = curunit->uend;
  75:     if(curunit->uwrt && ! nowreading(curunit)) err(errflag, errno, nml_rd)
  76: 
  77:     /* look for " &namelistname " */
  78:     nmlist_nm = a->namelist->namelistname;
  79:     while(isblnk(GETC)) ;
  80:     /* check for "&end" (like IBM) or "$end" (like DEC) */
  81:     if(ch != '&' && ch != '$') goto rderr;
  82:     /* save it - write out using the same character as used on input */
  83:     namelistkey_ = ch;
  84:     while( *nmlist_nm )
  85:         if( GETC != *nmlist_nm++ )
  86:             {
  87:                 nml_rd = "incorrect namelist name";
  88:                 goto rderr;
  89:             }
  90:     if(!isblnk(GETC)) goto rderr;
  91:     while(isblnk(GETC)) ;
  92:     if(leof) goto rderr;
  93:     UNGETC();
  94: 
  95:     while( GETC != namelistkey_ )
  96:     {
  97:         UNGETC();
  98:         /* get variable name */
  99:         if(!nameflag && rd_name(var_name)) goto rderr;
 100: 
 101:         entry = a->namelist->names;
 102:         /* loop through namelist entries looking for this variable name */
 103:         while( entry->varname[0] != 0 )
 104:         {
 105:         if( strcmp(entry->varname, var_name) == 0 ) goto got_name;
 106:         entry++;
 107:         }
 108:         nml_rd = "incorrect variable name";
 109:         goto rderr;
 110: got_name:
 111:         if( n = get_pars( entry, &addr, &nelem, &vlen, &vtype ))
 112:                             goto rderr_n;
 113:         while(isblnk(GETC)) ;
 114:         if(ch != '=') goto rderr;
 115: 
 116:         nameflag = NO;
 117:         if(n = l_read( nelem, addr, vlen, vtype )) goto rderr_n;
 118:         while(isblnk(GETC));
 119:         if(ch == ',') while(isblnk(GETC));
 120:         UNGETC();
 121:         if(leof) goto rderr;
 122:     }
 123:     /* check for 'end' after '&' or '$'*/
 124:     if(GETC!='e' || GETC!='n' || GETC!='d' )
 125:         goto rderr;
 126:     /* flush to next input record */
 127: flush:
 128:     while(GETC != '\n' && ch != EOF);
 129:     return(ch == EOF ? EOF : OK);
 130: 
 131: rderr:
 132:     if(leof)
 133:         n = EOF;
 134:     else
 135:         n = F_ERNMLIST;
 136: rderr_n:
 137:     if(n == EOF ) err(endflag,EOF,nml_rd);
 138:     /* flush after error in case restart I/O */
 139:     if(ch != '\n')  while(GETC != '\n' && ch != EOF) ;
 140:     err(errflag,n,nml_rd)
 141: }
 142: 
 143: #define MAXSUBS 7
 144: 
 145: LOCAL
 146: get_pars( entry, addr, nelem, vlen, vtype )
 147: struct namelistentry *entry;
 148: char    **addr;     /* beginning address to read into */
 149: int *nelem,     /* number of elements to read */
 150:     *vlen,      /* length of elements */
 151:     *vtype;     /* type of elements */
 152: {
 153:     int offset, i, n,
 154:         *dimptr,    /* points to dimensioning info */
 155:         ndim,       /* number of dimensions */
 156:         baseoffset, /* offset of corner element */
 157:         *span,      /* subscript span for each dimension */
 158:         subs[MAXSUBS],  /* actual subscripts */
 159:         subcnt = -1;    /* number of actual subscripts */
 160: 
 161: 
 162:     /* get element size and base address */
 163:     *vlen = entry->typelen;
 164:     *addr = entry->varaddr;
 165: 
 166:     /* get type */
 167:     switch ( *vtype = entry->type ) {
 168:         case TYSHORT:
 169:         case TYLONG:
 170:         case TYREAL:
 171:         case TYDREAL:
 172:         case TYCOMPLEX:
 173:         case TYDCOMPLEX:
 174:         case TYLOGICAL:
 175:         case TYCHAR:
 176:             break;
 177:         default:
 178:             fatal(F_ERSYS,"unknown type in rsnmle");
 179:     }
 180: 
 181:     /* get number of elements */
 182:     dimptr = entry->dimp;
 183:     if( dimptr==NULL )
 184:     {       /* scalar */
 185:         *nelem = 1;
 186:         return(OK);
 187:     }
 188: 
 189:     if( GETC != '(' )
 190:     {       /* entire array */
 191:         *nelem = dimptr[1];
 192:         UNGETC();
 193:         return(OK);
 194:     }
 195: 
 196:     /* get element length, number of dimensions, base, span vector */
 197:     ndim = dimptr[0];
 198:     if(ndim<=0 || ndim>MAXSUBS) fatal(F_ERSYS,"illegal dimensions");
 199:     baseoffset = dimptr[2];
 200:     span = dimptr+3;
 201: 
 202:     /* get subscripts from input data */
 203:     while(ch!=')') {
 204:         if( ++subcnt > MAXSUBS-1 ) return F_ERNMLIST;
 205:         if(n=get_int(&subs[subcnt])) return n;
 206:         GETC;
 207:         if(leof) return EOF;
 208:         if(ch != ',' && ch != ')') return F_ERNMLIST;
 209:     }
 210:     if( ++subcnt != ndim ) return F_ERNMLIST;
 211: 
 212:     offset = subs[ndim-1];
 213:     for( i = ndim-2; i>=0; i-- )
 214:         offset = subs[i] + span[i]*offset;
 215:     offset -= baseoffset;
 216:     *nelem = dimptr[1] - offset;
 217:     if( offset < 0 || offset >= dimptr[1] )
 218:         return F_ERNMLIST;
 219:     *addr = *addr + (*vlen)*offset;
 220:     return OK;
 221: }
 222: 
 223: LOCAL
 224: get_int(subval)
 225: int *subval;
 226: {
 227:     int sign=0, value=0, cnt=0;
 228: 
 229:     /* look for sign */
 230:     if(GETC == '-') sign = -1;
 231:     else if(ch == '+') ;
 232:     else UNGETC();
 233:     if(ch == EOF) return(EOF);
 234: 
 235:     while(isdigit(GETC))
 236:     {
 237:         value = 10*value + ch-'0';
 238:         cnt++;
 239:     }
 240:     UNGETC();
 241: #ifndef pdp11
 242:     if(ch == 'EOF') return EOF;
 243: #endif
 244:     if(cnt == 0 ) return F_ERNMLIST;
 245:     if(sign== -1) value = -value;
 246:     *subval = value;
 247:     return OK;
 248: }
 249: 
 250: LOCAL
 251: rd_name(ptr)
 252: char *ptr;
 253: {
 254:     /* read a variable name from the input stream */
 255:     char *init = ptr-1;
 256: 
 257:     if(!isalpha(GETC)) {
 258:         UNGETC();
 259:         return(ERROR);
 260:     }
 261:     *ptr++ = ch;
 262:     while(isalnum(GETC))
 263:     {
 264:         if(ptr-init > VL ) return(ERROR);
 265:         *ptr++ = ch;
 266:     }
 267:     *ptr = '\0';
 268:     UNGETC();
 269:     return(OK);
 270: }
 271: 
 272: LOCAL
 273: t_getc()
 274: {   int ch;
 275:     static newline = YES;
 276: rd:
 277:     if(curunit->uend) {
 278:         leof = EOF;
 279:         return(EOF);
 280:     }
 281:     if((ch=getc(cf))!=EOF)
 282:     {
 283:         if(ch == '\n') newline = YES;
 284:         else if(newline==YES)
 285:         {   /* skip first character on each line for namelist */
 286:             newline = NO;
 287:             goto rd;
 288:         }
 289:         return(ch);
 290:     }
 291:     if(feof(cf))
 292:     {   curunit->uend = YES;
 293:         leof = EOF;
 294:     }
 295:     else clearerr(cf);
 296:     return(EOF);
 297: }
 298: 
 299: LOCAL
 300: l_read(number,ptr,len,type) ftnint number,type; flex *ptr; ftnlen len;
 301: {   int i,n;
 302:     double *yy;
 303:     float *xx;
 304: 
 305:     lcount = 0;
 306:     for(i=0;i<number;i++)
 307:     {
 308:         if(leof) return EOF;
 309:         if(lcount==0)
 310:         {
 311:             ltype = NULL;
 312:             if(i!=0)
 313:             {   /* skip to comma */
 314:                 while(isblnk(GETC));
 315:                 if(leof) return(EOF);
 316:                 if(ch == namelistkey_)
 317:                 {   UNGETC();
 318:                     return(OK);
 319:                 }
 320:                 if(ch != ',' ) return(F_ERNMLIST);
 321:             }
 322:             while(isblnk(GETC));
 323:             if(leof) return(EOF);
 324:             UNGETC();
 325:             if(i!=0 && ch == namelistkey_) return(OK);
 326: 
 327:             switch((int)type)
 328:             {
 329:             case TYSHORT:
 330:             case TYLONG:
 331:                 if(!isint(ch)) return(OK);
 332:                 ERRNM(l_R(1));
 333:                 break;
 334:             case TYREAL:
 335:             case TYDREAL:
 336:                 if(!isrl(ch)) return(OK);
 337:                 ERRNM(l_R(1));
 338:                 break;
 339:             case TYCOMPLEX:
 340:             case TYDCOMPLEX:
 341:                 if(!isdigit(ch) && ch!='(') return(OK);
 342:                 ERRNM(l_C());
 343:                 break;
 344:             case TYLOGICAL:
 345:                 if(!islgc(ch)) return(OK);
 346:                 ERRNM(l_L());
 347:                 if(nameflag) return(OK);
 348:                 break;
 349:             case TYCHAR:
 350:                 if(!isdigit(ch) && !isapos(ch)) return(OK);
 351:                 ERRNM(l_CHAR());
 352:                 break;
 353:             }
 354: 
 355:             if(leof) return(EOF);
 356:             /* peek at next character -
 357: 				should be separator or namelistkey_ */
 358:             GETC; UNGETC();
 359:             if(!issep(ch) && (ch != namelistkey_))
 360:             return( leof?EOF:F_ERNMLIST );
 361:         }
 362: 
 363:         if(!ltype) return(F_ERNMLIST);
 364:         switch((int)type)
 365:         {
 366:         case TYSHORT:
 367:             ptr->flshort=lx;
 368:             break;
 369:         case TYLOGICAL:
 370:             if(len == sizeof(short))
 371:                 ptr->flshort = lx;
 372:             else
 373:                 ptr->flint = lx;
 374:             break;
 375:         case TYLONG:
 376:             ptr->flint=lx;
 377:             break;
 378:         case TYREAL:
 379:             ptr->flreal=lx;
 380:             break;
 381:         case TYDREAL:
 382:             ptr->fldouble=lx;
 383:             break;
 384:         case TYCOMPLEX:
 385:             xx=(float *)ptr;
 386:             *xx++ = ly;
 387:             *xx = lx;
 388:             break;
 389:         case TYDCOMPLEX:
 390:             yy=(double *)ptr;
 391:             *yy++ = ly;
 392:             *yy = lx;
 393:             break;
 394:         case TYCHAR:
 395:             b_char(lchar,(char *)ptr,len);
 396:             break;
 397:         }
 398:         if(lcount>0) lcount--;
 399:         ptr = (flex *)((char *)ptr + len);
 400:     }
 401:     if(lcount>0) return F_ERNMLIST;
 402:     return(OK);
 403: }
 404: 
 405: LOCAL
 406: get_repet()
 407: {
 408:     double lc;
 409:     if(isdigit(GETC))
 410:     {   UNGETC();
 411:         rd_int(&lc);
 412:         lcount = (int)lc;
 413:         if(GETC!='*')
 414:             if(leof) return(EOF);
 415:             else return(F_ERREPT);
 416:     }
 417:     else
 418:     {   lcount = 1;
 419:         UNGETC();
 420:     }
 421:     return(OK);
 422: }
 423: 
 424: LOCAL
 425: l_R(flg) int flg;
 426: {   double a,b,c,d;
 427:     int da,db,dc,dd;
 428:     int i,sign=0;
 429:     a=b=c=d=0;
 430:     da=db=dc=dd=0;
 431: 
 432:     if( flg )       /* real */
 433:     {
 434:         da=rd_int(&a);  /* repeat count ? */
 435:         if(GETC=='*')
 436:         {
 437:             if (a <= 0.) return(F_ERNREP);
 438:             lcount=(int)a;
 439:             db=rd_int(&b);  /* whole part of number */
 440:         }
 441:         else
 442:         {   UNGETC();
 443:             db=da;
 444:             b=a;
 445:             lcount=1;
 446:         }
 447:     }
 448:     else           /* complex */
 449:     {
 450:         db=rd_int(&b);
 451:     }
 452: 
 453:     if(GETC=='.' && isdigit(GETC))
 454:     {   UNGETC();
 455:         dc=rd_int(&c);  /* fractional part of number */
 456:     }
 457:     else
 458:     {   UNGETC();
 459:         dc=0;
 460:         c=0.;
 461:     }
 462:     if(isexp(GETC))
 463:         dd=rd_int(&d);  /* exponent */
 464:     else if (ch == '+' || ch == '-')
 465:     {   UNGETC();
 466:         dd=rd_int(&d);
 467:     }
 468:     else
 469:     {   UNGETC();
 470:         dd=0;
 471:     }
 472:     if(db<0 || b<0)
 473:     {   sign=1;
 474:         b = -b;
 475:     }
 476:     for(i=0;i<dc;i++) c/=10.;
 477:     b=b+c;
 478:     if (dd > 0)
 479:     {   for(i=0;i<d;i++) b *= 10.;
 480:         for(i=0;i< -d;i++) b /= 10.;
 481:     }
 482:     lx=sign?-b:b;
 483:     ltype=TYLONG;
 484:     return(OK);
 485: }
 486: 
 487: LOCAL
 488: rd_int(x) double *x;
 489: {   int sign=0,i=0;
 490:     double y=0.0;
 491:     if(GETC=='-') sign = -1;
 492:     else if(ch=='+') sign=0;
 493:     else UNGETC();
 494:     while(isdigit(GETC))
 495:     {   i++;
 496:         y=10*y + ch-'0';
 497:     }
 498:     UNGETC();
 499:     if(sign) y = -y;
 500:     *x = y;
 501:     return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */
 502: }
 503: 
 504: LOCAL
 505: l_C()
 506: {   int n;
 507:     if(n=get_repet()) return(n);        /* get repeat count */
 508:     if(GETC!='(') err(errflag,F_ERNMLIST,"no (")
 509:     while(isblnk(GETC));
 510:     UNGETC();
 511:     l_R(0);     /* get real part */
 512:     ly = lx;
 513:     while(isblnk(GETC));  /* get comma */
 514:     if(leof) return(EOF);
 515:     if(ch!=',') return(F_ERNMLIST);
 516:     while(isblnk(GETC));
 517:     UNGETC();
 518:     if(leof) return(EOF);
 519:     l_R(0);     /* get imag part */
 520:     while(isblnk(GETC));
 521:     if(ch!=')') err(errflag,F_ERNMLIST,"no )")
 522:     ltype = TYCOMPLEX;
 523:     return(OK);
 524: }
 525: 
 526: LOCAL
 527: l_L()
 528: {
 529:     int n, keychar=ch, scanned=NO;
 530:     if(ch=='f' || ch=='F' || ch=='t' || ch=='T')
 531:     {
 532:         scanned=YES;
 533:         if(rd_name(var_name))
 534:             return(leof?EOF:F_ERNMLIST);
 535:         while(isblnk(GETC));
 536:         UNGETC();
 537:         if(ch == '=' || ch == '(')
 538:         {   /* found a name, not a value */
 539:             nameflag = YES;
 540:             return(OK);
 541:         }
 542:     }
 543:     else
 544:     {
 545:         if(n=get_repet()) return(n);        /* get repeat count */
 546:         if(GETC=='.') GETC;
 547:         keychar = ch;
 548:     }
 549:     switch(keychar)
 550:     {
 551:     case 't':
 552:     case 'T':
 553:         lx=1;
 554:         break;
 555:     case 'f':
 556:     case 'F':
 557:         lx=0;
 558:         break;
 559:     default:
 560:         if(ch==EOF) return(EOF);
 561:         else    err(errflag,F_ERNMLIST,"logical not T or F");
 562:     }
 563:     ltype=TYLOGICAL;
 564:     if(scanned==NO)
 565:     {
 566:         while(!issep(GETC) && ch!=EOF) ;
 567:         UNGETC();
 568:     }
 569:     if(ch == EOF ) return(EOF);
 570:     return(OK);
 571: }
 572: 
 573: #define BUFSIZE 128
 574: LOCAL
 575: l_CHAR()
 576: {   int size,i,n;
 577:     char quote,*p;
 578:     if(n=get_repet()) return(n);        /* get repeat count */
 579:     if(isapos(GETC)) quote=ch;
 580:     else if(ch == EOF) return EOF;
 581:     else return F_ERNMLIST;
 582:     ltype=TYCHAR;
 583:     if(lchar!=NULL) free(lchar);
 584:     size=BUFSIZE-1;
 585:     p=lchar=(char *)malloc(BUFSIZE);
 586:     if(lchar==NULL) return (F_ERSPACE);
 587:     for(i=0;;)
 588:     {   while( GETC!=quote && ch!='\n' && ch!=EOF && ++i<size )
 589:                 *p++ = ch;
 590:         if(i==size)
 591:         {
 592:         newone:
 593:             size += BUFSIZE;
 594:             lchar=(char *)realloc(lchar, size+1);
 595:             if(lchar==NULL) return( F_ERSPACE );
 596:             p=lchar+i-1;
 597:             *p++ = ch;
 598:         }
 599:         else if(ch==EOF) return(EOF);
 600:         else if(ch=='\n')
 601:         {   if(*(p-1) == '\\') *(p-1) = ch;
 602:         }
 603:         else if(GETC==quote)
 604:         {   if(++i<size) *p++ = ch;
 605:             else goto newone;
 606:         }
 607:         else
 608:         {   UNGETC();
 609:             *p = '\0';
 610:             return(OK);
 611:         }
 612:     }
 613: }

Defined functions

get_int defined in line 223; used 1 times
get_pars defined in line 145; used 1 times
get_repet defined in line 405; used 3 times
l_C defined in line 504; used 1 times
l_CHAR defined in line 574; used 1 times
l_L defined in line 526; used 1 times
l_R defined in line 424; used 4 times
l_read defined in line 299; used 3 times
rd_int defined in line 487; used 7 times
rd_name defined in line 250; used 2 times
s_rsne defined in line 60; never used
t_getc defined in line 272; used 3 times

Defined variables

ch defined in line 20; used 63 times
lchar defined in line 43; used 9 times
ltab defined in line 48; used 7 times
ltype defined in line 45; used 6 times
lx defined in line 44; used 12 times
ly defined in line 44; used 3 times
nml_rd defined in line 18; used 6 times
var_name defined in line 22; used 3 times

Defined macros

AP defined in line 26; used 3 times
B defined in line 25; used 4 times
BUFSIZE defined in line 573; used 3 times
EX defined in line 27; used 5 times
GETC defined in line 40; used 42 times
INTG defined in line 28; used 4 times
IRL defined in line 31; used 10 times
  • in line 53(10)
LGC defined in line 30; used 7 times
MAXSUBS defined in line 143; used 3 times
RL defined in line 29; used 5 times
SP defined in line 24; used 5 times
UNGETC defined in line 41; used 25 times
isapos defined in line 34; used 2 times
isblnk defined in line 32; used 13 times
isexp defined in line 35; used 1 times
isint defined in line 36; used 1 times
islgc defined in line 38; used 1 times
isrl defined in line 37; used 1 times
issep defined in line 33; used 2 times
Last modified: 1994-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5183
Valid CSS Valid XHTML 1.0 Strict