]> Kevux Git Server - fll/commitdiff
Update: Add f_conversion unit tests.
authorKevin Day <thekevinday@gmail.com>
Wed, 26 Jan 2022 03:26:26 +0000 (21:26 -0600)
committerKevin Day <thekevinday@gmail.com>
Wed, 26 Jan 2022 03:46:24 +0000 (21:46 -0600)
There are far more permutations than what are handled within this commit.
Focus on only the most basic set of checks to write the unit tests for.

There are problems with mocking fwrite_unlocked() via the wrap strategy used by the linker.
I do not know why this is not working so I commented out the code and moved on.

Several problems are exposed and are solved.
- This exposed the fwrite_unlocked() return results problems.
- Add support for big endian (untested).
- Zero values are not correctly built (see below).

Make sure to count the zero number as a single digit.
Get rid of the "used" count and rely only on the digits.
Do not include the 0 digit when determining the padding.
Change the prefix append function to accommodate 0 and consistently call the prefix append function.

Update documentation comments.

39 files changed:
level_0/f_conversion/c/conversion.c
level_0/f_conversion/c/conversion.h
level_0/f_conversion/c/private-conversion.c
level_0/f_conversion/c/private-conversion.h
level_0/f_conversion/data/build/settings-mocks [new file with mode: 0644]
level_0/f_conversion/data/build/settings-tests [new file with mode: 0644]
level_0/f_conversion/data/build/testfile [new file with mode: 0644]
level_0/f_conversion/tests/c/mock-conversion.c [new file with mode: 0644]
level_0/f_conversion/tests/c/mock-conversion.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_is_binary.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_is_binary.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_is_decimal.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_is_decimal.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_is_duodecimal.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_is_duodecimal.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_is_hexidecimal.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_is_hexidecimal.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_is_octal.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_is_octal.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_to_binary.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_to_binary.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_to_decimal.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_to_decimal.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_to_duodecimal.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_to_duodecimal.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_to_hexidecimal.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_to_hexidecimal.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_to_octal.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-character_to_octal.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-number_signed_print.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-number_signed_print.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-number_signed_to_string.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-number_signed_to_string.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-number_unsigned_print.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-number_unsigned_print.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-number_unsigned_to_string.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion-number_unsigned_to_string.h [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion.c [new file with mode: 0644]
level_0/f_conversion/tests/c/test-conversion.h [new file with mode: 0644]

index 852a2a51386a6c9c007f3329aee53b2d97017857..26a23715347e36204a975d0529d9eaab65c5d1b6 100644 (file)
@@ -52,10 +52,12 @@ extern "C" {
     if (character > 0x2f && character < 0x3a) {
       return F_true;
     }
-    else if (character > 0x40 && character < 0x47) {
+
+    if (character > 0x40 && character < 0x47) {
       return F_true;
     }
-    else if (character > 0x60 && character < 0x67) {
+
+    if (character > 0x60 && character < 0x67) {
       return F_true;
     }
 
index 0bdd97c6831d16b6dc3bfc99d84ce638c6f29657..738771ed24fb351fe9bb43708075b7fe68d37b96 100644 (file)
@@ -33,7 +33,11 @@ extern "C" {
 #endif
 
 /**
- * Convert a single character into the binary digit that it represents.
+ * Identify whether or not the given 1-byte character represents a boolean digit.
+ *
+ * A boolean digit is either '0' or '1'.
+ *
+ * This only checks against ASCII characters.
  *
  * @param character
  *   The character to validate.
@@ -47,7 +51,11 @@ extern "C" {
 #endif // _di_f_conversion_character_is_binary_
 
 /**
- * Convert a single character into the decimal value that it represents.
+ * Identify whether or not the given 1-byte character represents a decimal digit.
+ *
+ * A decimal digit is a character from the numbers '0' to '9'.
+ *
+ * This only checks against ASCII characters.
  *
  * @param character
  *   The character to validate.
@@ -61,7 +69,13 @@ extern "C" {
 #endif // _di_f_conversion_character_is_decimal_
 
 /**
- * Convert a single character into the duodecimal digit that it represents.
+ * Identify whether or not the given 1-byte character represents a duodecimal digit.
+ *
+ * A decimal digit is a character from the numbers '0' to '9' and the following:
+ *   - 'a' or 'A': Character used to represent the number 10.
+ *   - 'b' or 'B': Character used to represent the number 11.
+ *
+ * This only checks against ASCII characters.
  *
  * @param character
  *   The character to validate.
@@ -75,7 +89,17 @@ extern "C" {
 #endif // _di_f_conversion_character_is_duodecimal_
 
 /**
- * Convert a single character into the hexidecimal digit that it represents.
+ * Identify whether or not the given 1-byte character represents a hexidecimal digit.
+ *
+ * A decimal digit is a character from the numbers '0' to '9' and the following:
+ *   - 'a' or 'A': Character used to represent the number 10.
+ *   - 'b' or 'B': Character used to represent the number 11.
+ *   - 'c' or 'C': Character used to represent the number 12.
+ *   - 'd' or 'D': Character used to represent the number 13.
+ *   - 'e' or 'E': Character used to represent the number 14.
+ *   - 'f' or 'F': Character used to represent the number 15.
+ *
+ * This only checks against ASCII characters.
  *
  * @param character
  *   The character to validate.
@@ -89,7 +113,11 @@ extern "C" {
 #endif // _di_f_conversion_character_is_hexidecimal_
 
 /**
- * Convert a single character into the octal digit that it represents.
+ * Identify whether or not the given 1-byte character represents a octal digit.
+ *
+ * A decimal digit is a character from the numbers '0' to '7'.
+ *
+ * This only checks against ASCII characters.
  *
  * @param character
  *   The character to validate.
@@ -251,9 +279,9 @@ extern "C" {
  *
  *   F_parameter (with error bit) if a parameter is invalid.
  *
- *   Errors (with error bit) from: f_string_dynamic_resize()
+ *   Errors (with error bit) from: f_string_dynamic_increase_by()
  *
- * @see f_string_dynamic_resize()
+ * @see f_string_dynamic_increase_by()
  */
 #ifndef _di_f_conversion_number_signed_to_string_
   extern f_status_t f_conversion_number_signed_to_string(const f_number_signed_t number, const f_conversion_data_t data, f_string_dynamic_t *destination);
@@ -315,9 +343,9 @@ extern "C" {
  *
  *   F_parameter (with error bit) if a parameter is invalid.
  *
- *   Errors (with error bit) from: f_string_dynamic_resize()
+ *   Errors (with error bit) from: f_string_dynamic_increase_by()
  *
- * @see f_string_dynamic_resize()
+ * @see f_string_dynamic_increase_by()
  */
 #ifndef _di_f_conversion_number_unsigned_to_string_
   extern f_status_t f_conversion_number_unsigned_to_string(const f_number_unsigned_t number, const f_conversion_data_t data, f_string_dynamic_t *destination);
index 496fdd56cb4dff0593110c2380f2180e4ff0d4d7..3f65cb99eaba919f67a30087062e97f33d91a69d 100644 (file)
@@ -64,14 +64,7 @@ extern "C" {
           return F_status_set_error(F_output);
         }
 
-        if (fwrite_unlocked(f_string_ascii_0_s, 1, 1, output) == -1) {
-          if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
-          if (errno == EFAULT) return F_status_set_error(F_buffer);
-          if (errno == EINTR) return F_status_set_error(F_interrupt);
-          if (errno == EINVAL) return F_status_set_error(F_parameter);
-          if (errno == EIO) return F_status_set_error(F_input_output);
-          if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
+        if (!fwrite_unlocked(f_string_ascii_0_s, 1, 1, output)) {
           return F_status_set_error(F_output);
         }
       }
@@ -113,14 +106,7 @@ extern "C" {
         }
       }
       else if (data.width) {
-        if (fwrite_unlocked(f_string_ascii_0_s, 1, 1, output) == -1) {
-          if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
-          if (errno == EFAULT) return F_status_set_error(F_buffer);
-          if (errno == EINTR) return F_status_set_error(F_interrupt);
-          if (errno == EINVAL) return F_status_set_error(F_parameter);
-          if (errno == EIO) return F_status_set_error(F_input_output);
-          if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
+        if (!fwrite_unlocked(f_string_ascii_0_s, 1, 1, output)) {
           return F_status_set_error(F_output);
         }
       }
@@ -144,18 +130,15 @@ extern "C" {
 
       while (digits--) {
 
-        if (fwrite_unlocked((work & number) ? f_string_ascii_1_s : f_string_ascii_0_s, 1, 1, output) == -1) {
-          if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
-          if (errno == EFAULT) return F_status_set_error(F_buffer);
-          if (errno == EINTR) return F_status_set_error(F_interrupt);
-          if (errno == EINVAL) return F_status_set_error(F_parameter);
-          if (errno == EIO) return F_status_set_error(F_input_output);
-          if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
+        if (!fwrite_unlocked((work & number) ? f_string_ascii_1_s : f_string_ascii_0_s, 1, 1, output)) {
           return F_status_set_error(F_output);
         }
 
-        work >>= 1;
+        #ifdef _is_F_endian_big
+          work <<= 1; // @todo review this and see if there is more that needs to be done.
+        #else
+          work >>= 1;
+        #endif // _is_F_endian_big
       } // while
 
       return F_none;
@@ -182,14 +165,7 @@ extern "C" {
         }
       }
 
-      if (fwrite_unlocked(&c, 1, 1, output) == -1) {
-        if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
-        if (errno == EFAULT) return F_status_set_error(F_buffer);
-        if (errno == EINTR) return F_status_set_error(F_interrupt);
-        if (errno == EINVAL) return F_status_set_error(F_parameter);
-        if (errno == EIO) return F_status_set_error(F_input_output);
-        if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
+      if (!fwrite_unlocked(&c, 1, 1, output)) {
         return F_status_set_error(F_output);
       }
     } // for
@@ -203,14 +179,7 @@ extern "C" {
 
     for (; total; --total) {
 
-      if (fwrite_unlocked(&pad, 1, 1, output) == -1) {
-        if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
-        if (errno == EFAULT) return F_status_set_error(F_buffer);
-        if (errno == EINTR) return F_status_set_error(F_interrupt);
-        if (errno == EINVAL) return F_status_set_error(F_parameter);
-        if (errno == EIO) return F_status_set_error(F_input_output);
-        if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
+      if (!fwrite_unlocked(&pad, 1, 1, output)) {
         return F_status_set_error(F_output);
       }
     } // for
@@ -224,52 +193,24 @@ extern "C" {
 
     if (negative) {
       if (negative == 1) {
-        if (fwrite_unlocked(f_string_ascii_minus_s, 1, 1, output) == -1) {
-          if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
-          if (errno == EFAULT) return F_status_set_error(F_buffer);
-          if (errno == EINTR) return F_status_set_error(F_interrupt);
-          if (errno == EINVAL) return F_status_set_error(F_parameter);
-          if (errno == EIO) return F_status_set_error(F_input_output);
-          if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
+        if (!fwrite_unlocked(f_string_ascii_minus_s, 1, 1, output)) {
           return F_status_set_error(F_output);
         }
       }
     }
     else if (data.flag & F_conversion_data_flag_sign_always_d) {
-      if (fwrite_unlocked(f_string_ascii_plus_s, 1, 1, output) == -1) {
-        if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
-        if (errno == EFAULT) return F_status_set_error(F_buffer);
-        if (errno == EINTR) return F_status_set_error(F_interrupt);
-        if (errno == EINVAL) return F_status_set_error(F_parameter);
-        if (errno == EIO) return F_status_set_error(F_input_output);
-        if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
+      if (!fwrite_unlocked(f_string_ascii_plus_s, 1, 1, output)) {
         return F_status_set_error(F_output);
       }
     }
     else if (data.flag & F_conversion_data_flag_sign_pad_d) {
-      if (fwrite_unlocked(f_string_ascii_space_s, 1, 1, output) == -1) {
-        if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
-        if (errno == EFAULT) return F_status_set_error(F_buffer);
-        if (errno == EINTR) return F_status_set_error(F_interrupt);
-        if (errno == EINVAL) return F_status_set_error(F_parameter);
-        if (errno == EIO) return F_status_set_error(F_input_output);
-        if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
+      if (!fwrite_unlocked(f_string_ascii_space_s, 1, 1, output)) {
         return F_status_set_error(F_output);
       }
     }
 
     if (data.flag & F_conversion_data_flag_base_prepend_d) {
-      if (fwrite_unlocked(f_string_ascii_0_s, 1, 1, output) == -1) {
-        if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
-        if (errno == EFAULT) return F_status_set_error(F_buffer);
-        if (errno == EINTR) return F_status_set_error(F_interrupt);
-        if (errno == EINVAL) return F_status_set_error(F_parameter);
-        if (errno == EIO) return F_status_set_error(F_input_output);
-        if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
+      if (!fwrite_unlocked(f_string_ascii_0_s, 1, 1, output)) {
         return F_status_set_error(F_output);
       }
 
@@ -301,14 +242,7 @@ extern "C" {
       }
 
       if (c) {
-        if (fwrite_unlocked(&c, 1, 1, output) == -1) {
-          if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
-          if (errno == EFAULT) return F_status_set_error(F_buffer);
-          if (errno == EINTR) return F_status_set_error(F_interrupt);
-          if (errno == EINVAL) return F_status_set_error(F_parameter);
-          if (errno == EIO) return F_status_set_error(F_input_output);
-          if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
+        if (!fwrite_unlocked(&c, 1, 1, output)) {
           return F_status_set_error(F_output);
         }
       }
@@ -327,6 +261,11 @@ extern "C" {
       remaining /= data.base;
     } // for
 
+    // A zero value should always show at least 1 zero when width is not 0.
+    if (data.width && !number) {
+      ++digits;
+    }
+
     // Ensure there is enough space for pad, adding the sign (1) and the prepend units (2).
     {
       long max = 3;
@@ -338,59 +277,35 @@ extern "C" {
         max += data.width;
       }
 
-      if (destination->used + max > destination->size) {
-        const f_status_t status = f_string_dynamic_resize(destination->used + max, destination);
-        if (F_status_is_error(status)) return status;
-      }
+      const f_status_t status = f_string_dynamic_increase_by(max, destination);
+      if (F_status_is_error(status)) return status;
     }
 
-    if (data.flag & F_conversion_data_flag_base_prepend_d) {
-      const int used = digits + 2 + (data.flag & F_conversion_data_flag_sign_always_d & F_conversion_data_flag_sign_pad_d ? 1 : 0);
-
-      if (data.width > used) {
-        if (data.flag & F_conversion_data_flag_zeros_leading_d) {
-          private_f_conversion_digit_to_string_prefix(data, negative, destination);
-          private_f_conversion_digit_to_string_pad(data, f_string_ascii_0_s[0], data.width - used, destination);
-          private_f_conversion_digit_to_string_number(data, number, digits, destination);
-        }
-        else {
-          private_f_conversion_digit_to_string_pad(data, f_string_ascii_space_s[0], data.width - used, destination);
-          private_f_conversion_digit_to_string_prefix(data, negative, destination);
-          private_f_conversion_digit_to_string_number(data, number, digits, destination);
-        }
+    if (data.width > digits) {
+      if (data.flag & F_conversion_data_flag_zeros_leading_d) {
+        private_f_conversion_digit_to_string_prefix(data, negative, destination);
+        private_f_conversion_digit_to_string_pad(data, f_string_ascii_0_s[0], data.width - digits, destination);
+        private_f_conversion_digit_to_string_number(data, number, digits, destination);
       }
       else if (number) {
+        private_f_conversion_digit_to_string_pad(data, f_string_ascii_space_s[0], data.width - digits, destination);
         private_f_conversion_digit_to_string_prefix(data, negative, destination);
         private_f_conversion_digit_to_string_number(data, number, digits, destination);
       }
-      else if (data.width) {
+      else {
+        private_f_conversion_digit_to_string_pad(data, f_string_ascii_space_s[0], data.width - digits, destination);
         private_f_conversion_digit_to_string_prefix(data, negative, destination);
-
-        destination->string[destination->used++] = f_string_ascii_0_s[0];
+        private_f_conversion_digit_to_string_number(data, number, digits, destination);
       }
     }
-    else {
-      const int used = digits + (data.flag & (F_conversion_data_flag_sign_always_d | F_conversion_data_flag_sign_pad_d) ? 1 : 0);
+    else if (number) {
+      private_f_conversion_digit_to_string_prefix(data, negative, destination);
+      private_f_conversion_digit_to_string_number(data, number, digits, destination);
+    }
+    else if (data.width) {
+      private_f_conversion_digit_to_string_prefix(data, negative, destination);
 
-      if (data.width > used) {
-        if (data.flag & F_conversion_data_flag_zeros_leading_d) {
-          private_f_conversion_digit_to_string_prefix(data, negative, destination);
-          private_f_conversion_digit_to_string_pad(data, f_string_ascii_0_s[0], data.width - used, destination);
-          private_f_conversion_digit_to_string_number(data, number, digits, destination);
-        }
-        else {
-          private_f_conversion_digit_to_string_pad(data, f_string_ascii_space_s[0], data.width - used, destination);
-          private_f_conversion_digit_to_string_prefix(data, negative, destination);
-          private_f_conversion_digit_to_string_number(data, number, digits, destination);
-        }
-      }
-      else if (number) {
-        private_f_conversion_digit_to_string_prefix(data, negative, destination);
-        private_f_conversion_digit_to_string_number(data, number, digits, destination);
-      }
-      else if (data.width) {
-        destination->string[destination->used++] = f_string_ascii_0_s[0];
-      }
+      destination->string[destination->used++] = f_string_ascii_0_s[0];
     }
 
     return F_none;
@@ -412,7 +327,12 @@ extern "C" {
       while (digits--) {
 
         destination->string[destination->used++] = (work & number) ? f_string_ascii_1_s[0] : f_string_ascii_0_s[1];
-        work >>= 1;
+
+        #ifdef _is_F_endian_big
+          work <<= 1; // @todo review this and see if there is more that needs to be done.
+        #else
+          work >>= 1;
+        #endif // _is_F_endian_big
       } // while
 
       return;
@@ -460,6 +380,9 @@ extern "C" {
       if (negative == 1) {
         destination->string[destination->used++] = f_string_ascii_minus_s[0];
       }
+      else if (data.flag & (F_conversion_data_flag_sign_always_d | F_conversion_data_flag_sign_pad_d)) {
+        destination->string[destination->used++] = f_string_ascii_space_s[0];
+      }
     }
     else if (data.flag & F_conversion_data_flag_sign_always_d) {
       destination->string[destination->used++] = f_string_ascii_plus_s[0];
index e79acd6c69a3ad597fda0561bc67d5129c06c61b..1d060aed0386af071ff408daba78cedc28e8b00c 100644 (file)
@@ -35,12 +35,7 @@ extern "C" {
  * @return
  *   F_none on success.
  *
- *   F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation.
- *   F_buffer (with error bit) if the buffer is invalid.
- *   F_file_type_directory (with error bit) if file descriptor represents a directory.
- *   F_input_output (with error bit) on I/O error.
- *   F_interrupt (with error bit) if interrupt was received.
- *   F_output (with error bit) on any other file output error.
+ *   F_output (with error bit) on failure.
  *   F_parameter (with error bit) if a parameter is invalid.
  *
  * @see fwrite_unlocked()
@@ -74,12 +69,7 @@ extern "C" {
  * @return
  *   F_none on success.
  *
- *   F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation.
- *   F_buffer (with error bit) if the buffer is invalid.
- *   F_file_type_directory (with error bit) if file descriptor represents a directory.
- *   F_input_output (with error bit) on I/O error.
- *   F_interrupt (with error bit) if interrupt was received.
- *   F_output (with error bit) on any other file output error.
+ *   F_output (with error bit) on failure.
  *   F_parameter (with error bit) if a parameter is invalid.
  *
  * @see fwrite_unlocked()
@@ -108,12 +98,7 @@ extern "C" {
  * @return
  *   F_none on success.
  *
- *   F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation.
- *   F_buffer (with error bit) if the buffer is invalid.
- *   F_file_type_directory (with error bit) if file descriptor represents a directory.
- *   F_input_output (with error bit) on I/O error.
- *   F_interrupt (with error bit) if interrupt was received.
- *   F_output (with error bit) on any other file output error.
+ *   F_output (with error bit) on failure.
  *   F_parameter (with error bit) if a parameter is invalid.
  *
  * @see fwrite_unlocked()
@@ -143,12 +128,7 @@ extern "C" {
  * @return
  *   F_none on success.
  *
- *   F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation.
- *   F_buffer (with error bit) if the buffer is invalid.
- *   F_file_type_directory (with error bit) if file descriptor represents a directory.
- *   F_input_output (with error bit) on I/O error.
- *   F_interrupt (with error bit) if interrupt was received.
- *   F_output (with error bit) on any other file output error.
+ *   F_output (with error bit) on failure.
  *   F_parameter (with error bit) if a parameter is invalid.
  *
  * @see fwrite_unlocked()
@@ -180,7 +160,7 @@ extern "C" {
  * @return
  *   F_none on success.
  *
- *   Errors (with error bit) from: f_string_dynamic_resize()
+ *   Errors (with error bit) from: f_string_dynamic_increase_by()
  *
  * @see f_conversion_number_signed_to_string()
  * @see f_conversion_number_unsigned_to_string()
diff --git a/level_0/f_conversion/data/build/settings-mocks b/level_0/f_conversion/data/build/settings-mocks
new file mode 100644 (file)
index 0000000..d8f5109
--- /dev/null
@@ -0,0 +1,78 @@
+# fss-0001
+
+project_name f_conversion
+
+version_major 0
+version_minor 5
+version_micro 8
+version_file micro
+version_target minor
+
+environment
+
+process_pre
+process_post
+
+modes individual
+modes_default individual
+
+build_compiler gcc
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+build_libraries -lc
+build_libraries-individual -lf_memory -lf_string -lf_utf
+build_libraries_shared
+build_libraries_static
+build_sources_library conversion.c conversion-common.c private-conversion.c ../../tests/c/mock-conversion.c
+build_sources_library_shared
+build_sources_library_static
+build_sources_program
+build_sources_program_shared
+build_sources_program_static
+build_sources_headers conversion.h conversion-common.h
+build_sources_headers_shared
+build_sources_headers_static
+build_sources_script
+build_sources_setting
+build_script yes
+build_shared yes
+build_static no
+
+path_headers fll/level_0
+path_headers_preserve no
+path_library_script script
+path_library_shared shared
+path_library_static static
+path_program_script script
+path_program_shared shared
+path_program_static static
+path_sources
+path_standard yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines
+defines_library
+defines_library_shared
+defines_library_static
+defines_program
+defines_program_shared
+defines_program_static
+defines_static
+defines_shared
+
+flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-logical-op-parentheses -Wno-parentheses
+flags_library -fPIC
+flags_library_shared
+flags_library_static
+flags_program -fPIE
+flags_program_shared
+flags_program_static
+flags_shared
+flags_static
+
+# Inject mocks.
+flags -Wl,--wrap=fwrite_unlocked
diff --git a/level_0/f_conversion/data/build/settings-tests b/level_0/f_conversion/data/build/settings-tests
new file mode 100644 (file)
index 0000000..6772395
--- /dev/null
@@ -0,0 +1,45 @@
+# fss-0001
+
+project_name test-f_conversion
+
+version_major 0
+version_minor 5
+version_micro 8
+version_file major
+version_target major
+
+modes individual level monolithic
+modes_default individual
+
+build_compiler gcc
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+build_libraries -lc -lcmocka
+build_libraries-individual -lf_memory -lf_string -lf_utf -lf_conversion
+build_libraries-level -lfll_0
+build_libraries-monolithic -lfll
+build_sources_program test-conversion-character_is_binary.c test-conversion-character_is_decimal.c test-conversion-character_is_duodecimal.c test-conversion-character_is_hexidecimal.c test-conversion-character_is_octal.c test-conversion-character_to_binary.c test-conversion-character_to_decimal.c test-conversion-character_to_duodecimal.c test-conversion-character_to_hexidecimal.c test-conversion-character_to_octal.c test-conversion-number_signed_print.c test-conversion-number_signed_to_string.c test-conversion-number_unsigned_print.c test-conversion-number_unsigned_to_string.c test-conversion.c
+build_script no
+build_shared yes
+build_static no
+
+path_headers tests/c
+path_headers_preserve no
+path_sources tests/c
+path_standard no
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines -Ibuild/includes
+defines_static -Lbuild/libraries/static
+defines_shared -Lbuild/libraries/shared
+
+flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-logical-op-parentheses -Wno-parentheses
+flags_program -fPIE
+flags_program_shared
+flags_program_static
+flags_shared
+flags_static
diff --git a/level_0/f_conversion/data/build/testfile b/level_0/f_conversion/data/build/testfile
new file mode 100644 (file)
index 0000000..f3dfc09
--- /dev/null
@@ -0,0 +1,47 @@
+# fss-0005 iki-0002
+
+settings:
+  load_build yes
+  fail exit
+
+  environment LD_LIBRARY_PATH
+
+main:
+  # Disable mocks until mocking can be fixed for this project.
+  #build settings-mocks
+  build settings
+  build settings-tests
+
+  operate ld_library_path
+
+  if exists build/programs/shared/test-f_conversion
+    shell build/programs/shared/test-f_conversion
+
+  if exists build/programs/static/test-f_conversion
+    shell build/programs/static/test-f_conversion
+
+  if not exists build/programs/shared/test-f_conversion
+  and not exists build/programs/static/test-f_conversion
+    operate not_created
+
+not_created:
+  print
+  print context:"error"Failed to test due to being unable to find either a shared or static test binary to perform tests. context:"error"
+
+  exit failure
+
+ld_library_path:
+  if defined environment LD_LIBRARY_PATH
+  and defined parameter work
+    define LD_LIBRARY_PATH 'build/libraries/shared:parameter:"work:value"libraries/shared:define:"LD_LIBRARY_PATH"'
+
+  else
+  if defined environment LD_LIBRARY_PATH
+    define LD_LIBRARY_PATH 'build/libraries/shared:parameter:define:"LD_LIBRARY_PATH"'
+
+  else
+  if defined parameter work
+    define LD_LIBRARY_PATH 'build/libraries/shared:parameter:"work:value"libraries/shared'
+
+  else
+    define LD_LIBRARY_PATH build/libraries/shared
diff --git a/level_0/f_conversion/tests/c/mock-conversion.c b/level_0/f_conversion/tests/c/mock-conversion.c
new file mode 100644 (file)
index 0000000..5f7581e
--- /dev/null
@@ -0,0 +1,22 @@
+#include "mock-conversion.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+size_t __wrap_fwrite_unlocked(const void *ptr, size_t size, size_t n, FILE *stream) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    return mock_type(int);
+  }
+
+  check_expected(ptr);
+
+  return n;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/mock-conversion.h b/level_0/f_conversion/tests/c/mock-conversion.h
new file mode 100644 (file)
index 0000000..62b1fba
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _MOCK__conversion_h
+#define _MOCK__conversion_h
+
+// libc includes.
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+
+// cmocka includes.
+#include <cmocka.h>
+
+// fll-0 includes.
+#include <fll/level_0/conversion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const static int mock_errno_generic = 32767;
+
+extern size_t __wrap_fwrite_unlocked(const void *ptr, size_t size, size_t n, FILE *stream);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _MOCK__conversion_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_is_binary.c b/level_0/f_conversion/tests/c/test-conversion-character_is_binary.c
new file mode 100644 (file)
index 0000000..29077c9
--- /dev/null
@@ -0,0 +1,31 @@
+#include "test-conversion.h"
+#include "test-conversion-character_is_binary.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_character_is_binary__works(void **state) {
+
+  for (uint8_t i = 0; i <= 0xff; ++i) {
+
+    const f_status_t status = f_conversion_character_is_binary(i);
+
+    switch (i) {
+      case '0':
+      case '1':
+        assert_int_equal(status, F_true);
+        break;
+
+      default:
+        assert_int_equal(status, F_false);
+        break;
+    }
+
+    if (i == 0xff) break;
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_is_binary.h b/level_0/f_conversion/tests/c/test-conversion-character_is_binary.h
new file mode 100644 (file)
index 0000000..1bee177
--- /dev/null
@@ -0,0 +1,24 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_character_is_binary_h
+#define _TEST__F_conversion_character_is_binary_h
+
+// f_conversion_character_is_binary() doesn't return failure.
+
+// f_conversion_character_is_binary() doesn't use parameter checking.
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_character_is_binary()
+ */
+extern void test__f_conversion_character_is_binary__works(void **state);
+
+#endif // _TEST__F_conversion_character_is_binary_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_is_decimal.c b/level_0/f_conversion/tests/c/test-conversion-character_is_decimal.c
new file mode 100644 (file)
index 0000000..85324e5
--- /dev/null
@@ -0,0 +1,39 @@
+#include "test-conversion.h"
+#include "test-conversion-character_is_decimal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_character_is_decimal__works(void **state) {
+
+  for (uint8_t i = 0; i <= 0xff; ++i) {
+
+    const f_status_t status = f_conversion_character_is_decimal(i);
+
+    switch (i) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        assert_int_equal(status, F_true);
+        break;
+
+      default:
+        assert_int_equal(status, F_false);
+        break;
+    }
+
+    if (i == 0xff) break;
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_is_decimal.h b/level_0/f_conversion/tests/c/test-conversion-character_is_decimal.h
new file mode 100644 (file)
index 0000000..9ced179
--- /dev/null
@@ -0,0 +1,24 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_character_is_decimal_h
+#define _TEST__F_conversion_character_is_decimal_h
+
+// f_conversion_character_is_decimal() doesn't return failure.
+
+// f_conversion_character_is_decimal() doesn't use parameter checking.
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_character_is_decimal()
+ */
+extern void test__f_conversion_character_is_decimal__works(void **state);
+
+#endif // _TEST__F_conversion_character_is_decimal_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_is_duodecimal.c b/level_0/f_conversion/tests/c/test-conversion-character_is_duodecimal.c
new file mode 100644 (file)
index 0000000..0fe0aeb
--- /dev/null
@@ -0,0 +1,43 @@
+#include "test-conversion.h"
+#include "test-conversion-character_is_duodecimal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_character_is_duodecimal__works(void **state) {
+
+  for (uint8_t i = 0; i <= 0xff; ++i) {
+
+    const f_status_t status = f_conversion_character_is_duodecimal(i);
+
+    switch (i) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case 'a':
+      case 'A':
+      case 'b':
+      case 'B':
+        assert_int_equal(status, F_true);
+        break;
+
+      default:
+        assert_int_equal(status, F_false);
+        break;
+    }
+
+    if (i == 0xff) break;
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_is_duodecimal.h b/level_0/f_conversion/tests/c/test-conversion-character_is_duodecimal.h
new file mode 100644 (file)
index 0000000..1481298
--- /dev/null
@@ -0,0 +1,24 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_character_is_duodecimal_h
+#define _TEST__F_conversion_character_is_duodecimal_h
+
+// f_conversion_character_is_duodecimal() doesn't return failure.
+
+// f_conversion_character_is_duodecimal() doesn't use parameter checking.
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_character_is_duodecimal()
+ */
+extern void test__f_conversion_character_is_duodecimal__works(void **state);
+
+#endif // _TEST__F_conversion_character_is_duodecimal_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_is_hexidecimal.c b/level_0/f_conversion/tests/c/test-conversion-character_is_hexidecimal.c
new file mode 100644 (file)
index 0000000..b47809c
--- /dev/null
@@ -0,0 +1,51 @@
+#include "test-conversion.h"
+#include "test-conversion-character_is_hexidecimal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_character_is_hexidecimal__works(void **state) {
+
+  for (uint8_t i = 0; i <= 0xff; ++i) {
+
+    const f_status_t status = f_conversion_character_is_hexidecimal(i);
+
+    switch (i) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case 'a':
+      case 'A':
+      case 'b':
+      case 'B':
+      case 'c':
+      case 'C':
+      case 'd':
+      case 'D':
+      case 'e':
+      case 'E':
+      case 'f':
+      case 'F':
+        assert_int_equal(status, F_true);
+        break;
+
+      default:
+        assert_int_equal(status, F_false);
+        break;
+    }
+
+    if (i == 0xff) break;
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_is_hexidecimal.h b/level_0/f_conversion/tests/c/test-conversion-character_is_hexidecimal.h
new file mode 100644 (file)
index 0000000..9c2b8ef
--- /dev/null
@@ -0,0 +1,24 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_character_is_hexidecimal_h
+#define _TEST__F_conversion_character_is_hexidecimal_h
+
+// f_conversion_character_is_hexidecimal() doesn't return failure.
+
+// f_conversion_character_is_hexidecimal() doesn't use parameter checking.
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_character_is_hexidecimal()
+ */
+extern void test__f_conversion_character_is_hexidecimal__works(void **state);
+
+#endif // _TEST__F_conversion_character_is_hexidecimal_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_is_octal.c b/level_0/f_conversion/tests/c/test-conversion-character_is_octal.c
new file mode 100644 (file)
index 0000000..5d0b675
--- /dev/null
@@ -0,0 +1,37 @@
+#include "test-conversion.h"
+#include "test-conversion-character_is_octal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_character_is_octal__works(void **state) {
+
+  for (uint8_t i = 0; i <= 0xff; ++i) {
+
+    const f_status_t status = f_conversion_character_is_octal(i);
+
+    switch (i) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+        assert_int_equal(status, F_true);
+        break;
+
+      default:
+        assert_int_equal(status, F_false);
+        break;
+    }
+
+    if (i == 0xff) break;
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_is_octal.h b/level_0/f_conversion/tests/c/test-conversion-character_is_octal.h
new file mode 100644 (file)
index 0000000..004ed84
--- /dev/null
@@ -0,0 +1,24 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_character_is_octal_h
+#define _TEST__F_conversion_character_is_octal_h
+
+// f_conversion_character_is_octal() doesn't return failure.
+
+// f_conversion_character_is_octal() doesn't use parameter checking.
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_character_is_octal()
+ */
+extern void test__f_conversion_character_is_octal__works(void **state);
+
+#endif // _TEST__F_conversion_character_is_octal_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_to_binary.c b/level_0/f_conversion/tests/c/test-conversion-character_to_binary.c
new file mode 100644 (file)
index 0000000..b3a4a86
--- /dev/null
@@ -0,0 +1,71 @@
+#include "test-conversion.h"
+#include "test-conversion-character_to_binary.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_character_to_binary__fails(void **state) {
+
+  uint8_t number;
+
+  for (uint8_t i = 0; i <= 0xff; ++i) {
+
+    const f_status_t status = f_conversion_character_to_binary(i, &number);
+
+    switch (i) {
+      case '0':
+      case '1':
+        assert_true(F_status_is_error_not(status));
+        break;
+
+      default:
+        assert_true(F_status_is_error(status));
+        break;
+    }
+
+    if (i == 0xff) break;
+  } // for
+}
+
+#ifndef _di_level_0_parameter_checking_
+  void test__f_conversion_character_to_binary__parameter_checking(void **state) {
+
+    {
+      const f_status_t status = f_conversion_character_to_binary(0, 0);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+  }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_conversion_character_to_binary__works(void **state) {
+
+  uint8_t number;
+
+  for (uint8_t i = '0'; i <= '1'; ++i) {
+
+    number = 255;
+
+    const f_status_t status = f_conversion_character_to_binary(i, &number);
+
+    switch (i) {
+      case '0':
+        assert_int_equal(number, 0);
+        break;
+
+      case '1':
+        assert_int_equal(number, 1);
+        break;
+
+      default:
+        break;
+    }
+
+    if (i == '1') break;
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_to_binary.h b/level_0/f_conversion/tests/c/test-conversion-character_to_binary.h
new file mode 100644 (file)
index 0000000..485d090
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_character_to_binary_h
+#define _TEST__F_conversion_character_to_binary_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_conversion_character_to_binary()
+ */
+extern void test__f_conversion_character_to_binary__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_conversion_character_to_binary()
+ */
+#ifndef _di_level_0_parameter_checking_
+  extern void test__f_conversion_character_to_binary__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_character_to_binary()
+ */
+extern void test__f_conversion_character_to_binary__works(void **state);
+
+#endif // _TEST__F_conversion_character_to_binary_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_to_decimal.c b/level_0/f_conversion/tests/c/test-conversion-character_to_decimal.c
new file mode 100644 (file)
index 0000000..606dd17
--- /dev/null
@@ -0,0 +1,111 @@
+#include "test-conversion.h"
+#include "test-conversion-character_to_decimal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_character_to_decimal__fails(void **state) {
+
+  uint8_t number;
+
+  for (uint8_t i = 0; i <= 0xff; ++i) {
+
+    const f_status_t status = f_conversion_character_to_decimal(i, &number);
+
+    switch (i) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        assert_true(F_status_is_error_not(status));
+        break;
+
+      default:
+        assert_true(F_status_is_error(status));
+        break;
+    }
+
+    if (i == 0xff) break;
+  } // for
+}
+
+#ifndef _di_level_0_parameter_checking_
+  void test__f_conversion_character_to_decimal__parameter_checking(void **state) {
+
+    {
+      const f_status_t status = f_conversion_character_to_decimal(0, 0);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+  }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_conversion_character_to_decimal__works(void **state) {
+
+  uint8_t number;
+
+  for (uint8_t i = '0'; i <= '9'; ++i) {
+
+    number = 255;
+
+    const f_status_t status = f_conversion_character_to_decimal(i, &number);
+
+    switch (i) {
+      case '0':
+        assert_int_equal(number, 0);
+        break;
+
+      case '1':
+        assert_int_equal(number, 1);
+        break;
+
+      case '2':
+        assert_int_equal(number, 2);
+        break;
+
+      case '3':
+        assert_int_equal(number, 3);
+        break;
+
+      case '4':
+        assert_int_equal(number, 4);
+        break;
+
+      case '5':
+        assert_int_equal(number, 5);
+        break;
+
+      case '6':
+        assert_int_equal(number, 6);
+        break;
+
+      case '7':
+        assert_int_equal(number, 7);
+        break;
+
+      case '8':
+        assert_int_equal(number, 8);
+        break;
+
+      case '9':
+        assert_int_equal(number, 9);
+        break;
+
+      default:
+        break;
+    }
+
+    if (i == '9') break;
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_to_decimal.h b/level_0/f_conversion/tests/c/test-conversion-character_to_decimal.h
new file mode 100644 (file)
index 0000000..57de425
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_character_to_decimal_h
+#define _TEST__F_conversion_character_to_decimal_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_conversion_character_to_decimal()
+ */
+extern void test__f_conversion_character_to_decimal__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_conversion_character_to_decimal()
+ */
+#ifndef _di_level_0_parameter_checking_
+  extern void test__f_conversion_character_to_decimal__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_character_to_decimal()
+ */
+extern void test__f_conversion_character_to_decimal__works(void **state);
+
+#endif // _TEST__F_conversion_character_to_decimal_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_to_duodecimal.c b/level_0/f_conversion/tests/c/test-conversion-character_to_duodecimal.c
new file mode 100644 (file)
index 0000000..07ad746
--- /dev/null
@@ -0,0 +1,125 @@
+#include "test-conversion.h"
+#include "test-conversion-character_to_duodecimal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_character_to_duodecimal__fails(void **state) {
+
+  uint8_t number;
+
+  for (uint8_t i = 0; i <= 0xff; ++i) {
+
+    const f_status_t status = f_conversion_character_to_duodecimal(i, &number);
+
+    switch (i) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case 'a':
+      case 'A':
+      case 'b':
+      case 'B':
+        assert_true(F_status_is_error_not(status));
+        break;
+
+      default:
+        assert_true(F_status_is_error(status));
+        break;
+    }
+
+    if (i == 0xff) break;
+  } // for
+}
+
+#ifndef _di_level_0_parameter_checking_
+  void test__f_conversion_character_to_duodecimal__parameter_checking(void **state) {
+
+    {
+      const f_status_t status = f_conversion_character_to_duodecimal(0, 0);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+  }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_conversion_character_to_duodecimal__works(void **state) {
+
+  uint8_t number;
+
+  for (uint8_t i = '0'; i <= 'b'; ++i) {
+
+    number = 255;
+
+    const f_status_t status = f_conversion_character_to_duodecimal(i, &number);
+
+    switch (i) {
+      case '0':
+        assert_int_equal(number, 0);
+        break;
+
+      case '1':
+        assert_int_equal(number, 1);
+        break;
+
+      case '2':
+        assert_int_equal(number, 2);
+        break;
+
+      case '3':
+        assert_int_equal(number, 3);
+        break;
+
+      case '4':
+        assert_int_equal(number, 4);
+        break;
+
+      case '5':
+        assert_int_equal(number, 5);
+        break;
+
+      case '6':
+        assert_int_equal(number, 6);
+        break;
+
+      case '7':
+        assert_int_equal(number, 7);
+        break;
+
+      case '8':
+        assert_int_equal(number, 8);
+        break;
+
+      case '9':
+        assert_int_equal(number, 9);
+        break;
+
+      case 'a':
+      case 'A':
+        assert_int_equal(number, 10);
+        break;
+
+      case 'b':
+      case 'B':
+        assert_int_equal(number, 11);
+        break;
+
+      default:
+        break;
+    }
+
+    if (i == 'b') break;
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_to_duodecimal.h b/level_0/f_conversion/tests/c/test-conversion-character_to_duodecimal.h
new file mode 100644 (file)
index 0000000..dc43c75
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_character_to_duodecimal_h
+#define _TEST__F_conversion_character_to_duodecimal_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_conversion_character_to_duodecimal()
+ */
+extern void test__f_conversion_character_to_duodecimal__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_conversion_character_to_duodecimal()
+ */
+#ifndef _di_level_0_parameter_checking_
+  extern void test__f_conversion_character_to_duodecimal__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_character_to_duodecimal()
+ */
+extern void test__f_conversion_character_to_duodecimal__works(void **state);
+
+#endif // _TEST__F_conversion_character_to_duodecimal_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_to_hexidecimal.c b/level_0/f_conversion/tests/c/test-conversion-character_to_hexidecimal.c
new file mode 100644 (file)
index 0000000..700c8f6
--- /dev/null
@@ -0,0 +1,153 @@
+#include "test-conversion.h"
+#include "test-conversion-character_to_hexidecimal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_character_to_hexidecimal__fails(void **state) {
+
+  uint8_t number;
+
+  for (uint8_t i = 0; i <= 0xff; ++i) {
+
+    const f_status_t status = f_conversion_character_to_hexidecimal(i, &number);
+
+    switch (i) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case 'a':
+      case 'A':
+      case 'b':
+      case 'B':
+      case 'c':
+      case 'C':
+      case 'd':
+      case 'D':
+      case 'e':
+      case 'E':
+      case 'f':
+      case 'F':
+        assert_true(F_status_is_error_not(status));
+        break;
+
+      default:
+        assert_true(F_status_is_error(status));
+        break;
+    }
+
+    if (i == 0xff) break;
+  } // for
+}
+
+#ifndef _di_level_0_parameter_checking_
+  void test__f_conversion_character_to_hexidecimal__parameter_checking(void **state) {
+
+    {
+      const f_status_t status = f_conversion_character_to_hexidecimal(0, 0);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+  }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_conversion_character_to_hexidecimal__works(void **state) {
+
+  uint8_t number;
+
+  for (uint8_t i = '0'; i <= 'f'; ++i) {
+
+    number = 255;
+
+    const f_status_t status = f_conversion_character_to_hexidecimal(i, &number);
+
+    switch (i) {
+      case '0':
+        assert_int_equal(number, 0);
+        break;
+
+      case '1':
+        assert_int_equal(number, 1);
+        break;
+
+      case '2':
+        assert_int_equal(number, 2);
+        break;
+
+      case '3':
+        assert_int_equal(number, 3);
+        break;
+
+      case '4':
+        assert_int_equal(number, 4);
+        break;
+
+      case '5':
+        assert_int_equal(number, 5);
+        break;
+
+      case '6':
+        assert_int_equal(number, 6);
+        break;
+
+      case '7':
+        assert_int_equal(number, 7);
+        break;
+
+      case '8':
+        assert_int_equal(number, 8);
+        break;
+
+      case '9':
+        assert_int_equal(number, 9);
+        break;
+
+      case 'a':
+      case 'A':
+        assert_int_equal(number, 10);
+        break;
+
+      case 'b':
+      case 'B':
+        assert_int_equal(number, 11);
+        break;
+
+      case 'c':
+      case 'C':
+        assert_int_equal(number, 12);
+        break;
+
+      case 'd':
+      case 'D':
+        assert_int_equal(number, 13);
+        break;
+
+      case 'e':
+      case 'E':
+        assert_int_equal(number, 14);
+        break;
+
+      case 'f':
+      case 'F':
+        assert_int_equal(number, 15);
+        break;
+
+      default:
+        break;
+    }
+
+    if (i == 'f') break;
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_to_hexidecimal.h b/level_0/f_conversion/tests/c/test-conversion-character_to_hexidecimal.h
new file mode 100644 (file)
index 0000000..8e07d0a
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_character_to_hexidecimal_h
+#define _TEST__F_conversion_character_to_hexidecimal_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_conversion_character_to_hexidecimal()
+ */
+extern void test__f_conversion_character_to_hexidecimal__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_conversion_character_to_hexidecimal()
+ */
+#ifndef _di_level_0_parameter_checking_
+  extern void test__f_conversion_character_to_hexidecimal__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_character_to_hexidecimal()
+ */
+extern void test__f_conversion_character_to_hexidecimal__works(void **state);
+
+#endif // _TEST__F_conversion_character_to_hexidecimal_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_to_octal.c b/level_0/f_conversion/tests/c/test-conversion-character_to_octal.c
new file mode 100644 (file)
index 0000000..5c454bf
--- /dev/null
@@ -0,0 +1,98 @@
+#include "test-conversion.h"
+#include "test-conversion-character_to_octal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_character_to_octal__fails(void **state) {
+
+  uint8_t number;
+
+  for (uint8_t i = 0; i <= 0xff; ++i) {
+
+    const f_status_t status = f_conversion_character_to_octal(i, &number);
+
+    switch (i) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+        assert_true(F_status_is_error_not(status));
+        break;
+
+      default:
+        assert_true(F_status_is_error(status));
+        break;
+    }
+
+    if (i == 0xff) break;
+  } // for
+}
+
+#ifndef _di_level_0_parameter_checking_
+  void test__f_conversion_character_to_octal__parameter_checking(void **state) {
+
+    {
+      const f_status_t status = f_conversion_character_to_octal(0, 0);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+  }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_conversion_character_to_octal__works(void **state) {
+
+  uint8_t number;
+
+  for (uint8_t i = '0'; i <= '7'; ++i) {
+
+    number = 255;
+
+    const f_status_t status = f_conversion_character_to_octal(i, &number);
+
+    switch (i) {
+      case '0':
+        assert_int_equal(number, 0);
+        break;
+
+      case '1':
+        assert_int_equal(number, 1);
+        break;
+
+      case '2':
+        assert_int_equal(number, 2);
+        break;
+
+      case '3':
+        assert_int_equal(number, 3);
+        break;
+
+      case '4':
+        assert_int_equal(number, 4);
+        break;
+
+      case '5':
+        assert_int_equal(number, 5);
+        break;
+
+      case '6':
+        assert_int_equal(number, 6);
+        break;
+
+      case '7':
+        assert_int_equal(number, 7);
+        break;
+    }
+
+    if (i == '7') break;
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-character_to_octal.h b/level_0/f_conversion/tests/c/test-conversion-character_to_octal.h
new file mode 100644 (file)
index 0000000..041b15e
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_character_to_octal_h
+#define _TEST__F_conversion_character_to_octal_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_conversion_character_to_octal()
+ */
+extern void test__f_conversion_character_to_octal__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_conversion_character_to_octal()
+ */
+#ifndef _di_level_0_parameter_checking_
+  extern void test__f_conversion_character_to_octal__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_character_to_octal()
+ */
+extern void test__f_conversion_character_to_octal__works(void **state);
+
+#endif // _TEST__F_conversion_character_to_octal_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-number_signed_print.c b/level_0/f_conversion/tests/c/test-conversion-number_signed_print.c
new file mode 100644 (file)
index 0000000..c2c79e6
--- /dev/null
@@ -0,0 +1,89 @@
+#include "test-conversion.h"
+#include "test-conversion-number_signed_print.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_number_signed_print__fails(void **state) {
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 1);
+
+    will_return(__wrap_fwrite_unlocked, true);
+    will_return(__wrap_fwrite_unlocked, 0);
+
+    const f_status_t status = f_conversion_number_signed_print(1, data, stdout);
+
+    assert_int_equal(F_status_set_fine(status), F_output);
+  }
+}
+
+void test__f_conversion_number_signed_print__fails_for_prepend(void **state) {
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_base_prepend_d, 0);
+
+    will_return(__wrap_fwrite_unlocked, true);
+    will_return(__wrap_fwrite_unlocked, 0);
+
+    const f_status_t status = f_conversion_number_signed_print(1, data, stdout);
+
+    assert_int_equal(F_status_set_fine(status), F_output);
+  }
+}
+
+void test__f_conversion_number_signed_print__fails_for_zero(void **state) {
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 0);
+
+    will_return(__wrap_fwrite_unlocked, true);
+    will_return(__wrap_fwrite_unlocked, 0);
+
+    const f_status_t status = f_conversion_number_signed_print(0, data, stdout);
+
+    assert_int_equal(F_status_set_fine(status), F_output);
+  }
+}
+
+#ifndef _di_level_0_parameter_checking_
+  void test__f_conversion_number_signed_print__parameter_checking(void **state) {
+
+    {
+      const f_conversion_data_t data = macro_f_conversion_data_t_initialize(2, 0, 0);
+
+      const f_status_t status = f_conversion_number_signed_print(0, data, 0);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+
+    {
+      FILE file;
+      const f_conversion_data_t data = macro_f_conversion_data_t_initialize(1, 0, 0);
+
+      const f_status_t status = f_conversion_number_signed_print(0, data, &file);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+  }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_conversion_number_signed_print__works(void **state) {
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 0);
+
+    const f_status_t status = f_conversion_number_signed_print(1, data, stdout);
+
+    will_return(__wrap_fwrite_unlocked, false);
+
+    expect_string(__wrap_fwrite_unlocked, ptr, "1");
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-number_signed_print.h b/level_0/f_conversion/tests/c/test-conversion-number_signed_print.h
new file mode 100644 (file)
index 0000000..0c9ed82
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_number_signed_print_h
+#define _TEST__F_conversion_number_signed_print_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_conversion_number_signed_print()
+ */
+extern void test__f_conversion_number_signed_print__fails(void **state);
+
+/**
+ * Test that function fails when the prepend flag is used.
+ *
+ * @see f_conversion_number_signed_print()
+ */
+extern void test__f_conversion_number_signed_print__fails_for_prepend(void **state);
+
+/**
+ * Test that function fails for 0.
+ *
+ * @see f_conversion_number_signed_print()
+ */
+extern void test__f_conversion_number_signed_print__fails_for_zero(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_conversion_number_signed_print()
+ */
+#ifndef _di_level_0_parameter_checking_
+  extern void test__f_conversion_number_signed_print__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_number_signed_print()
+ */
+extern void test__f_conversion_number_signed_print__works(void **state);
+
+#endif // _TEST__F_conversion_number_signed_print_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-number_signed_to_string.c b/level_0/f_conversion/tests/c/test-conversion-number_signed_to_string.c
new file mode 100644 (file)
index 0000000..e99047e
--- /dev/null
@@ -0,0 +1,296 @@
+#include "test-conversion.h"
+#include "test-conversion-number_signed_to_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_level_0_parameter_checking_
+  void test__f_conversion_number_signed_to_string__parameter_checking(void **state) {
+
+    {
+      const f_conversion_data_t data = macro_f_conversion_data_t_initialize(2, 0, 0);
+
+      const f_status_t status = f_conversion_number_signed_to_string(0, data, 0);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+
+    {
+      f_string_dynamic_t string;
+      const f_conversion_data_t data = macro_f_conversion_data_t_initialize(1, 0, 0);
+
+      const f_status_t status = f_conversion_number_signed_to_string(0, data, &string);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+  }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_conversion_number_signed_to_string__works(void **state) {
+
+  f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "1");
+  }
+
+  f_string_dynamic_resize(0, &destination);
+}
+
+void test__f_conversion_number_signed_to_string__works_for_prepend(void **state) {
+
+  f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(2, F_conversion_data_flag_base_prepend_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0b1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(2, F_conversion_data_flag_base_prepend_d | F_conversion_data_flag_base_upper_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0B1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(8, F_conversion_data_flag_base_prepend_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0o1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(8, F_conversion_data_flag_base_prepend_d | F_conversion_data_flag_base_upper_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0O1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_base_prepend_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0t1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_base_prepend_d | F_conversion_data_flag_base_upper_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0T1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(12, F_conversion_data_flag_base_prepend_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0d1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(12, F_conversion_data_flag_base_prepend_d | F_conversion_data_flag_base_upper_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0D1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(16, F_conversion_data_flag_base_prepend_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0x1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(16, F_conversion_data_flag_base_prepend_d | F_conversion_data_flag_base_upper_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0X1");
+  }
+
+  f_string_dynamic_resize(0, &destination);
+}
+
+void test__f_conversion_number_signed_to_string__works_for_zero(void **state) {
+
+  f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 1);
+
+    const f_status_t status = f_conversion_number_signed_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_zeros_leading_d, 1);
+
+    const f_status_t status = f_conversion_number_signed_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 2);
+
+    const f_status_t status = f_conversion_number_signed_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, " 0");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_zeros_leading_d, 2);
+
+    const f_status_t status = f_conversion_number_signed_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "00");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_sign_pad_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_sign_pad_d, 1);
+
+    const f_status_t status = f_conversion_number_signed_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, " 0");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_sign_always_d, 0);
+
+    const f_status_t status = f_conversion_number_signed_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_sign_always_d, 1);
+
+    const f_status_t status = f_conversion_number_signed_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, " 0");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_sign_always_d | F_conversion_data_flag_zeros_leading_d, 2);
+
+    const f_status_t status = f_conversion_number_signed_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, " 00");
+  }
+
+  f_string_dynamic_resize(0, &destination);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-number_signed_to_string.h b/level_0/f_conversion/tests/c/test-conversion-number_signed_to_string.h
new file mode 100644 (file)
index 0000000..f3c9c90
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_number_signed_to_string_h
+#define _TEST__F_conversion_number_signed_to_string_h
+
+// f_conversion_number_signed_to_string() only returns memory failures.
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_conversion_number_signed_to_string()
+ */
+#ifndef _di_level_0_parameter_checking_
+  extern void test__f_conversion_number_signed_to_string__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_number_signed_to_string()
+ */
+extern void test__f_conversion_number_signed_to_string__works(void **state);
+
+/**
+ * Test that function works when the prepend flag is used.
+ *
+ * @see f_conversion_number_signed_to_string()
+ */
+extern void test__f_conversion_number_signed_to_string__works_for_prepend(void **state);
+
+/**
+ * Test that function works for 0.
+ *
+ * @see f_conversion_number_signed_to_string()
+ */
+extern void test__f_conversion_number_signed_to_string__works_for_zero(void **state);
+
+#endif // _TEST__F_conversion_number_signed_to_string_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-number_unsigned_print.c b/level_0/f_conversion/tests/c/test-conversion-number_unsigned_print.c
new file mode 100644 (file)
index 0000000..2beaf7b
--- /dev/null
@@ -0,0 +1,89 @@
+#include "test-conversion.h"
+#include "test-conversion-number_unsigned_print.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_conversion_number_unsigned_print__fails(void **state) {
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 1);
+
+    will_return(__wrap_fwrite_unlocked, true);
+    will_return(__wrap_fwrite_unlocked, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_print(1, data, stdout);
+
+    assert_int_equal(F_status_set_fine(status), F_output);
+  }
+}
+
+void test__f_conversion_number_unsigned_print__fails_for_prepend(void **state) {
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_base_prepend_d, 0);
+
+    will_return(__wrap_fwrite_unlocked, true);
+    will_return(__wrap_fwrite_unlocked, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_print(1, data, stdout);
+
+    assert_int_equal(F_status_set_fine(status), F_output);
+  }
+}
+
+void test__f_conversion_number_unsigned_print__fails_for_zero(void **state) {
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 0);
+
+    will_return(__wrap_fwrite_unlocked, true);
+    will_return(__wrap_fwrite_unlocked, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_print(0, data, stdout);
+
+    assert_int_equal(F_status_set_fine(status), F_output);
+  }
+}
+
+#ifndef _di_level_0_parameter_checking_
+  void test__f_conversion_number_unsigned_print__parameter_checking(void **state) {
+
+    {
+      const f_conversion_data_t data = macro_f_conversion_data_t_initialize(2, 0, 0);
+
+      const f_status_t status = f_conversion_number_unsigned_print(0, data, 0);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+
+    {
+      FILE file;
+      const f_conversion_data_t data = macro_f_conversion_data_t_initialize(1, 0, 0);
+
+      const f_status_t status = f_conversion_number_unsigned_print(0, data, &file);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+  }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_conversion_number_unsigned_print__works(void **state) {
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_print(1, data, stdout);
+
+    will_return(__wrap_fwrite_unlocked, false);
+
+    expect_string(__wrap_fwrite_unlocked, ptr, "1");
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-number_unsigned_print.h b/level_0/f_conversion/tests/c/test-conversion-number_unsigned_print.h
new file mode 100644 (file)
index 0000000..cb8e365
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_number_unsigned_print_h
+#define _TEST__F_conversion_number_unsigned_print_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_conversion_number_unsigned_print()
+ */
+extern void test__f_conversion_number_unsigned_print__fails(void **state);
+
+/**
+ * Test that function fails when the prepend flag is used.
+ *
+ * @see f_conversion_number_unsigned_print()
+ */
+extern void test__f_conversion_number_unsigned_print__fails_for_prepend(void **state);
+
+/**
+ * Test that function fails for 0.
+ *
+ * @see f_conversion_number_unsigned_print()
+ */
+extern void test__f_conversion_number_unsigned_print__fails_for_zero(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_conversion_number_unsigned_print()
+ */
+#ifndef _di_level_0_parameter_checking_
+  extern void test__f_conversion_number_unsigned_print__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_number_unsigned_print()
+ */
+extern void test__f_conversion_number_unsigned_print__works(void **state);
+
+#endif // _TEST__F_conversion_number_unsigned_print_h
diff --git a/level_0/f_conversion/tests/c/test-conversion-number_unsigned_to_string.c b/level_0/f_conversion/tests/c/test-conversion-number_unsigned_to_string.c
new file mode 100644 (file)
index 0000000..7715597
--- /dev/null
@@ -0,0 +1,296 @@
+#include "test-conversion.h"
+#include "test-conversion-number_unsigned_to_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_level_0_parameter_checking_
+  void test__f_conversion_number_unsigned_to_string__parameter_checking(void **state) {
+
+    {
+      const f_conversion_data_t data = macro_f_conversion_data_t_initialize(2, 0, 0);
+
+      const f_status_t status = f_conversion_number_unsigned_to_string(0, data, 0);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+
+    {
+      f_string_dynamic_t string;
+      const f_conversion_data_t data = macro_f_conversion_data_t_initialize(1, 0, 0);
+
+      const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &string);
+
+      assert_int_equal(F_status_set_fine(status), F_parameter);
+    }
+  }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_conversion_number_unsigned_to_string__works(void **state) {
+
+  f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "1");
+  }
+
+  f_string_dynamic_resize(0, &destination);
+}
+
+void test__f_conversion_number_unsigned_to_string__works_for_prepend(void **state) {
+
+  f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(2, F_conversion_data_flag_base_prepend_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0b1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(2, F_conversion_data_flag_base_prepend_d | F_conversion_data_flag_base_upper_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0B1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(8, F_conversion_data_flag_base_prepend_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0o1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(8, F_conversion_data_flag_base_prepend_d | F_conversion_data_flag_base_upper_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0O1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_base_prepend_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0t1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_base_prepend_d | F_conversion_data_flag_base_upper_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0T1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(12, F_conversion_data_flag_base_prepend_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0d1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(12, F_conversion_data_flag_base_prepend_d | F_conversion_data_flag_base_upper_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0D1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(16, F_conversion_data_flag_base_prepend_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0x1");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(16, F_conversion_data_flag_base_prepend_d | F_conversion_data_flag_base_upper_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(1, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0X1");
+  }
+
+  f_string_dynamic_resize(0, &destination);
+}
+
+void test__f_conversion_number_unsigned_to_string__works_for_zero(void **state) {
+
+  f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 1);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_zeros_leading_d, 1);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "0");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, 0, 2);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, " 0");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_zeros_leading_d, 2);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "00");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_sign_pad_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_sign_pad_d, 1);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, " 0");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_sign_always_d, 0);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, "");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_sign_always_d, 1);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, " 0");
+  }
+
+  destination.used = 0;
+  memset(destination.string, 0, destination.size);
+
+  {
+    const f_conversion_data_t data = macro_f_conversion_data_t_initialize(10, F_conversion_data_flag_sign_always_d | F_conversion_data_flag_zeros_leading_d, 2);
+
+    const f_status_t status = f_conversion_number_unsigned_to_string(0, data, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(destination.string, " 00");
+  }
+
+  f_string_dynamic_resize(0, &destination);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion-number_unsigned_to_string.h b/level_0/f_conversion/tests/c/test-conversion-number_unsigned_to_string.h
new file mode 100644 (file)
index 0000000..8c16f89
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_number_unsigned_to_string_h
+#define _TEST__F_conversion_number_unsigned_to_string_h
+
+// f_conversion_number_unsigned_to_string() only returns memory failures.
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_conversion_number_unsigned_to_string()
+ */
+#ifndef _di_level_0_parameter_checking_
+  extern void test__f_conversion_number_unsigned_to_string__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_conversion_number_unsigned_to_string()
+ */
+extern void test__f_conversion_number_unsigned_to_string__works(void **state);
+
+/**
+ * Test that function works when the prepend flag is used.
+ *
+ * @see f_conversion_number_unsigned_to_string()
+ */
+extern void test__f_conversion_number_unsigned_to_string__works_for_prepend(void **state);
+
+/**
+ * Test that function works for 0.
+ *
+ * @see f_conversion_number_unsigned_to_string()
+ */
+extern void test__f_conversion_number_unsigned_to_string__works_for_zero(void **state);
+
+#endif // _TEST__F_conversion_number_unsigned_to_string_h
diff --git a/level_0/f_conversion/tests/c/test-conversion.c b/level_0/f_conversion/tests/c/test-conversion.c
new file mode 100644 (file)
index 0000000..2528f95
--- /dev/null
@@ -0,0 +1,98 @@
+#include "test-conversion.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int setup(void **state) {
+
+  return 0;
+}
+
+int setdown(void **state) {
+
+  errno = 0;
+
+  return 0;
+}
+
+int main(void) {
+
+  const struct CMUnitTest tests[] = {
+
+    // f_conversion_character_is_binary() doesn't return failure.
+    cmocka_unit_test(test__f_conversion_character_is_binary__works),
+
+    // f_conversion_character_is_decimal() doesn't return failure.
+    cmocka_unit_test(test__f_conversion_character_is_decimal__works),
+
+    // f_conversion_character_is_duodecimal() doesn't return failure.
+    cmocka_unit_test(test__f_conversion_character_is_duodecimal__works),
+
+    // f_conversion_character_is_hexidecimal() doesn't return failure.
+    cmocka_unit_test(test__f_conversion_character_is_hexidecimal__works),
+
+    // f_conversion_character_is_octal() doesn't return failure.
+    cmocka_unit_test(test__f_conversion_character_is_octal__works),
+
+    cmocka_unit_test(test__f_conversion_character_to_binary__fails),
+    cmocka_unit_test(test__f_conversion_character_to_binary__works),
+
+    cmocka_unit_test(test__f_conversion_character_to_decimal__fails),
+    cmocka_unit_test(test__f_conversion_character_to_decimal__works),
+
+    cmocka_unit_test(test__f_conversion_character_to_duodecimal__fails),
+    cmocka_unit_test(test__f_conversion_character_to_duodecimal__works),
+
+    cmocka_unit_test(test__f_conversion_character_to_hexidecimal__fails),
+    cmocka_unit_test(test__f_conversion_character_to_hexidecimal__works),
+
+    cmocka_unit_test(test__f_conversion_character_to_octal__fails),
+    cmocka_unit_test(test__f_conversion_character_to_octal__works),
+
+    // Currently failing for uknown reasons, it appears __wrap_fwrite_unlocked() is somehow not being wrapped properly.
+    //cmocka_unit_test(test__f_conversion_number_signed_print__fails),
+    //cmocka_unit_test(test__f_conversion_number_signed_print__fails_for_prepend),
+    //cmocka_unit_test(test__f_conversion_number_signed_print__fails_for_zero),
+    //cmocka_unit_test(test__f_conversion_number_signed_print__works),
+
+    // f_conversion_number_signed_to_string() only returns memory failures.
+    cmocka_unit_test(test__f_conversion_number_signed_to_string__works),
+    cmocka_unit_test(test__f_conversion_number_signed_to_string__works_for_prepend),
+    cmocka_unit_test(test__f_conversion_number_signed_to_string__works_for_zero),
+
+    // // Currently failing for uknown reasons, it appears __wrap_fwrite_unlocked() is somehow not being wrapped properly.
+    //cmocka_unit_test(test__f_conversion_number_unsigned_print__fails),
+    //cmocka_unit_test(test__f_conversion_number_unsigned_print__fails_for_prepend),
+    //cmocka_unit_test(test__f_conversion_number_unsigned_print__fails_for_zero),
+    //cmocka_unit_test(test__f_conversion_number_unsigned_print__works),
+
+    // f_conversion_number_unsigned_to_string() only returns memory failures.
+    cmocka_unit_test(test__f_conversion_number_unsigned_to_string__works),
+    cmocka_unit_test(test__f_conversion_number_unsigned_to_string__works_for_prepend),
+    cmocka_unit_test(test__f_conversion_number_unsigned_to_string__works_for_zero),
+
+    #ifndef _di_level_0_parameter_checking_
+      // f_conversion_character_is_binary() doesn't use parameter checking.
+      // f_conversion_character_is_decimal() doesn't use parameter checking.
+      // f_conversion_character_is_duodecimal() doesn't use parameter checking.
+      // f_conversion_character_is_hexidecimal() doesn't use parameter checking.
+      // f_conversion_character_is_octal() doesn't use parameter checking.
+      cmocka_unit_test(test__f_conversion_character_to_binary__parameter_checking),
+      cmocka_unit_test(test__f_conversion_character_to_decimal__parameter_checking),
+      cmocka_unit_test(test__f_conversion_character_to_duodecimal__parameter_checking),
+      cmocka_unit_test(test__f_conversion_character_to_hexidecimal__parameter_checking),
+      cmocka_unit_test(test__f_conversion_character_to_octal__parameter_checking),
+      cmocka_unit_test(test__f_conversion_number_signed_print__parameter_checking),
+      cmocka_unit_test(test__f_conversion_number_signed_to_string__parameter_checking),
+      cmocka_unit_test(test__f_conversion_number_unsigned_print__parameter_checking),
+      cmocka_unit_test(test__f_conversion_number_unsigned_to_string__parameter_checking),
+    #endif // _di_level_0_parameter_checking_
+  };
+
+  return cmocka_run_group_tests(tests, setup, setdown);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_conversion/tests/c/test-conversion.h b/level_0/f_conversion/tests/c/test-conversion.h
new file mode 100644 (file)
index 0000000..a9a1d68
--- /dev/null
@@ -0,0 +1,85 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Conversion
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the conversion project.
+ */
+#ifndef _TEST__F_conversion_h
+#define _TEST__F_conversion_h
+
+// libc includes.
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+
+// cmocka includes.
+#include <cmocka.h>
+
+// fll-0 includes.
+#include <fll/level_0/conversion.h>
+
+// mock includes.
+#include "mock-conversion.h"
+
+// test includes.
+#include "test-conversion-character_is_binary.h"
+#include "test-conversion-character_is_decimal.h"
+#include "test-conversion-character_is_duodecimal.h"
+#include "test-conversion-character_is_hexidecimal.h"
+#include "test-conversion-character_is_octal.h"
+#include "test-conversion-character_to_binary.h"
+#include "test-conversion-character_to_decimal.h"
+#include "test-conversion-character_to_duodecimal.h"
+#include "test-conversion-character_to_hexidecimal.h"
+#include "test-conversion-character_to_octal.h"
+#include "test-conversion-number_signed_print.h"
+#include "test-conversion-number_signed_to_string.h"
+#include "test-conversion-number_unsigned_print.h"
+#include "test-conversion-number_unsigned_to_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform any setup operations.
+ *
+ * @param state
+ *   The test state.
+ *
+ * @return
+ *   The status of this function, where 0 means success.
+ */
+extern int setup(void **state);
+
+/**
+ * Peform any setdown operations.
+ *
+ * @param state
+ *   The test state.
+ *
+ * @return
+ *   The status of this function, where 0 means success.
+ */
+extern int setdown(void **state);
+
+/**
+ * Run all tests.
+ *
+ * @return
+ *   The final result of the tests.
+ *
+ * @see cmocka_run_group_tests()
+ * @see cmocka_unit_test()
+ */
+extern int main(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _TEST__F_conversion_h