Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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/acpi.h>
  45. #include "accommon.h"
  46.  
  47. #define _COMPONENT          ACPI_UTILITIES
  48. ACPI_MODULE_NAME("utnonansi")
  49.  
  50. /*
  51.  * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit
  52.  * version of strtoul.
  53.  */
  54. /*******************************************************************************
  55.  *
  56.  * FUNCTION:    acpi_ut_strlwr (strlwr)
  57.  *
  58.  * PARAMETERS:  src_string      - The source string to convert
  59.  *
  60.  * RETURN:      None
  61.  *
  62.  * DESCRIPTION: Convert a string to lowercase
  63.  *
  64.  ******************************************************************************/
  65. void acpi_ut_strlwr(char *src_string)
  66. {
  67.         char *string;
  68.  
  69.         ACPI_FUNCTION_ENTRY();
  70.  
  71.         if (!src_string) {
  72.                 return;
  73.         }
  74.  
  75.         /* Walk entire string, lowercasing the letters */
  76.  
  77.         for (string = src_string; *string; string++) {
  78.                 *string = (char)tolower((int)*string);
  79.         }
  80. }
  81.  
  82. /*******************************************************************************
  83.  *
  84.  * FUNCTION:    acpi_ut_strupr (strupr)
  85.  *
  86.  * PARAMETERS:  src_string      - The source string to convert
  87.  *
  88.  * RETURN:      None
  89.  *
  90.  * DESCRIPTION: Convert a string to uppercase
  91.  *
  92.  ******************************************************************************/
  93.  
  94. void acpi_ut_strupr(char *src_string)
  95. {
  96.         char *string;
  97.  
  98.         ACPI_FUNCTION_ENTRY();
  99.  
  100.         if (!src_string) {
  101.                 return;
  102.         }
  103.  
  104.         /* Walk entire string, uppercasing the letters */
  105.  
  106.         for (string = src_string; *string; string++) {
  107.                 *string = (char)toupper((int)*string);
  108.         }
  109. }
  110.  
  111. /******************************************************************************
  112.  *
  113.  * FUNCTION:    acpi_ut_stricmp (stricmp)
  114.  *
  115.  * PARAMETERS:  string1             - first string to compare
  116.  *              string2             - second string to compare
  117.  *
  118.  * RETURN:      int that signifies string relationship. Zero means strings
  119.  *              are equal.
  120.  *
  121.  * DESCRIPTION: Case-insensitive string compare. Implementation of the
  122.  *              non-ANSI stricmp function.
  123.  *
  124.  ******************************************************************************/
  125.  
  126. int acpi_ut_stricmp(char *string1, char *string2)
  127. {
  128.         int c1;
  129.         int c2;
  130.  
  131.         do {
  132.                 c1 = tolower((int)*string1);
  133.                 c2 = tolower((int)*string2);
  134.  
  135.                 string1++;
  136.                 string2++;
  137.         }
  138.         while ((c1 == c2) && (c1));
  139.  
  140.         return (c1 - c2);
  141. }
  142.  
  143. /*******************************************************************************
  144.  *
  145.  * FUNCTION:    acpi_ut_strtoul64
  146.  *
  147.  * PARAMETERS:  string          - Null terminated string
  148.  *              base            - Radix of the string: 16 or ACPI_ANY_BASE;
  149.  *                                ACPI_ANY_BASE means 'in behalf of to_integer'
  150.  *              ret_integer     - Where the converted integer is returned
  151.  *
  152.  * RETURN:      Status and Converted value
  153.  *
  154.  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
  155.  *              32-bit or 64-bit conversion, depending on the current mode
  156.  *              of the interpreter.
  157.  *
  158.  * NOTE:        Does not support Octal strings, not needed.
  159.  *
  160.  ******************************************************************************/
  161.  
  162. acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer)
  163. {
  164.         u32 this_digit = 0;
  165.         u64 return_value = 0;
  166.         u64 quotient;
  167.         u64 dividend;
  168.         u32 to_integer_op = (base == ACPI_ANY_BASE);
  169.         u32 mode32 = (acpi_gbl_integer_byte_width == 4);
  170.         u8 valid_digits = 0;
  171.         u8 sign_of0x = 0;
  172.         u8 term = 0;
  173.  
  174.         ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
  175.  
  176.         switch (base) {
  177.         case ACPI_ANY_BASE:
  178.         case 16:
  179.  
  180.                 break;
  181.  
  182.         default:
  183.  
  184.                 /* Invalid Base */
  185.  
  186.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  187.         }
  188.  
  189.         if (!string) {
  190.                 goto error_exit;
  191.         }
  192.  
  193.         /* Skip over any white space in the buffer */
  194.  
  195.         while ((*string) && (isspace((int)*string) || *string == '\t')) {
  196.                 string++;
  197.         }
  198.  
  199.         if (to_integer_op) {
  200.                 /*
  201.                  * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
  202.                  * We need to determine if it is decimal or hexadecimal.
  203.                  */
  204.                 if ((*string == '0') && (tolower((int)*(string + 1)) == 'x')) {
  205.                         sign_of0x = 1;
  206.                         base = 16;
  207.  
  208.                         /* Skip over the leading '0x' */
  209.                         string += 2;
  210.                 } else {
  211.                         base = 10;
  212.                 }
  213.         }
  214.  
  215.         /* Any string left? Check that '0x' is not followed by white space. */
  216.  
  217.         if (!(*string) || isspace((int)*string) || *string == '\t') {
  218.                 if (to_integer_op) {
  219.                         goto error_exit;
  220.                 } else {
  221.                         goto all_done;
  222.                 }
  223.         }
  224.  
  225.         /*
  226.          * Perform a 32-bit or 64-bit conversion, depending upon the current
  227.          * execution mode of the interpreter
  228.          */
  229.         dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
  230.  
  231.         /* Main loop: convert the string to a 32- or 64-bit integer */
  232.  
  233.         while (*string) {
  234.                 if (isdigit((int)*string)) {
  235.  
  236.                         /* Convert ASCII 0-9 to Decimal value */
  237.  
  238.                         this_digit = ((u8)*string) - '0';
  239.                 } else if (base == 10) {
  240.  
  241.                         /* Digit is out of range; possible in to_integer case only */
  242.  
  243.                         term = 1;
  244.                 } else {
  245.                         this_digit = (u8)toupper((int)*string);
  246.                         if (isxdigit((int)this_digit)) {
  247.  
  248.                                 /* Convert ASCII Hex char to value */
  249.  
  250.                                 this_digit = this_digit - 'A' + 10;
  251.                         } else {
  252.                                 term = 1;
  253.                         }
  254.                 }
  255.  
  256.                 if (term) {
  257.                         if (to_integer_op) {
  258.                                 goto error_exit;
  259.                         } else {
  260.                                 break;
  261.                         }
  262.                 } else if ((valid_digits == 0) && (this_digit == 0)
  263.                            && !sign_of0x) {
  264.  
  265.                         /* Skip zeros */
  266.                         string++;
  267.                         continue;
  268.                 }
  269.  
  270.                 valid_digits++;
  271.  
  272.                 if (sign_of0x
  273.                     && ((valid_digits > 16)
  274.                         || ((valid_digits > 8) && mode32))) {
  275.                         /*
  276.                          * This is to_integer operation case.
  277.                          * No any restrictions for string-to-integer conversion,
  278.                          * see ACPI spec.
  279.                          */
  280.                         goto error_exit;
  281.                 }
  282.  
  283.                 /* Divide the digit into the correct position */
  284.  
  285.                 (void)acpi_ut_short_divide((dividend - (u64)this_digit),
  286.                                            base, &quotient, NULL);
  287.  
  288.                 if (return_value > quotient) {
  289.                         if (to_integer_op) {
  290.                                 goto error_exit;
  291.                         } else {
  292.                                 break;
  293.                         }
  294.                 }
  295.  
  296.                 return_value *= base;
  297.                 return_value += this_digit;
  298.                 string++;
  299.         }
  300.  
  301.         /* All done, normal exit */
  302.  
  303. all_done:
  304.  
  305.         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
  306.                           ACPI_FORMAT_UINT64(return_value)));
  307.  
  308.         *ret_integer = return_value;
  309.         return_ACPI_STATUS(AE_OK);
  310.  
  311. error_exit:
  312.         /* Base was set/validated above */
  313.  
  314.         if (base == 10) {
  315.                 return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT);
  316.         } else {
  317.                 return_ACPI_STATUS(AE_BAD_HEX_CONSTANT);
  318.         }
  319. }
  320.  
  321. #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
  322. /*******************************************************************************
  323.  *
  324.  * FUNCTION:    acpi_ut_safe_strcpy, acpi_ut_safe_strcat, acpi_ut_safe_strncat
  325.  *
  326.  * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
  327.  *              functions. This is the size of the Destination buffer.
  328.  *
  329.  * RETURN:      TRUE if the operation would overflow the destination buffer.
  330.  *
  331.  * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
  332.  *              the result of the operation will not overflow the output string
  333.  *              buffer.
  334.  *
  335.  * NOTE:        These functions are typically only helpful for processing
  336.  *              user input and command lines. For most ACPICA code, the
  337.  *              required buffer length is precisely calculated before buffer
  338.  *              allocation, so the use of these functions is unnecessary.
  339.  *
  340.  ******************************************************************************/
  341.  
  342. u8 acpi_ut_safe_strcpy(char *dest, acpi_size dest_size, char *source)
  343. {
  344.  
  345.         if (strlen(source) >= dest_size) {
  346.                 return (TRUE);
  347.         }
  348.  
  349.         strcpy(dest, source);
  350.         return (FALSE);
  351. }
  352.  
  353. u8 acpi_ut_safe_strcat(char *dest, acpi_size dest_size, char *source)
  354. {
  355.  
  356.         if ((strlen(dest) + strlen(source)) >= dest_size) {
  357.                 return (TRUE);
  358.         }
  359.  
  360.         strcat(dest, source);
  361.         return (FALSE);
  362. }
  363.  
  364. u8
  365. acpi_ut_safe_strncat(char *dest,
  366.                      acpi_size dest_size,
  367.                      char *source, acpi_size max_transfer_length)
  368. {
  369.         acpi_size actual_transfer_length;
  370.  
  371.         actual_transfer_length = ACPI_MIN(max_transfer_length, strlen(source));
  372.  
  373.         if ((strlen(dest) + actual_transfer_length) >= dest_size) {
  374.                 return (TRUE);
  375.         }
  376.  
  377.         strncat(dest, source, max_transfer_length);
  378.         return (FALSE);
  379. }
  380. #endif
  381.