9409 acpica: this statement may fall through
[unleashed.git] / usr / src / uts / intel / io / acpica / utilities / utprint.c
blobaedcc78be51cf6c9b34891f15ec21ba68480e325
1 /******************************************************************************
3 * Module Name: utprint - Formatted printing routines
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2016, Intel Corp.
9 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
44 #include "acpi.h"
45 #include "accommon.h"
47 #define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME ("utprint")
51 #define ACPI_FORMAT_SIGN 0x01
52 #define ACPI_FORMAT_SIGN_PLUS 0x02
53 #define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
54 #define ACPI_FORMAT_ZERO 0x08
55 #define ACPI_FORMAT_LEFT 0x10
56 #define ACPI_FORMAT_UPPER 0x20
57 #define ACPI_FORMAT_PREFIX 0x40
60 /* Local prototypes */
62 static ACPI_SIZE
63 AcpiUtBoundStringLength (
64 const char *String,
65 ACPI_SIZE Count);
67 static char *
68 AcpiUtBoundStringOutput (
69 char *String,
70 const char *End,
71 char c);
73 static char *
74 AcpiUtFormatNumber (
75 char *String,
76 char *End,
77 UINT64 Number,
78 UINT8 Base,
79 INT32 Width,
80 INT32 Precision,
81 UINT8 Type);
83 static char *
84 AcpiUtPutNumber (
85 char *String,
86 UINT64 Number,
87 UINT8 Base,
88 BOOLEAN Upper);
91 /*******************************************************************************
93 * FUNCTION: AcpiUtBoundStringLength
95 * PARAMETERS: String - String with boundary
96 * Count - Boundary of the string
98 * RETURN: Length of the string. Less than or equal to Count.
100 * DESCRIPTION: Calculate the length of a string with boundary.
102 ******************************************************************************/
104 static ACPI_SIZE
105 AcpiUtBoundStringLength (
106 const char *String,
107 ACPI_SIZE Count)
109 UINT32 Length = 0;
112 while (*String && Count)
114 Length++;
115 String++;
116 Count--;
119 return (Length);
123 /*******************************************************************************
125 * FUNCTION: AcpiUtBoundStringOutput
127 * PARAMETERS: String - String with boundary
128 * End - Boundary of the string
129 * c - Character to be output to the string
131 * RETURN: Updated position for next valid character
133 * DESCRIPTION: Output a character into a string with boundary check.
135 ******************************************************************************/
137 static char *
138 AcpiUtBoundStringOutput (
139 char *String,
140 const char *End,
141 char c)
144 if (String < End)
146 *String = c;
149 ++String;
150 return (String);
154 /*******************************************************************************
156 * FUNCTION: AcpiUtPutNumber
158 * PARAMETERS: String - Buffer to hold reverse-ordered string
159 * Number - Integer to be converted
160 * Base - Base of the integer
161 * Upper - Whether or not using upper cased digits
163 * RETURN: Updated position for next valid character
165 * DESCRIPTION: Convert an integer into a string, note that, the string holds a
166 * reversed ordered number without the trailing zero.
168 ******************************************************************************/
170 static char *
171 AcpiUtPutNumber (
172 char *String,
173 UINT64 Number,
174 UINT8 Base,
175 BOOLEAN Upper)
177 const char *Digits;
178 UINT64 DigitIndex;
179 char *Pos;
182 Pos = String;
183 Digits = Upper ? AcpiGbl_UpperHexDigits : AcpiGbl_LowerHexDigits;
185 if (Number == 0)
187 *(Pos++) = '0';
189 else
191 while (Number)
193 (void) AcpiUtDivide (Number, Base, &Number, &DigitIndex);
194 *(Pos++) = Digits[DigitIndex];
198 /* *(Pos++) = '0'; */
199 return (Pos);
203 /*******************************************************************************
205 * FUNCTION: AcpiUtScanNumber
207 * PARAMETERS: String - String buffer
208 * NumberPtr - Where the number is returned
210 * RETURN: Updated position for next valid character
212 * DESCRIPTION: Scan a string for a decimal integer.
214 ******************************************************************************/
216 const char *
217 AcpiUtScanNumber (
218 const char *String,
219 UINT64 *NumberPtr)
221 UINT64 Number = 0;
224 while (isdigit ((int) *String))
226 Number *= 10;
227 Number += *(String++) - '0';
230 *NumberPtr = Number;
231 return (String);
235 /*******************************************************************************
237 * FUNCTION: AcpiUtPrintNumber
239 * PARAMETERS: String - String buffer
240 * Number - The number to be converted
242 * RETURN: Updated position for next valid character
244 * DESCRIPTION: Print a decimal integer into a string.
246 ******************************************************************************/
248 const char *
249 AcpiUtPrintNumber (
250 char *String,
251 UINT64 Number)
253 char AsciiString[20];
254 const char *Pos1;
255 char *Pos2;
258 Pos1 = AcpiUtPutNumber (AsciiString, Number, 10, FALSE);
259 Pos2 = String;
261 while (Pos1 != AsciiString)
263 *(Pos2++) = *(--Pos1);
266 *Pos2 = 0;
267 return (String);
271 /*******************************************************************************
273 * FUNCTION: AcpiUtFormatNumber
275 * PARAMETERS: String - String buffer with boundary
276 * End - Boundary of the string
277 * Number - The number to be converted
278 * Base - Base of the integer
279 * Width - Field width
280 * Precision - Precision of the integer
281 * Type - Special printing flags
283 * RETURN: Updated position for next valid character
285 * DESCRIPTION: Print an integer into a string with any base and any precision.
287 ******************************************************************************/
289 static char *
290 AcpiUtFormatNumber (
291 char *String,
292 char *End,
293 UINT64 Number,
294 UINT8 Base,
295 INT32 Width,
296 INT32 Precision,
297 UINT8 Type)
299 char *Pos;
300 char Sign;
301 char Zero;
302 BOOLEAN NeedPrefix;
303 BOOLEAN Upper;
304 INT32 i;
305 char ReversedString[66];
308 /* Parameter validation */
310 if (Base < 2 || Base > 16)
312 return (NULL);
315 if (Type & ACPI_FORMAT_LEFT)
317 Type &= ~ACPI_FORMAT_ZERO;
320 NeedPrefix = ((Type & ACPI_FORMAT_PREFIX) && Base != 10) ? TRUE : FALSE;
321 Upper = (Type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
322 Zero = (Type & ACPI_FORMAT_ZERO) ? '0' : ' ';
324 /* Calculate size according to sign and prefix */
326 Sign = '\0';
327 if (Type & ACPI_FORMAT_SIGN)
329 if ((INT64) Number < 0)
331 Sign = '-';
332 Number = - (INT64) Number;
333 Width--;
335 else if (Type & ACPI_FORMAT_SIGN_PLUS)
337 Sign = '+';
338 Width--;
340 else if (Type & ACPI_FORMAT_SIGN_PLUS_SPACE)
342 Sign = ' ';
343 Width--;
346 if (NeedPrefix)
348 Width--;
349 if (Base == 16)
351 Width--;
355 /* Generate full string in reverse order */
357 Pos = AcpiUtPutNumber (ReversedString, Number, Base, Upper);
358 i = ACPI_PTR_DIFF (Pos, ReversedString);
360 /* Printing 100 using %2d gives "100", not "00" */
362 if (i > Precision)
364 Precision = i;
367 Width -= Precision;
369 /* Output the string */
371 if (!(Type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT)))
373 while (--Width >= 0)
375 String = AcpiUtBoundStringOutput (String, End, ' ');
378 if (Sign)
380 String = AcpiUtBoundStringOutput (String, End, Sign);
382 if (NeedPrefix)
384 String = AcpiUtBoundStringOutput (String, End, '0');
385 if (Base == 16)
387 String = AcpiUtBoundStringOutput (
388 String, End, Upper ? 'X' : 'x');
391 if (!(Type & ACPI_FORMAT_LEFT))
393 while (--Width >= 0)
395 String = AcpiUtBoundStringOutput (String, End, Zero);
399 while (i <= --Precision)
401 String = AcpiUtBoundStringOutput (String, End, '0');
403 while (--i >= 0)
405 String = AcpiUtBoundStringOutput (String, End,
406 ReversedString[i]);
408 while (--Width >= 0)
410 String = AcpiUtBoundStringOutput (String, End, ' ');
413 return (String);
417 /*******************************************************************************
419 * FUNCTION: AcpiUtVsnprintf
421 * PARAMETERS: String - String with boundary
422 * Size - Boundary of the string
423 * Format - Standard printf format
424 * Args - Argument list
426 * RETURN: Number of bytes actually written.
428 * DESCRIPTION: Formatted output to a string using argument list pointer.
430 ******************************************************************************/
433 AcpiUtVsnprintf (
434 char *String,
435 ACPI_SIZE Size,
436 const char *Format,
437 va_list Args)
439 UINT8 Base;
440 UINT8 Type;
441 INT32 Width;
442 INT32 Precision;
443 char Qualifier;
444 UINT64 Number;
445 char *Pos;
446 char *End;
447 char c;
448 const char *s;
449 const void *p;
450 INT32 Length;
451 int i;
454 Pos = String;
455 End = String + Size;
457 for (; *Format; ++Format)
459 if (*Format != '%')
461 Pos = AcpiUtBoundStringOutput (Pos, End, *Format);
462 continue;
465 Type = 0;
466 Base = 10;
468 /* Process sign */
472 ++Format;
473 if (*Format == '#')
475 Type |= ACPI_FORMAT_PREFIX;
477 else if (*Format == '0')
479 Type |= ACPI_FORMAT_ZERO;
481 else if (*Format == '+')
483 Type |= ACPI_FORMAT_SIGN_PLUS;
485 else if (*Format == ' ')
487 Type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
489 else if (*Format == '-')
491 Type |= ACPI_FORMAT_LEFT;
493 else
495 break;
498 } while (1);
500 /* Process width */
502 Width = -1;
503 if (isdigit ((int) *Format))
505 Format = AcpiUtScanNumber (Format, &Number);
506 Width = (INT32) Number;
508 else if (*Format == '*')
510 ++Format;
511 Width = va_arg (Args, int);
512 if (Width < 0)
514 Width = -Width;
515 Type |= ACPI_FORMAT_LEFT;
519 /* Process precision */
521 Precision = -1;
522 if (*Format == '.')
524 ++Format;
525 if (isdigit ((int) *Format))
527 Format = AcpiUtScanNumber (Format, &Number);
528 Precision = (INT32) Number;
530 else if (*Format == '*')
532 ++Format;
533 Precision = va_arg (Args, int);
536 if (Precision < 0)
538 Precision = 0;
542 /* Process qualifier */
544 Qualifier = -1;
545 if (*Format == 'h' || *Format == 'l' || *Format == 'L')
547 Qualifier = *Format;
548 ++Format;
550 if (Qualifier == 'l' && *Format == 'l')
552 Qualifier = 'L';
553 ++Format;
557 switch (*Format)
559 case '%':
561 Pos = AcpiUtBoundStringOutput (Pos, End, '%');
562 continue;
564 case 'c':
566 if (!(Type & ACPI_FORMAT_LEFT))
568 while (--Width > 0)
570 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
574 c = (char) va_arg (Args, int);
575 Pos = AcpiUtBoundStringOutput (Pos, End, c);
577 while (--Width > 0)
579 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
581 continue;
583 case 's':
585 s = va_arg (Args, char *);
586 if (!s)
588 s = "<NULL>";
590 Length = AcpiUtBoundStringLength (s, Precision);
591 if (!(Type & ACPI_FORMAT_LEFT))
593 while (Length < Width--)
595 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
599 for (i = 0; i < Length; ++i)
601 Pos = AcpiUtBoundStringOutput (Pos, End, *s);
602 ++s;
605 while (Length < Width--)
607 Pos = AcpiUtBoundStringOutput (Pos, End, ' ');
609 continue;
611 case 'o':
613 Base = 8;
614 break;
616 case 'X':
618 Type |= ACPI_FORMAT_UPPER;
619 /* FALLTHROUGH */
621 case 'x':
623 Base = 16;
624 break;
626 case 'd':
627 case 'i':
629 Type |= ACPI_FORMAT_SIGN;
631 case 'u':
633 break;
635 case 'p':
637 if (Width == -1)
639 Width = 2 * sizeof (void *);
640 Type |= ACPI_FORMAT_ZERO;
643 p = va_arg (Args, void *);
644 Pos = AcpiUtFormatNumber (
645 Pos, End, ACPI_TO_INTEGER (p), 16, Width, Precision, Type);
646 continue;
648 default:
650 Pos = AcpiUtBoundStringOutput (Pos, End, '%');
651 if (*Format)
653 Pos = AcpiUtBoundStringOutput (Pos, End, *Format);
655 else
657 --Format;
659 continue;
662 if (Qualifier == 'L')
664 Number = va_arg (Args, UINT64);
665 if (Type & ACPI_FORMAT_SIGN)
667 Number = (INT64) Number;
670 else if (Qualifier == 'l')
672 Number = va_arg (Args, unsigned long);
673 if (Type & ACPI_FORMAT_SIGN)
675 Number = (INT32) Number;
678 else if (Qualifier == 'h')
680 Number = (UINT16) va_arg (Args, int);
681 if (Type & ACPI_FORMAT_SIGN)
683 Number = (INT16) Number;
686 else
688 Number = va_arg (Args, unsigned int);
689 if (Type & ACPI_FORMAT_SIGN)
691 Number = (signed int) Number;
695 Pos = AcpiUtFormatNumber (Pos, End, Number, Base,
696 Width, Precision, Type);
699 if (Size > 0)
701 if (Pos < End)
703 *Pos = '\0';
705 else
707 End[-1] = '\0';
711 return (ACPI_PTR_DIFF (Pos, String));
715 /*******************************************************************************
717 * FUNCTION: AcpiUtSnprintf
719 * PARAMETERS: String - String with boundary
720 * Size - Boundary of the string
721 * Format, ... - Standard printf format
723 * RETURN: Number of bytes actually written.
725 * DESCRIPTION: Formatted output to a string.
727 ******************************************************************************/
730 AcpiUtSnprintf (
731 char *String,
732 ACPI_SIZE Size,
733 const char *Format,
734 ...)
736 va_list Args;
737 int Length;
740 va_start (Args, Format);
741 Length = AcpiUtVsnprintf (String, Size, Format, Args);
742 va_end (Args);
744 return (Length);
748 #ifdef ACPI_APPLICATION
749 /*******************************************************************************
751 * FUNCTION: AcpiUtFileVprintf
753 * PARAMETERS: File - File descriptor
754 * Format - Standard printf format
755 * Args - Argument list
757 * RETURN: Number of bytes actually written.
759 * DESCRIPTION: Formatted output to a file using argument list pointer.
761 ******************************************************************************/
764 AcpiUtFileVprintf (
765 ACPI_FILE File,
766 const char *Format,
767 va_list Args)
769 ACPI_CPU_FLAGS Flags;
770 int Length;
773 Flags = AcpiOsAcquireLock (AcpiGbl_PrintLock);
774 Length = AcpiUtVsnprintf (AcpiGbl_PrintBuffer,
775 sizeof (AcpiGbl_PrintBuffer), Format, Args);
777 (void) AcpiOsWriteFile (File, AcpiGbl_PrintBuffer, Length, 1);
778 AcpiOsReleaseLock (AcpiGbl_PrintLock, Flags);
780 return (Length);
784 /*******************************************************************************
786 * FUNCTION: AcpiUtFilePrintf
788 * PARAMETERS: File - File descriptor
789 * Format, ... - Standard printf format
791 * RETURN: Number of bytes actually written.
793 * DESCRIPTION: Formatted output to a file.
795 ******************************************************************************/
798 AcpiUtFilePrintf (
799 ACPI_FILE File,
800 const char *Format,
801 ...)
803 va_list Args;
804 int Length;
807 va_start (Args, Format);
808 Length = AcpiUtFileVprintf (File, Format, Args);
809 va_end (Args);
811 return (Length);
813 #endif