]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/LibC/StdLib/NumericInt.c
Fix TCP4/TCP6 connections. Connections were transitioning into the connected state...
[mirror_edk2.git] / StdLib / LibC / StdLib / NumericInt.c
index 058ad04959ba30c8fa3ccc9488d7e431814cd76d..97e52eb1bd3be8e4ab2838585873aa5fbd7501f7 100644 (file)
@@ -8,7 +8,7 @@
     - atol: strtol(nptr, (char **)NULL, 10)\r
     - atoll: strtoll(nptr, (char **)NULL, 10)\r
 \r
-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\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
@@ -120,7 +120,7 @@ atoll(const char *nptr)
 static int\r
 Digit2Val( int c)\r
 {\r
-  if(__isHexLetter(c)) {  /* If c is one of [A-Fa-f]... */\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
@@ -183,13 +183,18 @@ Digit2Val( int c)
 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
@@ -204,9 +209,29 @@ strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
     Negative = TRUE;\r
     ++nptr;\r
   }\r
-  if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {\r
-    nptr += 2;\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
@@ -221,15 +246,15 @@ strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
       errno = ERANGE;\r
       break;\r
     }\r
-    ++nptr;\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 *)nptr;\r
+  if(endptr != NULL) {\r
+    *endptr = (char *)pEnd;\r
   }\r
   return Result;\r
 }\r
@@ -247,12 +272,17 @@ strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
 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
@@ -262,9 +292,29 @@ strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
   if(*nptr == '+') {\r
     ++nptr;\r
   }\r
-  if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {\r
-    nptr += 2;\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
@@ -273,12 +323,12 @@ strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
       errno = ERANGE;\r
       break;\r
     }\r
-    ++nptr;\r
+    pEnd = ++nptr;\r
   }\r
 \r
   // Save pointer to final sequence\r
-  if( endptr != NULL) {\r
-    *endptr = (char *)nptr;\r
+  if(endptr != NULL) {\r
+    *endptr = (char *)pEnd;\r
   }\r
   return Result;\r
 }\r
@@ -297,13 +347,18 @@ strtoul(const char * __restrict nptr, char ** __restrict endptr, int base)
 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
@@ -318,9 +373,29 @@ strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
     Negative = TRUE;\r
     ++nptr;\r
   }\r
-  if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {\r
-    nptr += 2;\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
@@ -335,15 +410,15 @@ strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
       errno = ERANGE;\r
       break;\r
     }\r
-    ++nptr;\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 *)nptr;\r
+  if(endptr != NULL) {\r
+    *endptr = (char *)pEnd;\r
   }\r
   return Result;\r
 }\r
@@ -361,12 +436,17 @@ strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
 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
@@ -376,9 +456,29 @@ strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)
   if(*nptr == '+') {\r
     ++nptr;\r
   }\r
-  if( (base == 16) && (*nptr == '0') && (toupper(nptr[1]) == 'X')) {\r
-    nptr += 2;\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
@@ -387,12 +487,12 @@ strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)
       errno = ERANGE;\r
       break;\r
     }\r
-    ++nptr;\r
+    pEnd = ++nptr;\r
   }\r
 \r
   // Save pointer to final sequence\r
-  if( endptr != NULL) {\r
-    *endptr = (char *)nptr;\r
+  if(endptr != NULL) {\r
+    *endptr = (char *)pEnd;\r
   }\r
   return Result;\r
 }\r