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[66];
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 const 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
221 len = strnlen(s, precision);
222
223 if (!(flags & LEFT))
224 while (len < field_width--)
225 *str++ = ' ';
226 for (i = 0; i < len; ++i)
227 *str++ = *s++;
228 while (len < field_width--)
229 *str++ = ' ';
230 continue;
231
232 case 'p':
233 if (field_width == -1) {
234 field_width = 2*sizeof(void *);
235 flags |= ZEROPAD;
236 }
237 str = number(str,
238 (unsigned long) va_arg(args, void *), 16,
239 field_width, precision, flags);
240 continue;
241
242
243 case 'n':
244 if (qualifier == 'l') {
245 long * ip = va_arg(args, long *);
246 *ip = (str - buf);
247 } else {
248 int * ip = va_arg(args, int *);
249 *ip = (str - buf);
250 }
251 continue;
252
253
254 case 'o':
255 base = 8;
256 break;
257
258 case 'X':
259 flags |= LARGE;
260 case 'x':
261 base = 16;
262 break;
263
264 case 'd':
265 case 'i':
266 flags |= SIGN;
267 case 'u':
268 break;
269
270 default:
271 if (*fmt != '%')
272 *str++ = '%';
273 if (*fmt)
274 *str++ = *fmt;
275 else
276 --fmt;
277 continue;
278 }
279 if (qualifier == 'l')
280 num = va_arg(args, unsigned long);
281 else if (qualifier == 'h')
282 if (flags & SIGN)
283 num = va_arg(args, short);
284 else
285 num = va_arg(args, unsigned short);
286 else if (flags & SIGN)
287 num = va_arg(args, int);
288 else
289 num = va_arg(args, unsigned int);
290 str = number(str, num, base, field_width, precision, flags);
291 }
292 *str = '\0';
293 return str-buf;
294 }
295
296 int sprintf(char * buf, const char *fmt, ...)
297 {
298 va_list args;
299 int i;
300
301 va_start(args, fmt);
302 i=vsprintf(buf,fmt,args);
303 va_end(args);
304 return i;
305 }
306