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