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