Home | History | Annotate | Line # | Download | only in utilities
utstring.c revision 1.1.1.3
      1 /*******************************************************************************
      2  *
      3  * Module Name: utstring - Common functions for strings and characters
      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 #include "acnamesp.h"
     47 
     48 
     49 #define _COMPONENT          ACPI_UTILITIES
     50         ACPI_MODULE_NAME    ("utstring")
     51 
     52 
     53 /*
     54  * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit
     55  * version of strtoul.
     56  */
     57 
     58 #ifdef ACPI_ASL_COMPILER
     59 /*******************************************************************************
     60  *
     61  * FUNCTION:    AcpiUtStrlwr (strlwr)
     62  *
     63  * PARAMETERS:  SrcString       - The source string to convert
     64  *
     65  * RETURN:      None
     66  *
     67  * DESCRIPTION: Convert string to lowercase
     68  *
     69  * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
     70  *
     71  ******************************************************************************/
     72 
     73 void
     74 AcpiUtStrlwr (
     75     char                    *SrcString)
     76 {
     77     char                    *String;
     78 
     79 
     80     ACPI_FUNCTION_ENTRY ();
     81 
     82 
     83     if (!SrcString)
     84     {
     85         return;
     86     }
     87 
     88     /* Walk entire string, lowercasing the letters */
     89 
     90     for (String = SrcString; *String; String++)
     91     {
     92         *String = (char) ACPI_TOLOWER (*String);
     93     }
     94 
     95     return;
     96 }
     97 
     98 
     99 /******************************************************************************
    100  *
    101  * FUNCTION:    AcpiUtStricmp (stricmp)
    102  *
    103  * PARAMETERS:  String1             - first string to compare
    104  *              String2             - second string to compare
    105  *
    106  * RETURN:      int that signifies string relationship. Zero means strings
    107  *              are equal.
    108  *
    109  * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare
    110  *              strings with no case sensitivity)
    111  *
    112  ******************************************************************************/
    113 
    114 int
    115 AcpiUtStricmp (
    116     char                    *String1,
    117     char                    *String2)
    118 {
    119     int                     c1;
    120     int                     c2;
    121 
    122 
    123     do
    124     {
    125         c1 = tolower ((int) *String1);
    126         c2 = tolower ((int) *String2);
    127 
    128         String1++;
    129         String2++;
    130     }
    131     while ((c1 == c2) && (c1));
    132 
    133     return (c1 - c2);
    134 }
    135 #endif
    136 
    137 
    138 /*******************************************************************************
    139  *
    140  * FUNCTION:    AcpiUtStrupr (strupr)
    141  *
    142  * PARAMETERS:  SrcString       - The source string to convert
    143  *
    144  * RETURN:      None
    145  *
    146  * DESCRIPTION: Convert string to uppercase
    147  *
    148  * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
    149  *
    150  ******************************************************************************/
    151 
    152 void
    153 AcpiUtStrupr (
    154     char                    *SrcString)
    155 {
    156     char                    *String;
    157 
    158 
    159     ACPI_FUNCTION_ENTRY ();
    160 
    161 
    162     if (!SrcString)
    163     {
    164         return;
    165     }
    166 
    167     /* Walk entire string, uppercasing the letters */
    168 
    169     for (String = SrcString; *String; String++)
    170     {
    171         *String = (char) ACPI_TOUPPER (*String);
    172     }
    173 
    174     return;
    175 }
    176 
    177 
    178 /*******************************************************************************
    179  *
    180  * FUNCTION:    AcpiUtStrtoul64
    181  *
    182  * PARAMETERS:  String          - Null terminated string
    183  *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
    184  *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
    185  *              RetInteger      - Where the converted integer is returned
    186  *
    187  * RETURN:      Status and Converted value
    188  *
    189  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
    190  *              32-bit or 64-bit conversion, depending on the current mode
    191  *              of the interpreter.
    192  *              NOTE: Does not support Octal strings, not needed.
    193  *
    194  ******************************************************************************/
    195 
    196 ACPI_STATUS
    197 AcpiUtStrtoul64 (
    198     char                    *String,
    199     UINT32                  Base,
    200     UINT64                  *RetInteger)
    201 {
    202     UINT32                  ThisDigit = 0;
    203     UINT64                  ReturnValue = 0;
    204     UINT64                  Quotient;
    205     UINT64                  Dividend;
    206     UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
    207     UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
    208     UINT8                   ValidDigits = 0;
    209     UINT8                   SignOf0x = 0;
    210     UINT8                   Term = 0;
    211 
    212 
    213     ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
    214 
    215 
    216     switch (Base)
    217     {
    218     case ACPI_ANY_BASE:
    219     case 16:
    220 
    221         break;
    222 
    223     default:
    224 
    225         /* Invalid Base */
    226 
    227         return_ACPI_STATUS (AE_BAD_PARAMETER);
    228     }
    229 
    230     if (!String)
    231     {
    232         goto ErrorExit;
    233     }
    234 
    235     /* Skip over any white space in the buffer */
    236 
    237     while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t'))
    238     {
    239         String++;
    240     }
    241 
    242     if (ToIntegerOp)
    243     {
    244         /*
    245          * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
    246          * We need to determine if it is decimal or hexadecimal.
    247          */
    248         if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x'))
    249         {
    250             SignOf0x = 1;
    251             Base = 16;
    252 
    253             /* Skip over the leading '0x' */
    254             String += 2;
    255         }
    256         else
    257         {
    258             Base = 10;
    259         }
    260     }
    261 
    262     /* Any string left? Check that '0x' is not followed by white space. */
    263 
    264     if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t')
    265     {
    266         if (ToIntegerOp)
    267         {
    268             goto ErrorExit;
    269         }
    270         else
    271         {
    272             goto AllDone;
    273         }
    274     }
    275 
    276     /*
    277      * Perform a 32-bit or 64-bit conversion, depending upon the current
    278      * execution mode of the interpreter
    279      */
    280     Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
    281 
    282     /* Main loop: convert the string to a 32- or 64-bit integer */
    283 
    284     while (*String)
    285     {
    286         if (ACPI_IS_DIGIT (*String))
    287         {
    288             /* Convert ASCII 0-9 to Decimal value */
    289 
    290             ThisDigit = ((UINT8) *String) - '0';
    291         }
    292         else if (Base == 10)
    293         {
    294             /* Digit is out of range; possible in ToInteger case only */
    295 
    296             Term = 1;
    297         }
    298         else
    299         {
    300             ThisDigit = (UINT8) ACPI_TOUPPER (*String);
    301             if (ACPI_IS_XDIGIT ((char) ThisDigit))
    302             {
    303                 /* Convert ASCII Hex char to value */
    304 
    305                 ThisDigit = ThisDigit - 'A' + 10;
    306             }
    307             else
    308             {
    309                 Term = 1;
    310             }
    311         }
    312 
    313         if (Term)
    314         {
    315             if (ToIntegerOp)
    316             {
    317                 goto ErrorExit;
    318             }
    319             else
    320             {
    321                 break;
    322             }
    323         }
    324         else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x)
    325         {
    326             /* Skip zeros */
    327             String++;
    328             continue;
    329         }
    330 
    331         ValidDigits++;
    332 
    333         if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
    334         {
    335             /*
    336              * This is ToInteger operation case.
    337              * No any restrictions for string-to-integer conversion,
    338              * see ACPI spec.
    339              */
    340             goto ErrorExit;
    341         }
    342 
    343         /* Divide the digit into the correct position */
    344 
    345         (void) AcpiUtShortDivide ((Dividend - (UINT64) ThisDigit),
    346                     Base, &Quotient, NULL);
    347 
    348         if (ReturnValue > Quotient)
    349         {
    350             if (ToIntegerOp)
    351             {
    352                 goto ErrorExit;
    353             }
    354             else
    355             {
    356                 break;
    357             }
    358         }
    359 
    360         ReturnValue *= Base;
    361         ReturnValue += ThisDigit;
    362         String++;
    363     }
    364 
    365     /* All done, normal exit */
    366 
    367 AllDone:
    368 
    369     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
    370         ACPI_FORMAT_UINT64 (ReturnValue)));
    371 
    372     *RetInteger = ReturnValue;
    373     return_ACPI_STATUS (AE_OK);
    374 
    375 
    376 ErrorExit:
    377     /* Base was set/validated above */
    378 
    379     if (Base == 10)
    380     {
    381         return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT);
    382     }
    383     else
    384     {
    385         return_ACPI_STATUS (AE_BAD_HEX_CONSTANT);
    386     }
    387 }
    388 
    389 
    390 /*******************************************************************************
    391  *
    392  * FUNCTION:    AcpiUtPrintString
    393  *
    394  * PARAMETERS:  String          - Null terminated ASCII string
    395  *              MaxLength       - Maximum output length. Used to constrain the
    396  *                                length of strings during debug output only.
    397  *
    398  * RETURN:      None
    399  *
    400  * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
    401  *              sequences.
    402  *
    403  ******************************************************************************/
    404 
    405 void
    406 AcpiUtPrintString (
    407     char                    *String,
    408     UINT16                  MaxLength)
    409 {
    410     UINT32                  i;
    411 
    412 
    413     if (!String)
    414     {
    415         AcpiOsPrintf ("<\"NULL STRING PTR\">");
    416         return;
    417     }
    418 
    419     AcpiOsPrintf ("\"");
    420     for (i = 0; (i < MaxLength) && String[i]; i++)
    421     {
    422         /* Escape sequences */
    423 
    424         switch (String[i])
    425         {
    426         case 0x07:
    427 
    428             AcpiOsPrintf ("\\a");       /* BELL */
    429             break;
    430 
    431         case 0x08:
    432 
    433             AcpiOsPrintf ("\\b");       /* BACKSPACE */
    434             break;
    435 
    436         case 0x0C:
    437 
    438             AcpiOsPrintf ("\\f");       /* FORMFEED */
    439             break;
    440 
    441         case 0x0A:
    442 
    443             AcpiOsPrintf ("\\n");       /* LINEFEED */
    444             break;
    445 
    446         case 0x0D:
    447 
    448             AcpiOsPrintf ("\\r");       /* CARRIAGE RETURN*/
    449             break;
    450 
    451         case 0x09:
    452 
    453             AcpiOsPrintf ("\\t");       /* HORIZONTAL TAB */
    454             break;
    455 
    456         case 0x0B:
    457 
    458             AcpiOsPrintf ("\\v");       /* VERTICAL TAB */
    459             break;
    460 
    461         case '\'':                      /* Single Quote */
    462         case '\"':                      /* Double Quote */
    463         case '\\':                      /* Backslash */
    464 
    465             AcpiOsPrintf ("\\%c", (int) String[i]);
    466             break;
    467 
    468         default:
    469 
    470             /* Check for printable character or hex escape */
    471 
    472             if (ACPI_IS_PRINT (String[i]))
    473             {
    474                 /* This is a normal character */
    475 
    476                 AcpiOsPrintf ("%c", (int) String[i]);
    477             }
    478             else
    479             {
    480                 /* All others will be Hex escapes */
    481 
    482                 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]);
    483             }
    484             break;
    485         }
    486     }
    487     AcpiOsPrintf ("\"");
    488 
    489     if (i == MaxLength && String[i])
    490     {
    491         AcpiOsPrintf ("...");
    492     }
    493 }
    494 
    495 
    496 /*******************************************************************************
    497  *
    498  * FUNCTION:    AcpiUtValidAcpiChar
    499  *
    500  * PARAMETERS:  Char            - The character to be examined
    501  *              Position        - Byte position (0-3)
    502  *
    503  * RETURN:      TRUE if the character is valid, FALSE otherwise
    504  *
    505  * DESCRIPTION: Check for a valid ACPI character. Must be one of:
    506  *              1) Upper case alpha
    507  *              2) numeric
    508  *              3) underscore
    509  *
    510  *              We allow a '!' as the last character because of the ASF! table
    511  *
    512  ******************************************************************************/
    513 
    514 BOOLEAN
    515 AcpiUtValidAcpiChar (
    516     char                    Character,
    517     UINT32                  Position)
    518 {
    519 
    520     if (!((Character >= 'A' && Character <= 'Z') ||
    521           (Character >= '0' && Character <= '9') ||
    522           (Character == '_')))
    523     {
    524         /* Allow a '!' in the last position */
    525 
    526         if (Character == '!' && Position == 3)
    527         {
    528             return (TRUE);
    529         }
    530 
    531         return (FALSE);
    532     }
    533 
    534     return (TRUE);
    535 }
    536 
    537 
    538 /*******************************************************************************
    539  *
    540  * FUNCTION:    AcpiUtValidAcpiName
    541  *
    542  * PARAMETERS:  Name            - The name to be examined. Does not have to
    543  *                                be NULL terminated string.
    544  *
    545  * RETURN:      TRUE if the name is valid, FALSE otherwise
    546  *
    547  * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
    548  *              1) Upper case alpha
    549  *              2) numeric
    550  *              3) underscore
    551  *
    552  ******************************************************************************/
    553 
    554 BOOLEAN
    555 AcpiUtValidAcpiName (
    556     char                    *Name)
    557 {
    558     UINT32                  i;
    559 
    560 
    561     ACPI_FUNCTION_ENTRY ();
    562 
    563 
    564     for (i = 0; i < ACPI_NAME_SIZE; i++)
    565     {
    566         if (!AcpiUtValidAcpiChar (Name[i], i))
    567         {
    568             return (FALSE);
    569         }
    570     }
    571 
    572     return (TRUE);
    573 }
    574 
    575 
    576 /*******************************************************************************
    577  *
    578  * FUNCTION:    AcpiUtRepairName
    579  *
    580  * PARAMETERS:  Name            - The ACPI name to be repaired
    581  *
    582  * RETURN:      Repaired version of the name
    583  *
    584  * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
    585  *              return the new name. NOTE: the Name parameter must reside in
    586  *              read/write memory, cannot be a const.
    587  *
    588  * An ACPI Name must consist of valid ACPI characters. We will repair the name
    589  * if necessary because we don't want to abort because of this, but we want
    590  * all namespace names to be printable. A warning message is appropriate.
    591  *
    592  * This issue came up because there are in fact machines that exhibit
    593  * this problem, and we want to be able to enable ACPI support for them,
    594  * even though there are a few bad names.
    595  *
    596  ******************************************************************************/
    597 
    598 void
    599 AcpiUtRepairName (
    600     char                    *Name)
    601 {
    602     UINT32                  i;
    603     BOOLEAN                 FoundBadChar = FALSE;
    604     UINT32                  OriginalName;
    605 
    606 
    607     ACPI_FUNCTION_NAME (UtRepairName);
    608 
    609 
    610     ACPI_MOVE_NAME (&OriginalName, Name);
    611 
    612     /* Check each character in the name */
    613 
    614     for (i = 0; i < ACPI_NAME_SIZE; i++)
    615     {
    616         if (AcpiUtValidAcpiChar (Name[i], i))
    617         {
    618             continue;
    619         }
    620 
    621         /*
    622          * Replace a bad character with something printable, yet technically
    623          * still invalid. This prevents any collisions with existing "good"
    624          * names in the namespace.
    625          */
    626         Name[i] = '*';
    627         FoundBadChar = TRUE;
    628     }
    629 
    630     if (FoundBadChar)
    631     {
    632         /* Report warning only if in strict mode or debug mode */
    633 
    634         if (!AcpiGbl_EnableInterpreterSlack)
    635         {
    636             ACPI_WARNING ((AE_INFO,
    637                 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
    638                 OriginalName, Name));
    639         }
    640         else
    641         {
    642             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    643                 "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
    644                 OriginalName, Name));
    645         }
    646     }
    647 }
    648 
    649 
    650 #if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
    651 /*******************************************************************************
    652  *
    653  * FUNCTION:    UtConvertBackslashes
    654  *
    655  * PARAMETERS:  Pathname        - File pathname string to be converted
    656  *
    657  * RETURN:      Modifies the input Pathname
    658  *
    659  * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
    660  *              the entire input file pathname string.
    661  *
    662  ******************************************************************************/
    663 
    664 void
    665 UtConvertBackslashes (
    666     char                    *Pathname)
    667 {
    668 
    669     if (!Pathname)
    670     {
    671         return;
    672     }
    673 
    674     while (*Pathname)
    675     {
    676         if (*Pathname == '\\')
    677         {
    678             *Pathname = '/';
    679         }
    680 
    681         Pathname++;
    682     }
    683 }
    684 #endif
    685 
    686 #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
    687 /*******************************************************************************
    688  *
    689  * FUNCTION:    AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat
    690  *
    691  * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
    692  *              functions. This is the size of the Destination buffer.
    693  *
    694  * RETURN:      TRUE if the operation would overflow the destination buffer.
    695  *
    696  * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
    697  *              the result of the operation will not overflow the output string
    698  *              buffer.
    699  *
    700  * NOTE:        These functions are typically only helpful for processing
    701  *              user input and command lines. For most ACPICA code, the
    702  *              required buffer length is precisely calculated before buffer
    703  *              allocation, so the use of these functions is unnecessary.
    704  *
    705  ******************************************************************************/
    706 
    707 BOOLEAN
    708 AcpiUtSafeStrcpy (
    709     char                    *Dest,
    710     ACPI_SIZE               DestSize,
    711     char                    *Source)
    712 {
    713 
    714     if (ACPI_STRLEN (Source) >= DestSize)
    715     {
    716         return (TRUE);
    717     }
    718 
    719     ACPI_STRCPY (Dest, Source);
    720     return (FALSE);
    721 }
    722 
    723 BOOLEAN
    724 AcpiUtSafeStrcat (
    725     char                    *Dest,
    726     ACPI_SIZE               DestSize,
    727     char                    *Source)
    728 {
    729 
    730     if ((ACPI_STRLEN (Dest) + ACPI_STRLEN (Source)) >= DestSize)
    731     {
    732         return (TRUE);
    733     }
    734 
    735     ACPI_STRCAT (Dest, Source);
    736     return (FALSE);
    737 }
    738 
    739 BOOLEAN
    740 AcpiUtSafeStrncat (
    741     char                    *Dest,
    742     ACPI_SIZE               DestSize,
    743     char                    *Source,
    744     ACPI_SIZE               MaxTransferLength)
    745 {
    746     ACPI_SIZE               ActualTransferLength;
    747 
    748 
    749     ActualTransferLength = ACPI_MIN (MaxTransferLength, ACPI_STRLEN (Source));
    750 
    751     if ((ACPI_STRLEN (Dest) + ActualTransferLength) >= DestSize)
    752     {
    753         return (TRUE);
    754     }
    755 
    756     ACPI_STRNCAT (Dest, Source, MaxTransferLength);
    757     return (FALSE);
    758 }
    759 #endif
    760