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	8/28/85
   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:     if(ch == 'EOF') return EOF;
 242:     if(cnt == 0 ) return F_ERNMLIST;
 243:     if(sign== -1) value = -value;
 244:     *subval = value;
 245:     return OK;
 246: }
 247: 
 248: LOCAL
 249: rd_name(ptr)
 250: char *ptr;
 251: {
 252:     /* read a variable name from the input stream */
 253:     char *init = ptr-1;
 254: 
 255:     if(!isalpha(GETC)) {
 256:         UNGETC();
 257:         return(ERROR);
 258:     }
 259:     *ptr++ = ch;
 260:     while(isalnum(GETC))
 261:     {
 262:         if(ptr-init > VL ) return(ERROR);
 263:         *ptr++ = ch;
 264:     }
 265:     *ptr = '\0';
 266:     UNGETC();
 267:     return(OK);
 268: }
 269: 
 270: LOCAL
 271: t_getc()
 272: {   int ch;
 273:     static newline = YES;
 274: rd:
 275:     if(curunit->uend) {
 276:         leof = EOF;
 277:         return(EOF);
 278:     }
 279:     if((ch=getc(cf))!=EOF)
 280:     {
 281:         if(ch == '\n') newline = YES;
 282:         else if(newline==YES)
 283:         {   /* skip first character on each line for namelist */
 284:             newline = NO;
 285:             goto rd;
 286:         }
 287:         return(ch);
 288:     }
 289:     if(feof(cf))
 290:     {   curunit->uend = YES;
 291:         leof = EOF;
 292:     }
 293:     else clearerr(cf);
 294:     return(EOF);
 295: }
 296: 
 297: LOCAL
 298: l_read(number,ptr,len,type) ftnint number,type; flex *ptr; ftnlen len;
 299: {   int i,n;
 300:     double *yy;
 301:     float *xx;
 302: 
 303:     lcount = 0;
 304:     for(i=0;i<number;i++)
 305:     {
 306:         if(leof) return EOF;
 307:         if(lcount==0)
 308:         {
 309:             ltype = NULL;
 310:             if(i!=0)
 311:             {   /* skip to comma */
 312:                 while(isblnk(GETC));
 313:                 if(leof) return(EOF);
 314:                 if(ch == namelistkey_)
 315:                 {   UNGETC();
 316:                     return(OK);
 317:                 }
 318:                 if(ch != ',' ) return(F_ERNMLIST);
 319:             }
 320:             while(isblnk(GETC));
 321:             if(leof) return(EOF);
 322:             UNGETC();
 323:             if(i!=0 && ch == namelistkey_) return(OK);
 324: 
 325:             switch((int)type)
 326:             {
 327:             case TYSHORT:
 328:             case TYLONG:
 329:                 if(!isint(ch)) return(OK);
 330:                 ERRNM(l_R(1));
 331:                 break;
 332:             case TYREAL:
 333:             case TYDREAL:
 334:                 if(!isrl(ch)) return(OK);
 335:                 ERRNM(l_R(1));
 336:                 break;
 337:             case TYCOMPLEX:
 338:             case TYDCOMPLEX:
 339:                 if(!isdigit(ch) && ch!='(') return(OK);
 340:                 ERRNM(l_C());
 341:                 break;
 342:             case TYLOGICAL:
 343:                 if(!islgc(ch)) return(OK);
 344:                 ERRNM(l_L());
 345:                 if(nameflag) return(OK);
 346:                 break;
 347:             case TYCHAR:
 348:                 if(!isdigit(ch) && !isapos(ch)) return(OK);
 349:                 ERRNM(l_CHAR());
 350:                 break;
 351:             }
 352: 
 353:             if(leof) return(EOF);
 354:             /* peek at next character -
 355: 				should be separator or namelistkey_ */
 356:             GETC; UNGETC();
 357:             if(!issep(ch) && (ch != namelistkey_))
 358:             return( leof?EOF:F_ERNMLIST );
 359:         }
 360: 
 361:         if(!ltype) return(F_ERNMLIST);
 362:         switch((int)type)
 363:         {
 364:         case TYSHORT:
 365:             ptr->flshort=lx;
 366:             break;
 367:         case TYLOGICAL:
 368:             if(len == sizeof(short))
 369:                 ptr->flshort = lx;
 370:             else
 371:                 ptr->flint = lx;
 372:             break;
 373:         case TYLONG:
 374:             ptr->flint=lx;
 375:             break;
 376:         case TYREAL:
 377:             ptr->flreal=lx;
 378:             break;
 379:         case TYDREAL:
 380:             ptr->fldouble=lx;
 381:             break;
 382:         case TYCOMPLEX:
 383:             xx=(float *)ptr;
 384:             *xx++ = ly;
 385:             *xx = lx;
 386:             break;
 387:         case TYDCOMPLEX:
 388:             yy=(double *)ptr;
 389:             *yy++ = ly;
 390:             *yy = lx;
 391:             break;
 392:         case TYCHAR:
 393:             b_char(lchar,(char *)ptr,len);
 394:             break;
 395:         }
 396:         if(lcount>0) lcount--;
 397:         ptr = (flex *)((char *)ptr + len);
 398:     }
 399:     if(lcount>0) return F_ERNMLIST;
 400:     return(OK);
 401: }
 402: 
 403: LOCAL
 404: get_repet()
 405: {
 406:     double lc;
 407:     if(isdigit(GETC))
 408:     {   UNGETC();
 409:         rd_int(&lc);
 410:         lcount = (int)lc;
 411:         if(GETC!='*')
 412:             if(leof) return(EOF);
 413:             else return(F_ERREPT);
 414:     }
 415:     else
 416:     {   lcount = 1;
 417:         UNGETC();
 418:     }
 419:     return(OK);
 420: }
 421: 
 422: LOCAL
 423: l_R(flg) int flg;
 424: {   double a,b,c,d;
 425:     int da,db,dc,dd;
 426:     int i,sign=0;
 427:     a=b=c=d=0;
 428:     da=db=dc=dd=0;
 429: 
 430:     if( flg )       /* real */
 431:     {
 432:         da=rd_int(&a);  /* repeat count ? */
 433:         if(GETC=='*')
 434:         {
 435:             if (a <= 0.) return(F_ERNREP);
 436:             lcount=(int)a;
 437:             db=rd_int(&b);  /* whole part of number */
 438:         }
 439:         else
 440:         {   UNGETC();
 441:             db=da;
 442:             b=a;
 443:             lcount=1;
 444:         }
 445:     }
 446:     else           /* complex */
 447:     {
 448:         db=rd_int(&b);
 449:     }
 450: 
 451:     if(GETC=='.' && isdigit(GETC))
 452:     {   UNGETC();
 453:         dc=rd_int(&c);  /* fractional part of number */
 454:     }
 455:     else
 456:     {   UNGETC();
 457:         dc=0;
 458:         c=0.;
 459:     }
 460:     if(isexp(GETC))
 461:         dd=rd_int(&d);  /* exponent */
 462:     else if (ch == '+' || ch == '-')
 463:     {   UNGETC();
 464:         dd=rd_int(&d);
 465:     }
 466:     else
 467:     {   UNGETC();
 468:         dd=0;
 469:     }
 470:     if(db<0 || b<0)
 471:     {   sign=1;
 472:         b = -b;
 473:     }
 474:     for(i=0;i<dc;i++) c/=10.;
 475:     b=b+c;
 476:     if (dd > 0)
 477:     {   for(i=0;i<d;i++) b *= 10.;
 478:         for(i=0;i< -d;i++) b /= 10.;
 479:     }
 480:     lx=sign?-b:b;
 481:     ltype=TYLONG;
 482:     return(OK);
 483: }
 484: 
 485: LOCAL
 486: rd_int(x) double *x;
 487: {   int sign=0,i=0;
 488:     double y=0.0;
 489:     if(GETC=='-') sign = -1;
 490:     else if(ch=='+') sign=0;
 491:     else UNGETC();
 492:     while(isdigit(GETC))
 493:     {   i++;
 494:         y=10*y + ch-'0';
 495:     }
 496:     UNGETC();
 497:     if(sign) y = -y;
 498:     *x = y;
 499:     return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */
 500: }
 501: 
 502: LOCAL
 503: l_C()
 504: {   int n;
 505:     if(n=get_repet()) return(n);        /* get repeat count */
 506:     if(GETC!='(') err(errflag,F_ERNMLIST,"no (")
 507:     while(isblnk(GETC));
 508:     UNGETC();
 509:     l_R(0);     /* get real part */
 510:     ly = lx;
 511:     while(isblnk(GETC));  /* get comma */
 512:     if(leof) return(EOF);
 513:     if(ch!=',') return(F_ERNMLIST);
 514:     while(isblnk(GETC));
 515:     UNGETC();
 516:     if(leof) return(EOF);
 517:     l_R(0);     /* get imag part */
 518:     while(isblnk(GETC));
 519:     if(ch!=')') err(errflag,F_ERNMLIST,"no )")
 520:     ltype = TYCOMPLEX;
 521:     return(OK);
 522: }
 523: 
 524: LOCAL
 525: l_L()
 526: {
 527:     int n, keychar=ch, scanned=NO;
 528:     if(ch=='f' || ch=='F' || ch=='t' || ch=='T')
 529:     {
 530:         scanned=YES;
 531:         if(rd_name(var_name))
 532:             return(leof?EOF:F_ERNMLIST);
 533:         while(isblnk(GETC));
 534:         UNGETC();
 535:         if(ch == '=' || ch == '(')
 536:         {   /* found a name, not a value */
 537:             nameflag = YES;
 538:             return(OK);
 539:         }
 540:     }
 541:     else
 542:     {
 543:         if(n=get_repet()) return(n);        /* get repeat count */
 544:         if(GETC=='.') GETC;
 545:         keychar = ch;
 546:     }
 547:     switch(keychar)
 548:     {
 549:     case 't':
 550:     case 'T':
 551:         lx=1;
 552:         break;
 553:     case 'f':
 554:     case 'F':
 555:         lx=0;
 556:         break;
 557:     default:
 558:         if(ch==EOF) return(EOF);
 559:         else    err(errflag,F_ERNMLIST,"logical not T or F");
 560:     }
 561:     ltype=TYLOGICAL;
 562:     if(scanned==NO)
 563:     {
 564:         while(!issep(GETC) && ch!=EOF) ;
 565:         UNGETC();
 566:     }
 567:     if(ch == EOF ) return(EOF);
 568:     return(OK);
 569: }
 570: 
 571: #define BUFSIZE 128
 572: LOCAL
 573: l_CHAR()
 574: {   int size,i,n;
 575:     char quote,*p;
 576:     if(n=get_repet()) return(n);        /* get repeat count */
 577:     if(isapos(GETC)) quote=ch;
 578:     else if(ch == EOF) return EOF;
 579:     else return F_ERNMLIST;
 580:     ltype=TYCHAR;
 581:     if(lchar!=NULL) free(lchar);
 582:     size=BUFSIZE-1;
 583:     p=lchar=(char *)malloc(BUFSIZE);
 584:     if(lchar==NULL) return (F_ERSPACE);
 585:     for(i=0;;)
 586:     {   while( GETC!=quote && ch!='\n' && ch!=EOF && ++i<size )
 587:                 *p++ = ch;
 588:         if(i==size)
 589:         {
 590:         newone:
 591:             size += BUFSIZE;
 592:             lchar=(char *)realloc(lchar, size+1);
 593:             if(lchar==NULL) return( F_ERSPACE );
 594:             p=lchar+i-1;
 595:             *p++ = ch;
 596:         }
 597:         else if(ch==EOF) return(EOF);
 598:         else if(ch=='\n')
 599:         {   if(*(p-1) == '\\') *(p-1) = ch;
 600:         }
 601:         else if(GETC==quote)
 602:         {   if(++i<size) *p++ = ch;
 603:             else goto newone;
 604:         }
 605:         else
 606:         {   UNGETC();
 607:             *p = '\0';
 608:             return(OK);
 609:         }
 610:     }
 611: }

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 403; used 3 times
l_C defined in line 502; used 1 times
l_CHAR defined in line 572; used 1 times
l_L defined in line 524; used 1 times
l_R defined in line 422; used 4 times
l_read defined in line 297; used 3 times
rd_int defined in line 485; used 7 times
rd_name defined in line 248; used 2 times
s_rsne defined in line 60; never used
t_getc defined in line 270; 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 571; 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: 1985-08-29
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2817
Valid CSS Valid XHTML 1.0 Strict