Annotation of 43BSD/contrib/icon/operators/bang.c, revision 1.1.1.1

1.1       root        1: #include "../h/rt.h"
                      2: #include "../h/record.h"
                      3: 
                      4: /*
                      5:  * !x - generate successive values from object x.
                      6:  */
                      7: 
                      8: bang(nargs, arg1v, arg1, arg0)
                      9: int nargs;
                     10: struct descrip arg1v, arg1, arg0;
                     11:    {
                     12:    register int i, j, slen;
                     13:    register union block *bp, *ep;
                     14:    register struct descrip *dp;
                     15:    int typ1;
                     16:    char sbuf[MAXSTRING];
                     17:    FILE *fd;
                     18:    extern char *alcstr();
                     19: 
                     20:    SetBound;
                     21:    arg1v = arg1;
                     22: 
                     23:    if ((typ1 = cvstr(&arg1, sbuf)) != NULL) {
                     24:       /*
                     25:        * A string is being banged.
                     26:        */
                     27:       i = 1;
                     28:       while (i <= STRLEN(arg1)) {
                     29:          /*
                     30:           * Loop through the string using i as an index.
                     31:           */
                     32:          if (typ1 == 1) {
                     33:             /*
                     34:              * x was converted to a string, thus, the resulting string
                     35:              *  can't be modified and a trapped variable isn't needed.
                     36:              *  Make a one-character string out of the next character
                     37:              *  in x and suspend it.
                     38:              */
                     39:             sneed(1);
                     40:             STRLEN(arg0) = 1;
                     41:             STRLOC(arg0) = alcstr(STRLOC(arg1)+i-1, 1);
                     42:             suspend();
                     43:             }
                     44:          else {
                     45:             /*
                     46:              * x a string and thus a trapped variable must be made
                     47:              *  for the one character string being suspended.
                     48:              */
                     49:             hneed(sizeof(struct b_tvsubs));
                     50:             mksubs(&arg1v, &arg1, i, 1, &arg0);
                     51:             suspend();
                     52:             arg1 = arg1v;
                     53:             DeRef(arg1)
                     54:             if (!QUAL(arg1))
                     55:                runerr(103, &arg1);
                     56:             }
                     57:          i++;
                     58:          }
                     59:       }
                     60:    else {
                     61:       /*
                     62:        * x isn't a string.
                     63:        */
                     64:       DeRef(arg1)
                     65:       switch (TYPE(arg1)) {
                     66:          case T_LIST:
                     67:             /*
                     68:              * x is a list.  Chain through each list element block and for
                     69:              *  each one, suspend with a variable pointing to each
                     70:              *  element contained in the block.
                     71:              */
                     72:             bp = BLKLOC(arg1);
                     73:             for (arg1 = bp->list.listhead; arg1.type == D_LELEM;
                     74:                arg1 = BLKLOC(arg1)->lelem.listnext) {
                     75:                bp = BLKLOC(arg1);
                     76:                for (i = 0; i < bp->lelem.nused; i++) {
                     77:                   j = bp->lelem.first + i;
                     78:                   if (j >= bp->lelem.nelem)
                     79:                      j -= bp->lelem.nelem;
                     80:                   dp = &bp->lelem.lslots[j];
                     81:                   arg0.type = D_VAR + ((int *)dp - (int *)bp);
                     82:                   VARLOC(arg0) = dp;
                     83:                   suspend();
                     84:                   bp = BLKLOC(arg1);   /* bp is untended, must reset */
                     85:                   }
                     86:                }
                     87:             break;
                     88: 
                     89: 
                     90:          case T_FILE:
                     91:             /*
                     92:              * x is a file.  Read the next line into the string space
                     93:              *  and suspend the newly allocated string.
                     94:              */
                     95:             fd = BLKLOC(arg1)->file.fd;
                     96:             if ((BLKLOC(arg1)->file.status & FS_READ) == 0)
                     97:                runerr(212, &arg1);
                     98:             while ((slen = getstr(sbuf,MAXSTRING,fd)) >= 0) {
                     99:                sneed(slen);
                    100:                STRLEN(arg0) = slen;
                    101:                STRLOC(arg0) = alcstr(sbuf,slen);
                    102:                suspend();
                    103:                }
                    104:             break;
                    105: 
                    106:          case T_TABLE:
                    107:             /*
                    108:              * x is a table.  Chain down the element list in each bucket
                    109:              *  and suspend a variable pointing to each element in turn.
                    110:              */
                    111:             for (i = 0; i < NBUCKETS; i++) {
                    112:                bp = BLKLOC(arg1);
                    113:                for (arg1v = bp->table.buckets[i]; arg1v.type == D_TELEM;
                    114:                     arg1v = BLKLOC(arg1v)->telem.blink) {
                    115:                   ep = BLKLOC(arg1v);
                    116:                   dp = &ep->telem.tval;
                    117:                   arg0.type = D_VAR + ((int *)dp - (int *)bp);
                    118:                   VARLOC(arg0) = dp;
                    119:                   suspend();
                    120:                   bp = BLKLOC(arg1);   /* bp is untended, must reset */
                    121:                   }
                    122:                }
                    123:             break;
                    124: 
                    125: #ifdef SETS
                    126:          case T_SET:
                    127:            /*
                    128:             *  This is similar to the method for tables except that a
                    129:             *  value is returned instead of a variable.
                    130:             */
                    131:                for(i = 0; i < NBUCKETS; i++) {
                    132:                   bp = BLKLOC(arg1);
                    133:                   for(arg1v = bp->set.sbucks[i]; arg1v.type == D_SELEM;
                    134:                      arg1v = BLKLOC(arg1v)->selem.sblink) {
                    135:                      arg0 = BLKLOC(arg1v)->selem.setmem;
                    136:                      suspend();
                    137:                     bp = BLKLOC(arg1); /* bp untended, must be reset */
                    138:                     }
                    139:                 }
                    140:                 break;
                    141: #endif SETS
                    142: 
                    143:          case T_RECORD:
                    144:             /*
                    145:              * x is a record.  Loop through the fields and suspend
                    146:              *  a variable pointing to each one.
                    147:              */
                    148:             bp = BLKLOC(arg1);
                    149:             j = bp->record.recptr->nfields;
                    150:             for (i = 0; i < j; i++) {
                    151:                dp = &bp->record.fields[i];
                    152:                arg0.type = D_VAR + ((int *)dp - (int *)bp);
                    153:                VARLOC(arg0) = dp;
                    154:                suspend();
                    155:                bp = BLKLOC(arg1);   /* bp is untended, must reset */
                    156:                }
                    157:             break;
                    158: 
                    159:          default: /* This object can not be compromised. */
                    160:             runerr(116, &arg1);
                    161:          }
                    162:       }
                    163: 
                    164:    /*
                    165:     * Eventually fail.
                    166:     */
                    167:    fail();
                    168:    }
                    169: 
                    170: Opblockx(bang,2,"!",1)

unix.superglobalmegacorp.com

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