Annotation of 43BSDReno/lib/libI77/lread.c, revision 1.1.1.1

1.1       root        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:  *     @(#)lread.c     5.2     7/30/85
                      7:  */
                      8: 
                      9: /*
                     10:  * list directed read
                     11:  */
                     12: 
                     13: #include "fio.h"
                     14: #include "lio.h"
                     15: 
                     16: #define SP 1
                     17: #define B  2
                     18: #define AP 4
                     19: #define EX 8
                     20: #define D 16
                     21: #define EIN 32
                     22: #define isblnk(x)      (ltab[x+1]&B)   /* space, tab, newline */
                     23: #define issep(x)       (ltab[x+1]&SP)  /* space, tab, newline, comma */
                     24: #define isapos(x)      (ltab[x+1]&AP)  /* apost., quote mark, \02 */
                     25: #define isexp(x)       (ltab[x+1]&EX)  /* d, e, D, E */
                     26: #define isdigit(x)     (ltab[x+1]&D)
                     27: #define endlinp(x)     (ltab[x+1]&EIN) /* EOF, newline, / */
                     28: 
                     29: #define GETC(x) (x=(*getn)())
                     30: 
                     31: LOCAL char lrd[] = "list read";
                     32: LOCAL char *lchar;
                     33: LOCAL double lx,ly;
                     34: LOCAL int ltype;
                     35: int l_read(),t_getc(),ungetc();
                     36: 
                     37: LOCAL char ltab[128+1] =
                     38: {                      EIN,            /* offset one for EOF */
                     39: /*   0- 15 */  0,0,AP,0,0,0,0,0,0,SP|B,SP|B|EIN,0,0,0,0,0, /* ^B,TAB,NEWLINE */
                     40: /*  16- 31 */  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                     41: /*  32- 47 */  SP|B,0,AP,0,0,0,0,AP,0,0,0,0,SP,0,0,EIN, /* space,",',comma,/ */
                     42: /*  48- 63 */  D,D,D,D,D,D,D,D,D,D,0,0,0,0,0,0,        /* digits 0-9 */
                     43: /*  64- 79 */  0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0,      /* D,E */
                     44: /*  80- 95 */  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                     45: /*  96-111 */  0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0,      /* d,e */
                     46: /* 112-127 */  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                     47: };
                     48: 
                     49: s_rsle(a) cilist *a;   /* start read sequential list external */
                     50: {
                     51:        int n;
                     52:        reading = YES;
                     53:        formatted = LISTDIRECTED;
                     54:        fmtbuf = "ext list io";
                     55:        if(n=c_le(a,READ)) return(n);
                     56:        l_first = YES;
                     57:        lquit = NO;
                     58:        lioproc = l_read;
                     59:        getn = t_getc;
                     60:        ungetn = ungetc;
                     61:        leof = curunit->uend;
                     62:        lcount = 0;
                     63:        ltype = NULL;
                     64:        if(curunit->uwrt && ! nowreading(curunit)) err(errflag, errno, lrd)
                     65:        return(OK);
                     66: }
                     67: 
                     68: LOCAL
                     69: t_getc()
                     70: {      int ch;
                     71:        if(curunit->uend) return(EOF);
                     72:        if((ch=getc(cf))!=EOF) return(ch);
                     73:        if(feof(cf))
                     74:        {       curunit->uend = YES;
                     75:                leof = EOF;
                     76:        }
                     77:        else clearerr(cf);
                     78:        return(EOF);
                     79: }
                     80: 
                     81: e_rsle()
                     82: {
                     83:        int ch;
                     84:        if(curunit->uend) return(EOF);
                     85:        while(GETC(ch) != '\n' && ch != EOF);
                     86:        return(ch==EOF?EOF:OK);
                     87: }
                     88: 
                     89: l_read(number,ptr,len,type) ftnint *number,type; flex *ptr; ftnlen len;
                     90: {      int i,n,ch;
                     91:        double *yy;
                     92:        float *xx;
                     93:        for(i=0;i<*number;i++)
                     94:        {
                     95:                if(leof) err(endflag, EOF, lrd)
                     96:                if(l_first)
                     97:                {       l_first = NO;
                     98:                        while(isblnk(GETC(ch)));        /* skip blanks */
                     99:                        (*ungetn)(ch,cf);
                    100:                }
                    101:                else if(lcount==0)              /* repeat count == 0 ? */
                    102:                {       ERR(t_sep());  /* look for non-blank, allow 1 comma */
                    103:                        if(lquit) return(OK);   /* slash found */
                    104:                }
                    105:                switch((int)type)
                    106:                {
                    107:                case TYSHORT:
                    108:                case TYLONG:
                    109:                case TYREAL:
                    110:                case TYDREAL:
                    111:                        ERR(l_R(1));
                    112:                        break;
                    113:                case TYCOMPLEX:
                    114:                case TYDCOMPLEX:
                    115:                        ERR(l_C());
                    116:                        break;
                    117:                case TYLOGICAL:
                    118:                        ERR(l_L());
                    119:                        break;
                    120:                case TYCHAR:
                    121:                        ERR(l_CHAR());
                    122:                        break;
                    123:                }
                    124:                
                    125:                /* peek at next character; it should be separator or new line */
                    126:                GETC(ch); (*ungetn)(ch,cf);
                    127:                if(!issep(ch) && !endlinp(ch)) {
                    128:                        while(GETC(ch)!= '\n' && ch != EOF);
                    129:                        err(errflag,F_ERLIO,lrd);
                    130:                }
                    131:  
                    132:                if(lquit) return(OK);
                    133:                if(leof) err(endflag,EOF,lrd)
                    134:                else if(external && ferror(cf)) err(errflag,errno,lrd)
                    135:                if(ltype) switch((int)type)
                    136:                {
                    137:                case TYSHORT:
                    138:                        ptr->flshort=lx;
                    139:                        break;
                    140:                case TYLOGICAL:
                    141:                        if(len == sizeof(short))
                    142:                                ptr->flshort = lx;
                    143:                        else
                    144:                                ptr->flint = lx;
                    145:                        break;
                    146:                case TYLONG:
                    147:                        ptr->flint=lx;
                    148:                        break;
                    149:                case TYREAL:
                    150:                        ptr->flreal=lx;
                    151:                        break;
                    152:                case TYDREAL:
                    153:                        ptr->fldouble=lx;
                    154:                        break;
                    155:                case TYCOMPLEX:
                    156:                        xx=(float *)ptr;
                    157:                        *xx++ = ly;
                    158:                        *xx = lx;
                    159:                        break;
                    160:                case TYDCOMPLEX:
                    161:                        yy=(double *)ptr;
                    162:                        *yy++ = ly;
                    163:                        *yy = lx;
                    164:                        break;
                    165:                case TYCHAR:
                    166:                        b_char(lchar,(char *)ptr,len);
                    167:                        break;
                    168:                }
                    169:                if(lcount>0) lcount--;
                    170:                ptr = (flex *)((char *)ptr + len);
                    171:        }
                    172:        return(OK);
                    173: }
                    174: 
                    175: LOCAL
                    176: lr_comm()
                    177: {      int ch;
                    178:        if(lcount) return(lcount);
                    179:        ltype=NULL;
                    180:        while(isblnk(GETC(ch)));
                    181:        (*ungetn)(ch,cf);
                    182:        if(ch==',')
                    183:        {       lcount=1;
                    184:                return(lcount);
                    185:        }
                    186:        if(ch=='/')
                    187:        {       lquit = YES;
                    188:                return(lquit);
                    189:        }
                    190:        else
                    191:                return(OK);
                    192: }
                    193: 
                    194: LOCAL
                    195: get_repet()
                    196: {      char ch;
                    197:        double lc;
                    198:        if(isdigit(GETC(ch)))
                    199:        {       (*ungetn)(ch,cf);
                    200:                rd_int(&lc);
                    201:                lcount = (int)lc;
                    202:                if(GETC(ch)!='*')
                    203:                        if(leof) return(EOF);
                    204:                        else return(F_ERREPT);
                    205:        }
                    206:        else
                    207:        {       lcount = 1;
                    208:                (*ungetn)(ch,cf);
                    209:        }
                    210:        return(OK);
                    211: }
                    212: 
                    213: LOCAL
                    214: l_R(flg) int flg;
                    215: {      double a,b,c,d;
                    216:        int da,db,dc,dd;
                    217:        int i,ch,sign=0;
                    218:        a=b=c=d=0;
                    219:        da=db=dc=dd=0;
                    220: 
                    221:        if( flg )               /* real */
                    222:        {
                    223:                if(lr_comm()) return(OK);
                    224:                da=rd_int(&a);  /* repeat count ? */
                    225:                if(GETC(ch)=='*')
                    226:                {
                    227:                        if (a <= 0.) return(F_ERNREP);
                    228:                        lcount=(int)a;
                    229:                        if (nullfld()) return(OK);      /* could be R* */
                    230:                        db=rd_int(&b);  /* whole part of number */
                    231:                }
                    232:                else
                    233:                {       (*ungetn)(ch,cf);
                    234:                        db=da;
                    235:                        b=a;
                    236:                        lcount=1;
                    237:                }
                    238:        }
                    239:        else               /* complex */
                    240:        {
                    241:                db=rd_int(&b);
                    242:        }
                    243: 
                    244:        if(GETC(ch)=='.' && isdigit(GETC(ch)))
                    245:        {       (*ungetn)(ch,cf);
                    246:                dc=rd_int(&c);  /* fractional part of number */
                    247:        }
                    248:        else
                    249:        {       (*ungetn)(ch,cf);
                    250:                dc=0;
                    251:                c=0.;
                    252:        }
                    253:        if(isexp(GETC(ch)))
                    254:                dd=rd_int(&d);  /* exponent */
                    255:        else if (ch == '+' || ch == '-')
                    256:        {       (*ungetn)(ch,cf);
                    257:                dd=rd_int(&d);
                    258:        }
                    259:        else
                    260:        {       (*ungetn)(ch,cf);
                    261:                dd=0;
                    262:        }
                    263:        if(db<0 || b<0)
                    264:        {       sign=1;
                    265:                b = -b;
                    266:        }
                    267:        for(i=0;i<dc;i++) c/=10.;
                    268:        b=b+c;
                    269:        if (dd > 0)
                    270:        {       for(i=0;i<d;i++) b *= 10.;
                    271:                for(i=0;i< -d;i++) b /= 10.;
                    272:        }
                    273:        lx=sign?-b:b;
                    274:        ltype=TYLONG;
                    275:        return(OK);
                    276: }
                    277: 
                    278: LOCAL
                    279: rd_int(x) double *x;
                    280: {      int ch,sign=0,i=0;
                    281:        double y=0.0;
                    282:        if(GETC(ch)=='-') sign = -1;
                    283:        else if(ch=='+') sign=0;
                    284:        else (*ungetn)(ch,cf);
                    285:        while(isdigit(GETC(ch)))
                    286:        {       i++;
                    287:                y=10*y + ch-'0';
                    288:        }
                    289:        (*ungetn)(ch,cf);
                    290:        if(sign) y = -y;
                    291:        *x = y;
                    292:        return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */
                    293: }
                    294: 
                    295: LOCAL
                    296: l_C()
                    297: {      int ch,n;
                    298:        if(lr_comm()) return(OK);
                    299:        if(n=get_repet()) return(n);            /* get repeat count */
                    300:        if (nullfld()) return(OK);              /* could be R* */
                    301:        if(GETC(ch)!='(') err(errflag,F_ERLIO,"no (")
                    302:        while(isblnk(GETC(ch)));
                    303:        (*ungetn)(ch,cf);
                    304:        l_R(0);         /* get real part */
                    305:        ly = lx;
                    306:        if(t_sep()) return(EOF);
                    307:        l_R(0);         /* get imag part */
                    308:        while(isblnk(GETC(ch)));
                    309:        if(ch!=')') err(errflag,F_ERLIO,"no )")
                    310:        ltype = TYCOMPLEX;
                    311:        return(OK);
                    312: }
                    313: 
                    314: LOCAL
                    315: l_L()
                    316: {
                    317:        int ch,n;
                    318:        if(lr_comm()) return(OK);
                    319:        if(n=get_repet()) return(n);            /* get repeat count */
                    320:        if (nullfld()) return(OK);              /* could be R* */
                    321:        if(GETC(ch)=='.') GETC(ch);
                    322:        switch(ch)
                    323:        {
                    324:        case 't':
                    325:        case 'T':
                    326:                lx=1;
                    327:                break;
                    328:        case 'f':
                    329:        case 'F':
                    330:                lx=0;
                    331:                break;
                    332:        default:
                    333:                if(issep(ch))
                    334:                {       (*ungetn)(ch,cf);
                    335:                        lx=0;
                    336:                        return(OK);
                    337:                }
                    338:                else if(ch==EOF) return(EOF);
                    339:                else    err(errflag,F_ERLIO,"logical not T or F");
                    340:        }
                    341:        ltype=TYLOGICAL;
                    342:        while(!issep(GETC(ch)) && !endlinp(ch));
                    343:        (*ungetn)(ch,cf);
                    344:        return(OK);
                    345: }
                    346: 
                    347: #define BUFSIZE        128
                    348: LOCAL
                    349: l_CHAR()
                    350: {      int ch,size,i,n;
                    351:        char quote,*p;
                    352:        if(lr_comm()) return(OK);
                    353:        if(n=get_repet()) return(n);            /* get repeat count */
                    354:        if (nullfld()) return(OK);              /* could be R* */
                    355:        if(isapos(GETC(ch))) quote=ch;
                    356:        else if(issep(ch) || ch==EOF || ch=='\n')
                    357:        {       if(ch==EOF) return(EOF);
                    358:                (*ungetn)(ch,cf);
                    359:                return(OK);
                    360:        }
                    361:        else
                    362:        {       quote = '\0';   /* to allow single word non-quoted */
                    363:                (*ungetn)(ch,cf);
                    364:        }
                    365:        ltype=TYCHAR;
                    366:        if(lchar!=NULL) free(lchar);
                    367:        size=BUFSIZE-1;
                    368:        p=lchar=(char *)malloc(BUFSIZE);
                    369:        if(lchar==NULL) err(errflag,F_ERSPACE,lrd)
                    370:        for(i=0;;)
                    371:        {       while( ( (quote && GETC(ch)!=quote) ||
                    372:                        (!quote && !issep(GETC(ch)) && !endlinp(ch)) )
                    373:                        && ch!='\n' && ch!=EOF && ++i<size )
                    374:                                *p++ = ch;
                    375:                if(i==size)
                    376:                {
                    377:                newone:
                    378:                        size += BUFSIZE;
                    379:                        lchar=(char *)realloc(lchar, size+1);
                    380:                        if(lchar==NULL) err(errflag,F_ERSPACE,lrd)
                    381:                        p=lchar+i-1;
                    382:                        *p++ = ch;
                    383:                }
                    384:                else if(ch==EOF) return(EOF);
                    385:                else if(ch=='\n')
                    386:                {       if(*(p-1) == '\\') *(p-1) = ch;
                    387:                        else if(!quote)
                    388:                        {       *p = '\0';
                    389:                                (*ungetn)(ch,cf);
                    390:                                return(OK);
                    391:                        }
                    392:                }
                    393:                else if(quote && GETC(ch)==quote)
                    394:                {       if(++i<size) *p++ = ch;
                    395:                        else goto newone;
                    396:                }
                    397:                else
                    398:                {       (*ungetn)(ch,cf);
                    399:                        *p = '\0';
                    400:                        return(OK);
                    401:                }
                    402:        }
                    403: }
                    404: 
                    405: LOCAL
                    406: t_sep()
                    407: {
                    408:        int ch;
                    409:        while(isblnk(GETC(ch)));
                    410:        if(leof) return(EOF);
                    411:        if(ch=='/')
                    412:        {       lquit = YES;
                    413:                (*ungetn)(ch,cf);
                    414:                return(OK);
                    415:        }
                    416:        if(issep(ch)) while(isblnk(GETC(ch)));
                    417:        if(leof) return(EOF);
                    418:        (*ungetn)(ch,cf);
                    419:        return(OK);
                    420: }
                    421: 
                    422: LOCAL
                    423: nullfld()      /* look for null field following a repeat count */
                    424: {
                    425:        int     ch;
                    426: 
                    427:        GETC(ch);
                    428:        (*ungetn)(ch,cf);
                    429:        if (issep(ch) || endlinp(ch))
                    430:                return(YES);
                    431:        return(NO);
                    432: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.