utstrtoul64.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*******************************************************************************
  2. *
  3. * Module Name: utstrtoul64 - string to 64-bit integer support
  4. *
  5. ******************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2016, Intel Corp.
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions, and the following disclaimer,
  15. * without modification.
  16. * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  17. * substantially similar to the "NO WARRANTY" disclaimer below
  18. * ("Disclaimer") and any redistribution must be conditioned upon
  19. * including a substantially similar Disclaimer requirement for further
  20. * binary redistribution.
  21. * 3. Neither the names of the above-listed copyright holders nor the names
  22. * of any contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * Alternatively, this software may be distributed under the terms of the
  26. * GNU General Public License ("GPL") version 2 as published by the Free
  27. * Software Foundation.
  28. *
  29. * NO WARRANTY
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  33. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  34. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  38. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  39. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGES.
  41. */
  42. #include <acpi/acpi.h>
  43. #include "accommon.h"
  44. /*******************************************************************************
  45. *
  46. * The functions in this module satisfy the need for 64-bit string-to-integer
  47. * conversions on both 32-bit and 64-bit platforms.
  48. *
  49. ******************************************************************************/
  50. #define _COMPONENT ACPI_UTILITIES
  51. ACPI_MODULE_NAME("utstrtoul64")
  52. /* Local prototypes */
  53. static u64 acpi_ut_strtoul_base10(char *string, u32 flags);
  54. static u64 acpi_ut_strtoul_base16(char *string, u32 flags);
  55. /*******************************************************************************
  56. *
  57. * String conversion rules as written in the ACPI specification. The error
  58. * conditions and behavior are different depending on the type of conversion.
  59. *
  60. *
  61. * Implicit data type conversion: string-to-integer
  62. * --------------------------------------------------
  63. *
  64. * Base is always 16. This is the ACPI_STRTOUL_BASE16 case.
  65. *
  66. * Example:
  67. * Add ("BA98", Arg0, Local0)
  68. *
  69. * The integer is initialized to the value zero.
  70. * The ASCII string is interpreted as a hexadecimal constant.
  71. *
  72. * 1) A "0x" prefix is not allowed. However, ACPICA allows this for
  73. * compatibility with previous ACPICA. (NO ERROR)
  74. *
  75. * 2) Terminates when the size of an integer is reached (32 or 64 bits).
  76. * (NO ERROR)
  77. *
  78. * 3) The first non-hex character terminates the conversion without error.
  79. * (NO ERROR)
  80. *
  81. * 4) Conversion of a null (zero-length) string to an integer is not
  82. * allowed. However, ACPICA allows this for compatibility with previous
  83. * ACPICA. This conversion returns the value 0. (NO ERROR)
  84. *
  85. *
  86. * Explicit data type conversion: to_integer() with string operand
  87. * ---------------------------------------------------------------
  88. *
  89. * Base is either 10 (default) or 16 (with 0x prefix)
  90. *
  91. * Examples:
  92. * to_integer ("1000")
  93. * to_integer ("0xABCD")
  94. *
  95. * 1) Can be (must be) either a decimal or hexadecimal numeric string.
  96. * A hex value must be prefixed by "0x" or it is interpreted as a decimal.
  97. *
  98. * 2) The value must not exceed the maximum of an integer value. ACPI spec
  99. * states the behavior is "unpredictable", so ACPICA matches the behavior
  100. * of the implicit conversion case.(NO ERROR)
  101. *
  102. * 3) Behavior on the first non-hex character is not specified by the ACPI
  103. * spec, so ACPICA matches the behavior of the implicit conversion case
  104. * and terminates. (NO ERROR)
  105. *
  106. * 4) A null (zero-length) string is illegal.
  107. * However, ACPICA allows this for compatibility with previous ACPICA.
  108. * This conversion returns the value 0. (NO ERROR)
  109. *
  110. ******************************************************************************/
  111. /*******************************************************************************
  112. *
  113. * FUNCTION: acpi_ut_strtoul64
  114. *
  115. * PARAMETERS: string - Null terminated input string
  116. * flags - Conversion info, see below
  117. * return_value - Where the converted integer is
  118. * returned
  119. *
  120. * RETURN: Status and Converted value
  121. *
  122. * DESCRIPTION: Convert a string into an unsigned value. Performs either a
  123. * 32-bit or 64-bit conversion, depending on the input integer
  124. * size in Flags (often the current mode of the interpreter).
  125. *
  126. * Values for Flags:
  127. * ACPI_STRTOUL_32BIT - Max integer value is 32 bits
  128. * ACPI_STRTOUL_64BIT - Max integer value is 64 bits
  129. * ACPI_STRTOUL_BASE16 - Input string is hexadecimal. Default
  130. * is 10/16 based on string prefix (0x).
  131. *
  132. * NOTES:
  133. * Negative numbers are not supported, as they are not supported by ACPI.
  134. *
  135. * Supports only base 16 or base 10 strings/values. Does not
  136. * support Octal strings, as these are not supported by ACPI.
  137. *
  138. * Current users of this support:
  139. *
  140. * interpreter - Implicit and explicit conversions, GPE method names
  141. * debugger - Command line input string conversion
  142. * iASL - Main parser, conversion of constants to integers
  143. * iASL - Data Table Compiler parser (constant math expressions)
  144. * iASL - Preprocessor (constant math expressions)
  145. * acpi_dump - Input table addresses
  146. * acpi_exec - Testing of the acpi_ut_strtoul64 function
  147. *
  148. * Note concerning callers:
  149. * acpi_gbl_integer_byte_width can be used to set the 32/64 limit. If used,
  150. * this global should be set to the proper width. For the core ACPICA code,
  151. * this width depends on the DSDT version. For iASL, the default byte
  152. * width is always 8 for the parser, but error checking is performed later
  153. * to flag cases where a 64-bit constant is defined in a 32-bit DSDT/SSDT.
  154. *
  155. ******************************************************************************/
  156. acpi_status acpi_ut_strtoul64(char *string, u32 flags, u64 *return_value)
  157. {
  158. acpi_status status = AE_OK;
  159. u32 base;
  160. ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string);
  161. /* Parameter validation */
  162. if (!string || !return_value) {
  163. return_ACPI_STATUS(AE_BAD_PARAMETER);
  164. }
  165. *return_value = 0;
  166. /* Check for zero-length string, returns 0 */
  167. if (*string == 0) {
  168. return_ACPI_STATUS(AE_OK);
  169. }
  170. /* Skip over any white space at start of string */
  171. while (isspace((int)*string)) {
  172. string++;
  173. }
  174. /* End of string? return 0 */
  175. if (*string == 0) {
  176. return_ACPI_STATUS(AE_OK);
  177. }
  178. /*
  179. * 1) The "0x" prefix indicates base 16. Per the ACPI specification,
  180. * the "0x" prefix is only allowed for implicit (non-strict) conversions.
  181. * However, we always allow it for compatibility with older ACPICA.
  182. */
  183. if ((*string == ACPI_ASCII_ZERO) &&
  184. (tolower((int)*(string + 1)) == 'x')) {
  185. string += 2; /* Go past the 0x */
  186. if (*string == 0) {
  187. return_ACPI_STATUS(AE_OK); /* Return value 0 */
  188. }
  189. base = 16;
  190. }
  191. /* 2) Force to base 16 (implicit conversion case) */
  192. else if (flags & ACPI_STRTOUL_BASE16) {
  193. base = 16;
  194. }
  195. /* 3) Default fallback is to Base 10 */
  196. else {
  197. base = 10;
  198. }
  199. /* Skip all leading zeros */
  200. while (*string == ACPI_ASCII_ZERO) {
  201. string++;
  202. if (*string == 0) {
  203. return_ACPI_STATUS(AE_OK); /* Return value 0 */
  204. }
  205. }
  206. /* Perform the base 16 or 10 conversion */
  207. if (base == 16) {
  208. *return_value = acpi_ut_strtoul_base16(string, flags);
  209. } else {
  210. *return_value = acpi_ut_strtoul_base10(string, flags);
  211. }
  212. return_ACPI_STATUS(status);
  213. }
  214. /*******************************************************************************
  215. *
  216. * FUNCTION: acpi_ut_strtoul_base10
  217. *
  218. * PARAMETERS: string - Null terminated input string
  219. * flags - Conversion info
  220. *
  221. * RETURN: 64-bit converted integer
  222. *
  223. * DESCRIPTION: Performs a base 10 conversion of the input string to an
  224. * integer value, either 32 or 64 bits.
  225. * Note: String must be valid and non-null.
  226. *
  227. ******************************************************************************/
  228. static u64 acpi_ut_strtoul_base10(char *string, u32 flags)
  229. {
  230. int ascii_digit;
  231. u64 next_value;
  232. u64 return_value = 0;
  233. /* Main loop: convert each ASCII byte in the input string */
  234. while (*string) {
  235. ascii_digit = *string;
  236. if (!isdigit(ascii_digit)) {
  237. /* Not ASCII 0-9, terminate */
  238. goto exit;
  239. }
  240. /* Convert and insert (add) the decimal digit */
  241. next_value =
  242. (return_value * 10) + (ascii_digit - ACPI_ASCII_ZERO);
  243. /* Check for overflow (32 or 64 bit) - return current converted value */
  244. if (((flags & ACPI_STRTOUL_32BIT) && (next_value > ACPI_UINT32_MAX)) || (next_value < return_value)) { /* 64-bit overflow case */
  245. goto exit;
  246. }
  247. return_value = next_value;
  248. string++;
  249. }
  250. exit:
  251. return (return_value);
  252. }
  253. /*******************************************************************************
  254. *
  255. * FUNCTION: acpi_ut_strtoul_base16
  256. *
  257. * PARAMETERS: string - Null terminated input string
  258. * flags - conversion info
  259. *
  260. * RETURN: 64-bit converted integer
  261. *
  262. * DESCRIPTION: Performs a base 16 conversion of the input string to an
  263. * integer value, either 32 or 64 bits.
  264. * Note: String must be valid and non-null.
  265. *
  266. ******************************************************************************/
  267. static u64 acpi_ut_strtoul_base16(char *string, u32 flags)
  268. {
  269. int ascii_digit;
  270. u32 valid_digits = 1;
  271. u64 return_value = 0;
  272. /* Main loop: convert each ASCII byte in the input string */
  273. while (*string) {
  274. /* Check for overflow (32 or 64 bit) - return current converted value */
  275. if ((valid_digits > 16) ||
  276. ((valid_digits > 8) && (flags & ACPI_STRTOUL_32BIT))) {
  277. goto exit;
  278. }
  279. ascii_digit = *string;
  280. if (!isxdigit(ascii_digit)) {
  281. /* Not Hex ASCII A-F, a-f, or 0-9, terminate */
  282. goto exit;
  283. }
  284. /* Convert and insert the hex digit */
  285. return_value =
  286. (return_value << 4) |
  287. acpi_ut_ascii_char_to_hex(ascii_digit);
  288. string++;
  289. valid_digits++;
  290. }
  291. exit:
  292. return (return_value);
  293. }