]>
Commit | Line | Data |
---|---|---|
5ebd2eaa BM |
1 | /******************************************************************************* |
2 | * | |
3 | * Module Name: utstrtoul64 - string to 64-bit integer support | |
4 | * | |
5 | ******************************************************************************/ | |
6 | ||
7 | /* | |
7735ca0e | 8 | * Copyright (C) 2000 - 2017, Intel Corp. |
5ebd2eaa BM |
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 | |
55 | ACPI_MODULE_NAME("utstrtoul64") | |
56 | ||
57 | /* Local prototypes */ | |
58 | static u64 acpi_ut_strtoul_base10(char *string, u32 flags); | |
59 | ||
60 | static 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 | ||
165 | acpi_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 | ||
260 | static 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 | ||
292 | exit: | |
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 | ||
311 | static 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 | ||
346 | exit: | |
347 | return (return_value); | |
348 | } |