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