Annotation of 43BSD/contrib/icon/operators/bang.c, revision 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.