GadgetSeed  0.9.6
vtprintf.c
[詳解]
1 /** @file
2  @brief 機能限定printf
3 
4  @date 2011.02.03
5  @date 2007.03.10
6  @date 2002.03.02
7 
8  @author Takashi SHUDO
9 */
10 
11 #include "vtprintf.h"
12 #include "tprintf.h"
13 #include "tkprintf.h"
14 #include "str.h"
15 #include "console.h"
16 
17 static int print_write(io_write write, unsigned int *len, unsigned int size, uchar *str, unsigned int slen)
18 {
19  if((size != 0) && (slen > (size - *len))) {
20  slen = size - *len;
21  }
22 
23  write(str, (unsigned int)slen);
24 
25  *len += slen;
26 
27  if((size != 0) && (*len >= size)) {
28  return 1;
29  }
30 
31  return 0;
32 }
33 
34 /**
35  @brief 簡易printf、float,doubleは使えない
36 
37  %ns,%nd,%nx,%nXのみ<br>
38  %[n]s - 文字列表示<br>
39  [n] 省略時:文字列長<br>
40  %[n]d - 10進数表示<br>
41  [n] 省略時:デコード文字列長<br>
42  %の次が"0"ならば"0"付き表示<br>
43  %[n]X - 16進数表示(大文字)<br>
44  %[n]x - 16進数表示(小文字)(必ず"0"付きで桁数分表示)<br>
45  [n] 0-8 省略時:桁数分<br>
46  %c - 文字表示<br>
47  %p - アドレス表示(32bit:XXXXXXXX, 64bit:XXXXXXXXXXXXXXXX<br>
48 
49  @param[in] dev 出力デバイス
50  @param[in] fmt フォーマット文字列
51  @param[in] args 引数リスト
52 
53  @return 出力文字数
54 */
55 int vtprintf(io_write write, const char *fmt, unsigned int size, va_list args)
56 {
57  uchar str[MAXFORMATSTR]; // フォーマットデコードバッファ
58  int dec = 0; // 1:%デコード中
59  unsigned int strlen = 0; // 桁数
60  int zero = 0; // "0"付きか 0:不明,1:"0"付き,-1:"0"無し
61  int flong = 0; // 0:int, 1:long, 2:long long
62  unsigned int len = 0;
63  unsigned int slen;
64 
65  if(write == 0) {
66  SYSERR_PRINT("write = 0\n");
67  }
68 
69  while(*fmt != 0) {
70  if(dec == 0) {
71  if(*fmt == '%') {
72  strlen = 0;
73  zero = 0;
74  dec = 1;
75  flong = 0;
76  } else {
77 #if 0 // LF = CRLF
78  if(*fmt == '\n') {
79  if(print_write(write, &len, size, (uchar *)"\r", 1) != 0) {
80  return (int)len;
81  }
82  }
83 #endif
84  if(print_write(write, &len, size, (uchar *)fmt, 1) != 0) {
85  return (int)len;
86  }
87  }
88  } else {
89  if(('0' <= *fmt) && (*fmt <= '9')) {
90  if(zero == 0) {
91  if(*fmt == '0') {
92  zero = 1;
93  } else {
94  zero = -1;
95  strlen = (strlen*10) + *fmt - '0';
96  }
97  } else {
98  strlen = (strlen*10) + *fmt - '0';
99  }
100  } else {
101  switch(*fmt) {
102  case '%':
103  if(print_write(write, &len, size, (uchar *)"%", 1) != 0) {
104  return (int)len;
105  }
106  dec = 0;
107  break;
108 
109  case 'l':
110  if(flong == 0) {
111  flong = 1;
112  } else {
113  flong = 2;
114  }
115  break;
116 
117  case 's':
118  if(strlen) {
119  unsigned int i;
120  uchar *p = va_arg(args, uchar *);
121  for(i=0; i<strlen; i++) {
122  if((*p) != 0) {
123  if(print_write(write, &len, size, p, 1) != 0) {
124  return (int)len;
125  }
126  p++;
127  } else {
128  if(print_write(write, &len, size, (uchar *)" ", 1) != 0) {
129  return (int)len;
130  }
131  }
132  }
133  } else {
134  uchar *p = va_arg(args, uchar *);
135  slen = strleng(p);
136  if((size != 0) && (slen > (size - len))) {
137  slen = size - len;
138  }
139  if(print_write(write, &len, size, p, slen) != 0) {
140  return (int)len;
141  }
142  }
143  dec = 0;
144  break;
145 
146  case 'i':
147  case 'd':
148  if(strlen == 0) {
149  uchar *p;
150  if(flong == 1) {
151  long val = va_arg(args, long);
152  (void)itods(str, MAXFORMATSTR-1, val);
153  } else if(flong == 2) {
154  long long val = va_arg(args, long long);
155 #ifdef LONGLONGSWAP
156  val = (val >> 32) | (val << 32);
157 #endif
158  (void)lltods(str, MAXFORMATSTR-1, val);
159  } else {
160  int val = va_arg(args, int);
161  (void)itods(str, MAXFORMATSTR-1, val);
162  }
163  for(p=str;
164  p<&str[MAXFORMATSTR];
165  p++) {
166  if(*p != ' ') {
167  slen = strleng((uchar *)p);
168  if((size != 0) && (slen > (size - len))) {
169  slen = size - len;
170  }
171  if(print_write(write, &len, size, p, slen) != 0) {
172  return (int)len;
173  }
174  break;
175  }
176  }
177  } else {
178  if(zero == 1) {
179  if(flong == 1) {
180  long val = va_arg(args, long);
181  (void)itodsz(str, strlen, val);
182  } else if(flong == 2) {
183  long long val = va_arg(args, long long);
184 #ifdef LONGLONGSWAP
185  val = (val >> 32) | (val << 32);
186 #endif
187  (void)lltodsz(str, strlen, val);
188  } else {
189  int val = va_arg(args, int);
190  (void)itodsz(str, strlen, val);
191  }
192  } else {
193  if(flong == 1) {
194  long val = va_arg(args, long);
195  (void)itods(str, strlen, val);
196  } else if(flong == 2) {
197  long long val = va_arg(args, long long);
198 #ifdef LONGLONGSWAP
199  val = (val >> 32) | (val << 32);
200 #endif
201  (void)lltods(str, strlen, val);
202  } else {
203  int val = va_arg(args, int);
204  (void)itods(str, strlen, val);
205  }
206  }
207  slen = strleng(str);
208  if((size != 0) && (slen > (size - len))) {
209  slen = size - len;
210  }
211  if(print_write(write, &len, size, str, slen) != 0) {
212  return (int)len;
213  }
214  }
215  dec = 0;
216  break;
217 
218  case 'u':
219  if(strlen == 0) {
220  uchar *p;
221  if(flong == 1) {
222  unsigned long val = va_arg(args, unsigned long);
223  (void)uitods(str, MAXFORMATSTR-1, (unsigned int)val);
224  } else if(flong == 2) {
225  unsigned long long val = va_arg(args, unsigned long long);
226 #ifdef LONGLONGSWAP
227  val = (val >> 32) | (val << 32);
228 #endif
229  (void)ulltods(str, MAXFORMATSTR-1, val);
230  } else {
231  unsigned int val = va_arg(args, unsigned int);
232  (void)uitods(str, MAXFORMATSTR-1, val);
233  }
234  for(p=str;
235  p<&str[MAXFORMATSTR];
236  p++) {
237  if(*p != ' ') {
238  slen = strleng(p);
239  if((size != 0) && (slen > (size - len))) {
240  slen = size - len;
241  }
242  if(print_write(write, &len, size, p, slen) != 0) {
243  return (int)len;
244  }
245  dec = 0;
246  break;
247  }
248  }
249  } else {
250  if(zero == 1) {
251  if(flong == 1) {
252  unsigned long val = va_arg(args, unsigned long);
253  (void)uitodsz(str, strlen, (unsigned int)val);
254  } else if(flong == 2) {
255  unsigned long long val = va_arg(args, unsigned long long);
256 #ifdef LONGLONGSWAP
257  val = (val >> 32) | (val << 32);
258 #endif
259  (void)ulltodsz(str, strlen, val);
260  } else {
261  unsigned int val = va_arg(args, unsigned int);
262  (void)uitodsz(str, strlen, val);
263  }
264  } else {
265  if(flong == 1) {
266  unsigned long val = va_arg(args, unsigned long);
267  (void)uitods(str, strlen, (unsigned int)val);
268  } else if(flong == 2) {
269  unsigned long long val = va_arg(args, unsigned long long);
270 #ifdef LONGLONGSWAP
271  val = (val >> 32) | (val << 32);
272 #endif
273  (void)ulltods(str, strlen, val);
274  } else {
275  unsigned int val = va_arg(args, unsigned int);
276  (void)uitods(str, strlen, val);
277  }
278  }
279  slen = strleng(str);
280  if((size != 0) && (slen > (size - len))) {
281  slen = size - len;
282  }
283  if(print_write(write, &len, size, str, slen) != 0) {
284  return (int)len;
285  }
286  }
287  dec = 0;
288  break;
289 
290  case 'x':
291  case 'X':
292  if(flong == 1) {
293  long val = va_arg(args, long);
294  if(strlen == 0) {
295  strlen = (unsigned int)sizeof(long)*2;
296  }
297  (void)itohs(str, strlen, val);
298  } else if(flong == 2) {
299  long long val = va_arg(args, long long);
300  if(strlen == 0) {
301  strlen = (unsigned int)sizeof(long)*4;
302  }
303 #ifdef LONGLONGSWAP
304  val = (val >> 32) | (val << 32);
305 #endif
306  (void)lltohs(str, strlen, val);
307  } else {
308  int val = va_arg(args, int);
309  if(strlen == 0) {
310  strlen = (unsigned int)sizeof(int)*2;
311  }
312  (void)itohs(str, strlen, val);
313  }
314  if(*fmt == 'X') {
315  (void)str2cap(str);
316  }
317  slen = strleng(str);
318  if((size != 0) && (slen > (size - len))) {
319  slen = size - len;
320  }
321  if(print_write(write, &len, size, str, slen) != 0) {
322  return (int)len;
323  }
324  dec = 0;
325  break;
326 
327  case 'c':
328  {
329  uchar data[1];
330  data[0] = (uchar)va_arg(args, int);
331  if(print_write(write, &len, size, data, 1) != 0) {
332  return (int)len;
333  }
334  dec = 0;
335  }
336  break;
337 
338  case 'p':
339  case 'P':
340 #ifdef __x86_64__
341  (void)lltohs(str, 16, va_arg(args, long long));
342 #else
343  (void)itohs(str, 8, va_arg(args, int));
344 #endif
345  if(*fmt == 'P') {
346  (void)str2cap(str);
347  }
348  slen = 8;
349  if((size != 0) && (slen > (size - len))) {
350  slen = size - len;
351  }
352 #ifdef __x86_64__
353  if(print_write(write, &len, size, str+8, slen) != 0) {
354  return (int)len;
355  }
356 #else
357  if(print_write(write, &len, size, str, slen) != 0) {
358  return (int)len;
359  }
360 #endif
361  dec = 0;
362  break;
363 
364  default:
365  break;
366  }
367  }
368  }
369 
370  fmt ++;
371  }
372 
373  return (int)len;
374 }
375 
376 
377 void vxdump(unsigned int addr, unsigned char *data, unsigned int len,
378  int addr_type, /* XDUMP_ADDR_* */
379  int data_size, /* XDUMP_DATA_* */
380  int(* print)(const char *fmt, ...))
381 {
382  int i = 0, j;
383  uchar cbuf[16];
384 
385  switch(addr_type) {
386  case XDUMP_ADDR_ANY_WORD:
387  print("%04X : ", addr + i);
388  break;
389 
390  case XDUMP_ADDR_ANY_LONG:
391  print("%08X : ", addr + i);
392  break;
393 
394  case XDUMP_ADDR_DATA_ADDR:
395  print("%p : ", data);
396  break;
397 
398  default:
399  print("%p : ", data);
400  break;
401  }
402 
403  while(len) {
404  cbuf[i % 16] = *data;
405  switch(data_size) {
406  case 0:
407  print("%02X ", *data);
408  break;
409 
410  case XDUMP_DATA_WORD:
411 #ifdef __x86_64__
412  if(((unsigned long long)data % 2) == 0) {
413 #else
414  if(((unsigned long)data % 2) == 0) {
415 #endif
416  print("%04lX ", *(unsigned long *)data);
417  }
418  break;
419 
420  case XDUMP_DATA_LONG:
421 #ifdef __x86_64__
422  if(((unsigned long long)data % 4) == 0) {
423 #else
424  if(((unsigned long)data % 4) == 0) {
425 #endif
426  print("%08lX ", *(unsigned long *)data);
427  }
428  break;
429 
430  default:
431  print("%02X ", *data);
432  break;
433  }
434  data ++;
435  len --;
436  i ++;
437  if((i % 8) == 0) {
438  print(" ");
439  }
440  if((i % 16) == 0) {
441  print(" \"");
442  for(j=0; j<16; j++) {
443  if((' ' <= cbuf[j]) && (cbuf[j] <= '~')) {
444  print("%c", cbuf[j]);
445  } else {
446  print(".");
447  }
448  }
449  print("\"");
450  if(len != 0) {
451  switch(addr_type) {
452  case XDUMP_ADDR_ANY_WORD:
453  print("\n%04X : ", addr + i);
454  break;
455 
456  case XDUMP_ADDR_ANY_LONG:
457  print("\n%08X : ", addr + i);
458  break;
459 
460  case XDUMP_ADDR_DATA_ADDR:
461  print("\n%p : ", data);
462  break;
463 
464  default:
465  break;
466  }
467  } else {
468  print("\n");
469  }
470  } else {
471  if(len == 0) {
472  if((i % 16) < 8) {
473  print(" ");
474  } else {
475  print(" ");
476  }
477  for(j=0; j<(16-(i % 16)); j++) {
478  print(" ");
479  }
480  print(" \"");
481  for(j=0; j<(i % 16); j++) {
482  if((' ' <= cbuf[j]) && (cbuf[j] <= '~')) {
483  print("%c", cbuf[j]);
484  } else {
485  print(".");
486  }
487  }
488  print("\"\n");
489  }
490  }
491  }
492 }
unsigned char uchar
GadgetSeedの文字(列)は unsigned char 型となる
Definition: str.h:13
uchar * uitodsz(uchar *str, unsigned int strlen, unsigned int val)
unsigned int 符号なし"0"付き10進数文字列変換
Definition: str.c:461
uchar * uitods(uchar *str, unsigned int strlen, unsigned int val)
unsigned int 10進数文字列変換
Definition: str.c:311
uchar * itods(uchar *str, unsigned int strlen, int val)
int 10進数文字列変換
Definition: str.c:217
文字列処理
機能限定printf
uchar * itohs(uchar *str, unsigned int strlen, int val)
intを16進数字列変換
Definition: str.c:83
uchar * itodsz(uchar *str, unsigned int strlen, int val)
int "0"付き10進数文字列変換
Definition: str.c:383
カーネル用機能限定printf
unsigned int strleng(const uchar *str)
文字列長
Definition: str.c:657
uchar * lltods(uchar *str, unsigned int strlen, long long val)
long long 10進数文字列変換
Definition: str.c:264
uchar * str2cap(uchar *str)
小文字から大文字へ変換
Definition: str.c:678
コンソールI/O
uchar * lltodsz(uchar *str, unsigned int strlen, long long val)
long long 10進数文字列変換
Definition: str.c:422
uchar * lltohs(uchar *str, unsigned int strlen, long long val)
long long 16進数字列変換
Definition: str.c:115
uchar * ulltods(uchar *str, unsigned int strlen, unsigned long long val)
unsigned long long 10進数文字列変換
Definition: str.c:347
int vtprintf(io_write write, const char *fmt, unsigned int size, va_list args)
簡易printf、float,doubleは使えない
Definition: vtprintf.c:55
機能限定printf
uchar * ulltodsz(uchar *str, unsigned int strlen, unsigned long long val)
unsigned long long 符号なし"0"付き10進数文字列変換
Definition: str.c:493