This source file includes following definitions.
- acpi_ut_bound_string_length
- acpi_ut_bound_string_output
- acpi_ut_put_number
- acpi_ut_scan_number
- acpi_ut_print_number
- acpi_ut_format_number
- vsnprintf
- snprintf
- sprintf
- vprintf
- printf
- vfprintf
- fprintf
1
2
3
4
5
6
7
8
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12
13 #define _COMPONENT ACPI_UTILITIES
14 ACPI_MODULE_NAME("utprint")
15
16 #define ACPI_FORMAT_SIGN 0x01
17 #define ACPI_FORMAT_SIGN_PLUS 0x02
18 #define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
19 #define ACPI_FORMAT_ZERO 0x08
20 #define ACPI_FORMAT_LEFT 0x10
21 #define ACPI_FORMAT_UPPER 0x20
22 #define ACPI_FORMAT_PREFIX 0x40
23
24 static acpi_size
25 acpi_ut_bound_string_length(const char *string, acpi_size count);
26
27 static char *acpi_ut_bound_string_output(char *string, const char *end, char c);
28
29 static char *acpi_ut_format_number(char *string,
30 char *end,
31 u64 number,
32 u8 base, s32 width, s32 precision, u8 type);
33
34 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper);
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 static acpi_size
50 acpi_ut_bound_string_length(const char *string, acpi_size count)
51 {
52 u32 length = 0;
53
54 while (*string && count) {
55 length++;
56 string++;
57 count--;
58 }
59
60 return (length);
61 }
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 static char *acpi_ut_bound_string_output(char *string, const char *end, char c)
78 {
79
80 if (string < end) {
81 *string = c;
82 }
83
84 ++string;
85 return (string);
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
105 {
106 const char *digits;
107 u64 digit_index;
108 char *pos;
109
110 pos = string;
111 digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
112
113 if (number == 0) {
114 *(pos++) = '0';
115 } else {
116 while (number) {
117 (void)acpi_ut_divide(number, base, &number,
118 &digit_index);
119 *(pos++) = digits[digit_index];
120 }
121 }
122
123
124 return (pos);
125 }
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 const char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
141 {
142 u64 number = 0;
143
144 while (isdigit((int)*string)) {
145 acpi_ut_short_multiply(number, 10, &number);
146 number += *(string++) - '0';
147 }
148
149 *number_ptr = number;
150 return (string);
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166 const char *acpi_ut_print_number(char *string, u64 number)
167 {
168 char ascii_string[20];
169 const char *pos1;
170 char *pos2;
171
172 pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
173 pos2 = string;
174
175 while (pos1 != ascii_string) {
176 *(pos2++) = *(--pos1);
177 }
178
179 *pos2 = 0;
180 return (string);
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 static char *acpi_ut_format_number(char *string,
202 char *end,
203 u64 number,
204 u8 base, s32 width, s32 precision, u8 type)
205 {
206 char *pos;
207 char sign;
208 char zero;
209 u8 need_prefix;
210 u8 upper;
211 s32 i;
212 char reversed_string[66];
213
214
215
216 if (base < 2 || base > 16) {
217 return (NULL);
218 }
219
220 if (type & ACPI_FORMAT_LEFT) {
221 type &= ~ACPI_FORMAT_ZERO;
222 }
223
224 need_prefix = ((type & ACPI_FORMAT_PREFIX)
225 && base != 10) ? TRUE : FALSE;
226 upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
227 zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';
228
229
230
231 sign = '\0';
232 if (type & ACPI_FORMAT_SIGN) {
233 if ((s64)number < 0) {
234 sign = '-';
235 number = -(s64)number;
236 width--;
237 } else if (type & ACPI_FORMAT_SIGN_PLUS) {
238 sign = '+';
239 width--;
240 } else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
241 sign = ' ';
242 width--;
243 }
244 }
245 if (need_prefix) {
246 width--;
247 if (base == 16) {
248 width--;
249 }
250 }
251
252
253
254 pos = acpi_ut_put_number(reversed_string, number, base, upper);
255 i = (s32)ACPI_PTR_DIFF(pos, reversed_string);
256
257
258
259 if (i > precision) {
260 precision = i;
261 }
262
263 width -= precision;
264
265
266
267 if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
268 while (--width >= 0) {
269 string = acpi_ut_bound_string_output(string, end, ' ');
270 }
271 }
272 if (sign) {
273 string = acpi_ut_bound_string_output(string, end, sign);
274 }
275 if (need_prefix) {
276 string = acpi_ut_bound_string_output(string, end, '0');
277 if (base == 16) {
278 string =
279 acpi_ut_bound_string_output(string, end,
280 upper ? 'X' : 'x');
281 }
282 }
283 if (!(type & ACPI_FORMAT_LEFT)) {
284 while (--width >= 0) {
285 string = acpi_ut_bound_string_output(string, end, zero);
286 }
287 }
288
289 while (i <= --precision) {
290 string = acpi_ut_bound_string_output(string, end, '0');
291 }
292 while (--i >= 0) {
293 string = acpi_ut_bound_string_output(string, end,
294 reversed_string[i]);
295 }
296 while (--width >= 0) {
297 string = acpi_ut_bound_string_output(string, end, ' ');
298 }
299
300 return (string);
301 }
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318 int vsnprintf(char *string, acpi_size size, const char *format, va_list args)
319 {
320 u8 base;
321 u8 type;
322 s32 width;
323 s32 precision;
324 char qualifier;
325 u64 number;
326 char *pos;
327 char *end;
328 char c;
329 const char *s;
330 const void *p;
331 s32 length;
332 int i;
333
334 pos = string;
335 end = string + size;
336
337 for (; *format; ++format) {
338 if (*format != '%') {
339 pos = acpi_ut_bound_string_output(pos, end, *format);
340 continue;
341 }
342
343 type = 0;
344 base = 10;
345
346
347
348 do {
349 ++format;
350 if (*format == '#') {
351 type |= ACPI_FORMAT_PREFIX;
352 } else if (*format == '0') {
353 type |= ACPI_FORMAT_ZERO;
354 } else if (*format == '+') {
355 type |= ACPI_FORMAT_SIGN_PLUS;
356 } else if (*format == ' ') {
357 type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
358 } else if (*format == '-') {
359 type |= ACPI_FORMAT_LEFT;
360 } else {
361 break;
362 }
363
364 } while (1);
365
366
367
368 width = -1;
369 if (isdigit((int)*format)) {
370 format = acpi_ut_scan_number(format, &number);
371 width = (s32)number;
372 } else if (*format == '*') {
373 ++format;
374 width = va_arg(args, int);
375 if (width < 0) {
376 width = -width;
377 type |= ACPI_FORMAT_LEFT;
378 }
379 }
380
381
382
383 precision = -1;
384 if (*format == '.') {
385 ++format;
386 if (isdigit((int)*format)) {
387 format = acpi_ut_scan_number(format, &number);
388 precision = (s32)number;
389 } else if (*format == '*') {
390 ++format;
391 precision = va_arg(args, int);
392 }
393
394 if (precision < 0) {
395 precision = 0;
396 }
397 }
398
399
400
401 qualifier = -1;
402 if (*format == 'h' || *format == 'l' || *format == 'L') {
403 qualifier = *format;
404 ++format;
405
406 if (qualifier == 'l' && *format == 'l') {
407 qualifier = 'L';
408 ++format;
409 }
410 }
411
412 switch (*format) {
413 case '%':
414
415 pos = acpi_ut_bound_string_output(pos, end, '%');
416 continue;
417
418 case 'c':
419
420 if (!(type & ACPI_FORMAT_LEFT)) {
421 while (--width > 0) {
422 pos =
423 acpi_ut_bound_string_output(pos,
424 end,
425 ' ');
426 }
427 }
428
429 c = (char)va_arg(args, int);
430 pos = acpi_ut_bound_string_output(pos, end, c);
431
432 while (--width > 0) {
433 pos =
434 acpi_ut_bound_string_output(pos, end, ' ');
435 }
436 continue;
437
438 case 's':
439
440 s = va_arg(args, char *);
441 if (!s) {
442 s = "<NULL>";
443 }
444 length = (s32)acpi_ut_bound_string_length(s, precision);
445 if (!(type & ACPI_FORMAT_LEFT)) {
446 while (length < width--) {
447 pos =
448 acpi_ut_bound_string_output(pos,
449 end,
450 ' ');
451 }
452 }
453
454 for (i = 0; i < length; ++i) {
455 pos = acpi_ut_bound_string_output(pos, end, *s);
456 ++s;
457 }
458
459 while (length < width--) {
460 pos =
461 acpi_ut_bound_string_output(pos, end, ' ');
462 }
463 continue;
464
465 case 'o':
466
467 base = 8;
468 break;
469
470 case 'X':
471
472 type |= ACPI_FORMAT_UPPER;
473
474
475 case 'x':
476
477 base = 16;
478 break;
479
480 case 'd':
481 case 'i':
482
483 type |= ACPI_FORMAT_SIGN;
484
485 case 'u':
486
487 break;
488
489 case 'p':
490
491 if (width == -1) {
492 width = 2 * sizeof(void *);
493 type |= ACPI_FORMAT_ZERO;
494 }
495
496 p = va_arg(args, void *);
497 pos =
498 acpi_ut_format_number(pos, end, ACPI_TO_INTEGER(p),
499 16, width, precision, type);
500 continue;
501
502 default:
503
504 pos = acpi_ut_bound_string_output(pos, end, '%');
505 if (*format) {
506 pos =
507 acpi_ut_bound_string_output(pos, end,
508 *format);
509 } else {
510 --format;
511 }
512 continue;
513 }
514
515 if (qualifier == 'L') {
516 number = va_arg(args, u64);
517 if (type & ACPI_FORMAT_SIGN) {
518 number = (s64)number;
519 }
520 } else if (qualifier == 'l') {
521 number = va_arg(args, unsigned long);
522 if (type & ACPI_FORMAT_SIGN) {
523 number = (s32)number;
524 }
525 } else if (qualifier == 'h') {
526 number = (u16)va_arg(args, int);
527 if (type & ACPI_FORMAT_SIGN) {
528 number = (s16)number;
529 }
530 } else {
531 number = va_arg(args, unsigned int);
532 if (type & ACPI_FORMAT_SIGN) {
533 number = (signed int)number;
534 }
535 }
536
537 pos = acpi_ut_format_number(pos, end, number, base,
538 width, precision, type);
539 }
540
541 if (size > 0) {
542 if (pos < end) {
543 *pos = '\0';
544 } else {
545 end[-1] = '\0';
546 }
547 }
548
549 return ((int)ACPI_PTR_DIFF(pos, string));
550 }
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566 int snprintf(char *string, acpi_size size, const char *format, ...)
567 {
568 va_list args;
569 int length;
570
571 va_start(args, format);
572 length = vsnprintf(string, size, format, args);
573 va_end(args);
574
575 return (length);
576 }
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591 int sprintf(char *string, const char *format, ...)
592 {
593 va_list args;
594 int length;
595
596 va_start(args, format);
597 length = vsnprintf(string, ACPI_UINT32_MAX, format, args);
598 va_end(args);
599
600 return (length);
601 }
602
603 #ifdef ACPI_APPLICATION
604
605
606
607
608
609
610
611
612
613
614
615
616
617 int vprintf(const char *format, va_list args)
618 {
619 acpi_cpu_flags flags;
620 int length;
621
622 flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
623 length = vsnprintf(acpi_gbl_print_buffer,
624 sizeof(acpi_gbl_print_buffer), format, args);
625
626 (void)fwrite(acpi_gbl_print_buffer, length, 1, ACPI_FILE_OUT);
627 acpi_os_release_lock(acpi_gbl_print_lock, flags);
628
629 return (length);
630 }
631
632
633
634
635
636
637
638
639
640
641
642
643
644 int printf(const char *format, ...)
645 {
646 va_list args;
647 int length;
648
649 va_start(args, format);
650 length = vprintf(format, args);
651 va_end(args);
652
653 return (length);
654 }
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670 int vfprintf(FILE * file, const char *format, va_list args)
671 {
672 acpi_cpu_flags flags;
673 int length;
674
675 flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
676 length = vsnprintf(acpi_gbl_print_buffer,
677 sizeof(acpi_gbl_print_buffer), format, args);
678
679 (void)fwrite(acpi_gbl_print_buffer, length, 1, file);
680 acpi_os_release_lock(acpi_gbl_print_lock, flags);
681
682 return (length);
683 }
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698 int fprintf(FILE * file, const char *format, ...)
699 {
700 va_list args;
701 int length;
702
703 va_start(args, format);
704 length = vfprintf(file, format, args);
705 va_end(args);
706
707 return (length);
708 }
709 #endif