Annotation of coherent/g/usr/bin/vi/tinyprnt.c, revision 1.1

1.1     ! root        1: /* tinyprnt.c */
        !             2: 
        !             3: #if OSK
        !             4: #define sprintf Sprintf
        !             5: #endif
        !             6: 
        !             7: /* This is a limited version of sprintf().  It is useful for Minix-PC and
        !             8:  * Coherent-286 because those systems are both limited to 64k+64k and the
        !             9:  * standard sprintf() is just too damn big.
        !            10:  *
        !            11:  * It should also be useful for OS-9 because OS-9's sprintf() doesn't
        !            12:  * understand the true meaning of asterisks in a format string.  This one
        !            13:  * does.
        !            14:  */
        !            15: 
        !            16: /* Place-holders in format strings look like "%<pad><clip><type>".
        !            17:  *
        !            18:  * The <pad> adds space to the front (or, if negative, to the back) of the
        !            19:  * output value, to pad it to a given width.  If <pad> is absent, then 0 is
        !            20:  * assumed.  If <pad> is an asterisk, then the next argument is assumed to
        !            21:  * be an (int) which used as the pad width.
        !            22:  *
        !            23:  * The <clip> string can be absent, in which case no clipping is done.
        !            24:  * However, if it is present, then it should be either a "." followed by
        !            25:  * a number, or a "." followed by an asterisk.  The asterisk means that the
        !            26:  * next argument is an (int) which should be used as the pad width.  Clipping
        !            27:  * only affects strings; for other data types it is ignored.
        !            28:  *
        !            29:  * The <type> is one of "s" for strings, "c" for characters (really ints that
        !            30:  * are assumed to be legal char values), "d" for ints, "ld" for long ints, or
        !            31:  * "%" to output a percent sign.
        !            32:  */
        !            33: 
        !            34: /* NOTE: Variable argument lists are handled by direct stack-twiddling. Sorry! */
        !            35: 
        !            36: static void cvtnum(buf, num, base)
        !            37:        char            *buf;   /* where to store the number */
        !            38:        unsigned long   num;    /* the number to convert */
        !            39:        int             base;   /* either 8, 10, or 16 */
        !            40: {
        !            41:        static char     digits[] = "0123456789abcdef";
        !            42:        unsigned long   tmp;
        !            43: 
        !            44:        /* if the number is 0, then just stuff a "0" into the buffer */
        !            45:        if (num == 0L)
        !            46:        {
        !            47:                buf[0] = '0';
        !            48:                buf[1] = '\0';
        !            49:                return;
        !            50:        }
        !            51: 
        !            52:        /* use tmp to figure out how many digits we'll need */
        !            53:        for (tmp = num; tmp > 0; tmp /= base)
        !            54:        {
        !            55:                buf++;
        !            56:        }
        !            57: 
        !            58:        /* mark the spot that will be the end of the string */
        !            59:        *buf = '\0';
        !            60: 
        !            61:        /* generate all digits, as needed */
        !            62:        for (tmp = num; tmp > 0; tmp /= base)
        !            63:        {
        !            64:                *--buf = digits[tmp % base];
        !            65:        }
        !            66: }
        !            67: 
        !            68: int sprintf(buf, fmt, argref)
        !            69:        char    *buf;   /* where to deposit the formatted output */
        !            70:        char    *fmt;   /* the format string */
        !            71:        int     argref; /* the first argument is located at &argref */
        !            72: {
        !            73:        char    *argptr;/* pointer to next argument on the stack */
        !            74:        int     pad;    /* value of the pad string */
        !            75:        int     clip;   /* value of the clip string */
        !            76:        long    num;    /* a binary number being converted to ASCII digits */
        !            77:        long    digit;  /* used during conversion */
        !            78:        char    *src, *dst;
        !            79: 
        !            80:        /* make argptr point to the first argument after the format string */
        !            81:        argptr = (char *)&argref;
        !            82: 
        !            83:        /* loop through the whole format string */
        !            84:        while (*fmt)
        !            85:        {
        !            86:                /* if not part of a place-holder, then copy it literally */
        !            87:                if (*fmt != '%')
        !            88:                {
        !            89:                        *buf++ = *fmt++;
        !            90:                        continue;
        !            91:                }
        !            92: 
        !            93:                /* found a place-holder!  Get <pad> value */
        !            94:                fmt++;
        !            95:                if ('*' == *fmt)
        !            96:                {
        !            97:                        pad = *((int *)argptr)++;
        !            98:                        fmt++;
        !            99:                }
        !           100:                else if (*fmt == '-' || (*fmt >= '0' && *fmt <= '9'))
        !           101:                {
        !           102:                        pad = atol(fmt);
        !           103:                        do
        !           104:                        {
        !           105:                                fmt++;
        !           106:                        } while (*fmt >= '0' && *fmt <= '9');
        !           107:                }
        !           108:                else
        !           109:                {
        !           110:                        pad = 0;
        !           111:                }
        !           112: 
        !           113:                /* get a <clip> value */
        !           114:                if (*fmt == '.')
        !           115:                {
        !           116:                        fmt++;
        !           117:                        if ('*' == *fmt)
        !           118:                        {
        !           119:                                clip = *((int *)argptr)++;
        !           120:                                fmt++;
        !           121:                        }
        !           122:                        else if (*fmt >= '0' && *fmt <= '9')
        !           123:                        {
        !           124:                                clip = atol(fmt);
        !           125:                                do
        !           126:                                {
        !           127:                                        fmt++;
        !           128:                                } while (*fmt >= '0' && *fmt <= '9');
        !           129:                        }
        !           130:                }
        !           131:                else
        !           132:                {
        !           133:                        clip = 0;
        !           134:                }
        !           135: 
        !           136:                /* handle <type>, possibly noticing <clip> */
        !           137:                switch (*fmt++)
        !           138:                {
        !           139:                  case 'c':
        !           140:                        buf[0] = *((int *)argptr)++;
        !           141:                        buf[1] = '\0';
        !           142:                        break;
        !           143: 
        !           144:                  case 's':
        !           145:                        src = *((char **)argptr)++;
        !           146:                        if (!src)
        !           147:                        {
        !           148:                                src = "(null)";
        !           149:                        }
        !           150:                        if (clip)
        !           151:                        {
        !           152:                                strncpy(buf, src, clip);
        !           153:                                buf[clip] = '\0';
        !           154:                        }
        !           155:                        else
        !           156:                        {
        !           157:                                strcpy(buf, src);
        !           158:                        }
        !           159:                        break;
        !           160: 
        !           161:                  case 'l':
        !           162:                        fmt++; /* to skip the "d" in "%ld" */
        !           163:                        num = *((long *)argptr)++;
        !           164:                        dst = buf;
        !           165:                        if (num < 0)
        !           166:                        {
        !           167:                                *dst++ = '-';
        !           168:                                num = -num;
        !           169:                        }
        !           170:                        cvtnum(dst, num, 10);
        !           171:                        break;
        !           172: 
        !           173:                  case 'x':
        !           174:                        num = *((int *)argptr)++;
        !           175:                        cvtnum(buf, num, 16);
        !           176:                        break;
        !           177: 
        !           178:                  case 'd':
        !           179:                        num = *((int *)argptr)++;
        !           180:                        dst = buf;
        !           181:                        if (num < 0)
        !           182:                        {
        !           183:                                *dst++ = '-';
        !           184:                                num = -num;
        !           185:                        }
        !           186:                        cvtnum(dst, num, 10);
        !           187:                        break;
        !           188: 
        !           189:                  default:
        !           190:                        buf[0] = fmt[-1];
        !           191:                        buf[1] = '\0';
        !           192:                }
        !           193: 
        !           194:                /* now fix the padding, if the value is too short */
        !           195:                clip = strlen(buf);
        !           196:                if (pad < 0)
        !           197:                {
        !           198:                        /* add spaces after the value */
        !           199:                        pad = -pad - clip;
        !           200:                        for (buf += clip; pad > 0; pad--)
        !           201:                        {
        !           202:                                *buf++ = ' ';
        !           203:                        }
        !           204:                        *buf = '\0';
        !           205:                }
        !           206:                else
        !           207:                {
        !           208:                        /* add spaces before the value */
        !           209:                        pad -= clip;
        !           210:                        if (pad > 0)
        !           211:                        {
        !           212:                                src = buf + clip;
        !           213:                                dst = src + pad;
        !           214:                                *dst = '\0';
        !           215:                                while (src > buf)
        !           216:                                {
        !           217:                                        *--dst = *--src;
        !           218:                                }
        !           219:                                while (dst > buf)
        !           220:                                {
        !           221:                                        *--dst = ' ';
        !           222:                                }
        !           223:                        }
        !           224:                        buf += strlen(buf);
        !           225:                }
        !           226:        }
        !           227: 
        !           228:        /* mark the end of the output string */
        !           229:        *buf = '\0';
        !           230: }

unix.superglobalmegacorp.com

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