]> Kevux Git Server - fll/commitdiff
Progress: f_conversion and fl_console changes
authorKevin Day <thekevinday@gmail.com>
Sat, 9 Nov 2019 07:27:49 +0000 (01:27 -0600)
committerKevin Day <thekevinday@gmail.com>
Sat, 9 Nov 2019 17:40:56 +0000 (11:40 -0600)
This includes adding support for duodecimal (base 12)

level_0/f_conversion/c/conversion.c
level_0/f_conversion/c/conversion.h
level_1/fl_console/c/console.c
level_1/fl_console/c/console.h

index dca1b3541b7e2fa8b181fcc0270b3500801744f2..bd7990ca07b939c8c8b5601f04bb904a3438718c 100644 (file)
@@ -26,6 +26,25 @@ extern "C" {
   }
 #endif // _di_f_conversion_character_is_decimal_
 
+#ifndef _di_f_conversion_character_is_duodecimal_
+  f_return_status f_conversion_character_is_duodecimal(const int8_t character) {
+
+    if (character > 0x29 && character < 0x40) {
+      return f_true;
+    }
+
+    if (character == 0x41 || character == 0x42) {
+      return f_true;
+    }
+
+    if (character == 0x61 || character == 0x62) {
+      return f_true;
+    }
+
+    return f_false;
+  }
+#endif // _di_f_conversion_character_is_duodecimal_
+
 #ifndef _di_f_conversion_character_is_hexidecimal_
   f_return_status f_conversion_character_is_hexidecimal(const int8_t character) {
 
@@ -96,6 +115,35 @@ extern "C" {
   }
 #endif // _di_f_conversion_character_to_decimal_
 
+#ifndef _di_f_conversion_character_to_duodecimal_
+  f_return_status f_conversion_character_to_duodecimal(const int8_t character, uint64_t *decimal) {
+    #ifndef _di_level_0_parameter_checking_
+      if (decimal == 0) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    switch (character) {
+      case 0x30: *decimal = 0; break;
+      case 0x31: *decimal = 1; break;
+      case 0x32: *decimal = 2; break;
+      case 0x33: *decimal = 3; break;
+      case 0x34: *decimal = 4; break;
+      case 0x35: *decimal = 5; break;
+      case 0x36: *decimal = 6; break;
+      case 0x37: *decimal = 7; break;
+      case 0x38: *decimal = 8; break;
+      case 0x39: *decimal = 9; break;
+      case 0x41: *decimal = 10; break;
+      case 0x42: *decimal = 11; break;
+      case 0x61: *decimal = 10; break;
+      case 0x62: *decimal = 11; break;
+      default:
+        return f_status_set_error(f_invalid_number);
+    }
+
+    return f_none;
+  }
+#endif // _di_f_conversion_character_to_duodecimal_
+
 #ifndef _di_f_conversion_character_to_hexidecimal_
   f_return_status f_conversion_character_to_hexidecimal(const int8_t character, uint64_t *decimal) {
     #ifndef _di_level_0_parameter_checking_
@@ -156,6 +204,66 @@ extern "C" {
   }
 #endif // _di_f_conversion_character_to_octal_
 
+#ifndef _di_f_conversion_string_to_binary_signed_
+  f_return_status f_conversion_string_to_binary_signed(const f_string string, int64_t *number, const f_string_location location, const bool negative) {
+    #ifndef _di_level_0_parameter_checking_
+      if (string == 0) return f_status_set_error(f_invalid_parameter);
+      if (number == 0) return f_status_set_error(f_invalid_parameter);
+      if (location.start < 0) return f_status_set_error(f_invalid_parameter);
+      if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    uint8_t scale = 0;
+    uint64_t digit = 0;
+    uint64_t converted = 0;
+
+    for (f_string_length i = location.start; i <= location.stop; i++) {
+      if (f_conversion_character_to_binary(string[i], &digit) == f_none) {
+        if (scale) {
+          scale++;
+
+          if (scale > 63) {
+            return f_status_set_error(f_overflow);
+          }
+
+          if (negative) {
+            if (scale > 63) {
+              return f_status_set_error(f_underflow);
+            }
+
+            converted <<= 1;
+            converted -= digit;
+          }
+          else {
+            if (scale > 63) {
+              return f_status_set_error(f_overflow);
+            }
+
+            converted <<= 1;
+            converted += digit;
+          }
+        }
+        else if (digit != 0) {
+          scale = 1;
+
+          if (negative) {
+            converted = 0 - digit;
+          }
+          else {
+            converted = digit;
+          }
+        }
+      }
+      else if (string[i] != '\0') {
+        return f_status_set_error(f_invalid_number);
+      }
+    } // for
+
+    *number = converted;
+    return f_none;
+  }
+#endif // _di_f_conversion_string_to_binary_signed_
+
 #ifndef _di_f_conversion_string_to_binary_unsigned_
   f_return_status f_conversion_string_to_binary_unsigned(const f_string string, uint64_t *number, const f_string_location location) {
     #ifndef _di_level_0_parameter_checking_
@@ -165,14 +273,19 @@ extern "C" {
       if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    bool scale = 0;
+    uint8_t scale = 0;
     uint64_t digit = 0;
     uint64_t converted = 0;
 
-    // @todo: needs overflow/underflow detection.
     for (f_string_length i = location.start; i <= location.stop; i++) {
       if (f_conversion_character_to_binary(string[i], &digit) == f_none) {
         if (scale) {
+          scale++;
+
+          if (scale > 64) {
+            return f_status_set_error(f_overflow);
+          }
+
           converted <<= 1;
           converted += digit;
         }
@@ -181,7 +294,7 @@ extern "C" {
           converted = digit;
         }
       }
-      else {
+      else if (string[i] != '\0') {
         return f_status_set_error(f_invalid_number);
       }
     } // for
@@ -191,6 +304,67 @@ extern "C" {
   }
 #endif // _di_f_conversion_string_to_binary_unsigned_
 
+#ifndef _di_f_conversion_string_to_decimal_signed_
+  f_return_status f_conversion_string_to_decimal_signed(const f_string string, int64_t *number, const f_string_location location, const bool negative) {
+    #ifndef _di_level_0_parameter_checking_
+      if (string == 0) return f_status_set_error(f_invalid_parameter);
+      if (number == 0) return f_status_set_error(f_invalid_parameter);
+      if (location.start < 0) return f_status_set_error(f_invalid_parameter);
+      if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    uint8_t scale = 0;
+    uint64_t digit = 0;
+    uint64_t converted = 0;
+
+    for (f_string_length i = location.start; i <= location.stop; i++) {
+      if (f_conversion_character_to_decimal(string[i], &digit) == f_none) {
+
+        if (scale) {
+          scale++;
+
+          if (negative) {
+            if (scale > 18) {
+              if ((converted * 10) - digit < LLONG_MIN || (converted * 10) - digit > converted) {
+                return f_status_set_error(f_underflow);
+              }
+            }
+
+            converted *= 10;
+            converted -= digit;
+          }
+          else {
+            if (scale > 18) {
+              if ((converted * 10) + digit > LLONG_MAX || (converted * 10) + digit < converted) {
+                return f_status_set_error(f_overflow);
+              }
+            }
+
+            converted *= 10;
+            converted += digit;
+          }
+        }
+        else if (digit != 0) {
+          scale = 1;
+
+          if (negative) {
+            converted = 0 - digit;
+          }
+          else {
+            converted = digit;
+          }
+        }
+      }
+      else if (string[i] != '\0') {
+        return f_status_set_error(f_invalid_number);
+      }
+    } // for
+
+    *number = converted;
+    return f_none;
+  }
+#endif // _di_f_conversion_string_to_decimal_signed_
+
 #ifndef _di_f_conversion_string_to_decimal_unsigned_
   f_return_status f_conversion_string_to_decimal_unsigned(const f_string string, uint64_t *number, const f_string_location location) {
     #ifndef _di_level_0_parameter_checking_
@@ -200,15 +374,22 @@ extern "C" {
       if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    bool scale = 0;
+    uint8_t scale = 0;
     uint64_t digit = 0;
     uint64_t converted = 0;
 
-    // @todo: needs overflow/underflow detection.
     for (f_string_length i = location.start; i <= location.stop; i++) {
       if (f_conversion_character_to_decimal(string[i], &digit) == f_none) {
 
         if (scale) {
+          scale++;
+
+          if (scale > 18) {
+            if ((converted * 10) + digit > ULLONG_MAX || (converted * 10) + digit < converted) {
+              return f_status_set_error(f_overflow);
+            }
+          }
+
           converted *= 10;
           converted += digit;
         }
@@ -217,7 +398,7 @@ extern "C" {
           converted = digit;
         }
       }
-      else {
+      else if (string[i] != '\0') {
         return f_status_set_error(f_invalid_number);
       }
     } // for
@@ -227,6 +408,171 @@ extern "C" {
   }
 #endif // _di_f_conversion_string_to_decimal_unsigned_
 
+#ifndef _di_f_conversion_string_to_duodecimal_signed_
+  f_return_status f_conversion_string_to_duodecimal_signed(const f_string string, int64_t *number, const f_string_location location, const bool negative) {
+    #ifndef _di_level_0_parameter_checking_
+      if (string == 0) return f_status_set_error(f_invalid_parameter);
+      if (number == 0) return f_status_set_error(f_invalid_parameter);
+      if (location.start < 0) return f_status_set_error(f_invalid_parameter);
+      if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    uint8_t scale = 0;
+    uint64_t digit = 0;
+    uint64_t converted = 0;
+
+    for (f_string_length i = location.start; i <= location.stop; i++) {
+      if (f_conversion_character_to_duodecimal(string[i], &digit) == f_none) {
+
+        if (scale) {
+          scale++;
+
+          if (negative) {
+            if (scale > 15) {
+              if ((converted * 12) - digit < LLONG_MIN || (converted * 12) - digit > converted) {
+                return f_status_set_error(f_underflow);
+              }
+            }
+
+            converted *= 12;
+            converted -= digit;
+          }
+          else {
+            if (scale > 15) {
+              if ((converted * 12) + digit > LLONG_MAX || (converted * 12) + digit < converted) {
+                return f_status_set_error(f_overflow);
+              }
+            }
+
+            converted *= 12;
+            converted += digit;
+          }
+        }
+        else if (digit != 0) {
+          scale = 1;
+
+          if (negative) {
+            converted = 0 - digit;
+          }
+          else {
+            converted = digit;
+          }
+        }
+      }
+      else if (string[i] != '\0') {
+        return f_status_set_error(f_invalid_number);
+      }
+    } // for
+
+    *number = converted;
+    return f_none;
+  }
+#endif // _di_f_conversion_string_to_duodecimal_signed_
+
+#ifndef _di_f_conversion_string_to_duodecimal_unsigned_
+  f_return_status f_conversion_string_to_duodecimal_unsigned(const f_string string, uint64_t *number, const f_string_location location) {
+    #ifndef _di_level_0_parameter_checking_
+      if (string == 0) return f_status_set_error(f_invalid_parameter);
+      if (number == 0) return f_status_set_error(f_invalid_parameter);
+      if (location.start < 0) return f_status_set_error(f_invalid_parameter);
+      if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    uint8_t scale = 0;
+    uint64_t digit = 0;
+    uint64_t converted = 0;
+
+    for (f_string_length i = location.start; i <= location.stop; i++) {
+      if (f_conversion_character_to_duodecimal(string[i], &digit) == f_none) {
+
+        if (scale) {
+          scale++;
+
+          if (scale > 16) {
+            if ((converted * 12) + digit > ULLONG_MAX || (converted * 12) + digit < converted) {
+              return f_status_set_error(f_overflow);
+            }
+          }
+
+          converted *= 12;
+          converted += digit;
+        }
+        else if (digit != 0) {
+          scale = 1;
+          converted = digit;
+        }
+      }
+      else if (string[i] != '\0') {
+        return f_status_set_error(f_invalid_number);
+      }
+    } // for
+
+    *number = converted;
+    return f_none;
+  }
+#endif // _di_f_conversion_string_to_duodecimal_unsigned_
+
+#ifndef _di_f_conversion_string_to_hexidecimal_signed_
+  f_return_status f_conversion_string_to_hexidecimal_signed(const f_string string, int64_t *number, const f_string_location location, const bool negative) {
+    #ifndef _di_level_0_parameter_checking_
+      if (string == 0) return f_status_set_error(f_invalid_parameter);
+      if (number == 0) return f_status_set_error(f_invalid_parameter);
+      if (location.start < 0) return f_status_set_error(f_invalid_parameter);
+      if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    uint8_t scale = 0;
+    uint64_t digit = 0;
+    uint64_t converted = 0;
+
+    for (f_string_length i = location.start; i <= location.stop; i++) {
+      if (f_conversion_character_to_hexidecimal(string[i], &digit) == f_none) {
+
+        if (scale) {
+          scale++;
+
+          if (negative) {
+            if (scale > 15) {
+              if ((converted << 4) - digit < LLONG_MIN || (converted << 4) - digit > converted) {
+                return f_status_set_error(f_underflow);
+              }
+            }
+
+            converted <<= 4;
+            converted -= digit;
+          }
+          else {
+            if (scale > 15) {
+              if ((converted << 4) + digit > LLONG_MAX || (converted << 4) + digit < converted) {
+                return f_status_set_error(f_overflow);
+              }
+            }
+
+            converted <<= 4;
+            converted += digit;
+          }
+        }
+        else if (digit != 0) {
+          scale = 1;
+
+          if (negative) {
+            converted = 0 - digit;
+          }
+          else {
+            converted = digit;
+          }
+        }
+      }
+      else if (string[i] != '\0') {
+        return f_status_set_error(f_invalid_number);
+      }
+    } // for
+
+    *number = converted;
+    return f_none;
+  }
+#endif // _di_f_conversion_string_to_hexidecimal_signed_
+
 #ifndef _di_f_conversion_string_to_hexidecimal_unsigned_
   f_return_status f_conversion_string_to_hexidecimal_unsigned(const f_string string, uint64_t *number, const f_string_location location) {
     #ifndef _di_level_0_parameter_checking_
@@ -236,15 +582,20 @@ extern "C" {
       if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    bool scale = 0;
+    uint8_t scale = 0;
     uint64_t digit = 0;
     uint64_t converted = 0;
 
-    // @todo: needs overflow/underflow detection.
     for (f_string_length i = location.start; i <= location.stop; i++) {
       if (f_conversion_character_to_hexidecimal(string[i], &digit) == f_none) {
 
         if (scale) {
+          scale++;
+
+          if (scale > 16) {
+            return f_status_set_error(f_overflow);
+          }
+
           converted <<= 4;
           converted += digit;
         }
@@ -253,7 +604,7 @@ extern "C" {
           converted = digit;
         }
       }
-      else {
+      else if (string[i] != '\0') {
         return f_status_set_error(f_invalid_number);
       }
     } // for
@@ -263,6 +614,67 @@ extern "C" {
   }
 #endif // _di_f_conversion_string_to_hexidecimal_unsigned_
 
+#ifndef _di_f_conversion_string_to_octal_signed_
+  f_return_status f_conversion_string_to_octal_signed(const f_string string, int64_t *number, const f_string_location location, const bool negative) {
+    #ifndef _di_level_0_parameter_checking_
+      if (string == 0) return f_status_set_error(f_invalid_parameter);
+      if (number == 0) return f_status_set_error(f_invalid_parameter);
+      if (location.start < 0) return f_status_set_error(f_invalid_parameter);
+      if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    uint8_t scale = 0;
+    uint64_t digit = 0;
+    uint64_t converted = 0;
+
+    for (f_string_length i = location.start; i <= location.stop; i++) {
+      if (f_conversion_character_to_octal(string[i], &digit) == f_none) {
+
+        if (scale) {
+          scale++;
+
+          if (negative) {
+            if (scale > 19) {
+              if ((converted << 3) - digit < LLONG_MIN || (converted << 3) - digit > converted) {
+                return f_status_set_error(f_underflow);
+              }
+            }
+
+            converted <<= 3;
+            converted -= digit;
+          }
+          else {
+            if (scale > 19) {
+              if ((converted << 3) + digit > LLONG_MAX || (converted << 3) + digit < converted) {
+                return f_status_set_error(f_overflow);
+              }
+            }
+
+            converted <<= 3;
+            converted += digit;
+          }
+        }
+        else if (digit != 0) {
+          scale = 1;
+
+          if (negative) {
+            converted = 0 - digit;
+          }
+          else {
+            converted = digit;
+          }
+        }
+      }
+      else if (string[i] != '\0') {
+        return f_status_set_error(f_invalid_number);
+      }
+    } // for
+
+    *number = converted;
+    return f_none;
+  }
+#endif // _di_f_conversion_string_to_octal_signed_
+
 #ifndef _di_f_conversion_string_to_octal_unsigned_
   f_return_status f_conversion_string_to_octal_unsigned(const f_string string, uint64_t *number, const f_string_location location) {
     #ifndef _di_level_0_parameter_checking_
@@ -272,17 +684,23 @@ extern "C" {
       if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    bool scale = 0;
+    uint8_t scale = 0;
     uint64_t digit = 0;
     uint64_t converted = 0;
 
-    // @todo: needs overflow/underflow detection.
     for (f_string_length i = location.start; i <= location.stop; i++) {
       if (f_conversion_character_to_octal(string[i], &digit) == f_none) {
 
-        // when the scale exists, then we need to make the number larger, for this function the scale is base 8.
         if (scale) {
-          converted *= 8;
+          scale++;
+
+          if (scale > 20) {
+            if ((converted << 3) + digit > ULLONG_MAX || (converted << 3) + digit < converted) {
+              return f_status_set_error(f_overflow);
+            }
+          }
+
+          converted <<= 3;
           converted += digit;
         }
         else if (digit != 0) {
@@ -290,7 +708,7 @@ extern "C" {
           converted = digit;
         }
       }
-      else {
+      else if (string[i] != '\0') {
         return f_status_set_error(f_invalid_number);
       }
     } // for
@@ -300,6 +718,151 @@ extern "C" {
   }
 #endif // _di_f_conversion_string_to_octal_unsigned_
 
+#ifndef _di_f_conversion_string_to_number_signed_
+  f_return_status f_conversion_string_to_number_signed(const f_string string, int64_t *number, const f_string_location location) {
+    #ifndef _di_level_0_parameter_checking_
+      if (string == 0) return f_status_set_error(f_invalid_parameter);
+      if (number == 0) return f_status_set_error(f_invalid_parameter);
+      if (location.start < 0) return f_status_set_error(f_invalid_parameter);
+      if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    uint8_t width = 0;
+    uint8_t width_max = 0;
+    uint8_t mode = 0;
+    int8_t vector = 0; // 0 for assumed positive, 1 for explicit positive, -1 for negative.
+    f_string_length j = 0;
+    f_string_length offset = 0;
+    f_status status = f_none;
+
+    for (f_string_length i = location.start; i <= location.stop; i++) {
+      width = f_macro_utf_byte_width_is(string[i]);
+
+      if (width == 0) {
+        if (isspace(string[i])) {
+          if (mode == 0 && vector == 0) {
+            offset++;
+            continue;
+          }
+
+          return f_status_set_error(f_invalid_number);
+        }
+      }
+      else {
+        if (mode == 0 && vector == 0) {
+          width_max = (location.stop - i) + 1;
+
+          status = f_utf_is_whitespace(string + i, width_max);
+
+          if (status == f_true) {
+            offset = i + 1;
+            continue;
+          }
+
+          if (f_status_is_error(status)) {
+            if (status == f_status_set_error(f_maybe)) {
+              status = f_status_set_error(f_incomplete_utf);
+            }
+
+            return status;
+          }
+        }
+
+        return f_status_set_error(f_invalid_number);
+      }
+
+      if (string[i] == 0x30) {
+        j = i + 1;
+
+        // immediate next value must be either '0', 'x', 'X', 'd', 'D', 'o', 'O', 'b', or 'B'.
+        if (j > location.stop) {
+          *number = 0;
+          return f_none;
+        }
+        else if (string[j] == 0x30) {
+          mode = 10;
+        }
+        else if (string[j] == 0x78 || string[j] == 0x58) {
+          mode = 16;
+          offset += 2;
+        }
+        else if (string[j] == 0x44 || string[j] == 0x64) {
+          mode = 12;
+          offset += 2;
+        }
+        else if (string[j] == 0x6f || string[j] == 0x4f) {
+          mode = 8;
+          offset += 2;
+        }
+        else if (string[j] == 0x62 || string[j] == 0x42) {
+          mode = 2;
+          offset += 2;
+        }
+        else {
+          return f_status_set_error(f_invalid_number);
+        }
+
+        break;
+      }
+
+      // plus sign is only allowed as the first non-whitespace character.
+      if (string[i] == 0x2b) {
+        if (mode == 0 && vector == 0) {
+          vector = 1;
+          offset++;
+        }
+        else {
+          return f_status_set_error(f_invalid_number);
+        }
+      }
+
+      // negative sign is not allowed.
+      if (string[i] == 0x2d) {
+        if (mode == 0 && vector == 0) {
+          vector = -1;
+          offset++;
+        }
+        else {
+          return f_status_set_error(f_invalid_number);
+        }
+      }
+
+      if (f_conversion_character_is_decimal(string[i]) == f_true) {
+        mode = 10;
+        break;
+      }
+
+      return f_status_set_error(f_negative_number);
+    } // for
+
+    if (mode == 0) {
+      return f_no_data;
+    }
+
+    f_string_location location_offset = f_string_location_initialize;
+    location_offset.start = location.start + offset;
+    location_offset.stop = location.stop;
+
+    if (mode == 10) {
+      return f_conversion_string_to_decimal_signed(string, number, location_offset, vector == -1);
+    }
+
+    if (mode == 16) {
+      return f_conversion_string_to_hexidecimal_signed(string, number, location_offset, vector == -1);
+    }
+
+    if (mode == 12) {
+      return f_conversion_string_to_duodecimal_signed(string, number, location_offset, vector == -1);
+    }
+
+    if (mode == 8) {
+      return f_conversion_string_to_octal_signed(string, number, location_offset, vector == -1);
+    }
+
+    return f_conversion_string_to_binary_signed(string, number, location_offset, vector == -1);
+  }
+#endif // _di_f_conversion_string_to_number_signed_
+
 #ifndef _di_f_conversion_string_to_number_unsigned_
   f_return_status f_conversion_string_to_number_unsigned(const f_string string, uint64_t *number, const f_string_location location) {
     #ifndef _di_level_0_parameter_checking_
@@ -309,9 +872,6 @@ extern "C" {
       if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    bool scale = 0;
-    uint64_t digit = 0;
-    uint64_t converted = 0;
     uint8_t width = 0;
     uint8_t width_max = 0;
     uint8_t mode = 0;
@@ -358,7 +918,7 @@ extern "C" {
       if (string[i] == 0x30) {
         j = i + 1;
 
-        // immediate next value must be either '0', 'x', 'X', 'o', 'O', 'b', or 'B'.
+        // immediate next value must be either '0', 'x', 'X', 'd', 'D', 'o', 'O', 'b', or 'B'.
         if (j > location.stop) {
           *number = 0;
           return f_none;
@@ -370,6 +930,10 @@ extern "C" {
           mode = 16;
           offset += 2;
         }
+        else if (string[j] == 0x44 || string[j] == 0x64) {
+          mode = 12;
+          offset += 2;
+        }
         else if (string[j] == 0x6f || string[j] == 0x4f) {
           mode = 8;
           offset += 2;
@@ -419,6 +983,10 @@ extern "C" {
       return f_conversion_string_to_hexidecimal_unsigned(string, number, location_offset);
     }
 
+    if (mode == 12) {
+      return f_conversion_string_to_duodecimal_unsigned(string, number, location_offset);
+    }
+
     if (mode == 8) {
       return f_conversion_string_to_octal_unsigned(string, number, location_offset);
     }
index cd94168b39f6928ce111d88e2706d39db8a00b1f..16fac6c56e614c69a65bbb9695e5b5d604c377bf 100644 (file)
@@ -12,6 +12,7 @@
 
 // libc includes
 #include <ctype.h>
+#include <limits.h>
 #include <stdlib.h>
 
 // fll-0 includes
@@ -53,6 +54,20 @@ extern "C" {
 #endif // _di_f_conversion_character_is_decimal_
 
 /**
+ * Convert a single character into the duodecimal digit that it represents.
+ *
+ * @param character
+ *   The character to validate.
+ *
+ * @return
+ *   f_true if character is a duodecimal.
+ *   f_false if character is not a duodecimal.
+ */
+#ifndef _di_f_conversion_character_is_duodecimal_
+  extern f_return_status f_conversion_character_is_duodecimal(const int8_t character);
+#endif // _di_f_conversion_character_is_duodecimal_
+
+/**
  * Convert a single character into the hexidecimal digit that it represents.
  *
  * @param character
@@ -81,7 +96,25 @@ extern "C" {
 #endif // _di_f_conversion_character_is_octal_
 
 /**
- * Convert a single character into the digit that it represents.
+ * Convert a single character into the binary digit that it represents.
+ *
+ * @param character
+ *   The character to convert.
+ * @param number
+ *   This will store the value of the converted character.
+ *   This value is only changed on success.
+ *
+ * @return
+ *   f_none if character was converted to a binary.
+ *   f_invalid_number (with error bit) if no conversion was made due to non-binary values being found.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_conversion_character_to_binary_
+  extern f_return_status f_conversion_character_to_binary(const int8_t character, uint64_t *number);
+#endif // _di_f_conversion_character_to_binary_
+
+/**
+ * Convert a single character into the decimal digit that it represents.
  *
  * @param character
  *   The character to convert.
@@ -99,6 +132,24 @@ extern "C" {
 #endif // _di_f_conversion_character_to_decimal_
 
 /**
+ * Convert a single character into the duodecimal digit that it represents.
+ *
+ * @param character
+ *   The character to convert.
+ * @param number
+ *   This will store the value of the converted character.
+ *   This value is only changed on success.
+ *
+ * @return
+ *   f_none if character was converted to a duodecimal.
+ *   f_invalid_number (with error bit) if no conversion was made due to non-duodecimal values being found.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_conversion_character_to_duodecimal_
+  extern f_return_status f_conversion_character_to_duodecimal(const int8_t character, uint64_t *number);
+#endif // _di_f_conversion_character_to_duodecimal_
+
+/**
  * Convert a single character into the hexidecimal digit that it represents.
  *
  * @param character
@@ -135,10 +186,38 @@ extern "C" {
 #endif // _di_f_conversion_character_to_octal_
 
 /**
+ * Convert a series of positive or negative binary number characters into a int64_t.
+ *
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
+ * This will not process signed statuses (+/-).
+ *
+ * @param string
+ *   The string to convert.
+ * @param number
+ *   This will store the value of the converted string.
+ *   This value is only changed on success.
+ * @param location
+ *   The start/stop range to convert.
+ * @param negative
+ *   Set to 0 to treat string as a positive number, 1 for as a negative number.
+ *
+ * @return
+ *   f_none if the binary string was converted to an signed long.
+ *   f_invalid_number (with error bit) if no conversion was made due to non-binary values being found.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_overflow (with error bit) on integer overflow.
+ *   f_underflow (with error bit) on integer underflow.
+ */
+#ifndef _di_f_conversion_string_to_binary_signed_
+  extern f_return_status f_conversion_string_to_binary_signed(const f_string string, int64_t *number, const f_string_location location, const bool negative);
+#endif // _di_f_conversion_string_to_binary_signed_
+
+/**
  * Convert a series of positive binary number characters into a uint64_t.
  *
- * This will stop at one of the following: EOS, location.stop, or a non-digit.
- * This works like atoi, except there is a start/stop range.
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
  * This will not process signed statuses (+/-).
  *
  * @param string
@@ -153,16 +232,45 @@ extern "C" {
  *   f_none if the binary string was converted to an unsigned long.
  *   f_invalid_number (with error bit) if no conversion was made due to non-binary values being found.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_overflow (with error bit) on integer overflow.
  */
 #ifndef _di_f_conversion_string_to_binary_unsigned_
   extern f_return_status f_conversion_string_to_binary_unsigned(const f_string string, uint64_t *number, const f_string_location location);
 #endif // _di_f_conversion_string_to_binary_unsigned_
 
 /**
+ * Convert a series of positive or negative decimal number characters into an int64_t.
+ *
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
+ * This will not process signed statuses (+/-).
+ *
+ * @param string
+ *   The string to convert.
+ * @param number
+ *   This will store the value of the converted string.
+ *   This value is only changed on success.
+ * @param location
+ *   The start/stop range to convert.
+ * @param negative
+ *   Set to 0 to treat string as a positive number, 1 for as a negative number.
+ *
+ * @return
+ *   f_none if the decimal string was converted to an signed long.
+ *   f_invalid_number (with error bit) if no conversion was made due to non-decimal values being found.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_overflow (with error bit) on integer overflow.
+ *   f_underflow (with error bit) on integer underflow.
+ */
+#ifndef _di_f_conversion_string_to_decimal_signed_
+  extern f_return_status f_conversion_string_to_decimal_signed(const f_string string, int64_t *number, const f_string_location location, const bool negative);
+#endif // _di_f_conversion_string_to_decimal_signed_
+
+/**
  * Convert a series of positive decimal number characters into an uint64_t.
  *
- * This will stop at one of the following: EOS, location.stop, or a non-digit.
- * This works like atoi, except there is a start/stop range.
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
  * This will not process signed statuses (+/-).
  *
  * @param string
@@ -177,16 +285,98 @@ extern "C" {
  *   f_none if the decimal string was converted to an unsigned long.
  *   f_invalid_number (with error bit) if no conversion was made due to non-decimal values being found.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_overflow (with error bit) on integer overflow.
  */
 #ifndef _di_f_conversion_string_to_decimal_unsigned_
   extern f_return_status f_conversion_string_to_decimal_unsigned(const f_string string, uint64_t *number, const f_string_location location);
 #endif // _di_f_conversion_string_to_decimal_unsigned_
 
 /**
+ * Convert a series of positive or negative duodecimal number characters into an int64_t.
+ *
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
+ * This will not process signed statuses (+/-).
+ *
+ * @param string
+ *   The string to convert.
+ * @param number
+ *   This will store the value of the converted string.
+ *   This value is only changed on success.
+ * @param location
+ *   The start/stop range to convert.
+ * @param negative
+ *   Set to 0 to treat string as a positive number, 1 for as a negative number.
+ *
+ * @return
+ *   f_none if the duodecimal string was converted to an signed long.
+ *   f_invalid_number (with error bit) if no conversion was made due to non-duodecimal values being found.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_overflow (with error bit) on integer overflow.
+ *   f_underflow (with error bit) on integer underflow.
+ */
+#ifndef _di_f_conversion_string_to_duodecimal_signed_
+  extern f_return_status f_conversion_string_to_duodecimal_signed(const f_string string, int64_t *number, const f_string_location location, const bool negative);
+#endif // _di_f_conversion_string_to_duodecimal_signed_
+
+/**
+ * Convert a series of positive duodecimal number characters into an uint64_t.
+ *
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
+ * This will not process signed statuses (+/-).
+ *
+ * @param string
+ *   The string to convert.
+ * @param number
+ *   This will store the value of the converted string.
+ *   This value is only changed on success.
+ * @param location
+ *   The start/stop range to convert.
+ *
+ * @return
+ *   f_none if the duodecimal string was converted to an unsigned long.
+ *   f_invalid_number (with error bit) if no conversion was made due to non-duodecimal values being found.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_overflow (with error bit) on integer overflow.
+ */
+#ifndef _di_f_conversion_string_to_duodecimal_unsigned_
+  extern f_return_status f_conversion_string_to_duodecimal_unsigned(const f_string string, uint64_t *number, const f_string_location location);
+#endif // _di_f_conversion_string_to_duodecimal_unsigned_
+
+/**
+ * Convert a series of positive or negative hexidecimal number characters into an int64_t.
+ *
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
+ * This will not process signed statuses (+/-).
+ *
+ * @param string
+ *   The string to convert.
+ * @param number
+ *   This will store the value of the converted string.
+ *   This value is only changed on success.
+ * @param location
+ *   The start/stop range to convert.
+ * @param negative
+ *   Set to 0 to treat string as a positive number, 1 for as a negative number.
+ *
+ * @return
+ *   f_none if the hexidecimal string was converted to an signed long.
+ *   f_invalid_number (with error bit) if no conversion was made due to non-hexidecimal values being found.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_overflow (with error bit) on integer overflow.
+ *   f_underflow (with error bit) on integer underflow.
+ */
+#ifndef _di_f_conversion_string_to_hexidecimal_signed_
+  extern f_return_status f_conversion_string_to_hexidecimal_signed(const f_string string, int64_t *number, const f_string_location location, const bool negative);
+#endif // _di_f_conversion_string_to_hexidecimal_signed_
+
+/**
  * Convert a series of positive hexidecimal number characters into an uint64_t.
  *
- * This will stop at one of the following: EOS, location.stop, or a non-digit.
- * This works like atoi, except there is a start/stop range.
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
  * This will not process signed statuses (+/-).
  *
  * @param string
@@ -201,16 +391,44 @@ extern "C" {
  *   f_none if the hexidecimal string was converted to an unsigned long.
  *   f_invalid_number (with error bit) if no conversion was made due to non-hexidecimal values being found.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_overflow (with error bit) on integer overflow.
  */
 #ifndef _di_f_conversion_string_to_hexidecimal_unsigned_
   extern f_return_status f_conversion_string_to_hexidecimal_unsigned(const f_string string, uint64_t *number, const f_string_location location);
 #endif // _di_f_conversion_string_to_hexidecimal_unsigned_
 
 /**
+ * Convert a series of positive or negative octal number characters into an int64_t.
+ *
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
+ * This will not process signed statuses (+/-).
+ *
+ * @param string
+ *   The string to convert.
+ * @param number
+ *   This will store the value of the converted string.
+ *   This value is only changed on success.
+ * @param location
+ *   The start/stop range to convert.
+ * @param negative
+ *   Set to 0 to treat string as a positive number, 1 for as a negative number.
+ *
+ * @return
+ *   f_none if the octal string was converted to an signed long.
+ *   f_invalid_number (with error bit) if no conversion was made due to non-octal values being found.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_overflow (with error bit) on integer overflow.
+ */
+#ifndef _di_f_conversion_string_to_octal_signed_
+  extern f_return_status f_conversion_string_to_octal_signed(const f_string string, int64_t *number, const f_string_location location, const bool negative);
+#endif // _di_f_conversion_string_to_octal_signed_
+
+/**
  * Convert a series of positive octal number characters into an uint64_t.
  *
- * This will stop at one of the following: EOS, location.stop, or a non-digit.
- * This works like atoi, except there is a start/stop range.
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
  * This will not process signed statuses (+/-).
  *
  * @param string
@@ -225,19 +443,63 @@ extern "C" {
  *   f_none if the octal string was converted to an unsigned long.
  *   f_invalid_number (with error bit) if no conversion was made due to non-octal values being found.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_overflow (with error bit) on integer overflow.
  */
 #ifndef _di_f_conversion_string_to_octal_unsigned_
   extern f_return_status f_conversion_string_to_octal_unsigned(const f_string string, uint64_t *number, const f_string_location location);
 #endif // _di_f_conversion_string_to_octal_unsigned_
 
 /**
- * Convert a series of positive number characters into an uint64_t.
+ * Convert a series of positive or negative number characters into an int64_t.
  *
- * This will stop at one of the following: EOS, location.stop, or a non-digit.
- * This works like atoi, except there is a start/stop range.
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
  * This will process signed statuses (+/-).
  * This will detect based types as follows:
  * - hexidecimals begin with either '0x' or '0X'.
+ * - duodecimals begin with either '0d' or '0D'.
+ * - octals begin with either '0o' or '0O'.
+ * - binaries begin with either '0b' or '0B'.
+ * - decimal is used for all other cases.
+ *
+ * Leading 0's and whitespace are ignored.
+ * Whitespace after the first digit is considered invalid.
+ *
+ * This function is similar to strtoll(), but the behavior of error handling and special bases are different.
+ * In particular, octals are specified here with '0b' prefix or '0B' prefix instead of the ridiculous '0' prefix.
+ *
+ * @param string
+ *   The string to convert.
+ * @param number
+ *   This will store the value of the converted string.
+ *   This value is only changed on success.
+ * @param location
+ *   The start/stop range to convert.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data is returned if string only contains valid whitespace.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_invalid_number (with error bit) if parameter is not a number.
+ *   f_overflow (with error bit) on integer overflow.
+ *   f_underflow (with error bit) on integer underflow.
+ *   f_incomplete_utf (with error bit) if an incomplete UTF-8 fragment is found.
+ *
+ * @see strtoll()
+ */
+#ifndef _di_f_conversion_string_to_number_signed_
+  extern f_return_status f_conversion_string_to_number_signed(const f_string string, int64_t *number, const f_string_location location);
+#endif // _di_f_conversion_string_to_number_signed_
+
+/**
+ * Convert a series of positive number characters into an uint64_t.
+ *
+ * This will stop at one of the following: location.stop or a non-digit.
+ * This will ignore NULL values.
+ * This will not process signed statuses (+/-).
+ * This will detect based types as follows:
+ * - hexidecimals begin with either '0x' or '0X'.
+ * - duodecimals begin with either '0d' or '0D'.
  * - octals begin with either '0o' or '0O'.
  * - binaries begin with either '0b' or '0B'.
  * - decimal is used for all other cases.
@@ -245,6 +507,10 @@ extern "C" {
  * Leading 0's and whitespace are ignored.
  * Whitespace after the first digit is considered invalid.
  *
+ * This function is similar to strtoull(), but the behavior of error handling and special bases are different.
+ * In particular, octals are specified here with '0b' prefix or '0B' prefix instead of the ridiculous '0' prefix.
+ * Negative values are reported as such instead of being converted into the unsigned equivalent.
+ *
  * @param string
  *   The string to convert.
  * @param number
@@ -259,9 +525,10 @@ extern "C" {
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_invalid_number (with error bit) if parameter is not a number.
  *   f_negative_number (with error bit) on negative value.
- *   f_underflow (with error bit) on underflow.
- *   f_overflow (with error bit) on overflow.
+ *   f_overflow (with error bit) on integer overflow.
  *   f_incomplete_utf (with error bit) if an incomplete UTF-8 fragment is found.
+ *
+ * @see strtoull()
  */
 #ifndef _di_f_conversion_string_to_number_unsigned_
   extern f_return_status f_conversion_string_to_number_unsigned(const f_string string, uint64_t *number, const f_string_location location);
index 847af523442bf1045b81c043d7357e06f04de4d3..4ce0e4e4bd9c44fddea457b66f88f77fb73499f8 100644 (file)
@@ -4,6 +4,42 @@
 extern "C" {
 #endif
 
+#ifndef _fl_console_parameter_to_number_signed_
+  f_return_status fl_console_parameter_to_number_signed(const f_string argument, int64_t *number) {
+    #ifndef _di_level_0_parameter_checking_
+      if (argument == 0) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_f
+
+    if (argument[0] == '\0') {
+      return f_no_data;
+    }
+
+    f_string_location location = f_string_location_initialize;
+    location.start = 0;
+    location.stop = strlen(argument) - 1;
+
+    return f_conversion_string_to_number_signed(argument, number, location);
+  }
+#endif // _fl_console_parameter_to_number_signed_
+
+#ifndef _fl_console_parameter_to_number_unsigned_
+  f_return_status fl_console_parameter_to_number_unsigned(const f_string argument, uint64_t *number) {
+    #ifndef _di_level_0_parameter_checking_
+      if (argument == 0) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_f
+
+    if (argument[0] == '\0') {
+      return f_no_data;
+    }
+
+    f_string_location location = f_string_location_initialize;
+    location.start = 0;
+    location.stop = strlen(argument) - 1;
+
+    return f_conversion_string_to_number_unsigned(argument, number, location);
+  }
+#endif // _fl_console_parameter_to_number_unsigned_
+
 #ifndef _di_fl_console_parameter_process_
   f_return_status fl_console_parameter_process(const f_console_arguments arguments, f_console_parameters parameters, f_string_lengths *remaining) {
     #ifndef _di_level_1_parameter_checking_
@@ -332,83 +368,6 @@ extern "C" {
   }
 #endif // _di_fl_console_parameter_prioritize_
 
-#ifndef _fl_console_parameter_to_number_unsigned_
-  f_return_status fl_console_parameter_to_number_unsigned(const f_string argument, uint64_t *number) {
-    #ifndef _di_level_0_parameter_checking_
-      if (argument == 0) return f_status_set_error(f_invalid_parameter);
-    #endif // _di_level_0_parameter_checking_f
-
-    if (argument[0] == '\0') {
-      return f_no_data;
-    }
-
-    f_string_location location = f_string_location_initialize;
-    location.start = 0;
-    location.stop = strlen(argument) - 1;
-
-    f_status status = f_conversion_string_to_number_unsigned(argument, number, location);
-
-    return status;
-/*
-    errno = 0;
-
-    f_string end = 0;
-    uint64_t converted = (uint64_t) strtoull(argument, &end, 0);
-
-    if (errno == ERANGE) {
-      if (converted == LLONG_MAX) {
-        return f_status_set_error(f_overflow);
-      }
-
-      return f_status_set_error(f_invalid_number);
-    }
-
-    if (*end == '\0') {
-      *number = converted;
-      return f_none;
-    }
-
-    return f_status_set_error(f_invalid_number);
-*/
-  }
-#endif // _fl_console_parameter_to_number_unsigned_
-
-#ifndef _fl_console_parameter_to_number_signed_
-  f_return_status fl_console_parameter_to_number_signed(const f_string argument, int64_t *number) {
-    #ifndef _di_level_0_parameter_checking_
-      if (argument == 0) return f_status_set_error(f_invalid_parameter);
-    #endif // _di_level_0_parameter_checking_f
-
-    if (argument[0] == '\0') {
-      return f_no_data;
-    }
-
-    errno = 0;
-
-    f_string end = 0;
-    int64_t converted = (int64_t) strtoull(argument, &end, 0);
-
-    if (errno == ERANGE) {
-      if (converted == LLONG_MAX) {
-        return f_status_set_error(f_overflow);
-      }
-
-      if (converted == LLONG_MIN) {
-        return f_status_set_error(f_underflow);
-      }
-
-      return f_status_set_error(f_invalid_number);
-    }
-
-    if (*end == '\0') {
-      *number = converted;
-      return f_none;
-    }
-
-    return f_status_set_error(f_invalid_number);
-  }
-#endif // _fl_console_parameter_to_number_signed_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
index d84e076786d0af8cb4666b8d0438229ba6c7b1eb..e1486fc36441436bac1baea4cecf67686cb54520 100644 (file)
@@ -27,6 +27,76 @@ extern "C" {
 #endif
 
 /**
+ * Convert a console parameter additional argument to a signed 64-bit integer.
+ *
+ * This will detect based types as follows:
+ * - hexidecimals begin with either '0x' or '0X'.
+ * - duodecimals begin with either '0d' or '0D'.
+ * - octals begin with either '0o' or '0O'.
+ * - binaries begin with either '0b' or '0B'.
+ * - decimal is used for all other cases.
+ *
+ * Leading 0's and whitespace are ignored.
+ * Whitespace after the first digit is considered invalid.
+ *
+ * @param argv
+ *   The argument string expected to be a number.
+ *   This is generally passed from the argv[].
+ * @param number
+ *   The converted number is stored here.
+ *   This only gets modified on success.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data the argument is empty or only contains valid whitespace.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_invalid_number (with error bit) if parameter is not a number.
+ *   f_overflow (with error bit) on integer overflow.
+ *   f_underflow (with error bit) on integer underflow.
+ *   f_incomplete_utf (with error bit) if an incomplete UTF-8 fragment is found.
+ *
+ * @see f_conversion_string_to_number_signed()
+ */
+#ifndef _fl_console_parameter_to_number_signed_
+  f_return_status fl_console_parameter_to_number_signed(const f_string argument, int64_t *number);
+#endif // _fl_console_parameter_to_number_signed_
+
+/**
+ * Convert a console parameter additional argument to an unsigned 64-bit integer.
+ *
+ * This will detect based types as follows:
+ * - hexidecimals begin with either '0x' or '0X'.
+ * - duodecimals begin with either '0d' or '0D'.
+ * - octals begin with either '0o' or '0O'.
+ * - binaries begin with either '0b' or '0B'.
+ * - decimal is used for all other cases.
+ *
+ * Leading 0's and whitespace are ignored.
+ * Whitespace after the first digit is considered invalid.
+ *
+ * @param argv
+ *   The argument string expected to be a number.
+ *   This is generally passed from the argv[].
+ * @param number
+ *   The converted number is stored here.
+ *   This only gets modified on success.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data the argument is empty or only contains valid whitespace.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_invalid_number (with error bit) if parameter is not a number.
+ *   f_negative_number (with error bit) on negative value.
+ *   f_overflow (with error bit) on integer overflow.
+ *   f_incomplete_utf (with error bit) if an incomplete UTF-8 fragment is found.
+ *
+ * @see f_conversion_string_to_number_unsigned()
+ */
+#ifndef _fl_console_parameter_to_number_unsigned_
+  f_return_status fl_console_parameter_to_number_unsigned(const f_string argument, uint64_t *number);
+#endif // _fl_console_parameter_to_number_unsigned_
+
+/**
  * Process console parameters.
  *
  * Short parameters are processed as follows:
@@ -99,80 +169,6 @@ extern "C" {
   extern f_return_status fl_console_parameter_prioritize(const f_console_parameters parameters, const f_console_parameter_ids choices, f_console_parameter_id *decision);
 #endif // _di_fl_console_parameter_prioritize__
 
-/**
- * Convert a console parameter additional argument to an unsigned integer.
- *
- * Unlike strtoull(), this only accepts complete numbers.
- * If the argument has anything else, such as "123abc", this will consider the number to be "123".
- *
- * This accepts base-16, base-10, and base-8.
- * - Base-16 is prefixed with '0x' or '0X'.
- * - Base-10 is not prefixed.
- * - Base-8 is prefixed with '0'.
- *
- * Note: The idea of an octal (base-8) being prefixed with '0' is a horrible mistake.
- *       This is done by strtoull().
- *       In the future, custom code may be used in place of strtoull() to use '0o' for octal.
- *       Furthermore, '0b' for binary should be supported as well.
- *
- * @param argv
- *   The argument string expected to be a number.
- *   This is generally passed from the argv[].
- * @param number
- *   The converted number is stored here.
- *   This only gets modified on success.
- *
- * @return
- *   f_none on success.
- *   f_no_data the argument is empty.
- *   f_invalid_parameter (with error bit) if a parameter is invalid.
- *   f_invalid_number (with error bit) if parameter is not a number.
- *   f_negative_number (with error bit) on negative value.
- *   f_overflow (with error bit) on overflow.
- *
- * @see strtoull()
- */
-#ifndef _fl_console_parameter_to_number_unsigned_
-  f_return_status fl_console_parameter_to_number_unsigned(const f_string argument, uint64_t *number);
-#endif // _fl_console_parameter_to_number_unsigned_
-
-/**
- * Convert a console parameter additional argument to a signed integer.
- *
- * Unlike strtoll(), this only accepts complete numbers.
- * If the argument has anything else, such as "123abc", this will consider the number to be "123".
- *
- * This accepts base-16, base-10, and base-8.
- * - Base-16 is prefixed with '0x' or '0X'.
- * - Base-10 is not prefixed.
- * - Base-8 is prefixed with '0'.
- *
- * Note: The idea of an octal (base-8) being prefixed with '0' is a horrible mistake.
- *       This is done by strtoull().
- *       In the future, custom code may be used in place of strtoull() to use '0o'/'0O' for octal.
- *       Furthermore, '0b'/'0B' for binary should be supported as well.
- *
- * @param argv
- *   The argument string expected to be a number.
- *   This is generally passed from the argv[].
- * @param number
- *   The converted number is stored here.
- *   This only gets modified on success.
- *
- * @return
- *   f_none on success.
- *   f_no_data the argument is empty.
- *   f_invalid_parameter (with error bit) if a parameter is invalid.
- *   f_invalid_number (with error bit) if parameter is not a number.
- *   f_underflow (with error bit) on underflow.
- *   f_overflow (with error bit) on overflow.
- *
- * @see strtoll()
- */
-#ifndef _fl_console_parameter_to_number_signed_
-  f_return_status fl_console_parameter_to_number_signed(const f_string argument, int64_t *number);
-#endif // _fl_console_parameter_to_number_signed_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif