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 ACPI_ANY_BASE; 210 * ACPI_ANY_BASE means 'in behalf of to_integer' 211 * ret_integer - Where the converted integer is returned 212 * 213 * RETURN: Status and Converted value 214 * 215 * DESCRIPTION: Convert a string into an unsigned value. Performs either a 216 * 32-bit or 64-bit conversion, depending on the current mode 217 * of the interpreter. 218 * 219 * NOTES: acpi_gbl_integer_byte_width should be set to the proper width. 220 * For the core ACPICA code, this width depends on the DSDT 221 * version. For iASL, the default byte width is always 8. 222 * 223 * Does not support Octal strings, not needed at this time. 224 * 225 * There is an earlier version of the function after this one, 226 * below. It is slightly different than this one, and the two 227 * may eventually may need to be merged. (01/2016). 228 * 229 ******************************************************************************/ 230 231 acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer) 232 { 233 u32 this_digit = 0; 234 u64 return_value = 0; 235 u64 quotient; 236 u64 dividend; 237 u32 to_integer_op = (base == ACPI_ANY_BASE); 238 u32 mode32 = (acpi_gbl_integer_byte_width == 4); 239 u8 valid_digits = 0; 240 u8 sign_of0x = 0; 241 u8 term = 0; 242 243 ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string); 244 245 switch (base) { 246 case ACPI_ANY_BASE: 247 case 16: 248 249 break; 250 251 default: 252 253 /* Invalid Base */ 254 255 return_ACPI_STATUS(AE_BAD_PARAMETER); 256 } 257 258 if (!string) { 259 goto error_exit; 260 } 261 262 /* Skip over any white space in the buffer */ 263 264 while ((*string) && (isspace((int)*string) || *string == '\t')) { 265 string++; 266 } 267 268 if (to_integer_op) { 269 /* 270 * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. 271 * We need to determine if it is decimal or hexadecimal. 272 */ 273 if ((*string == '0') && (tolower((int)*(string + 1)) == 'x')) { 274 sign_of0x = 1; 275 base = 16; 276 277 /* Skip over the leading '0x' */ 278 string += 2; 279 } else { 280 base = 10; 281 } 282 } 283 284 /* Any string left? Check that '0x' is not followed by white space. */ 285 286 if (!(*string) || isspace((int)*string) || *string == '\t') { 287 if (to_integer_op) { 288 goto error_exit; 289 } else { 290 goto all_done; 291 } 292 } 293 294 /* 295 * Perform a 32-bit or 64-bit conversion, depending upon the current 296 * execution mode of the interpreter 297 */ 298 dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; 299 300 /* Main loop: convert the string to a 32- or 64-bit integer */ 301 302 while (*string) { 303 if (isdigit((int)*string)) { 304 305 /* Convert ASCII 0-9 to Decimal value */ 306 307 this_digit = ((u8)*string) - '0'; 308 } else if (base == 10) { 309 310 /* Digit is out of range; possible in to_integer case only */ 311 312 term = 1; 313 } else { 314 this_digit = (u8)toupper((int)*string); 315 if (isxdigit((int)this_digit)) { 316 317 /* Convert ASCII Hex char to value */ 318 319 this_digit = this_digit - 'A' + 10; 320 } else { 321 term = 1; 322 } 323 } 324 325 if (term) { 326 if (to_integer_op) { 327 goto error_exit; 328 } else { 329 break; 330 } 331 } else if ((valid_digits == 0) && (this_digit == 0) 332 && !sign_of0x) { 333 334 /* Skip zeros */ 335 string++; 336 continue; 337 } 338 339 valid_digits++; 340 341 if (sign_of0x 342 && ((valid_digits > 16) 343 || ((valid_digits > 8) && mode32))) { 344 /* 345 * This is to_integer operation case. 346 * No any restrictions for string-to-integer conversion, 347 * see ACPI spec. 348 */ 349 goto error_exit; 350 } 351 352 /* Divide the digit into the correct position */ 353 354 (void)acpi_ut_short_divide((dividend - (u64)this_digit), base, 355 "ient, NULL); 356 357 if (return_value > quotient) { 358 if (to_integer_op) { 359 goto error_exit; 360 } else { 361 break; 362 } 363 } 364 365 return_value *= base; 366 return_value += this_digit; 367 string++; 368 } 369 370 /* All done, normal exit */ 371 372 all_done: 373 374 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 375 ACPI_FORMAT_UINT64(return_value))); 376 377 *ret_integer = return_value; 378 return_ACPI_STATUS(AE_OK); 379 380 error_exit: 381 /* Base was set/validated above */ 382 383 if (base == 10) { 384 return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT); 385 } else { 386 return_ACPI_STATUS(AE_BAD_HEX_CONSTANT); 387 } 388 } 389 390 #ifdef _OBSOLETE_FUNCTIONS 391 /* TBD: use version in ACPICA main code base? */ 392 /* DONE: 01/2016 */ 393 394 /******************************************************************************* 395 * 396 * FUNCTION: strtoul64 397 * 398 * PARAMETERS: string - Null terminated string 399 * terminater - Where a pointer to the terminating byte 400 * is returned 401 * base - Radix of the string 402 * 403 * RETURN: Converted value 404 * 405 * DESCRIPTION: Convert a string into an unsigned value. 406 * 407 ******************************************************************************/ 408 409 acpi_status strtoul64(char *string, u32 base, u64 *ret_integer) 410 { 411 u32 index; 412 u32 sign; 413 u64 return_value = 0; 414 acpi_status status = AE_OK; 415 416 *ret_integer = 0; 417 418 switch (base) { 419 case 0: 420 case 8: 421 case 10: 422 case 16: 423 424 break; 425 426 default: 427 /* 428 * The specified Base parameter is not in the domain of 429 * this function: 430 */ 431 return (AE_BAD_PARAMETER); 432 } 433 434 /* Skip over any white space in the buffer: */ 435 436 while (isspace((int)*string) || *string == '\t') { 437 ++string; 438 } 439 440 /* 441 * The buffer may contain an optional plus or minus sign. 442 * If it does, then skip over it but remember what is was: 443 */ 444 if (*string == '-') { 445 sign = ACPI_SIGN_NEGATIVE; 446 ++string; 447 } else if (*string == '+') { 448 ++string; 449 sign = ACPI_SIGN_POSITIVE; 450 } else { 451 sign = ACPI_SIGN_POSITIVE; 452 } 453 454 /* 455 * If the input parameter Base is zero, then we need to 456 * determine if it is octal, decimal, or hexadecimal: 457 */ 458 if (base == 0) { 459 if (*string == '0') { 460 if (tolower((int)*(++string)) == 'x') { 461 base = 16; 462 ++string; 463 } else { 464 base = 8; 465 } 466 } else { 467 base = 10; 468 } 469 } 470 471 /* 472 * For octal and hexadecimal bases, skip over the leading 473 * 0 or 0x, if they are present. 474 */ 475 if (base == 8 && *string == '0') { 476 string++; 477 } 478 479 if (base == 16 && *string == '0' && tolower((int)*(++string)) == 'x') { 480 string++; 481 } 482 483 /* Main loop: convert the string to an unsigned long */ 484 485 while (*string) { 486 if (isdigit((int)*string)) { 487 index = ((u8)*string) - '0'; 488 } else { 489 index = (u8)toupper((int)*string); 490 if (isupper((int)index)) { 491 index = index - 'A' + 10; 492 } else { 493 goto error_exit; 494 } 495 } 496 497 if (index >= base) { 498 goto error_exit; 499 } 500 501 /* Check to see if value is out of range: */ 502 503 if (return_value > ((ACPI_UINT64_MAX - (u64)index) / (u64)base)) { 504 goto error_exit; 505 } else { 506 return_value *= base; 507 return_value += index; 508 } 509 510 ++string; 511 } 512 513 /* If a minus sign was present, then "the conversion is negated": */ 514 515 if (sign == ACPI_SIGN_NEGATIVE) { 516 return_value = (ACPI_UINT32_MAX - return_value) + 1; 517 } 518 519 *ret_integer = return_value; 520 return (status); 521 522 error_exit: 523 switch (base) { 524 case 8: 525 526 status = AE_BAD_OCTAL_CONSTANT; 527 break; 528 529 case 10: 530 531 status = AE_BAD_DECIMAL_CONSTANT; 532 break; 533 534 case 16: 535 536 status = AE_BAD_HEX_CONSTANT; 537 break; 538 539 default: 540 541 /* Base validated above */ 542 543 break; 544 } 545 546 return (status); 547 } 548 #endif 549