+++ /dev/null
-/** @file\r
- Integer Numeric Conversion Functions.\r
-\r
- The atoi, atol, and atoll functions convert the initial portion of the string\r
- pointed to by nptr to int, long int, and long long int representation,\r
- respectively. They are equivalent to:\r
- - atoi: (int)strtol(nptr, (char **)NULL, 10)\r
- - atol: strtol(nptr, (char **)NULL, 10)\r
- - atoll: strtoll(nptr, (char **)NULL, 10)\r
-\r
- Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials are licensed and made available under\r
- the terms and conditions of the BSD License that accompanies this distribution.\r
- The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-**/\r
-#include <Uefi.h>\r
-#include <Library/BaseLib.h>\r
-\r
-#include <LibConfig.h>\r
-\r
-#include <ctype.h>\r
-#include <errno.h>\r
-#include <limits.h>\r
-#include <stdlib.h>\r
-\r
-/** The atoi function converts the initial portion of the string pointed to by\r
- nptr to int representation. Except for the behavior on error, it is\r
- equivalent to:\r
- - (int)strtol(nptr, (char **)NULL, 10)\r
-\r
- @return The atoi function returns the converted value.\r
-**/\r
-int\r
-atoi(const char *nptr)\r
-{\r
- int Retval;\r
- BOOLEAN Negative = FALSE;\r
-\r
- while(isspace((const unsigned char)*nptr)) ++nptr; // Skip leading spaces\r
-\r
- if(*nptr == '+') {\r
- Negative = FALSE;\r
- ++nptr;\r
- }\r
- else if(*nptr == '-') {\r
- Negative = TRUE;\r
- ++nptr;\r
- }\r
- Retval = (int)AsciiStrDecimalToUintn(nptr);\r
- if(Negative) {\r
- Retval = -Retval;\r
- }\r
- return Retval;\r
-}\r
-\r
-/** The atol function converts the initial portion of the string pointed to by\r
- nptr to long int representation. Except for the behavior on error, it is\r
- equivalent to:\r
- - strtol(nptr, (char **)NULL, 10)\r
-\r
- @return The atol function returns the converted value.\r
-**/\r
-long int\r
-atol(const char *nptr)\r
-{\r
- long int Retval;\r
- BOOLEAN Negative = FALSE;\r
-\r
- while(isspace(*nptr)) ++nptr; // Skip leading spaces\r
-\r
- if(*nptr == '+') {\r
- Negative = FALSE;\r
- ++nptr;\r
- }\r
- else if(*nptr == '-') {\r
- Negative = TRUE;\r
- ++nptr;\r
- }\r
- Retval = (long int)AsciiStrDecimalToUint64(nptr);\r
- if(Negative) {\r
- Retval = -Retval;\r
- }\r
- return Retval;\r
-}\r
-\r
-/** The atoll function converts the initial portion of the string pointed to by\r
- nptr to long long int representation. Except for the behavior on error, it\r
- is equivalent to:\r
- - strtoll(nptr, (char **)NULL, 10)\r
-\r
- @return The atoll function returns the converted value.\r
-**/\r
-long long int\r
-atoll(const char *nptr)\r
-{\r
- long long int Retval;\r
- BOOLEAN Negative = FALSE;\r
-\r
- while(isspace(*nptr)) ++nptr; // Skip leading spaces\r
-\r
- if(*nptr == '+') {\r
- Negative = FALSE;\r
- ++nptr;\r
- }\r
- else if(*nptr == '-') {\r
- Negative = TRUE;\r
- ++nptr;\r
- }\r
- Retval = (long long int)AsciiStrDecimalToUint64(nptr);\r
- if(Negative) {\r
- Retval = -Retval;\r
- }\r
- return Retval;\r
-}\r
-\r
-static int\r
-Digit2Val( int c)\r
-{\r
- if(isalpha(c)) { /* If c is one of [A-Za-z]... */\r
- c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)\r
- }\r
- return c - '0'; // Value returned is between 0 and 35, inclusive.\r
-}\r
-\r
-/** The strtol, strtoll, strtoul, and strtoull functions convert the initial\r
- portion of the string pointed to by nptr to long int, long long int,\r
- unsigned long int, and unsigned long long int representation, respectively.\r
- First, they decompose the input string into three parts: an initial,\r
- possibly empty, sequence of white-space characters (as specified by the\r
- isspace function), a subject sequence resembling an integer represented in\r
- some radix determined by the value of base, and a final string of one or\r
- more unrecognized characters, including the terminating null character of\r
- the input string. Then, they attempt to convert the subject sequence to an\r
- integer, and return the result.\r
-\r
- If the value of base is zero, the expected form of the subject sequence is\r
- that of an integer constant, optionally preceded\r
- by a plus or minus sign, but not including an integer suffix. If the value\r
- of base is between 2 and 36 (inclusive), the expected form of the subject\r
- sequence is a sequence of letters and digits representing an integer with\r
- the radix specified by base, optionally preceded by a plus or minus sign,\r
- but not including an integer suffix. The letters from a (or A) through z\r
- (or Z) are ascribed the values 10 through 35; only letters and digits whose\r
- ascribed values are less than that of base are permitted. If the value of\r
- base is 16, the characters 0x or 0X may optionally precede the sequence of\r
- letters and digits, following the sign if present.\r
-\r
- The subject sequence is defined as the longest initial subsequence of the\r
- input string, starting with the first non-white-space character, that is of\r
- the expected form. The subject sequence contains no characters if the input\r
- string is empty or consists entirely of white space, or if the first\r
- non-white-space character is other than a sign or a permissible letter or digit.\r
-\r
- If the subject sequence has the expected form and the value of base is\r
- zero, the sequence of characters starting with the first digit is\r
- interpreted as an integer constant. If the subject sequence has the\r
- expected form and the value of base is between 2 and 36, it is used as the\r
- base for conversion, ascribing to each letter its value as given above. If\r
- the subject sequence begins with a minus sign, the value resulting from the\r
- conversion is negated (in the return type). A pointer to the final string\r
- is stored in the object pointed to by endptr, provided that endptr is\r
- not a null pointer.\r
-\r
- In other than the "C" locale, additional locale-specific subject sequence\r
- forms may be accepted.\r
-\r
- If the subject sequence is empty or does not have the expected form, no\r
- conversion is performed; the value of nptr is stored in the object pointed\r
- to by endptr, provided that endptr is not a null pointer.\r
-\r
- @return The strtol, strtoll, strtoul, and strtoull functions return the\r
- converted value, if any. If no conversion could be performed, zero\r
- is returned. If the correct value is outside the range of\r
- representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,\r
- ULONG_MAX, or ULLONG_MAX is returned (according to the return type\r
- and sign of the value, if any), and the value of the macro ERANGE\r
- is stored in errno.\r
-**/\r
-long\r
-strtol(const char * __restrict nptr, char ** __restrict endptr, int base)\r
-{\r
- const char *pEnd;\r
- long Result = 0;\r
- long Previous;\r
- int temp;\r
- BOOLEAN Negative = FALSE;\r
-\r
- pEnd = nptr;\r
-\r
- if((base < 0) || (base == 1) || (base > 36)) {\r
- if(endptr != NULL) {\r
- *endptr = NULL;\r
- }\r
- return 0;\r
- }\r
- // Skip leading spaces.\r
- while(isspace(*nptr)) ++nptr;\r
-\r
- // Process Subject sequence: optional sign followed by digits.\r
- if(*nptr == '+') {\r
- Negative = FALSE;\r
- ++nptr;\r
- }\r
- else if(*nptr == '-') {\r
- Negative = TRUE;\r
- ++nptr;\r
- }\r
-\r
- if(*nptr == '0') { /* Might be Octal or Hex */\r
- if(toupper(nptr[1]) == 'X') { /* Looks like Hex */\r
- if((base == 0) || (base == 16)) {\r
- nptr += 2; /* Skip the "0X" */\r
- base = 16; /* In case base was 0 */\r
- }\r
- }\r
- else { /* Looks like Octal */\r
- if((base == 0) || (base == 8)) {\r
- ++nptr; /* Skip the leading "0" */\r
- base = 8; /* In case base was 0 */\r
- }\r
- }\r
- }\r
- if(base == 0) { /* If still zero then must be decimal */\r
- base = 10;\r
- }\r
- if(*nptr == '0') {\r
- for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */\r
- pEnd = nptr;\r
- }\r
-\r
- while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {\r
- Previous = Result;\r
- Result = (Result * base) + (long int)temp;\r
- if( Result <= Previous) { // Detect Overflow\r
- if(Negative) {\r
- Result = LONG_MIN;\r
- }\r
- else {\r
- Result = LONG_MAX;\r
- }\r
- Negative = FALSE;\r
- errno = ERANGE;\r
- break;\r
- }\r
- pEnd = ++nptr;\r
- }\r
- if(Negative) {\r
- Result = -Result;\r
- }\r
-\r
- // Save pointer to final sequence\r
- if(endptr != NULL) {\r
- *endptr = (char *)pEnd;\r
- }\r
- return Result;\r
-}\r
-\r
-/** The strtoul function converts the initial portion of the string pointed to\r
- by nptr to unsigned long int representation.\r
-\r
- See the description for strtol for more information.\r
-\r
- @return The strtoul function returns the converted value, if any. If no\r
- conversion could be performed, zero is returned. If the correct\r
- value is outside the range of representable values, ULONG_MAX is\r
- returned and the value of the macro ERANGE is stored in errno.\r
-**/\r
-unsigned long\r
-strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)\r
-{\r
- const char *pEnd;\r
- unsigned long Result = 0;\r
- unsigned long Previous;\r
- int temp;\r
-\r
- pEnd = nptr;\r
-\r
- if((base < 0) || (base == 1) || (base > 36)) {\r
- if(endptr != NULL) {\r
- *endptr = NULL;\r
- }\r
- return 0;\r
- }\r
- // Skip leading spaces.\r
- while(isspace(*nptr)) ++nptr;\r
-\r
- // Process Subject sequence: optional + sign followed by digits.\r
- if(*nptr == '+') {\r
- ++nptr;\r
- }\r
-\r
- if(*nptr == '0') { /* Might be Octal or Hex */\r
- if(toupper(nptr[1]) == 'X') { /* Looks like Hex */\r
- if((base == 0) || (base == 16)) {\r
- nptr += 2; /* Skip the "0X" */\r
- base = 16; /* In case base was 0 */\r
- }\r
- }\r
- else { /* Looks like Octal */\r
- if((base == 0) || (base == 8)) {\r
- ++nptr; /* Skip the leading "0" */\r
- base = 8; /* In case base was 0 */\r
- }\r
- }\r
- }\r
- if(base == 0) { /* If still zero then must be decimal */\r
- base = 10;\r
- }\r
- if(*nptr == '0') {\r
- for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */\r
- pEnd = nptr;\r
- }\r
-\r
- while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {\r
- Previous = Result;\r
- Result = (Result * base) + (unsigned long)temp;\r
- if( Result < Previous) { // If we overflowed\r
- Result = ULONG_MAX;\r
- errno = ERANGE;\r
- break;\r
- }\r
- pEnd = ++nptr;\r
- }\r
-\r
- // Save pointer to final sequence\r
- if(endptr != NULL) {\r
- *endptr = (char *)pEnd;\r
- }\r
- return Result;\r
-}\r
-\r
-/** The strtoll function converts the initial portion of the string pointed to\r
- by nptr to long long int representation.\r
-\r
- See the description for strtol for more information.\r
-\r
- @return The strtoll function returns the converted value, if any. If no\r
- conversion could be performed, zero is returned. If the correct\r
- value is outside the range of representable values, LLONG_MIN or\r
- LLONG_MAX is returned (according to the sign of the value, if any),\r
- and the value of the macro ERANGE is stored in errno.\r
-**/\r
-long long\r
-strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)\r
-{\r
- const char *pEnd;\r
- long long Result = 0;\r
- long long Previous;\r
- int temp;\r
- BOOLEAN Negative = FALSE;\r
-\r
- pEnd = nptr;\r
-\r
- if((base < 0) || (base == 1) || (base > 36)) {\r
- if(endptr != NULL) {\r
- *endptr = NULL;\r
- }\r
- return 0;\r
- }\r
- // Skip leading spaces.\r
- while(isspace(*nptr)) ++nptr;\r
-\r
- // Process Subject sequence: optional sign followed by digits.\r
- if(*nptr == '+') {\r
- Negative = FALSE;\r
- ++nptr;\r
- }\r
- else if(*nptr == '-') {\r
- Negative = TRUE;\r
- ++nptr;\r
- }\r
-\r
- if(*nptr == '0') { /* Might be Octal or Hex */\r
- if(toupper(nptr[1]) == 'X') { /* Looks like Hex */\r
- if((base == 0) || (base == 16)) {\r
- nptr += 2; /* Skip the "0X" */\r
- base = 16; /* In case base was 0 */\r
- }\r
- }\r
- else { /* Looks like Octal */\r
- if((base == 0) || (base == 8)) {\r
- ++nptr; /* Skip the leading "0" */\r
- base = 8; /* In case base was 0 */\r
- }\r
- }\r
- }\r
- if(base == 0) { /* If still zero then must be decimal */\r
- base = 10;\r
- }\r
- if(*nptr == '0') {\r
- for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */\r
- pEnd = nptr;\r
- }\r
-\r
- while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {\r
- Previous = Result;\r
- Result = (Result * base) + (long long int)temp;\r
- if( Result <= Previous) { // Detect Overflow\r
- if(Negative) {\r
- Result = LLONG_MIN;\r
- }\r
- else {\r
- Result = LLONG_MAX;\r
- }\r
- Negative = FALSE;\r
- errno = ERANGE;\r
- break;\r
- }\r
- pEnd = ++nptr;\r
- }\r
- if(Negative) {\r
- Result = -Result;\r
- }\r
-\r
- // Save pointer to final sequence\r
- if(endptr != NULL) {\r
- *endptr = (char *)pEnd;\r
- }\r
- return Result;\r
-}\r
-\r
-/** The strtoull function converts the initial portion of the string pointed to\r
- by nptr to unsigned long long int representation.\r
-\r
- See the description for strtol for more information.\r
-\r
- @return The strtoull function returns the converted value, if any. If no\r
- conversion could be performed, zero is returned. If the correct\r
- value is outside the range of representable values, ULLONG_MAX is\r
- returned and the value of the macro ERANGE is stored in errno.\r
-**/\r
-unsigned long long\r
-strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)\r
-{\r
- const char *pEnd;\r
- unsigned long long Result = 0;\r
- unsigned long long Previous;\r
- int temp;\r
-\r
- pEnd = nptr;\r
-\r
- if((base < 0) || (base == 1) || (base > 36)) {\r
- if(endptr != NULL) {\r
- *endptr = NULL;\r
- }\r
- return 0;\r
- }\r
- // Skip leading spaces.\r
- while(isspace(*nptr)) ++nptr;\r
-\r
- // Process Subject sequence: optional + sign followed by digits.\r
- if(*nptr == '+') {\r
- ++nptr;\r
- }\r
-\r
- if(*nptr == '0') { /* Might be Octal or Hex */\r
- if(toupper(nptr[1]) == 'X') { /* Looks like Hex */\r
- if((base == 0) || (base == 16)) {\r
- nptr += 2; /* Skip the "0X" */\r
- base = 16; /* In case base was 0 */\r
- }\r
- }\r
- else { /* Looks like Octal */\r
- if((base == 0) || (base == 8)) {\r
- ++nptr; /* Skip the leading "0" */\r
- base = 8; /* In case base was 0 */\r
- }\r
- }\r
- }\r
- if(base == 0) { /* If still zero then must be decimal */\r
- base = 10;\r
- }\r
- if(*nptr == '0') {\r
- for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */\r
- pEnd = nptr;\r
- }\r
-\r
- while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {\r
- Previous = Result;\r
- Result = (Result * base) + (unsigned long long)temp;\r
- if( Result < Previous) { // If we overflowed\r
- Result = ULLONG_MAX;\r
- errno = ERANGE;\r
- break;\r
- }\r
- pEnd = ++nptr;\r
- }\r
-\r
- // Save pointer to final sequence\r
- if(endptr != NULL) {\r
- *endptr = (char *)pEnd;\r
- }\r
- return Result;\r
-}\r