4 #define sprintf Sprintf
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.
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
16 /* Place-holders in format strings look like "%<pad><clip><type>".
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.
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.
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.
34 /* NOTE: Variable argument lists are handled by direct stack-twiddling. Sorry! */
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 */
41 static char digits
[] = "0123456789abcdef";
44 /* if the number is 0, then just stuff a "0" into the buffer */
52 /* use tmp to figure out how many digits we'll need */
53 for (tmp
= num
; tmp
> 0; tmp
/= base
)
58 /* mark the spot that will be the end of the string */
61 /* generate all digits, as needed */
62 for (tmp
= num
; tmp
> 0; tmp
/= base
)
64 *--buf
= digits
[tmp
% base
];
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 */
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 */
80 /* make argptr point to the first argument after the format string */
81 argptr
= (char *)&argref
;
83 /* loop through the whole format string */
86 /* if not part of a place-holder, then copy it literally */
93 /* found a place-holder! Get <pad> value */
97 pad
= *((int *)argptr
)++;
100 else if (*fmt
== '-' || (*fmt
>= '0' && *fmt
<= '9'))
106 } while (*fmt
>= '0' && *fmt
<= '9');
113 /* get a <clip> value */
119 clip
= *((int *)argptr
)++;
122 else if (*fmt
>= '0' && *fmt
<= '9')
128 } while (*fmt
>= '0' && *fmt
<= '9');
136 /* handle <type>, possibly noticing <clip> */
140 buf
[0] = *((int *)argptr
)++;
145 src
= *((char **)argptr
)++;
152 strncpy(buf
, src
, clip
);
162 fmt
++; /* to skip the "d" in "%ld" */
163 num
= *((long *)argptr
)++;
170 cvtnum(dst
, num
, 10);
174 num
= *((int *)argptr
)++;
175 cvtnum(buf
, num
, 16);
179 num
= *((int *)argptr
)++;
186 cvtnum(dst
, num
, 10);
194 /* now fix the padding, if the value is too short */
198 /* add spaces after the value */
200 for (buf
+= clip
; pad
> 0; pad
--)
208 /* add spaces before the value */
228 /* mark the end of the output string */