Annotation of 43BSD/contrib/icon/functions/image.c, revision 1.1

1.1     ! root        1: #include "../h/rt.h"
        !             2: #include "../h/record.h"
        !             3: 
        !             4: /*
        !             5:  * image(x) - return string image of object x.  Nothing fancy here,
        !             6:  *  just plug and chug on a case-wise basis.
        !             7:  */
        !             8: 
        !             9: Ximage(nargs, arg1, arg0)
        !            10: int nargs;
        !            11: struct descrip arg1, arg0;
        !            12:    {
        !            13:    register int len, outlen, rnlen;
        !            14:    register char *s;
        !            15:    register union block *bp;
        !            16:    char *type;
        !            17:    extern char *alcstr();
        !            18:    extern struct descrip *cstos();
        !            19:    char sbuf[MAXSTRING];
        !            20:    FILE *fd;
        !            21: 
        !            22:    DeRef(arg1)
        !            23: 
        !            24:    if (NULLDESC(arg1)) {       /* &null */
        !            25:       STRLOC(arg0) = "&null";
        !            26:       STRLEN(arg0) = 5;
        !            27:       return;
        !            28:       }
        !            29: 
        !            30:    if (QUAL(arg1)) {
        !            31:       /*
        !            32:        * Get some string space.  The magic 2 is for the double quote at each
        !            33:        *  end of the resulting string.
        !            34:        */
        !            35:       sneed(prescan(&arg1) + 2);
        !            36:       len = STRLEN(arg1);
        !            37:       s = STRLOC(arg1);
        !            38:       outlen = 2;
        !            39:       /*
        !            40:        * Form the image by putting a " in the string space, calling
        !            41:        *  doimage with each character in the string, and then putting
        !            42:        *  a " at then end.  Note that doimage directly writes into the
        !            43:        *  string space.  (Hence the indentation.)  This techinique is used
        !            44:        *  several times in this routine.
        !            45:        */
        !            46:       STRLOC(arg0) = alcstr("\"", 1);
        !            47:                      while (len-- > 0)
        !            48:                          outlen += doimage(*s++, '"');
        !            49:                          alcstr("\"", 1);
        !            50:       STRLEN(arg0) = outlen;
        !            51:       return;
        !            52:       }
        !            53: 
        !            54:    switch (TYPE(arg1)) {
        !            55:       case T_INTEGER:
        !            56: #ifdef LONGS
        !            57:       case T_LONGINT:
        !            58: #endif LONGS
        !            59:       case T_REAL:
        !            60:          /*
        !            61:           * Form a string representing the number and allocate it.
        !            62:           */
        !            63:          cvstr(&arg1, sbuf);
        !            64:          len = STRLEN(arg1);
        !            65:          sneed(len);
        !            66:          STRLOC(arg0) = alcstr(STRLOC(arg1), len);
        !            67:          STRLEN(arg0) = len;
        !            68:          return;
        !            69: 
        !            70:       case T_CSET:
        !            71:          /*
        !            72:           * Check for distinguished csets by looking at the address of
        !            73:           *  of the object to image.  If one is found, make a string
        !            74:           *  naming it and return.
        !            75:           */
        !            76:          if (BLKLOC(arg1) == ((union block *) &k_ascii)) {
        !            77:             STRLOC(arg0) = "&ascii";
        !            78:             STRLEN(arg0) = 6;
        !            79:             return;
        !            80:             }
        !            81:          else if (BLKLOC(arg1) == ((union block *) &k_cset)) {
        !            82:             STRLOC(arg0) = "&cset";
        !            83:             STRLEN(arg0) = 5;
        !            84:             return;
        !            85:             }
        !            86:          else if (BLKLOC(arg1) == ((union block *) &k_lcase)) {
        !            87:             STRLOC(arg0) = "&lcase";
        !            88:             STRLEN(arg0) = 6;
        !            89:             return;
        !            90:             }
        !            91:          else if (BLKLOC(arg1) == ((union block *) &k_ucase)) {
        !            92:             STRLOC(arg0) = "&ucase";
        !            93:             STRLEN(arg0) = 6;
        !            94:             return;
        !            95:             }
        !            96:          /*
        !            97:           * Convert the cset to a string and proceed as is done for
        !            98:           *  string images but use a ' rather than " to bound the
        !            99:           *  result string.
        !           100:           */
        !           101:          cvstr(&arg1, sbuf);
        !           102:          sneed(prescan(&arg1) + 2);
        !           103:          len = STRLEN(arg1);
        !           104:          s = STRLOC(arg1);
        !           105:          outlen = 2;
        !           106:          STRLOC(arg0) = alcstr("'", 1);
        !           107:                         while (len-- > 0)
        !           108:                             outlen += doimage(*s++, '\'');
        !           109:                         alcstr("'", 1);
        !           110:          STRLEN(arg0) = outlen;
        !           111:          return;
        !           112: 
        !           113:       case T_FILE:
        !           114:          /*
        !           115:           * Check for distinguished files by looking at the address of
        !           116:           *  of the object to image.  If one is found, make a string
        !           117:           *  naming it and return.
        !           118:           */
        !           119:          if ((fd = BLKLOC(arg1)->file.fd) == stdin) {
        !           120:             STRLEN(arg0) = 6;
        !           121:             STRLOC(arg0) = "&input";
        !           122:             }
        !           123:          else if (fd == stdout) {
        !           124:             STRLEN(arg0) = 7;
        !           125:             STRLOC(arg0) = "&output";
        !           126:             }
        !           127:          else if (fd == stderr) {
        !           128:             STRLEN(arg0) = 7;
        !           129:             STRLOC(arg0) = "&errout";
        !           130:             }
        !           131:          else {
        !           132:             /*
        !           133:              * The file is not a standard one, form a string of the form
        !           134:              *  file(nm) where nm is the argument originally given to
        !           135:              *  open.
        !           136:              */
        !           137:             sneed(prescan(&BLKLOC(arg1)->file.fname)+6);
        !           138:             len = STRLEN(BLKLOC(arg1)->file.fname);
        !           139:             s = STRLOC(BLKLOC(arg1)->file.fname);
        !           140:             outlen = 6;
        !           141:             STRLOC(arg0) = alcstr("file(", 5);
        !           142:                            while (len-- > 0)
        !           143:                               outlen += doimage(*s++, '\0');
        !           144:                            alcstr(")", 1);
        !           145:             STRLEN(arg0) = outlen;
        !           146:             }
        !           147:          return;
        !           148: 
        !           149:       case T_PROC:
        !           150:          /*
        !           151:           * Produce one of:
        !           152:           *  "procedure name"
        !           153:           *  "function name"
        !           154:           *  "record constructor name"
        !           155:           *
        !           156:           * Note that the number of dynamic locals is used to determine
        !           157:           *  what type of "procedure" is at hand.
        !           158:           */
        !           159:          len = STRLEN(BLKLOC(arg1)->proc.pname);
        !           160:          s = STRLOC(BLKLOC(arg1)->proc.pname);
        !           161:          switch (BLKLOC(arg1)->proc.ndynam) {
        !           162:             default:  type = "procedure "; break;
        !           163:             case -1:  type = "function "; break;
        !           164:             case -2:  type = "record constructor "; break;
        !           165:             }
        !           166:          outlen = strlen(type);
        !           167:          sneed(len + outlen);
        !           168:          STRLOC(arg0) = alcstr(type, outlen);
        !           169:                         alcstr(s, len);
        !           170:          STRLEN(arg0) = len + outlen;
        !           171:          return;
        !           172: 
        !           173:       case T_LIST:
        !           174:          /*
        !           175:           * Produce:
        !           176:           *  "list(n)"
        !           177:           * where n is the current size of the list.
        !           178:           */
        !           179:          bp = BLKLOC(arg1);
        !           180:          sprintf(sbuf, "list(%d)", bp->list.cursize);
        !           181:          len = strlen(sbuf);
        !           182:          sneed(len);
        !           183:          STRLOC(arg0) = alcstr(sbuf, len);
        !           184:          STRLEN(arg0) = len;
        !           185:          return;
        !           186: 
        !           187:       case T_LELEM:
        !           188:          STRLEN(arg0) = 18;
        !           189:          STRLOC(arg0) = "list element block";
        !           190:          return;
        !           191: 
        !           192:       case T_TABLE:
        !           193:          /*
        !           194:           * Produce:
        !           195:           *  "table(n)"
        !           196:           * where n is the size of the table.
        !           197:           */
        !           198:          bp = BLKLOC(arg1);
        !           199:          sprintf(sbuf, "table(%d)", bp->table.cursize);
        !           200:          len = strlen(sbuf);
        !           201:          sneed(len);
        !           202:          STRLOC(arg0) = alcstr(sbuf, len);
        !           203:          STRLEN(arg0) = len;
        !           204:          return;
        !           205: 
        !           206:       case T_TELEM:
        !           207:          STRLEN(arg0) = 19;
        !           208:          STRLOC(arg0) = "table element block";
        !           209:          return;
        !           210: 
        !           211: #ifdef SETS
        !           212:       case T_SET:
        !           213:          /*
        !           214:           * Produce "set(n)" where n is size of the set.
        !           215:           */
        !           216:          bp = BLKLOC(arg1);
        !           217:          sprintf(sbuf, "set(%d)", bp->set.setsize);
        !           218:          len = strlen(sbuf);
        !           219:          sneed(len);
        !           220:          STRLOC(arg0) = alcstr(sbuf,len);
        !           221:          STRLEN(arg0) = len;
        !           222:          return;
        !           223: 
        !           224:       case T_SELEM:
        !           225:          STRLEN(arg0) = 17;
        !           226:          STRLOC(arg0) = "set element block";
        !           227:          return;
        !           228: #endif SETS
        !           229: 
        !           230:       case T_RECORD:
        !           231:          /*
        !           232:           * Produce:
        !           233:           *  "record name(n)"
        !           234:           * where n is the number of fields.
        !           235:           */
        !           236:          bp = BLKLOC(arg1);
        !           237:          rnlen = STRLEN(bp->record.recptr->recname);
        !           238:          sneed(15 + rnlen);    /* 15 = *"record " + *"(nnnnnn)" */
        !           239:          bp = BLKLOC(arg1);
        !           240:          sprintf(sbuf, "(%d)", bp->record.recptr->nfields);
        !           241:          len = strlen(sbuf);
        !           242:          STRLOC(arg0) = alcstr("record ", 7);
        !           243:                         alcstr(STRLOC(bp->record.recptr->recname),
        !           244:                                rnlen);
        !           245:                         alcstr(sbuf, len);
        !           246:          STRLEN(arg0) = 7 + len + rnlen;
        !           247:          return;
        !           248: 
        !           249:       case T_ESTACK:
        !           250:          /*
        !           251:           * Produce:
        !           252:           *  "co-expression(n)"
        !           253:           * where n is the number of results that have been produced.
        !           254:           */
        !           255:          sneed(22);
        !           256:          sprintf(sbuf, "(%d)", BLKLOC(arg1)->estack.nresults);
        !           257:          len = strlen(sbuf);
        !           258:          STRLOC(arg0) = alcstr("co-expression", 13);
        !           259:                         alcstr(sbuf, len);
        !           260:          STRLEN(arg0) = 13 + len;
        !           261:          return;
        !           262: 
        !           263:       default:
        !           264:          syserr("image: unknown type.");
        !           265:       }
        !           266:    }
        !           267: 
        !           268: Procblock(image,1)
        !           269: 
        !           270: /*
        !           271:  * doimage(c,q) - allocate character c in string space, with escape
        !           272:  *  conventions if c is unprintable, '\', or equal to q.
        !           273:  *  Returns number of characters allocated.
        !           274:  */
        !           275: 
        !           276: doimage(c, q)
        !           277: int c, q;
        !           278:    {
        !           279:    static char *cbuf = "\\\0\0\0";
        !           280:    extern char *alcstr();
        !           281: 
        !           282:    if (c >= ' ' && c < '\177') {
        !           283:       /*
        !           284:        * c is printable, but special case ", ', and \.
        !           285:        */
        !           286:       switch (c) {
        !           287:          case '"':
        !           288:             if (c != q) goto def;
        !           289:             alcstr("\\\"", 2);
        !           290:             return (2);
        !           291:          case '\'':
        !           292:             if (c != q) goto def;
        !           293:             alcstr("\\'", 2);
        !           294:             return (2);
        !           295:          case '\\':
        !           296:             alcstr("\\\\", 2);
        !           297:             return (2);
        !           298:          default:
        !           299:          def:
        !           300:             cbuf[0] = c;
        !           301:             cbuf[1] = '\0';
        !           302:             alcstr(cbuf,1);
        !           303:             return (1);
        !           304:          }
        !           305:       }
        !           306: 
        !           307:    /*
        !           308:     * c is some sort of unprintable character.  If it is one of the common
        !           309:     *  ones, produce a special representation for it, otherwise, produce
        !           310:     *  its octal value.
        !           311:     */
        !           312:    switch (c) {
        !           313:       case '\b':                       /*      backspace    */
        !           314:          alcstr("\\b", 2);
        !           315:          return (2);
        !           316:       case '\177':                     /*      delete       */
        !           317:          alcstr("\\d", 2);
        !           318:          return (2);
        !           319:       case '\33':                      /*      escape       */
        !           320:          alcstr("\\e", 2);
        !           321:          return (2);
        !           322:       case '\f':                       /*      form feed    */
        !           323:          alcstr("\\f", 2);
        !           324:          return (2);
        !           325:       case '\n':                       /*      new line     */
        !           326:          alcstr("\\n", 2);
        !           327:          return (2);
        !           328:       case '\r':                       /*      return       */
        !           329:          alcstr("\\r", 2);
        !           330:          return (2);
        !           331:       case '\t':                       /*      horizontal tab     */
        !           332:          alcstr("\\t", 2);
        !           333:          return (2);
        !           334:       case '\13':                      /*      vertical tab     */
        !           335:          alcstr("\\v", 2);
        !           336:          return (2);
        !           337:       default:                         /*      octal constant  */
        !           338:          cbuf[0] = '\\';
        !           339:          cbuf[1] = ((c&0300) >> 6) + '0';
        !           340:          cbuf[2] = ((c&070) >> 3) + '0';
        !           341:          cbuf[3] = (c&07) + '0';
        !           342:          alcstr(cbuf, 4);
        !           343:          return (4);
        !           344:       }
        !           345:    }
        !           346: 
        !           347: /*
        !           348:  * prescan(d) - return upper bound on length of expanded string.  Note
        !           349:  *  that the only time that prescan is wrong is when the string contains
        !           350:  *  one of the "special" unprintable characters, e.g. tab.
        !           351:  */
        !           352: prescan(d)
        !           353: struct descrip *d;
        !           354:    {
        !           355:    register int slen, len;
        !           356:    register char *s, c;
        !           357: 
        !           358:    s = STRLOC(*d);
        !           359:    len = 0;
        !           360:    for (slen = STRLEN(*d); slen > 0; slen--)
        !           361:       if ((c = (*s++)) < ' ' || c >= 0177)
        !           362:          len += 4;
        !           363:       else if (c == '"' || c == '\\' || c == '\'')
        !           364:          len += 2;
        !           365:       else
        !           366:          len++;
        !           367: 
        !           368:    return (len);
        !           369:    }

unix.superglobalmegacorp.com

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