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 ++fmt;
173
174 field_width = va_arg(args, int);
175 if (field_width < 0) {
176 field_width = -field_width;
177 flags |= LEFT;
178 }
179 }
180
181
182 precision = -1;
183 if (*fmt == '.') {
184 ++fmt;
185 if (is_digit(*fmt))
186 precision = skip_atoi(&fmt);
187 else if (*fmt == '*') {
188 ++fmt;
189
190 precision = va_arg(args, int);
191 }
192 if (precision < 0)
193 precision = 0;
194 }
195
196
197 qualifier = -1;
198 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
199 qualifier = *fmt;
200 ++fmt;
201 }
202
203
204 base = 10;
205
206 switch (*fmt) {
207 case 'c':
208 if (!(flags & LEFT))
209 while (--field_width > 0)
210 *str++ = ' ';
211 *str++ = (unsigned char) va_arg(args, int);
212 while (--field_width > 0)
213 *str++ = ' ';
214 continue;
215
216 case 's':
217 s = va_arg(args, char *);
218 if (!s)
219 s = "<NULL>";
220 len = strlen(s);
221 if (precision < 0)
222 precision = len;
223 else if (len > precision)
224 len = precision;
225
226 if (!(flags & LEFT))
227 while (len < field_width--)
228 *str++ = ' ';
229 for (i = 0; i < len; ++i)
230 *str++ = *s++;
231 while (len < field_width--)
232 *str++ = ' ';
233 continue;
234
235 case 'p':
236 if (field_width == -1) {
237 field_width = 2*sizeof(void *);
238 flags |= ZEROPAD;
239 }
240 str = number(str,
241 (unsigned long) va_arg(args, void *), 16,
242 field_width, precision, flags);
243 continue;
244
245
246 case 'n':
247 if (qualifier == 'l') {
248 long * ip = va_arg(args, long *);
249 *ip = (str - buf);
250 } else {
251 int * ip = va_arg(args, int *);
252 *ip = (str - buf);
253 }
254 continue;
255
256
257 case 'o':
258 base = 8;
259 break;
260
261 case 'X':
262 flags |= LARGE;
263 case 'x':
264 base = 16;
265 break;
266
267 case 'd':
268 case 'i':
269 flags |= SIGN;
270 case 'u':
271 break;
272
273 default:
274 if (*fmt != '%')
275 *str++ = '%';
276 if (*fmt)
277 *str++ = *fmt;
278 else
279 --fmt;
280 continue;
281 }
282 if (qualifier == 'l')
283 num = va_arg(args, unsigned long);
284 else if (qualifier == 'h')
285 if (flags & SIGN)
286 num = va_arg(args, short);
287 else
288 num = va_arg(args, unsigned short);
289 else if (flags & SIGN)
290 num = va_arg(args, int);
291 else
292 num = va_arg(args, unsigned int);
293 str = number(str, num, base, field_width, precision, flags);
294 }
295 *str = '\0';
296 return str-buf;
297 }
298
299 int sprintf(char * buf, const char *fmt, ...)
300 {
301 va_list args;
302 int i;
303
304 va_start(args, fmt);
305 i=vsprintf(buf,fmt,args);
306 va_end(args);
307 return i;
308 }
309