This source file includes following definitions.
- simple_strtoul
- skip_atoi
- number
- vsprintf
- sprintf
1
2
3
4
5
6
7
8
9
10
11
12 #include <stdarg.h>
13 #include <linux/types.h>
14 #include <linux/string.h>
15 #include <linux/ctype.h>
16
17 unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
18 {
19 unsigned long result = 0,value;
20
21 if (!base) {
22 base = 10;
23 if (*cp == '0') {
24 base = 8;
25 cp++;
26 if ((*cp == 'x') && isxdigit(cp[1])) {
27 cp++;
28 base = 16;
29 }
30 }
31 }
32 while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
33 ? toupper(*cp) : *cp)-'A'+10) < base) {
34 result = result*base + value;
35 cp++;
36 }
37 if (endp)
38 *endp = (char *)cp;
39 return result;
40 }
41
42
43 #define is_digit(c) ((c) >= '0' && (c) <= '9')
44
45 static int skip_atoi(const char **s)
46 {
47 int i=0;
48
49 while (is_digit(**s))
50 i = i*10 + *((*s)++) - '0';
51 return i;
52 }
53
54 #define ZEROPAD 1
55 #define SIGN 2
56 #define PLUS 4
57 #define SPACE 8
58 #define LEFT 16
59 #define SPECIAL 32
60 #define LARGE 64
61
62 #define do_div(n,base) ({ \
63 int __res; \
64 __res = ((unsigned long) n) % (unsigned) base; \
65 n = ((unsigned long) n) / (unsigned) base; \
66 __res; })
67
68 static char * number(char * str, long num, int base, int size, int precision
69 ,int type)
70 {
71 char c,sign,tmp[36];
72 const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
73 int i;
74
75 if (type & LARGE)
76 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
77 if (type & LEFT)
78 type &= ~ZEROPAD;
79 if (base < 2 || base > 36)
80 return 0;
81 c = (type & ZEROPAD) ? '0' : ' ';
82 sign = 0;
83 if (type & SIGN) {
84 if (num < 0) {
85 sign = '-';
86 num = -num;
87 size--;
88 } else if (type & PLUS) {
89 sign = '+';
90 size--;
91 } else if (type & SPACE) {
92 sign = ' ';
93 size--;
94 }
95 }
96 if (type & SPECIAL) {
97 if (base == 16)
98 size -= 2;
99 else if (base == 8)
100 size--;
101 }
102 i = 0;
103 if (num == 0)
104 tmp[i++]='0';
105 else while (num != 0)
106 tmp[i++] = digits[do_div(num,base)];
107 if (i > precision)
108 precision = i;
109 size -= precision;
110 if (!(type&(ZEROPAD+LEFT)))
111 while(size-->0)
112 *str++ = ' ';
113 if (sign)
114 *str++ = sign;
115 if (type & SPECIAL)
116 if (base==8)
117 *str++ = '0';
118 else if (base==16) {
119 *str++ = '0';
120 *str++ = digits[33];
121 }
122 if (!(type & LEFT))
123 while (size-- > 0)
124 *str++ = c;
125 while (i < precision--)
126 *str++ = '0';
127 while (i-- > 0)
128 *str++ = tmp[i];
129 while (size-- > 0)
130 *str++ = ' ';
131 return str;
132 }
133
134 int vsprintf(char *buf, const char *fmt, va_list args)
135 {
136 int len;
137 unsigned long num;
138 int i, base;
139 char * str;
140 char *s;
141
142 int flags;
143
144 int field_width;
145 int precision;
146
147 int qualifier;
148
149 for (str=buf ; *fmt ; ++fmt) {
150 if (*fmt != '%') {
151 *str++ = *fmt;
152 continue;
153 }
154
155
156 flags = 0;
157 repeat:
158 ++fmt;
159 switch (*fmt) {
160 case '-': flags |= LEFT; goto repeat;
161 case '+': flags |= PLUS; goto repeat;
162 case ' ': flags |= SPACE; goto repeat;
163 case '#': flags |= SPECIAL; goto repeat;
164 case '0': flags |= ZEROPAD; goto repeat;
165 }
166
167
168 field_width = -1;
169 if (is_digit(*fmt))
170 field_width = skip_atoi(&fmt);
171 else if (*fmt == '*') {
172
173 field_width = va_arg(args, int);
174 if (field_width < 0) {
175 field_width = -field_width;
176 flags |= LEFT;
177 }
178 }
179
180
181 precision = -1;
182 if (*fmt == '.') {
183 ++fmt;
184 if (is_digit(*fmt))
185 precision = skip_atoi(&fmt);
186 else if (*fmt == '*') {
187
188 precision = va_arg(args, int);
189 }
190 if (precision < 0)
191 precision = 0;
192 }
193
194
195 qualifier = -1;
196 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
197 qualifier = *fmt;
198 ++fmt;
199 }
200
201
202 base = 10;
203
204 switch (*fmt) {
205 case 'c':
206 if (!(flags & LEFT))
207 while (--field_width > 0)
208 *str++ = ' ';
209 *str++ = (unsigned char) va_arg(args, int);
210 while (--field_width > 0)
211 *str++ = ' ';
212 continue;
213
214 case 's':
215 s = va_arg(args, char *);
216 if (!s)
217 s = "<NULL>";
218 len = strlen(s);
219 if (precision < 0)
220 precision = len;
221 else if (len > precision)
222 len = precision;
223
224 if (!(flags & LEFT))
225 while (len < field_width--)
226 *str++ = ' ';
227 for (i = 0; i < len; ++i)
228 *str++ = *s++;
229 while (len < field_width--)
230 *str++ = ' ';
231 continue;
232
233 case 'p':
234 if (field_width == -1) {
235 field_width = 8;
236 flags |= ZEROPAD;
237 }
238 str = number(str,
239 (unsigned long) va_arg(args, void *), 16,
240 field_width, precision, flags);
241 continue;
242
243
244 case 'n':
245 if (qualifier == 'l') {
246 long * ip = va_arg(args, long *);
247 *ip = (str - buf);
248 } else {
249 int * ip = va_arg(args, int *);
250 *ip = (str - buf);
251 }
252 continue;
253
254
255 case 'o':
256 base = 8;
257 break;
258
259 case 'X':
260 flags |= LARGE;
261 case 'x':
262 base = 16;
263 break;
264
265 case 'd':
266 case 'i':
267 flags |= SIGN;
268 case 'u':
269 break;
270
271 default:
272 if (*fmt != '%')
273 *str++ = '%';
274 if (*fmt)
275 *str++ = *fmt;
276 else
277 --fmt;
278 continue;
279 }
280 if (qualifier == 'l')
281 num = va_arg(args, unsigned long);
282 else if (qualifier == 'h')
283 if (flags & SIGN)
284 num = va_arg(args, short);
285 else
286 num = va_arg(args, unsigned short);
287 else if (flags & SIGN)
288 num = va_arg(args, int);
289 else
290 num = va_arg(args, unsigned int);
291 str = number(str, num, base, field_width, precision, flags);
292 }
293 *str = '\0';
294 return str-buf;
295 }
296
297 int sprintf(char * buf, const char *fmt, ...)
298 {
299 va_list args;
300 int i;
301
302 va_start(args, fmt);
303 i=vsprintf(buf,fmt,args);
304 va_end(args);
305 return i;
306 }
307