Home | History | Annotate | Line # | Download | only in utilities
utnonansi.c revision 1.1
      1 /*******************************************************************************
      2  *
      3  * Module Name: utnonansi - Non-ansi C library functions
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2015, 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 /*******************************************************************************
    168  *
    169  * FUNCTION:    AcpiUtStrtoul64
    170  *
    171  * PARAMETERS:  String          - Null terminated string
    172  *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
    173  *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
    174  *              RetInteger      - Where the converted integer is returned
    175  *
    176  * RETURN:      Status and Converted value
    177  *
    178  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
    179  *              32-bit or 64-bit conversion, depending on the current mode
    180  *              of the interpreter.
    181  *
    182  * NOTE:        Does not support Octal strings, not needed.
    183  *
    184  ******************************************************************************/
    185 
    186 ACPI_STATUS
    187 AcpiUtStrtoul64 (
    188     char                    *String,
    189     UINT32                  Base,
    190     UINT64                  *RetInteger)
    191 {
    192     UINT32                  ThisDigit = 0;
    193     UINT64                  ReturnValue = 0;
    194     UINT64                  Quotient;
    195     UINT64                  Dividend;
    196     UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
    197     UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
    198     UINT8                   ValidDigits = 0;
    199     UINT8                   SignOf0x = 0;
    200     UINT8                   Term = 0;
    201 
    202 
    203     ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
    204 
    205 
    206     switch (Base)
    207     {
    208     case ACPI_ANY_BASE:
    209     case 16:
    210 
    211         break;
    212 
    213     default:
    214 
    215         /* Invalid Base */
    216 
    217         return_ACPI_STATUS (AE_BAD_PARAMETER);
    218     }
    219 
    220     if (!String)
    221     {
    222         goto ErrorExit;
    223     }
    224 
    225     /* Skip over any white space in the buffer */
    226 
    227     while ((*String) && (isspace ((int) *String) || *String == '\t'))
    228     {
    229         String++;
    230     }
    231 
    232     if (ToIntegerOp)
    233     {
    234         /*
    235          * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
    236          * We need to determine if it is decimal or hexadecimal.
    237          */
    238         if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x'))
    239         {
    240             SignOf0x = 1;
    241             Base = 16;
    242 
    243             /* Skip over the leading '0x' */
    244             String += 2;
    245         }
    246         else
    247         {
    248             Base = 10;
    249         }
    250     }
    251 
    252     /* Any string left? Check that '0x' is not followed by white space. */
    253 
    254     if (!(*String) || isspace ((int) *String) || *String == '\t')
    255     {
    256         if (ToIntegerOp)
    257         {
    258             goto ErrorExit;
    259         }
    260         else
    261         {
    262             goto AllDone;
    263         }
    264     }
    265 
    266     /*
    267      * Perform a 32-bit or 64-bit conversion, depending upon the current
    268      * execution mode of the interpreter
    269      */
    270     Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
    271 
    272     /* Main loop: convert the string to a 32- or 64-bit integer */
    273 
    274     while (*String)
    275     {
    276         if (isdigit ((int) *String))
    277         {
    278             /* Convert ASCII 0-9 to Decimal value */
    279 
    280             ThisDigit = ((UINT8) *String) - '0';
    281         }
    282         else if (Base == 10)
    283         {
    284             /* Digit is out of range; possible in ToInteger case only */
    285 
    286             Term = 1;
    287         }
    288         else
    289         {
    290             ThisDigit = (UINT8) toupper ((int) *String);
    291             if (isxdigit ((int) ThisDigit))
    292             {
    293                 /* Convert ASCII Hex char to value */
    294 
    295                 ThisDigit = ThisDigit - 'A' + 10;
    296             }
    297             else
    298             {
    299                 Term = 1;
    300             }
    301         }
    302 
    303         if (Term)
    304         {
    305             if (ToIntegerOp)
    306             {
    307                 goto ErrorExit;
    308             }
    309             else
    310             {
    311                 break;
    312             }
    313         }
    314         else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
    315         {
    316             /* Skip zeros */
    317             String++;
    318             continue;
    319         }
    320 
    321         ValidDigits++;
    322 
    323         if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
    324         {
    325             /*
    326              * This is ToInteger operation case.
    327              * No any restrictions for string-to-integer conversion,
    328              * see ACPI spec.
    329              */
    330             goto ErrorExit;
    331         }
    332 
    333         /* Divide the digit into the correct position */
    334 
    335         (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
    336                     Base, &Quotient, NULL);
    337 
    338         if (ReturnValue > Quotient)
    339         {
    340             if (ToIntegerOp)
    341             {
    342                 goto ErrorExit;
    343             }
    344             else
    345             {
    346                 break;
    347             }
    348         }
    349 
    350         ReturnValue *= Base;
    351         ReturnValue += ThisDigit;
    352         String++;
    353     }
    354 
    355     /* All done, normal exit */
    356 
    357 AllDone:
    358 
    359     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
    360         ACPI_FORMAT_UINT64 (ReturnValue)));
    361 
    362     *RetInteger = ReturnValue;
    363     return_ACPI_STATUS (AE_OK);
    364 
    365 
    366 ErrorExit:
    367     /* Base was set/validated above */
    368 
    369     if (Base == 10)
    370     {
    371         return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
    372     }
    373     else
    374     {
    375         return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
    376     }
    377 }
    378 
    379 
    380 #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
    381 /*******************************************************************************
    382  *
    383  * FUNCTION:    AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat
    384  *
    385  * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
    386  *              functions. This is the size of the Destination buffer.
    387  *
    388  * RETURN:      TRUE if the operation would overflow the destination buffer.
    389  *
    390  * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
    391  *              the result of the operation will not overflow the output string
    392  *              buffer.
    393  *
    394  * NOTE:        These functions are typically only helpful for processing
    395  *              user input and command lines. For most ACPICA code, the
    396  *              required buffer length is precisely calculated before buffer
    397  *              allocation, so the use of these functions is unnecessary.
    398  *
    399  ******************************************************************************/
    400 
    401 BOOLEAN
    402 AcpiUtSafeStrcpy (
    403     char                    *Dest,
    404     ACPI_SIZE               DestSize,
    405     char                    *Source)
    406 {
    407 
    408     if (strlen (Source) >= DestSize)
    409     {
    410         return (TRUE);
    411     }
    412 
    413     strcpy (Dest, Source);
    414     return (FALSE);
    415 }
    416 
    417 BOOLEAN
    418 AcpiUtSafeStrcat (
    419     char                    *Dest,
    420     ACPI_SIZE               DestSize,
    421     char                    *Source)
    422 {
    423 
    424     if ((strlen (Dest) + strlen (Source)) >= DestSize)
    425     {
    426         return (TRUE);
    427     }
    428 
    429     strcat (Dest, Source);
    430     return (FALSE);
    431 }
    432 
    433 BOOLEAN
    434 AcpiUtSafeStrncat (
    435     char                    *Dest,
    436     ACPI_SIZE               DestSize,
    437     char                    *Source,
    438     ACPI_SIZE               MaxTransferLength)
    439 {
    440     ACPI_SIZE               ActualTransferLength;
    441 
    442 
    443     ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source));
    444 
    445     if ((strlen (Dest) + ActualTransferLength) >= DestSize)
    446     {
    447         return (TRUE);
    448     }
    449 
    450     strncat (Dest, Source, MaxTransferLength);
    451     return (FALSE);
    452 }
    453 #endif
    454