Home | History | Annotate | Line # | Download | only in utilities
utnonansi.c revision 1.1.1.3
      1 /*******************************************************************************
      2  *
      3  * Module Name: utnonansi - Non-ansi C library functions
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2016, Intel Corp.
      9  * All rights reserved.
     10  *
     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.
     25  *
     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.
     29  *
     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.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 
     47 
     48 #define _COMPONENT          ACPI_UTILITIES
     49         ACPI_MODULE_NAME    ("utnonansi")
     50 
     51 
     52 /*
     53  * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit
     54  * version of strtoul.
     55  */
     56 
     57 /*******************************************************************************
     58  *
     59  * FUNCTION:    AcpiUtStrlwr (strlwr)
     60  *
     61  * PARAMETERS:  SrcString       - The source string to convert
     62  *
     63  * RETURN:      None
     64  *
     65  * DESCRIPTION: Convert a string to lowercase
     66  *
     67  ******************************************************************************/
     68 
     69 void
     70 AcpiUtStrlwr (
     71     char                    *SrcString)
     72 {
     73     char                    *String;
     74 
     75 
     76     ACPI_FUNCTION_ENTRY ();
     77 
     78 
     79     if (!SrcString)
     80     {
     81         return;
     82     }
     83 
     84     /* Walk entire string, lowercasing the letters */
     85 
     86     for (String = SrcString; *String; String++)
     87     {
     88         *String = (char) tolower ((int) *String);
     89     }
     90 }
     91 
     92 
     93 /*******************************************************************************
     94  *
     95  * FUNCTION:    AcpiUtStrupr (strupr)
     96  *
     97  * PARAMETERS:  SrcString       - The source string to convert
     98  *
     99  * RETURN:      None
    100  *
    101  * DESCRIPTION: Convert a string to uppercase
    102  *
    103  ******************************************************************************/
    104 
    105 void
    106 AcpiUtStrupr (
    107     char                    *SrcString)
    108 {
    109     char                    *String;
    110 
    111 
    112     ACPI_FUNCTION_ENTRY ();
    113 
    114 
    115     if (!SrcString)
    116     {
    117         return;
    118     }
    119 
    120     /* Walk entire string, uppercasing the letters */
    121 
    122     for (String = SrcString; *String; String++)
    123     {
    124         *String = (char) toupper ((int) *String);
    125     }
    126 }
    127 
    128 
    129 /******************************************************************************
    130  *
    131  * FUNCTION:    AcpiUtStricmp (stricmp)
    132  *
    133  * PARAMETERS:  String1             - first string to compare
    134  *              String2             - second string to compare
    135  *
    136  * RETURN:      int that signifies string relationship. Zero means strings
    137  *              are equal.
    138  *
    139  * DESCRIPTION: Case-insensitive string compare. Implementation of the
    140  *              non-ANSI stricmp function.
    141  *
    142  ******************************************************************************/
    143 
    144 int
    145 AcpiUtStricmp (
    146     char                    *String1,
    147     char                    *String2)
    148 {
    149     int                     c1;
    150     int                     c2;
    151 
    152 
    153     do
    154     {
    155         c1 = tolower ((int) *String1);
    156         c2 = tolower ((int) *String2);
    157 
    158         String1++;
    159         String2++;
    160     }
    161     while ((c1 == c2) && (c1));
    162 
    163     return (c1 - c2);
    164 }
    165 
    166 
    167 #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
    168 /*******************************************************************************
    169  *
    170  * FUNCTION:    AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat
    171  *
    172  * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
    173  *              functions. This is the size of the Destination buffer.
    174  *
    175  * RETURN:      TRUE if the operation would overflow the destination buffer.
    176  *
    177  * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
    178  *              the result of the operation will not overflow the output string
    179  *              buffer.
    180  *
    181  * NOTE:        These functions are typically only helpful for processing
    182  *              user input and command lines. For most ACPICA code, the
    183  *              required buffer length is precisely calculated before buffer
    184  *              allocation, so the use of these functions is unnecessary.
    185  *
    186  ******************************************************************************/
    187 
    188 BOOLEAN
    189 AcpiUtSafeStrcpy (
    190     char                    *Dest,
    191     ACPI_SIZE               DestSize,
    192     char                    *Source)
    193 {
    194 
    195     if (strlen (Source) >= DestSize)
    196     {
    197         return (TRUE);
    198     }
    199 
    200     strcpy (Dest, Source);
    201     return (FALSE);
    202 }
    203 
    204 BOOLEAN
    205 AcpiUtSafeStrcat (
    206     char                    *Dest,
    207     ACPI_SIZE               DestSize,
    208     char                    *Source)
    209 {
    210 
    211     if ((strlen (Dest) + strlen (Source)) >= DestSize)
    212     {
    213         return (TRUE);
    214     }
    215 
    216     strcat (Dest, Source);
    217     return (FALSE);
    218 }
    219 
    220 BOOLEAN
    221 AcpiUtSafeStrncat (
    222     char                    *Dest,
    223     ACPI_SIZE               DestSize,
    224     char                    *Source,
    225     ACPI_SIZE               MaxTransferLength)
    226 {
    227     ACPI_SIZE               ActualTransferLength;
    228 
    229 
    230     ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source));
    231 
    232     if ((strlen (Dest) + ActualTransferLength) >= DestSize)
    233     {
    234         return (TRUE);
    235     }
    236 
    237     strncat (Dest, Source, MaxTransferLength);
    238     return (FALSE);
    239 }
    240 #endif
    241 
    242 
    243 /*******************************************************************************
    244  *
    245  * FUNCTION:    AcpiUtStrtoul64
    246  *
    247  * PARAMETERS:  String                  - Null terminated string
    248  *              Base                    - Radix of the string: 16 or 10 or
    249  *                                        ACPI_ANY_BASE
    250  *              MaxIntegerByteWidth     - Maximum allowable integer,in bytes:
    251  *                                        4 or 8 (32 or 64 bits)
    252  *              RetInteger              - Where the converted integer is
    253  *                                        returned
    254  *
    255  * RETURN:      Status and Converted value
    256  *
    257  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
    258  *              32-bit or 64-bit conversion, depending on the input integer
    259  *              size (often the current mode of the interpreter).
    260  *
    261  * NOTES:       Negative numbers are not supported, as they are not supported
    262  *              by ACPI.
    263  *
    264  *              AcpiGbl_IntegerByteWidth should be set to the proper width.
    265  *              For the core ACPICA code, this width depends on the DSDT
    266  *              version. For iASL, the default byte width is always 8 for the
    267  *              parser, but error checking is performed later to flag cases
    268  *              where a 64-bit constant is defined in a 32-bit DSDT/SSDT.
    269  *
    270  *              Does not support Octal strings, not needed at this time.
    271  *
    272  ******************************************************************************/
    273 
    274 ACPI_STATUS
    275 AcpiUtStrtoul64 (
    276     char                    *String,
    277     UINT32                  Base,
    278     UINT32                  MaxIntegerByteWidth,
    279     UINT64                  *RetInteger)
    280 {
    281     UINT32                  ThisDigit = 0;
    282     UINT64                  ReturnValue = 0;
    283     UINT64                  Quotient;
    284     UINT64                  Dividend;
    285     UINT8                   ValidDigits = 0;
    286     UINT8                   SignOf0x = 0;
    287     UINT8                   Term = 0;
    288 
    289 
    290     ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String);
    291 
    292 
    293     switch (Base)
    294     {
    295     case ACPI_ANY_BASE:
    296     case 10:
    297     case 16:
    298 
    299         break;
    300 
    301     default:
    302 
    303         /* Invalid Base */
    304 
    305         return_ACPI_STATUS (AE_BAD_PARAMETER);
    306     }
    307 
    308     if (!String)
    309     {
    310         goto ErrorExit;
    311     }
    312 
    313     /* Skip over any white space in the buffer */
    314 
    315     while ((*String) && (isspace ((int) *String) || *String == '\t'))
    316     {
    317         String++;
    318     }
    319 
    320     if (Base == ACPI_ANY_BASE)
    321     {
    322         /*
    323          * Base equal to ACPI_ANY_BASE means 'Either decimal or hex'.
    324          * We need to determine if it is decimal or hexadecimal.
    325          */
    326         if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x'))
    327         {
    328             SignOf0x = 1;
    329             Base = 16;
    330 
    331             /* Skip over the leading '0x' */
    332             String += 2;
    333         }
    334         else
    335         {
    336             Base = 10;
    337         }
    338     }
    339 
    340     /* Any string left? Check that '0x' is not followed by white space. */
    341 
    342     if (!(*String) || isspace ((int) *String) || *String == '\t')
    343     {
    344         if (Base == ACPI_ANY_BASE)
    345         {
    346             goto ErrorExit;
    347         }
    348         else
    349         {
    350             goto AllDone;
    351         }
    352     }
    353 
    354     /*
    355      * Perform a 32-bit or 64-bit conversion, depending upon the input
    356      * byte width
    357      */
    358     Dividend = (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH) ?
    359         ACPI_UINT32_MAX : ACPI_UINT64_MAX;
    360 
    361     /* Main loop: convert the string to a 32- or 64-bit integer */
    362 
    363     while (*String)
    364     {
    365         if (isdigit ((int) *String))
    366         {
    367             /* Convert ASCII 0-9 to Decimal value */
    368 
    369             ThisDigit = ((UINT8) *String) - '0';
    370         }
    371         else if (Base == 10)
    372         {
    373             /* Digit is out of range; possible in ToInteger case only */
    374 
    375             Term = 1;
    376         }
    377         else
    378         {
    379             ThisDigit = (UINT8) toupper ((int) *String);
    380             if (isxdigit ((int) ThisDigit))
    381             {
    382                 /* Convert ASCII Hex char to value */
    383 
    384                 ThisDigit = ThisDigit - 'A' + 10;
    385             }
    386             else
    387             {
    388                 Term = 1;
    389             }
    390         }
    391 
    392         if (Term)
    393         {
    394             if (Base == ACPI_ANY_BASE)
    395             {
    396                 goto ErrorExit;
    397             }
    398             else
    399             {
    400                 break;
    401             }
    402         }
    403         else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
    404         {
    405             /* Skip zeros */
    406             String++;
    407             continue;
    408         }
    409 
    410         ValidDigits++;
    411 
    412         if (SignOf0x && ((ValidDigits > 16) ||
    413             ((ValidDigits > 8) && (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH))))
    414         {
    415             /*
    416              * This is ToInteger operation case.
    417              * No restrictions for string-to-integer conversion,
    418              * see ACPI spec.
    419              */
    420             goto ErrorExit;
    421         }
    422 
    423         /* Divide the digit into the correct position */
    424 
    425         (void) AcpiUtShortDivide (
    426             (Dividend - (UINT64) ThisDigit), Base, &Quotient, NULL);
    427 
    428         if (ReturnValue > Quotient)
    429         {
    430             if (Base == ACPI_ANY_BASE)
    431             {
    432                 goto ErrorExit;
    433             }
    434             else
    435             {
    436                 break;
    437             }
    438         }
    439 
    440         ReturnValue *= Base;
    441         ReturnValue += ThisDigit;
    442         String++;
    443     }
    444 
    445     /* All done, normal exit */
    446 
    447 AllDone:
    448 
    449     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
    450         ACPI_FORMAT_UINT64 (ReturnValue)));
    451 
    452     *RetInteger = ReturnValue;
    453     return_ACPI_STATUS (AE_OK);
    454 
    455 
    456 ErrorExit:
    457 
    458     /* Base was set/validated above (10 or 16) */
    459 
    460     if (Base == 10)
    461     {
    462         return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
    463     }
    464     else
    465     {
    466         return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
    467     }
    468 }
    469 
    470 
    471 #ifdef _OBSOLETE_FUNCTIONS
    472 /* Removed: 01/2016 */
    473 
    474 /*******************************************************************************
    475  *
    476  * FUNCTION:    strtoul64
    477  *
    478  * PARAMETERS:  String              - Null terminated string
    479  *              Terminater          - Where a pointer to the terminating byte
    480  *                                    is returned
    481  *              Base                - Radix of the string
    482  *
    483  * RETURN:      Converted value
    484  *
    485  * DESCRIPTION: Convert a string into an unsigned value.
    486  *
    487  ******************************************************************************/
    488 
    489 ACPI_STATUS
    490 strtoul64 (
    491     char                    *String,
    492     UINT32                  Base,
    493     UINT64                  *RetInteger)
    494 {
    495     UINT32                  Index;
    496     UINT32                  Sign;
    497     UINT64                  ReturnValue = 0;
    498     ACPI_STATUS             Status = AE_OK;
    499 
    500 
    501     *RetInteger = 0;
    502 
    503     switch (Base)
    504     {
    505     case 0:
    506     case 8:
    507     case 10:
    508     case 16:
    509 
    510         break;
    511 
    512     default:
    513         /*
    514          * The specified Base parameter is not in the domain of
    515          * this function:
    516          */
    517         return (AE_BAD_PARAMETER);
    518     }
    519 
    520     /* Skip over any white space in the buffer: */
    521 
    522     while (isspace ((int) *String) || *String == '\t')
    523     {
    524         ++String;
    525     }
    526 
    527     /*
    528      * The buffer may contain an optional plus or minus sign.
    529      * If it does, then skip over it but remember what is was:
    530      */
    531     if (*String == '-')
    532     {
    533         Sign = ACPI_SIGN_NEGATIVE;
    534         ++String;
    535     }
    536     else if (*String == '+')
    537     {
    538         ++String;
    539         Sign = ACPI_SIGN_POSITIVE;
    540     }
    541     else
    542     {
    543         Sign = ACPI_SIGN_POSITIVE;
    544     }
    545 
    546     /*
    547      * If the input parameter Base is zero, then we need to
    548      * determine if it is octal, decimal, or hexadecimal:
    549      */
    550     if (Base == 0)
    551     {
    552         if (*String == '0')
    553         {
    554             if (tolower ((int) *(++String)) == 'x')
    555             {
    556                 Base = 16;
    557                 ++String;
    558             }
    559             else
    560             {
    561                 Base = 8;
    562             }
    563         }
    564         else
    565         {
    566             Base = 10;
    567         }
    568     }
    569 
    570     /*
    571      * For octal and hexadecimal bases, skip over the leading
    572      * 0 or 0x, if they are present.
    573      */
    574     if (Base == 8 && *String == '0')
    575     {
    576         String++;
    577     }
    578 
    579     if (Base == 16 &&
    580         *String == '0' &&
    581         tolower ((int) *(++String)) == 'x')
    582     {
    583         String++;
    584     }
    585 
    586     /* Main loop: convert the string to an unsigned long */
    587 
    588     while (*String)
    589     {
    590         if (isdigit ((int) *String))
    591         {
    592             Index = ((UINT8) *String) - '0';
    593         }
    594         else
    595         {
    596             Index = (UINT8) toupper ((int) *String);
    597             if (isupper ((int) Index))
    598             {
    599                 Index = Index - 'A' + 10;
    600             }
    601             else
    602             {
    603                 goto ErrorExit;
    604             }
    605         }
    606 
    607         if (Index >= Base)
    608         {
    609             goto ErrorExit;
    610         }
    611 
    612         /* Check to see if value is out of range: */
    613 
    614         if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
    615             (UINT64) Base))
    616         {
    617             goto ErrorExit;
    618         }
    619         else
    620         {
    621             ReturnValue *= Base;
    622             ReturnValue += Index;
    623         }
    624 
    625         ++String;
    626     }
    627 
    628 
    629     /* If a minus sign was present, then "the conversion is negated": */
    630 
    631     if (Sign == ACPI_SIGN_NEGATIVE)
    632     {
    633         ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
    634     }
    635 
    636     *RetInteger = ReturnValue;
    637     return (Status);
    638 
    639 
    640 ErrorExit:
    641     switch (Base)
    642     {
    643     case 8:
    644 
    645         Status = AE_BAD_OCTAL_CONSTANT;
    646         break;
    647 
    648     case 10:
    649 
    650         Status = AE_BAD_DECIMAL_CONSTANT;
    651         break;
    652 
    653     case 16:
    654 
    655         Status = AE_BAD_HEX_CONSTANT;
    656         break;
    657 
    658     default:
    659 
    660         /* Base validated above */
    661 
    662         break;
    663     }
    664 
    665     return (Status);
    666 }
    667 #endif
    668