Annotation of coherent/g/usr/bin/vi/tinyprnt.c, revision 1.1.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.