linux/drivers/acpi/acpica/utstrtoul64.c
<<
>>
Prefs
   1/*******************************************************************************
   2 *
   3 * Module Name: utstrtoul64 - string to 64-bit integer support
   4 *
   5 ******************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2017, 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/*******************************************************************************
  48 *
  49 * The functions in this module satisfy the need for 64-bit string-to-integer
  50 * conversions on both 32-bit and 64-bit platforms.
  51 *
  52 ******************************************************************************/
  53
  54#define _COMPONENT          ACPI_UTILITIES
  55ACPI_MODULE_NAME("utstrtoul64")
  56
  57/* Local prototypes */
  58static u64 acpi_ut_strtoul_base10(char *string, u32 flags);
  59
  60static u64 acpi_ut_strtoul_base16(char *string, u32 flags);
  61
  62/*******************************************************************************
  63 *
  64 * String conversion rules as written in the ACPI specification. The error
  65 * conditions and behavior are different depending on the type of conversion.
  66 *
  67 *
  68 * Implicit data type conversion: string-to-integer
  69 * --------------------------------------------------
  70 *
  71 * Base is always 16. This is the ACPI_STRTOUL_BASE16 case.
  72 *
  73 * Example:
  74 *      Add ("BA98", Arg0, Local0)
  75 *
  76 * The integer is initialized to the value zero.
  77 * The ASCII string is interpreted as a hexadecimal constant.
  78 *
  79 *  1)  A "0x" prefix is not allowed. However, ACPICA allows this for
  80 *      compatibility with previous ACPICA. (NO ERROR)
  81 *
  82 *  2)  Terminates when the size of an integer is reached (32 or 64 bits).
  83 *      (NO ERROR)
  84 *
  85 *  3)  The first non-hex character terminates the conversion without error.
  86 *      (NO ERROR)
  87 *
  88 *  4)  Conversion of a null (zero-length) string to an integer is not
  89 *      allowed. However, ACPICA allows this for compatibility with previous
  90 *      ACPICA. This conversion returns the value 0. (NO ERROR)
  91 *
  92 *
  93 * Explicit data type conversion:  to_integer() with string operand
  94 * ---------------------------------------------------------------
  95 *
  96 * Base is either 10 (default) or 16 (with 0x prefix)
  97 *
  98 * Examples:
  99 *      to_integer ("1000")
 100 *      to_integer ("0xABCD")
 101 *
 102 *  1)  Can be (must be) either a decimal or hexadecimal numeric string.
 103 *      A hex value must be prefixed by "0x" or it is interpreted as a decimal.
 104 *
 105 *  2)  The value must not exceed the maximum of an integer value. ACPI spec
 106 *      states the behavior is "unpredictable", so ACPICA matches the behavior
 107 *      of the implicit conversion case.(NO ERROR)
 108 *
 109 *  3)  Behavior on the first non-hex character is not specified by the ACPI
 110 *      spec, so ACPICA matches the behavior of the implicit conversion case
 111 *      and terminates. (NO ERROR)
 112 *
 113 *  4)  A null (zero-length) string is illegal.
 114 *      However, ACPICA allows this for compatibility with previous ACPICA.
 115 *      This conversion returns the value 0. (NO ERROR)
 116 *
 117 ******************************************************************************/
 118
 119/*******************************************************************************
 120 *
 121 * FUNCTION:    acpi_ut_strtoul64
 122 *
 123 * PARAMETERS:  string                  - Null terminated input string
 124 *              flags                   - Conversion info, see below
 125 *              return_value            - Where the converted integer is
 126 *                                        returned
 127 *
 128 * RETURN:      Status and Converted value
 129 *
 130 * DESCRIPTION: Convert a string into an unsigned value. Performs either a
 131 *              32-bit or 64-bit conversion, depending on the input integer
 132 *              size in Flags (often the current mode of the interpreter).
 133 *
 134 * Values for Flags:
 135 *      ACPI_STRTOUL_32BIT      - Max integer value is 32 bits
 136 *      ACPI_STRTOUL_64BIT      - Max integer value is 64 bits
 137 *      ACPI_STRTOUL_BASE16     - Input string is hexadecimal. Default
 138 *                                is 10/16 based on string prefix (0x).
 139 *
 140 * NOTES:
 141 *   Negative numbers are not supported, as they are not supported by ACPI.
 142 *
 143 *   Supports only base 16 or base 10 strings/values. Does not
 144 *   support Octal strings, as these are not supported by ACPI.
 145 *
 146 * Current users of this support:
 147 *
 148 *  interpreter - Implicit and explicit conversions, GPE method names
 149 *  debugger    - Command line input string conversion
 150 *  iASL        - Main parser, conversion of constants to integers
 151 *  iASL        - Data Table Compiler parser (constant math expressions)
 152 *  iASL        - Preprocessor (constant math expressions)
 153 *  acpi_dump   - Input table addresses
 154 *  acpi_exec   - Testing of the acpi_ut_strtoul64 function
 155 *
 156 * Note concerning callers:
 157 *   acpi_gbl_integer_byte_width can be used to set the 32/64 limit. If used,
 158 *   this global should be set to the proper width. For the core ACPICA code,
 159 *   this width depends on the DSDT version. For iASL, the default byte
 160 *   width is always 8 for the parser, but error checking is performed later
 161 *   to flag cases where a 64-bit constant is defined in a 32-bit DSDT/SSDT.
 162 *
 163 ******************************************************************************/
 164
 165acpi_status acpi_ut_strtoul64(char *string, u32 flags, u64 *return_value)
 166{
 167        acpi_status status = AE_OK;
 168        u32 base;
 169
 170        ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string);
 171
 172        /* Parameter validation */
 173
 174        if (!string || !return_value) {
 175                return_ACPI_STATUS(AE_BAD_PARAMETER);
 176        }
 177
 178        *return_value = 0;
 179
 180        /* Check for zero-length string, returns 0 */
 181
 182        if (*string == 0) {
 183                return_ACPI_STATUS(AE_OK);
 184        }
 185
 186        /* Skip over any white space at start of string */
 187
 188        while (isspace((int)*string)) {
 189                string++;
 190        }
 191
 192        /* End of string? return 0 */
 193
 194        if (*string == 0) {
 195                return_ACPI_STATUS(AE_OK);
 196        }
 197
 198        /*
 199         * 1) The "0x" prefix indicates base 16. Per the ACPI specification,
 200         * the "0x" prefix is only allowed for implicit (non-strict) conversions.
 201         * However, we always allow it for compatibility with older ACPICA.
 202         */
 203        if ((*string == ACPI_ASCII_ZERO) &&
 204            (tolower((int)*(string + 1)) == 'x')) {
 205                string += 2;    /* Go past the 0x */
 206                if (*string == 0) {
 207                        return_ACPI_STATUS(AE_OK);      /* Return value 0 */
 208                }
 209
 210                base = 16;
 211        }
 212
 213        /* 2) Force to base 16 (implicit conversion case) */
 214
 215        else if (flags & ACPI_STRTOUL_BASE16) {
 216                base = 16;
 217        }
 218
 219        /* 3) Default fallback is to Base 10 */
 220
 221        else {
 222                base = 10;
 223        }
 224
 225        /* Skip all leading zeros */
 226
 227        while (*string == ACPI_ASCII_ZERO) {
 228                string++;
 229                if (*string == 0) {
 230                        return_ACPI_STATUS(AE_OK);      /* Return value 0 */
 231                }
 232        }
 233
 234        /* Perform the base 16 or 10 conversion */
 235
 236        if (base == 16) {
 237                *return_value = acpi_ut_strtoul_base16(string, flags);
 238        } else {
 239                *return_value = acpi_ut_strtoul_base10(string, flags);
 240        }
 241
 242        return_ACPI_STATUS(status);
 243}
 244
 245/*******************************************************************************
 246 *
 247 * FUNCTION:    acpi_ut_strtoul_base10
 248 *
 249 * PARAMETERS:  string                  - Null terminated input string
 250 *              flags                   - Conversion info
 251 *
 252 * RETURN:      64-bit converted integer
 253 *
 254 * DESCRIPTION: Performs a base 10 conversion of the input string to an
 255 *              integer value, either 32 or 64 bits.
 256 *              Note: String must be valid and non-null.
 257 *
 258 ******************************************************************************/
 259
 260static u64 acpi_ut_strtoul_base10(char *string, u32 flags)
 261{
 262        int ascii_digit;
 263        u64 next_value;
 264        u64 return_value = 0;
 265
 266        /* Main loop: convert each ASCII byte in the input string */
 267
 268        while (*string) {
 269                ascii_digit = *string;
 270                if (!isdigit(ascii_digit)) {
 271
 272                        /* Not ASCII 0-9, terminate */
 273
 274                        goto exit;
 275                }
 276
 277                /* Convert and insert (add) the decimal digit */
 278
 279                next_value =
 280                    (return_value * 10) + (ascii_digit - ACPI_ASCII_ZERO);
 281
 282                /* Check for overflow (32 or 64 bit) - return current converted value */
 283
 284                if (((flags & ACPI_STRTOUL_32BIT) && (next_value > ACPI_UINT32_MAX)) || (next_value < return_value)) {  /* 64-bit overflow case */
 285                        goto exit;
 286                }
 287
 288                return_value = next_value;
 289                string++;
 290        }
 291
 292exit:
 293        return (return_value);
 294}
 295
 296/*******************************************************************************
 297 *
 298 * FUNCTION:    acpi_ut_strtoul_base16
 299 *
 300 * PARAMETERS:  string                  - Null terminated input string
 301 *              flags                   - conversion info
 302 *
 303 * RETURN:      64-bit converted integer
 304 *
 305 * DESCRIPTION: Performs a base 16 conversion of the input string to an
 306 *              integer value, either 32 or 64 bits.
 307 *              Note: String must be valid and non-null.
 308 *
 309 ******************************************************************************/
 310
 311static u64 acpi_ut_strtoul_base16(char *string, u32 flags)
 312{
 313        int ascii_digit;
 314        u32 valid_digits = 1;
 315        u64 return_value = 0;
 316
 317        /* Main loop: convert each ASCII byte in the input string */
 318
 319        while (*string) {
 320
 321                /* Check for overflow (32 or 64 bit) - return current converted value */
 322
 323                if ((valid_digits > 16) ||
 324                    ((valid_digits > 8) && (flags & ACPI_STRTOUL_32BIT))) {
 325                        goto exit;
 326                }
 327
 328                ascii_digit = *string;
 329                if (!isxdigit(ascii_digit)) {
 330
 331                        /* Not Hex ASCII A-F, a-f, or 0-9, terminate */
 332
 333                        goto exit;
 334                }
 335
 336                /* Convert and insert the hex digit */
 337
 338                return_value =
 339                    (return_value << 4) |
 340                    acpi_ut_ascii_char_to_hex(ascii_digit);
 341
 342                string++;
 343                valid_digits++;
 344        }
 345
 346exit:
 347        return (return_value);
 348}
 349