Mercurial > lcfOS
annotate cos/kernel/snprintf.c @ 18:6129643f5c34
Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
author | windel |
---|---|
date | Sun, 20 Nov 2011 20:35:51 +0100 |
parents | f3e3e0e9c4bc |
children | 8012221dd740 |
rev | line source |
---|---|
9 | 1 /* |
2 * snprintf.c | |
3 */ | |
4 #include "kernel.h" | |
5 | |
13 | 6 /* |
7 * NOTE! This ctype does not handle EOF like the standard C | |
8 * library is required to. | |
9 */ | |
10 | |
11 #define _U 0x01 /* upper */ | |
12 #define _L 0x02 /* lower */ | |
13 #define _D 0x04 /* digit */ | |
14 #define _C 0x08 /* cntrl */ | |
15 #define _P 0x10 /* punct */ | |
16 #define _S 0x20 /* white space (space/lf/tab) */ | |
17 #define _X 0x40 /* hex digit */ | |
18 #define _SP 0x80 /* hard space (0x20) */ | |
19 | |
9 | 20 |
17 | 21 uint8_t _ctype[] = { |
9 | 22 _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ |
23 _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ | |
24 _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ | |
25 _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ | |
26 _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ | |
27 _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ | |
28 _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ | |
29 _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ | |
30 _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ | |
31 _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ | |
32 _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ | |
33 _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ | |
34 _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ | |
35 _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ | |
36 _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ | |
37 _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ | |
38 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ | |
39 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ | |
40 _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ | |
41 _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ | |
42 _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ | |
43 _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ | |
44 _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ | |
45 _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ | |
46 | |
17 | 47 #define __ismask(x) (_ctype[(int)(uint8_t)(x)]) |
13 | 48 |
49 #define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) | |
50 #define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) | |
51 #define iscntrl(c) ((__ismask(c)&(_C)) != 0) | |
52 #define isdigit(c) ((__ismask(c)&(_D)) != 0) | |
53 #define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) | |
54 #define islower(c) ((__ismask(c)&(_L)) != 0) | |
55 #define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) | |
56 #define ispunct(c) ((__ismask(c)&(_P)) != 0) | |
57 #define isspace(c) ((__ismask(c)&(_S)) != 0) | |
58 #define isupper(c) ((__ismask(c)&(_U)) != 0) | |
59 #define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) | |
60 | |
61 #define isascii(c) (((unsigned char)(c))<=0x7f) | |
62 #define toascii(c) (((unsigned char)(c))&0x7f) | |
63 | |
17 | 64 static inline uint8_t tolower(uint8_t c) |
13 | 65 { |
66 if (isupper(c)) | |
67 c -= 'A'-'a'; | |
68 return c; | |
69 } | |
70 | |
17 | 71 static inline uint8_t toupper(uint8_t c) |
13 | 72 { |
73 if (islower(c)) | |
74 c -= 'a'-'A'; | |
75 return c; | |
76 } | |
9 | 77 |
78 #define MORE_THAN_YOU_WANT 1<<30 | |
79 #define MAX_STDOUT_CHARS 255 | |
80 | |
81 static char hexmap[] = { | |
82 '0', '1', '2', '3', '4', '5', '6', '7', | |
83 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' | |
84 }; | |
85 | |
86 void va_snprintf(char *b, int l, const char *fmt, va_list pvar) | |
87 { | |
88 int n, i; | |
17 | 89 uint32_t u; |
90 uint64_t ull; | |
9 | 91 char *t; |
92 char d[10]; | |
93 char mod_l; | |
94 char mod_ll; | |
95 | |
96 if (!fmt || !b || (l < 1)) | |
97 return; | |
98 | |
99 mod_l = 0; | |
100 mod_ll = 0; | |
101 | |
102 while (l && *fmt) { | |
103 if (*fmt == '%') { | |
104 if (!(--l)) | |
105 break; | |
106 again: | |
107 fmt++; | |
108 | |
109 switch (*fmt) { | |
110 case '.': /* precision modifier */ | |
111 while(isdigit(fmt[1])) | |
112 fmt++; | |
113 goto again; | |
114 | |
115 case 'l': /* long modifier */ | |
116 if (!mod_l) { | |
117 mod_l = 1; | |
118 } else if (!mod_ll) { | |
119 mod_l = 0; | |
120 mod_ll = 1; | |
121 } | |
122 goto again; | |
123 | |
124 case 's': /* string */ | |
125 t = va_arg(pvar, char *); | |
126 while (l && *t) | |
127 *b++ = *t++, l--; | |
128 break; | |
129 | |
130 case 'c': /* single character */ | |
18
6129643f5c34
Fixed interrupt issue, ds, es, ss, fs and gs were not initialized to 0
windel
parents:
17
diff
changeset
|
131 *b++ = (char)va_arg(pvar, int); |
9 | 132 l--; |
133 break; | |
134 | |
135 case 'S': /* uint32 as a short ... */ | |
136 if (l < 4) { | |
137 l = 0; | |
138 break; | |
139 } | |
140 u = va_arg(pvar, unsigned int); | |
141 for (i = 3; i >= 0; i--) { | |
142 b[i] = hexmap[u & 0x0F]; | |
143 u >>= 4; | |
144 } | |
145 b += 4; | |
146 l -= 4; | |
147 break; | |
148 | |
149 case 'x': | |
150 case 'p': | |
151 if (!mod_ll) { /* 8 digit, unsigned 32-bit hex integer */ | |
152 if (l < 8) { | |
153 l = 0; | |
154 break; | |
155 } | |
156 u = va_arg(pvar, unsigned int); | |
157 for (i = 7; i >= 0; i--) { | |
158 b[i] = hexmap[u & 0x0F]; | |
159 u >>= 4; | |
160 } | |
161 b += 8; | |
162 l -= 8; | |
163 } else if (mod_ll) { /* 16 digit, unsigned 64-bit hex integer */ | |
164 if (l < 16) { | |
165 l = 0; | |
166 break; | |
167 } | |
17 | 168 ull = va_arg(pvar, uint64_t); |
9 | 169 for (i = 15; i >= 0; i--) { |
170 b[i] = hexmap[ull & 0x0f]; | |
171 ull >>= 4; | |
172 } | |
173 b += 16; | |
174 l -= 16; | |
175 } | |
176 mod_l = mod_ll = 0; | |
177 break; | |
178 | |
179 case 'd': /* signed integer */ | |
180 n = va_arg(pvar, int); | |
181 if (n < 0) { | |
182 u = -n; | |
183 *b++ = '-'; | |
184 if (!(--l)) | |
185 break; | |
186 } else { | |
187 u = n; | |
188 } | |
189 goto u2; | |
190 | |
191 case 'u': /* unsigned integer */ | |
192 u = va_arg(pvar, unsigned int); | |
193 u2: | |
194 i = 9; | |
195 do { | |
196 d[i] = (u % 10) + '0'; | |
197 u /= 10; | |
198 i--; | |
199 } | |
200 while (u && i >= 0); | |
201 while (++i < 10) { | |
202 *b++ = d[i]; | |
203 if (!(--l)) | |
204 break; | |
205 } | |
206 break; | |
207 | |
208 case 'U': | |
209 u = va_arg(pvar, unsigned int); | |
210 i = 9; | |
211 d[8] = d[7] = d[6] = ' '; | |
212 do { | |
213 d[i] = (u % 10) + '0'; | |
214 u /= 10; | |
215 i--; | |
216 } | |
217 while (u && i >= 0); | |
218 i = 5; | |
219 while (++i < 10) { | |
220 *b++ = d[i]; | |
221 if (!(--l)) | |
222 break; | |
223 } | |
224 break; | |
225 | |
226 case 'X': /* 2 digit, unsigned 8bit hex int */ | |
227 if (l < 2) { | |
228 l = 0; | |
229 break; | |
230 } | |
231 n = va_arg(pvar, int); | |
232 *b++ = hexmap[(n & 0xF0) >> 4]; | |
233 *b++ = hexmap[n & 0x0F]; | |
234 l -= 2; | |
235 break; | |
236 default: | |
237 *b++ = *fmt; | |
238 } | |
239 } else { | |
240 *b++ = *fmt; | |
241 l--; | |
242 } | |
243 fmt++; | |
244 } | |
245 *b = 0; | |
246 } | |
247 | |
248 void snprintf(char *str, int len, char *fmt, ...) | |
249 { | |
250 va_list pvar; | |
251 va_start(pvar, fmt); | |
252 va_snprintf(str, len, fmt, pvar); | |
253 va_end(pvar); | |
254 } | |
255 | |
256 void | |
257 sprintf(char *dst, const char *fmt, ...) | |
258 { | |
259 va_list args; | |
260 va_start(args, fmt); | |
261 va_snprintf(dst, MORE_THAN_YOU_WANT, fmt, args); | |
262 va_end(args); | |
263 } | |
264 | |
265 void | |
266 printf(const char* fmt, ...) | |
267 { | |
268 static char buf[MAX_STDOUT_CHARS]; | |
269 | |
270 va_list args; | |
271 va_start(args, fmt); | |
272 va_snprintf(buf, MAX_STDOUT_CHARS, fmt, args); | |
273 va_end(args); | |
274 | |
275 print_string(buf); | |
276 } |