1 /******************************************************************************* 2 * 3 * Module Name: utnonansi - Non-ansi C library functions 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 <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 #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) 144 /******************************************************************************* 145 * 146 * FUNCTION: acpi_ut_safe_strcpy, acpi_ut_safe_strcat, acpi_ut_safe_strncat 147 * 148 * PARAMETERS: Adds a "DestSize" parameter to each of the standard string 149 * functions. This is the size of the Destination buffer. 150 * 151 * RETURN: TRUE if the operation would overflow the destination buffer. 152 * 153 * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that 154 * the result of the operation will not overflow the output string 155 * buffer. 156 * 157 * NOTE: These functions are typically only helpful for processing 158 * user input and command lines. For most ACPICA code, the 159 * required buffer length is precisely calculated before buffer 160 * allocation, so the use of these functions is unnecessary. 161 * 162 ******************************************************************************/ 163 164 u8 acpi_ut_safe_strcpy(char *dest, acpi_size dest_size, char *source) 165 { 166 167 if (strlen(source) >= dest_size) { 168 return (TRUE); 169 } 170 171 strcpy(dest, source); 172 return (FALSE); 173 } 174 175 u8 acpi_ut_safe_strcat(char *dest, acpi_size dest_size, char *source) 176 { 177 178 if ((strlen(dest) + strlen(source)) >= dest_size) { 179 return (TRUE); 180 } 181 182 strcat(dest, source); 183 return (FALSE); 184 } 185 186 u8 187 acpi_ut_safe_strncat(char *dest, 188 acpi_size dest_size, 189 char *source, acpi_size max_transfer_length) 190 { 191 acpi_size actual_transfer_length; 192 193 actual_transfer_length = ACPI_MIN(max_transfer_length, strlen(source)); 194 195 if ((strlen(dest) + actual_transfer_length) >= dest_size) { 196 return (TRUE); 197 } 198 199 strncat(dest, source, max_transfer_length); 200 return (FALSE); 201 } 202 #endif 203 204 /******************************************************************************* 205 * 206 * FUNCTION: acpi_ut_strtoul64 207 * 208 * PARAMETERS: string - Null terminated string 209 * base - Radix of the string: 16 or 10 or 210 * ACPI_ANY_BASE 211 * max_integer_byte_width - Maximum allowable integer,in bytes: 212 * 4 or 8 (32 or 64 bits) 213 * ret_integer - Where the converted integer is 214 * returned 215 * 216 * RETURN: Status and Converted value 217 * 218 * DESCRIPTION: Convert a string into an unsigned value. Performs either a 219 * 32-bit or 64-bit conversion, depending on the input integer 220 * size (often the current mode of the interpreter). 221 * 222 * NOTES: Negative numbers are not supported, as they are not supported 223 * by ACPI. 224 * 225 * acpi_gbl_integer_byte_width should be set to the proper width. 226 * For the core ACPICA code, this width depends on the DSDT 227 * version. For iASL, the default byte width is always 8 for the 228 * parser, but error checking is performed later to flag cases 229 * where a 64-bit constant is defined in a 32-bit DSDT/SSDT. 230 * 231 * Does not support Octal strings, not needed at this time. 232 * 233 ******************************************************************************/ 234 235 acpi_status 236 acpi_ut_strtoul64(char *string, 237 u32 base, u32 max_integer_byte_width, u64 *ret_integer) 238 { 239 u32 this_digit = 0; 240 u64 return_value = 0; 241 u64 quotient; 242 u64 dividend; 243 u8 valid_digits = 0; 244 u8 sign_of0x = 0; 245 u8 term = 0; 246 247 ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string); 248 249 switch (base) { 250 case ACPI_ANY_BASE: 251 case 10: 252 case 16: 253 254 break; 255 256 default: 257 258 /* Invalid Base */ 259 260 return_ACPI_STATUS(AE_BAD_PARAMETER); 261 } 262 263 if (!string) { 264 goto error_exit; 265 } 266 267 /* Skip over any white space in the buffer */ 268 269 while ((*string) && (isspace((int)*string) || *string == '\t')) { 270 string++; 271 } 272 273 if (base == ACPI_ANY_BASE) { 274 /* 275 * Base equal to ACPI_ANY_BASE means 'Either decimal or hex'. 276 * We need to determine if it is decimal or hexadecimal. 277 */ 278 if ((*string == '0') && (tolower((int)*(string + 1)) == 'x')) { 279 sign_of0x = 1; 280 base = 16; 281 282 /* Skip over the leading '0x' */ 283 string += 2; 284 } else { 285 base = 10; 286 } 287 } 288 289 /* Any string left? Check that '0x' is not followed by white space. */ 290 291 if (!(*string) || isspace((int)*string) || *string == '\t') { 292 if (base == ACPI_ANY_BASE) { 293 goto error_exit; 294 } else { 295 goto all_done; 296 } 297 } 298 299 /* 300 * Perform a 32-bit or 64-bit conversion, depending upon the input 301 * byte width 302 */ 303 dividend = (max_integer_byte_width <= ACPI_MAX32_BYTE_WIDTH) ? 304 ACPI_UINT32_MAX : ACPI_UINT64_MAX; 305 306 /* Main loop: convert the string to a 32- or 64-bit integer */ 307 308 while (*string) { 309 if (isdigit((int)*string)) { 310 311 /* Convert ASCII 0-9 to Decimal value */ 312 313 this_digit = ((u8)*string) - '0'; 314 } else if (base == 10) { 315 316 /* Digit is out of range; possible in to_integer case only */ 317 318 term = 1; 319 } else { 320 this_digit = (u8)toupper((int)*string); 321 if (isxdigit((int)this_digit)) { 322 323 /* Convert ASCII Hex char to value */ 324 325 this_digit = this_digit - 'A' + 10; 326 } else { 327 term = 1; 328 } 329 } 330 331 if (term) { 332 if (base == ACPI_ANY_BASE) { 333 goto error_exit; 334 } else { 335 break; 336 } 337 } else if ((valid_digits == 0) && (this_digit == 0) 338 && !sign_of0x) { 339 340 /* Skip zeros */ 341 string++; 342 continue; 343 } 344 345 valid_digits++; 346 347 if (sign_of0x && ((valid_digits > 16) || 348 ((valid_digits > 8) 349 && (max_integer_byte_width <= 350 ACPI_MAX32_BYTE_WIDTH)))) { 351 /* 352 * This is to_integer operation case. 353 * No restrictions for string-to-integer conversion, 354 * see ACPI spec. 355 */ 356 goto error_exit; 357 } 358 359 /* Divide the digit into the correct position */ 360 361 (void)acpi_ut_short_divide((dividend - (u64)this_digit), base, 362 "ient, NULL); 363 364 if (return_value > quotient) { 365 if (base == ACPI_ANY_BASE) { 366 goto error_exit; 367 } else { 368 break; 369 } 370 } 371 372 return_value *= base; 373 return_value += this_digit; 374 string++; 375 } 376 377 /* All done, normal exit */ 378 379 all_done: 380 381 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 382 ACPI_FORMAT_UINT64(return_value))); 383 384 *ret_integer = return_value; 385 return_ACPI_STATUS(AE_OK); 386 387 error_exit: 388 389 /* Base was set/validated above (10 or 16) */ 390 391 if (base == 10) { 392 return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT); 393 } else { 394 return_ACPI_STATUS(AE_BAD_HEX_CONSTANT); 395 } 396 } 397 398 #ifdef _OBSOLETE_FUNCTIONS 399 /* Removed: 01/2016 */ 400 401 /******************************************************************************* 402 * 403 * FUNCTION: strtoul64 404 * 405 * PARAMETERS: string - Null terminated string 406 * terminater - Where a pointer to the terminating byte 407 * is returned 408 * base - Radix of the string 409 * 410 * RETURN: Converted value 411 * 412 * DESCRIPTION: Convert a string into an unsigned value. 413 * 414 ******************************************************************************/ 415 416 acpi_status strtoul64(char *string, u32 base, u64 *ret_integer) 417 { 418 u32 index; 419 u32 sign; 420 u64 return_value = 0; 421 acpi_status status = AE_OK; 422 423 *ret_integer = 0; 424 425 switch (base) { 426 case 0: 427 case 8: 428 case 10: 429 case 16: 430 431 break; 432 433 default: 434 /* 435 * The specified Base parameter is not in the domain of 436 * this function: 437 */ 438 return (AE_BAD_PARAMETER); 439 } 440 441 /* Skip over any white space in the buffer: */ 442 443 while (isspace((int)*string) || *string == '\t') { 444 ++string; 445 } 446 447 /* 448 * The buffer may contain an optional plus or minus sign. 449 * If it does, then skip over it but remember what is was: 450 */ 451 if (*string == '-') { 452 sign = ACPI_SIGN_NEGATIVE; 453 ++string; 454 } else if (*string == '+') { 455 ++string; 456 sign = ACPI_SIGN_POSITIVE; 457 } else { 458 sign = ACPI_SIGN_POSITIVE; 459 } 460 461 /* 462 * If the input parameter Base is zero, then we need to 463 * determine if it is octal, decimal, or hexadecimal: 464 */ 465 if (base == 0) { 466 if (*string == '0') { 467 if (tolower((int)*(++string)) == 'x') { 468 base = 16; 469 ++string; 470 } else { 471 base = 8; 472 } 473 } else { 474 base = 10; 475 } 476 } 477 478 /* 479 * For octal and hexadecimal bases, skip over the leading 480 * 0 or 0x, if they are present. 481 */ 482 if (base == 8 && *string == '0') { 483 string++; 484 } 485 486 if (base == 16 && *string == '0' && tolower((int)*(++string)) == 'x') { 487 string++; 488 } 489 490 /* Main loop: convert the string to an unsigned long */ 491 492 while (*string) { 493 if (isdigit((int)*string)) { 494 index = ((u8)*string) - '0'; 495 } else { 496 index = (u8)toupper((int)*string); 497 if (isupper((int)index)) { 498 index = index - 'A' + 10; 499 } else { 500 goto error_exit; 501 } 502 } 503 504 if (index >= base) { 505 goto error_exit; 506 } 507 508 /* Check to see if value is out of range: */ 509 510 if (return_value > ((ACPI_UINT64_MAX - (u64)index) / (u64)base)) { 511 goto error_exit; 512 } else { 513 return_value *= base; 514 return_value += index; 515 } 516 517 ++string; 518 } 519 520 /* If a minus sign was present, then "the conversion is negated": */ 521 522 if (sign == ACPI_SIGN_NEGATIVE) { 523 return_value = (ACPI_UINT32_MAX - return_value) + 1; 524 } 525 526 *ret_integer = return_value; 527 return (status); 528 529 error_exit: 530 switch (base) { 531 case 8: 532 533 status = AE_BAD_OCTAL_CONSTANT; 534 break; 535 536 case 10: 537 538 status = AE_BAD_DECIMAL_CONSTANT; 539 break; 540 541 case 16: 542 543 status = AE_BAD_HEX_CONSTANT; 544 break; 545 546 default: 547 548 /* Base validated above */ 549 550 break; 551 } 552 553 return (status); 554 } 555 #endif 556