root / prex-0.9.0 / sys / lib / vsprintf.c @ 03e9c04a
History | View | Annotate | Download (3.32 KB)
1 |
/*-
|
---|---|
2 |
* Copyright (c) 2005, Kohsuke Ohtani
|
3 |
* All rights reserved.
|
4 |
*
|
5 |
* Redistribution and use in source and binary forms, with or without
|
6 |
* modification, are permitted provided that the following conditions
|
7 |
* are met:
|
8 |
* 1. Redistributions of source code must retain the above copyright
|
9 |
* notice, this list of conditions and the following disclaimer.
|
10 |
* 2. Redistributions in binary form must reproduce the above copyright
|
11 |
* notice, this list of conditions and the following disclaimer in the
|
12 |
* documentation and/or other materials provided with the distribution.
|
13 |
* 3. Neither the name of the author nor the names of any co-contributors
|
14 |
* may be used to endorse or promote products derived from this software
|
15 |
* without specific prior written permission.
|
16 |
*
|
17 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
18 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
21 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
22 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
23 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
24 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
26 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
27 |
* SUCH DAMAGE.
|
28 |
*/
|
29 |
|
30 |
/*
|
31 |
* vsprintf.c - Format and output data to buffer
|
32 |
*/
|
33 |
|
34 |
#include <kernel.h> |
35 |
|
36 |
#define isdigit(c) ((u_int)((c) - '0') < 10) |
37 |
|
38 |
static u_long
|
39 |
divide(long *n, int base) |
40 |
{ |
41 |
u_long res; |
42 |
|
43 |
res = ((u_long)*n) % base; |
44 |
*n = (long)(((u_long)*n) / base);
|
45 |
return res;
|
46 |
} |
47 |
|
48 |
static int |
49 |
atoi(const char **s) |
50 |
{ |
51 |
int i = 0; |
52 |
while (isdigit((int)**s)) |
53 |
i = i * 10 + *((*s)++) - '0'; |
54 |
return i;
|
55 |
} |
56 |
|
57 |
/*
|
58 |
* Print formatted output - scaled down version
|
59 |
*
|
60 |
* Identifiers:
|
61 |
* %d - Decimal signed int
|
62 |
* %x - Hex integer
|
63 |
* %u - Unsigned integer
|
64 |
* %c - Character
|
65 |
* %s - String
|
66 |
*
|
67 |
* Flags:
|
68 |
* 0 - Zero pad
|
69 |
*/
|
70 |
int
|
71 |
vsprintf(char *buf, const char *fmt, va_list args) |
72 |
{ |
73 |
char *p, *str;
|
74 |
const char *digits = "0123456789abcdef"; |
75 |
char pad, tmp[16]; |
76 |
int width, base, sign, i;
|
77 |
long num;
|
78 |
|
79 |
for (p = buf; *fmt; fmt++) {
|
80 |
if (*fmt != '%') { |
81 |
*p++ = *fmt; |
82 |
continue;
|
83 |
} |
84 |
/* get flags */
|
85 |
++fmt; |
86 |
pad = ' ';
|
87 |
if (*fmt == '0') { |
88 |
pad = '0';
|
89 |
fmt++; |
90 |
} |
91 |
/* get width */
|
92 |
width = -1;
|
93 |
if (isdigit(*fmt)) {
|
94 |
width = atoi(&fmt); |
95 |
} |
96 |
/* ignore long */
|
97 |
if (*fmt == 'l') |
98 |
fmt++; |
99 |
base = 10;
|
100 |
sign = 0;
|
101 |
switch (*fmt) {
|
102 |
case 'c': |
103 |
*p++ = (char)va_arg(args, int); |
104 |
continue;
|
105 |
case 's': |
106 |
str = va_arg(args, char *);
|
107 |
if (str == NULL) |
108 |
str = "<NULL>";
|
109 |
for (; *str && width != 0; str++, width--) { |
110 |
*p++ = *str; |
111 |
} |
112 |
while (width-- > 0) |
113 |
*p++ = pad; |
114 |
continue;
|
115 |
case 'X': |
116 |
case 'x': |
117 |
base = 16;
|
118 |
break;
|
119 |
case 'd': |
120 |
sign = 1;
|
121 |
break;
|
122 |
case 'u': |
123 |
break;
|
124 |
default:
|
125 |
continue;
|
126 |
} |
127 |
num = va_arg(args, long);
|
128 |
if (sign && num < 0) { |
129 |
num = -num; |
130 |
*p++ = '-';
|
131 |
width--; |
132 |
} |
133 |
i = 0;
|
134 |
if (num == 0) |
135 |
tmp[i++] = '0';
|
136 |
else
|
137 |
while (num != 0) |
138 |
tmp[i++] = digits[divide(&num, base)]; |
139 |
width -= i; |
140 |
while (width-- > 0) |
141 |
*p++ = pad; |
142 |
while (i-- > 0) |
143 |
*p++ = tmp[i]; |
144 |
} |
145 |
*p = '\0';
|
146 |
return 0; |
147 |
} |