]> Kevux Git Server - fll/commitdiff
Feature: Add f_random project for providing basic calls to getting and using entropy.
authorKevin Day <thekevinday@gmail.com>
Sun, 31 Dec 2023 03:09:24 +0000 (21:09 -0600)
committerKevin Day <thekevinday@gmail.com>
Sun, 31 Dec 2023 03:09:24 +0000 (21:09 -0600)
Update the stand alone build config files.

Add the appropriate unit tests.

30 files changed:
build/level_0/settings
build/monolithic/settings
build/scripts/bootstrap-example.sh
build/scripts/test.sh
build/stand_alone/byte_dump.config.h
build/stand_alone/fake.config.h
build/stand_alone/firewall.config.h
build/stand_alone/utf8.config.h
level_0/f_random/c/random.c [new file with mode: 0644]
level_0/f_random/c/random.h [new file with mode: 0644]
level_0/f_random/data/build/defines [new file with mode: 0644]
level_0/f_random/data/build/dependencies [new file with mode: 0644]
level_0/f_random/data/build/dependencies-tests [new file with mode: 0644]
level_0/f_random/data/build/fakefile [new file with mode: 0644]
level_0/f_random/data/build/settings [new file with mode: 0644]
level_0/f_random/data/build/settings-mocks [new file with mode: 0644]
level_0/f_random/data/build/settings-tests [new file with mode: 0644]
level_0/f_random/data/build/testfile [new file with mode: 0644]
level_0/f_random/tests/unit/c/mock-random.c [new file with mode: 0644]
level_0/f_random/tests/unit/c/mock-random.h [new file with mode: 0644]
level_0/f_random/tests/unit/c/test-random-get.c [new file with mode: 0644]
level_0/f_random/tests/unit/c/test-random-get.h [new file with mode: 0644]
level_0/f_random/tests/unit/c/test-random-read.c [new file with mode: 0644]
level_0/f_random/tests/unit/c/test-random-read.h [new file with mode: 0644]
level_0/f_random/tests/unit/c/test-random-seed.c [new file with mode: 0644]
level_0/f_random/tests/unit/c/test-random-seed.h [new file with mode: 0644]
level_0/f_random/tests/unit/c/test-random-seed_set.c [new file with mode: 0644]
level_0/f_random/tests/unit/c/test-random-seed_set.h [new file with mode: 0644]
level_0/f_random/tests/unit/c/test-random.c [new file with mode: 0644]
level_0/f_random/tests/unit/c/test-random.h [new file with mode: 0644]

index c6cd04df1b361d3d67795a3bb1b0db8547d270ff..140879c94e6d529f948a2606354bd10d8da0ddf1 100644 (file)
@@ -56,6 +56,7 @@ build_sources_library parse.c parse/utf.c
 build_sources_library path.c private-path.c path/common.c
 build_sources_library pipe.c
 build_sources_library print.c private-print.c print/common.c print/to.c print/private-to.c
+build_sources_library random.c
 build_sources_library rip.c rip/utf.c private-rip.c rip/private-utf.c
 build_sources_library serialize.c private-serialize.c serialize/common.c
 build_sources_library signal.c
@@ -104,6 +105,7 @@ build_sources_headers parse.h parse/utf.h
 build_sources_headers path.h path/common.h
 build_sources_headers pipe.h
 build_sources_headers print.h print/to.h print/common.h
+build_sources_headers random.h
 build_sources_headers rip.h rip/utf.h
 build_sources_headers serialize.h serialize/common.h
 build_sources_headers signal.h signal/common.h
index b5a63036edfb9bf36ff3c4ad7ddd75df5ed82818..ded3fc94a4a9d9573e4da8640950a6f0cfa913f7 100644 (file)
@@ -56,6 +56,7 @@ build_sources_library level_0/parse.c level_0/parse/utf.c
 build_sources_library level_0/path.c level_0/private-path.c level_0/path/common.c
 build_sources_library level_0/pipe.c
 build_sources_library level_0/print.c level_0/private-print.c level_0/print/common.c level_0/print/to.c level_0/print/private-to.c
+build_sources_library level_0/random.c
 build_sources_library level_0/rip.c level_0/rip/utf.c level_0/private-rip.c level_0/rip/private-utf.c
 build_sources_library level_0/serialize.c level_0/private-serialize.c level_0/serialize/common.c
 build_sources_library level_0/signal.c
@@ -125,6 +126,7 @@ build_sources_headers level_0/parse.h level_0/parse/utf.h
 build_sources_headers level_0/path.h level_0/path/common.h
 build_sources_headers level_0/pipe.h
 build_sources_headers level_0/print.h level_0/print/to.h level_0/print/common.h
+build_sources_headers level_0/random.h
 build_sources_headers level_0/rip.h level_0/rip/utf.h
 build_sources_headers level_0/serialize.h level_0/serialize/common.h
 build_sources_headers level_0/signal.h level_0/signal/common.h
index 07e1a572c8890f45bae30cb5e53c49ce841f1bf9..8fff50823cb3ccb440baf31621553cfe7fae2089 100644 (file)
@@ -130,7 +130,7 @@ if [[ ${1} == "individual" ]] ; then
   ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild -i
 
   if [[ ${?} -eq 0 ]] ; then
-    for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_status_string f_serialize f_signal f_socket f_thread f_time fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program ; do
+    for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_random f_rip f_serialize f_signal f_socket f_status_string f_thread f_time fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program ; do
       echo && echo "Processing ${i}." &&
 
       cd package/individual/${i}-${version}/ &&
index 60117c830e47ca1fd821c2a2af422e933ebb5521..3e6ef911e0d9548536e65719f28a47b792665690 100644 (file)
@@ -71,7 +71,7 @@ test_main() {
   local verbose=
   local verbose_common=
 
-  local projects="f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_serialize f_signal f_socket f_status_string f_thread f_time fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program"
+  local projects="f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_random f_rip f_serialize f_signal f_socket f_status_string f_thread f_time fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program"
   local projects_no_tests="f_type"
   local programs="fss_read"
 
index 979334d598074130634b75a1a8ea429b1984c5f4..b85aabbc144bc5474ec4cb4a5b17c719fcdcddfd 100644 (file)
@@ -8,9 +8,9 @@
 //
 // Example:
 //   echo > /tmp/all.txt
-//   for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done
-//   for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done
-//   for i in fll_error fll_execute fll_file fll_fss fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done
+//   for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_random f_rip f_serialize f_signal f_socket f_status_string f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done
+//   for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done
+//   for i in fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done
 //   sort /tmp/all.txt | uniq | sed -e 's|^_|#define &|g' > /tmp/sorted.txt
 //   echo "#define _di_private_inline_f_print_to_error_" >> /tmp/sorted.txt
 //   echo "#define _di_private_inline_private_f_print_to_error_" >> /tmp/sorted.txt
index cc212c26304f8db3b0159b30cb4b154aa841108e..8fe15947631282b9d4b0a90fa6d63fd90a64e75e 100644 (file)
@@ -8,9 +8,9 @@
 //
 // Example:
 //   echo > /tmp/all.txt
-//   for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done
-//   for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done
-//   for i in fll_error fll_execute fll_file fll_fss fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done
+//   for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_random f_rip f_serialize f_signal f_socket f_status_string f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done
+//   for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done
+//   for i in fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done
 //   sort /tmp/all.txt | uniq | sed -e 's|^_|#define &|g' > /tmp/sorted.txt
 //   echo "#define _di_private_inline_f_print_to_error_" >> /tmp/sorted.txt
 //   echo "#define _di_private_inline_private_f_print_to_error_" >> /tmp/sorted.txt
 #define _di_fll_fss_snatch_mash_
 #define _di_fll_fss_snatch_mash_apart_
 #define _di_fll_fss_snatch_together_
+#define _di_fll_fss_status_codes_
+#define _di_fll_fss_status_error_
+#define _di_fll_fss_status_string_
+#define _di_fll_fss_status_string_from_
+#define _di_fll_fss_status_string_to_
+#define _di_fll_fss_status_success_
+#define _di_fll_fss_status_warning_
+#define _di_fll_iki_content_escape_
+#define _di_fll_iki_content_partial_escape_
+#define _di_fll_iki_content_partial_unescape_
+#define _di_fll_iki_content_unescape_
 #define _di_fll_print_
 #define _di_fll_print_character_
 #define _di_fll_print_character_safely_
 #define _di_fl_print_trim_raw_safely_
 #define _di_fl_print_trim_safely_
 //#define _di_fl_print_warning_s_
+#define _di_fl_status_string_from_
+#define _di_fl_utf_file_read_
+#define _di_fl_utf_file_read_block_
+#define _di_fl_utf_file_read_range_
+#define _di_fl_utf_file_read_until_
+#define _di_fl_utf_file_write_
+#define _di_fl_utf_file_write_block_
+#define _di_fl_utf_file_write_range_
+#define _di_fl_utf_file_write_until_
 #define _di_f_memory_adjust_
 #define _di_f_memory_array_adjust_
 #define _di_f_memory_array_append_
 #define _di_f_print_to_safely_terminated_
 #define _di_f_print_to_terminated_
 //#define _di_f_print_write_max_d_
+#define _di_f_random_get_
+#define _di_f_random_read_
+#define _di_f_random_seed_
+#define _di_f_random_seed_set_
+#define _di_f_range_double_empty_c_
+#define _di_f_range_doubles_append_
+#define _di_f_range_doubles_append_all_
+#define _di_f_range_doubless_append_
+#define _di_f_range_doubless_append_all_
+#define _di_f_range_doubless_delete_callback_
+#define _di_f_range_doubless_destroy_callback_
+#define _di_f_range_doubless_t_
+#define _di_f_range_doubles_t_
+#define _di_f_range_double_t_
+#define _di_f_range_empty_c_
+#define _di_f_ranges_append_
+#define _di_f_ranges_append_all_
+#define _di_f_rangess_append_
+#define _di_f_rangess_append_all_
+//#define _di_f_rangess_delete_callback_
+#define _di_f_rangess_destroy_callback_
+//#define _di_f_rangess_t_
+//#define _di_f_ranges_t_
+//#define _di_f_range_t_
 #define _di_f_rip_
 //#define _di_f_rip_dynamic_
 #define _di_f_rip_dynamic_nulless_
 #define _di_f_rip_utf_dynamic_
 #define _di_f_rip_utf_dynamic_nulless_
 #define _di_f_rip_utf_nulless_
+#define _di_f_serialize_delimited_delimiter_s_
+#define _di_f_serialize_delimited_splitter_s_
+#define _di_f_serialize_from_simple_
+#define _di_f_serialize_from_simple_get_
+#define _di_f_serialize_from_simple_range_
+#define _di_f_serialize_from_simple_select_
+#define _di_f_serialize_splitter_s_
+#define _di_f_serialize_to_simple_
+#define _di_f_serialize_to_simple_splitter_s_
 #define _di_f_signal_action_
 //#define _di_f_signal_close_
 //#define _di_f_signal_how_t_
 #define _di_f_signal_wait_until_
 #define _di_f_socket_accept_
 #define _di_f_socket_address_family_e_
+#define _di_f_socket_address_form_e_
 #define _di_f_socket_addressss_delete_callback_
 #define _di_f_socket_addressss_destroy_callback_
 #define _di_f_socket_addressss_t_
 #define _di_f_socket_addresss_t_
 #define _di_f_socket_address_t_
 #define _di_f_socket_bind_
-#define _di_f_socket_bind_inet4_
-#define _di_f_socket_bind_inet6_
-#define _di_f_socket_bind_local_
 #define _di_f_socket_close_e_
 #define _di_f_socket_connect_
 #define _di_f_socket_create_
 #define _di_f_statess_t_
 #define _di_f_states_t_
 //#define _di_f_state_t_
+#define _di_f_status_directory_s_
 //#define _di_f_status_e_
 //#define _di_f_status_mask_d_
 #define _di_f_statusss_delete_callback_
 #define _di_f_statusss_destroy_callback_
 #define _di_f_statusss_t_
 #define _di_f_statuss_t_
+#define _di_f_status_string_s_
+#define _di_f_status_string_to_
 //#define _di_f_status_t_
 //#define _di_f_string_append_
 #define _di_f_string_append_assure_
 #define _di_f_string_quantityss_t_
 #define _di_f_string_quantitys_t_
 #define _di_f_string_quantity_t_
-#define _di_f_range_double_empty_c_
-#define _di_f_range_doubles_append_
-#define _di_f_range_doubles_append_all_
-#define _di_f_range_doubless_append_
-#define _di_f_range_doubless_append_all_
-#define _di_f_range_doubless_delete_callback_
-#define _di_f_range_doubless_destroy_callback_
-#define _di_f_range_doubless_t_
-#define _di_f_range_doubles_t_
-#define _di_f_range_double_t_
-#define _di_f_range_empty_c_
-#define _di_f_ranges_append_
-#define _di_f_ranges_append_all_
-#define _di_f_rangess_append_
-#define _di_f_rangess_append_all_
-//#define _di_f_rangess_delete_callback_
-#define _di_f_rangess_destroy_callback_
-//#define _di_f_rangess_t_
-//#define _di_f_ranges_t_
-//#define _di_f_range_t_
 #define _di_f_string_seek_line_
 #define _di_f_string_seek_line_to_
 #define _di_f_string_seek_to_
index 979334d598074130634b75a1a8ea429b1984c5f4..b85aabbc144bc5474ec4cb4a5b17c719fcdcddfd 100644 (file)
@@ -8,9 +8,9 @@
 //
 // Example:
 //   echo > /tmp/all.txt
-//   for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done
-//   for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done
-//   for i in fll_error fll_execute fll_file fll_fss fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done
+//   for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_random f_rip f_serialize f_signal f_socket f_status_string f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done
+//   for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done
+//   for i in fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done
 //   sort /tmp/all.txt | uniq | sed -e 's|^_|#define &|g' > /tmp/sorted.txt
 //   echo "#define _di_private_inline_f_print_to_error_" >> /tmp/sorted.txt
 //   echo "#define _di_private_inline_private_f_print_to_error_" >> /tmp/sorted.txt
index 979334d598074130634b75a1a8ea429b1984c5f4..b85aabbc144bc5474ec4cb4a5b17c719fcdcddfd 100644 (file)
@@ -8,9 +8,9 @@
 //
 // Example:
 //   echo > /tmp/all.txt
-//   for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done
-//   for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done
-//   for i in fll_error fll_execute fll_file fll_fss fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done
+//   for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_random f_rip f_serialize f_signal f_socket f_status_string f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done
+//   for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done
+//   for i in fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done
 //   sort /tmp/all.txt | uniq | sed -e 's|^_|#define &|g' > /tmp/sorted.txt
 //   echo "#define _di_private_inline_f_print_to_error_" >> /tmp/sorted.txt
 //   echo "#define _di_private_inline_private_f_print_to_error_" >> /tmp/sorted.txt
diff --git a/level_0/f_random/c/random.c b/level_0/f_random/c/random.c
new file mode 100644 (file)
index 0000000..7fda850
--- /dev/null
@@ -0,0 +1,86 @@
+#include "random.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_f_random_get_
+  f_status_t f_random_get(long * const destination) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!destination) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    *destination = random();
+
+    return F_okay;
+  }
+#endif // _di_f_random_get_
+
+#ifndef _di_f_random_read_
+  f_status_t f_random_read(const unsigned int flag, const f_number_unsigned_t length, f_string_t * const destination, ssize_t * const total) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!destination) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const ssize_t result = getrandom((void *) (*destination), length, flag);
+
+    if (result == -1) {
+      if (errno == EAGAIN) return F_status_set_error(F_again);
+      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 == ENOSYS) return F_status_set_error(F_support_not);
+
+      return F_status_set_error(F_failure);
+    }
+
+    if (total) {
+      *total = result;
+    }
+
+    return F_okay;
+  }
+#endif // _di_f_random_read_
+
+#ifndef _di_f_random_seed_
+  f_status_t f_random_seed(const unsigned int flag) {
+
+    char raw[4] = { 0 };
+
+    if (getrandom((void *) raw, sizeof(char) * 4, flag) == -1) {
+      if (errno == EAGAIN) return F_status_set_error(F_again);
+      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 == ENOSYS) return F_status_set_error(F_support_not);
+
+      return F_status_set_error(F_failure);
+    }
+
+    uint32_t entropy_digit = (uint32_t) ((uint8_t) raw[0]);
+    entropy_digit += ((uint32_t) ((uint8_t) raw[1])) << 8;
+    entropy_digit += ((uint32_t) ((uint8_t) raw[2])) << 16;
+    entropy_digit += ((uint32_t) ((uint8_t) raw[3])) << 24;
+
+    srandom(entropy_digit);
+
+    // Clear the memory before de-allocating to reduce chances of the seed being in free memory.
+    memset(&entropy_digit, 0, sizeof(uint32_t));
+    memset(raw, 0, sizeof(char) * 4);
+
+    return F_okay;
+  }
+#endif // _di_f_random_seed_
+
+#ifndef _di_f_random_seed_set_
+  f_status_t f_random_seed_set(unsigned int seed) {
+
+    srandom(seed);
+
+    return F_okay;
+  }
+#endif // _di_f_random_seed_set_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_random/c/random.h b/level_0/f_random/c/random.h
new file mode 100644 (file)
index 0000000..f58f739
--- /dev/null
@@ -0,0 +1,153 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Random
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides basic string random capabilities.
+ */
+#ifndef _F_random_h
+#define _F_random_h
+
+// Libc includes.
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/random.h>
+
+// FLL-0 includes.
+#include <fll/level_0/status.h>
+#include <fll/level_0/type.h>
+#include <fll/level_0/string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Set the destination string by reading from the random or urandom entropy source directly.
+ *
+ * The standard behavior of this is to call random().
+ *
+ * The random seed should be set by either calling f_random_seed(), f_random_seed_set(), or directly calling random().
+ * Calling f_random_seed() or f_random_seed_set() to set the seed is generally safer from a library implementation perspective for situations where the implementation of f_random_seed() or f_random_seed_set() and therefore f_random() is changed from the standard behavior.
+ *
+ * @param destination
+ *   The destination long to write to.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_random_get_
+  extern f_status_t f_random_get(long * const destination);
+#endif // _di_f_random_get_
+
+/**
+ * Set the destination string by reading from the random or urandom entropy source directly.
+ *
+ * The standard behavior of this is to call getrandom().
+ *
+ * The behavior of this function might also be replaced with calls to other libraries that are highly security specialized.
+ * If this is done, the meaning behind the flags passed should not be changed.
+ *
+ * This calls the Linux-specific getrandom() by default.
+ * If this is not available or pure POSIX is desired, then the implementation must handle accessing the /dev/random and /dev/urandom themselves (or something equivalent).
+ *
+ * @param flag
+ *   The flags to be passed to getrandom().
+ *
+ *   Flag bits:
+ *     - GRND_RANDOM:   Random data is taken from the random source, such as /dev/random and not the urandom source.
+ *     - GRND_NONBLOCK: Does not block when getting the bits.
+ * @param length
+ *   The size within the destination string to copy.
+ *   The standard max size is 255.
+ *   This length must not exceed the size allocated in destination or buffer overrun or other security problems may occur.
+ * @param destination
+ *   The destination string to write to.
+ *   The size of this is not dynamically allocated.
+ *   The caller must assure that the size allocated is not smaller than the size specified in the length parameter.
+ *
+ *   Must not be NULL.
+ * @param total
+ *   (optional) The total number of bytes actually read.
+ *   This value is not changed on error.
+ *
+ *   Set to NULL to not use.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_again (with error bit) when in non-blocking mode but reading entropy source would block (such as when the entropy source is busy).
+ *   F_buffer (with error bit) if the address represented by the buffer is outside accessible address space.
+ *   F_interrupt (with error bit) if stopping due to an interrupt.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_support_not (with error bit) if the running kernel does not support the getrandom() call.
+ */
+#ifndef _di_f_random_read_
+  extern f_status_t f_random_read(const unsigned int flag, const f_number_unsigned_t length, f_string_t * const destination, ssize_t * const total);
+#endif // _di_f_random_read_
+
+/**
+ * Set the random seed from random entropy, generally for the standard POSIX random() use cases.
+ *
+ * The standard behavior of this is to call getrandom().
+ *
+ * The behavior of this function might also be replaced with calls to other libraries that are highly security specialized.
+ * If this is done, the meaning behind the flags passed should not be changed.
+ *
+ * This calls the Linux-specific getrandom() by default.
+ * If this is not available or pure POSIX is desired, then the implementation must handle accessing the /dev/random and /dev/urandom themselves (or something equivalent).
+ *
+ * @param flag
+ *   The flags to be passed to getrandom().
+ *
+ *   Flag bits:
+ *     - GRND_RANDOM:   Random data is taken from the random source, such as /dev/random and not the urandom source.
+ *     - GRND_NONBLOCK: Does not block when getting the bits.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_again (with error bit) when in non-blocking mode but reading entropy source would block (such as when the entropy source is busy).
+ *   F_buffer (with error bit) if the address represented by the buffer is outside accessible address space.
+ *   F_interrupt (with error bit) if stopping due to an interrupt.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_support_not (with error bit) if the running kernel does not support the getrandom() call.
+ *
+ * @see getrandom()
+ * @see srandom()
+ */
+#ifndef _di_f_random_seed_
+  extern f_status_t f_random_seed(const unsigned int flag);
+#endif // _di_f_random_seed_
+
+/**
+ * Set the random seed manually using the given seed value, generally for the standard POSIX random() use cases.
+ *
+ * The standard behavior of this is to call srandom().
+ *
+ * The behavior of this function might also be replaced with calls to other libraries that are highly security specialized.
+ *
+ * @param seed
+ *   The seed value to assign.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_random_seed_set_
+  extern f_status_t f_random_seed_set(unsigned int seed);
+#endif // _di_f_random_seed_set_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _F_random_h
diff --git a/level_0/f_random/data/build/defines b/level_0/f_random/data/build/defines
new file mode 100644 (file)
index 0000000..4f13080
--- /dev/null
@@ -0,0 +1 @@
+# fss-0000
diff --git a/level_0/f_random/data/build/dependencies b/level_0/f_random/data/build/dependencies
new file mode 100644 (file)
index 0000000..c06dda5
--- /dev/null
@@ -0,0 +1,5 @@
+# fss-0000
+
+f_type
+f_status
+f_string
diff --git a/level_0/f_random/data/build/dependencies-tests b/level_0/f_random/data/build/dependencies-tests
new file mode 100644 (file)
index 0000000..dea3179
--- /dev/null
@@ -0,0 +1,3 @@
+# fss-0001
+
+cmocka 1.*
diff --git a/level_0/f_random/data/build/fakefile b/level_0/f_random/data/build/fakefile
new file mode 100644 (file)
index 0000000..90a7134
--- /dev/null
@@ -0,0 +1,12 @@
+# fss-0005 iki-0002
+
+settings:
+  fail exit
+  modes individual individual_thread level monolithic clang test fanalyzer thread threadless
+
+  environment PATH LD_LIBRARY_PATH
+  environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+
+main:
+
+  build
diff --git a/level_0/f_random/data/build/settings b/level_0/f_random/data/build/settings
new file mode 100644 (file)
index 0000000..b9bb7f8
--- /dev/null
@@ -0,0 +1,71 @@
+# fss-0001
+#
+# Modes:
+#   - individual:        Compile using per project (individual) libraries, does not handle thread or threadless cases.
+#   - individual_thread: This is required when compiling in individual mode with "thread" mode.
+#   - level:             Compile using per level libraries.
+#   - monolithic:        Compile using per monolithic libraries.
+#   - clang:             Use clang rather than the default, which is generally gcc.
+#   - test:              Compile for a test, such as unit testing.
+#   - fanalyzer:         Compile using GCC's -fanalyzer compile time option.
+#   - thread:            Compile with thread support.
+#   - threadless:        Compile without thread support.
+#
+
+build_name f_random
+
+version_major 0
+version_minor 7
+version_micro 0
+version_file micro
+version_target minor
+
+modes individual individual_thread level monolithic clang test fanalyzer thread threadless
+modes_default individual individual_thread thread
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc
+build_libraries-individual -lf_memory -lf_string
+
+build_sources_library random.c
+
+build_sources_headers random.h
+
+build_script yes
+build_shared yes
+build_static no
+
+path_headers fll/level_0
+path_library_script script
+path_library_shared shared
+path_library_static static
+path_object_script script
+path_object_shared shared
+path_object_static static
+path_program_script script
+path_program_shared shared
+path_program_static static
+
+has_path_standard yes
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+environment PATH LD_LIBRARY_PATH
+environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+
+flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses
+flags-clang -Wno-logical-op-parentheses
+flags-test -O0 -fstack-protector -Wall
+flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+
+flags_library -fPIC
+flags_object -fPIC
+flags_program -fPIE
diff --git a/level_0/f_random/data/build/settings-mocks b/level_0/f_random/data/build/settings-mocks
new file mode 100644 (file)
index 0000000..9548555
--- /dev/null
@@ -0,0 +1,57 @@
+# fss-0001
+
+build_name f_random
+
+version_major 0
+version_minor 7
+version_micro 0
+version_file micro
+version_target minor
+
+modes individual clang test coverage
+modes_default individual test
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc
+build_libraries-individual -lf_memory
+
+build_sources_library random.c
+build_sources_library ../../tests/unit/c/mock-random.c
+
+build_sources_headers random.h
+
+build_script yes
+build_shared yes
+build_static no
+
+path_headers fll/level_0
+path_library_script script
+path_library_shared shared
+path_library_static static
+
+has_path_standard yes
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+environment PATH LD_LIBRARY_PATH
+environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+
+flags -O0 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses
+flags-clang -Wno-logical-op-parentheses
+flags-test -fstack-protector -Wall
+flags-coverage --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+
+flags_library -fPIC
+
+# Inject mocks.
+flags -Wl,--wrap=getrandom
+flags -Wl,--wrap=random
+flags -Wl,--wrap=srandom
diff --git a/level_0/f_random/data/build/settings-tests b/level_0/f_random/data/build/settings-tests
new file mode 100644 (file)
index 0000000..db0efd7
--- /dev/null
@@ -0,0 +1,57 @@
+# fss-0001
+#
+# Builds a program that is links to the generated library and is executed to perform tests.
+#
+# Memory leaks in the test program can be checked for by running valgrind with this executable.
+#
+
+build_name test-f_random
+
+version_major 0
+version_minor 7
+version_micro 0
+version_file major
+version_target major
+
+modes individual clang test coverage
+modes_default individual test
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc -lcmocka
+build_libraries-individual -lf_memory -lf_random
+
+build_sources_program test-random-get.c test-random-read.c test-random-seed.c test-random-seed_set.c
+build_sources_program test-random.c
+
+build_script no
+build_shared yes
+build_static no
+
+path_headers tests/unit/c
+path_sources tests/unit/c
+
+has_path_standard no
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+environment PATH LD_LIBRARY_PATH
+environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+
+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-parentheses
+flags-clang -Wno-logical-op-parentheses
+flags-test -fstack-protector -Wall
+flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+
+flags_program -fPIE
diff --git a/level_0/f_random/data/build/testfile b/level_0/f_random/data/build/testfile
new file mode 100644 (file)
index 0000000..709fd21
--- /dev/null
@@ -0,0 +1,63 @@
+# fss-0005 iki-0002
+
+settings:
+  load_build yes
+  fail exit
+
+  environment PATH LD_LIBRARY_PATH
+  environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+  environment CMOCKA_XML_FILE CMOCKA_MESSAGE_OUTPUT CMOCKA_TEST_ABORT
+
+  # Cmocka is not fully thread-safe, set this to "1" to have cmocka call abort() on a test failure.
+  #CMOCKA_TEST_ABORT 1
+
+  # One of: STDOUT, SUBUNIT, TAP, or XML.
+  #define CMOCKA_MESSAGE_OUTPUT STDOUT
+
+  # When in "XML" output mode, output to this file rather than stdout.
+  #define CMOCKA_XML_FILE ./out.xml
+
+main:
+  build settings-mocks individual test
+  build settings-tests individual test
+
+  operate build_path
+  operate ld_library_path
+
+  if exist parameter:"build_path"programs/shared/test-f_random
+    shell parameter:"build_path"programs/shared/test-f_random
+
+  if exist parameter:"build_path"programs/static/test-f_random
+    shell parameter:"build_path"programs/static/test-f_random
+
+  if not exist parameter:"build_path"programs/shared/test-f_random
+  and not exist parameter:"build_path"programs/static/test-f_random
+    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:"reset"'
+
+  exit failure
+
+build_path:
+  parameter build_path build/
+
+  if parameter build:value
+    parameter build_path parameter:"build:value"
+
+ld_library_path:
+  if define LD_LIBRARY_PATH
+  and parameter work:value
+    define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared:parameter:"work:value"libraries/shared:define:"LD_LIBRARY_PATH"'
+
+  else
+  if define LD_LIBRARY_PATH
+    define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared:define:"LD_LIBRARY_PATH"'
+
+  else
+  if parameter work:value
+    define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared:parameter:"work:value"libraries/shared'
+
+  else
+    define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared'
diff --git a/level_0/f_random/tests/unit/c/mock-random.c b/level_0/f_random/tests/unit/c/mock-random.c
new file mode 100644 (file)
index 0000000..ec2dc0c
--- /dev/null
@@ -0,0 +1,32 @@
+#include "mock-random.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ssize_t __wrap_getrandom(void *buf, size_t buflen, unsigned int flags) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return mock_type(ssize_t);
+  }
+
+  memcpy(buf, mock_type(void *), buflen);
+
+  return mock_type(ssize_t);
+}
+
+long __wrap_random(void) {
+  return mock_type(long);
+}
+
+void __wrap_srandom(unsigned seed) {
+  // Do nothing.
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_random/tests/unit/c/mock-random.h b/level_0/f_random/tests/unit/c/mock-random.h
new file mode 100644 (file)
index 0000000..205f366
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Random
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the random project.
+ */
+#ifndef _MOCK__random_h
+#define _MOCK__random_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/random.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const static int mock_errno_generic = 32767;
+
+extern ssize_t __wrap_getrandom(void *buf, size_t buflen, unsigned int flags);
+extern long __wrap_random(void);
+extern void __wrap_srandom(unsigned seed);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _MOCK__random_h
diff --git a/level_0/f_random/tests/unit/c/test-random-get.c b/level_0/f_random/tests/unit/c/test-random-get.c
new file mode 100644 (file)
index 0000000..3ad505b
--- /dev/null
@@ -0,0 +1,36 @@
+#include "test-random.h"
+#include "test-random-get.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_random_get__works(void **state) {
+
+  const long mocked_data = 1234;
+
+  {
+    long data = 0;
+
+    will_return(__wrap_random, mocked_data);
+
+    const f_status_t status = f_random_get(&data);
+
+    assert_int_equal(status, F_okay);
+
+    assert_int_equal(data, mocked_data);
+  }
+}
+
+void test__f_random_get__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_random_get(0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_random/tests/unit/c/test-random-get.h b/level_0/f_random/tests/unit/c/test-random-get.h
new file mode 100644 (file)
index 0000000..e991e3b
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Random
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the get function in the random project.
+ */
+#ifndef _TEST__F_random_get_h
+#define _TEST__F_random_get_h
+
+/**
+ * Test that the function works.
+ *
+ * @see f_random_get()
+ */
+extern void test__f_random_get__works(void **state);
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_random_get()
+ */
+extern void test__f_random_get__parameter_checking(void **state);
+
+#endif // _TEST__F_random_get_h
diff --git a/level_0/f_random/tests/unit/c/test-random-read.c b/level_0/f_random/tests/unit/c/test-random-read.c
new file mode 100644 (file)
index 0000000..9c33377
--- /dev/null
@@ -0,0 +1,115 @@
+#include "test-random.h"
+#include "test-random-read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_random_read__fails(void **state) {
+
+  int errnos[] = {
+    EAGAIN,
+    EFAULT,
+    EINTR,
+    EINVAL,
+    ENOSYS,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_again,
+    F_buffer,
+    F_interrupt,
+    F_parameter,
+    F_support_not,
+    F_failure,
+  };
+
+  for (uint8_t i = 0; i < 6; ++i) {
+
+    will_return(__wrap_getrandom, true);
+    will_return(__wrap_getrandom, errnos[i]);
+    will_return(__wrap_getrandom, -1);
+
+    f_char_t buffer[4] = { 0, 0, 0, 0 };
+    f_string_t buffer_ptr = buffer;
+    ssize_t total = 0;
+
+    const f_status_t status = f_random_read(0, 4, &buffer_ptr, &total);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+
+  for (uint8_t i = 0; i < 6; ++i) {
+
+    will_return(__wrap_getrandom, true);
+    will_return(__wrap_getrandom, errnos[i]);
+    will_return(__wrap_getrandom, -1);
+
+    f_char_t buffer[4] = { 0, 0, 0, 0 };
+    f_string_t buffer_ptr = buffer;
+
+    const f_status_t status = f_random_read(0, 4, &buffer_ptr, 0);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_random_read__works(void **state) {
+
+  const f_number_unsigned_t length = 4;
+
+  {
+    char mocked_data[4] = "abcd";
+    f_char_t buffer[4] = { 0, 0, 0, 0 };
+    f_string_t buffer_ptr = buffer;
+    ssize_t total = 0;
+
+    will_return(__wrap_getrandom, false);
+    will_return(__wrap_getrandom, (void *) mocked_data);
+    will_return(__wrap_getrandom, length);
+
+    const f_status_t status = f_random_read(0, length, &buffer_ptr, &total);
+
+    assert_int_equal(status, F_okay);
+
+    assert_int_equal(buffer[0], mocked_data[0]);
+    assert_int_equal(buffer[1], mocked_data[1]);
+    assert_int_equal(buffer[2], mocked_data[2]);
+    assert_int_equal(buffer[3], mocked_data[3]);
+
+    assert_int_equal(total, length);
+  }
+
+  {
+    char mocked_data[4] = "abcd";
+    f_char_t buffer[4] = { 0, 0, 0, 0 };
+    f_string_t buffer_ptr = buffer;
+
+    will_return(__wrap_getrandom, false);
+    will_return(__wrap_getrandom, (void *) mocked_data);
+    will_return(__wrap_getrandom, length);
+
+    const f_status_t status = f_random_read(0, length, &buffer_ptr, 0);
+
+    assert_int_equal(status, F_okay);
+
+    assert_int_equal(buffer[0], mocked_data[0]);
+    assert_int_equal(buffer[1], mocked_data[1]);
+    assert_int_equal(buffer[2], mocked_data[2]);
+    assert_int_equal(buffer[3], mocked_data[3]);
+  }
+}
+
+void test__f_random_read__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_random_read(0, 0, 0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_random/tests/unit/c/test-random-read.h b/level_0/f_random/tests/unit/c/test-random-read.h
new file mode 100644 (file)
index 0000000..d60244b
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Random
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the read function in the random project.
+ */
+#ifndef _TEST__F_random_read_h
+#define _TEST__F_random_read_h
+
+/**
+ * Test that the function fails.
+ *
+ * @see f_random_read()
+ */
+extern void test__f_random_read__fails(void **state);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_random_read()
+ */
+extern void test__f_random_read__works(void **state);
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_random_read()
+ */
+extern void test__f_random_read__parameter_checking(void **state);
+
+#endif // _TEST__F_random_read_h
diff --git a/level_0/f_random/tests/unit/c/test-random-seed.c b/level_0/f_random/tests/unit/c/test-random-seed.c
new file mode 100644 (file)
index 0000000..2edf1a3
--- /dev/null
@@ -0,0 +1,59 @@
+#include "test-random.h"
+#include "test-random-seed.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_random_seed__fails(void **state) {
+
+  int errnos[] = {
+    EAGAIN,
+    EFAULT,
+    EINTR,
+    EINVAL,
+    ENOSYS,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_again,
+    F_buffer,
+    F_interrupt,
+    F_parameter,
+    F_support_not,
+    F_failure,
+  };
+
+  for (uint8_t i = 0; i < 6; ++i) {
+
+    will_return(__wrap_getrandom, true);
+    will_return(__wrap_getrandom, errnos[i]);
+    will_return(__wrap_getrandom, -1);
+
+    const f_status_t status = f_random_seed(0);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_random_seed__works(void **state) {
+
+  const f_number_unsigned_t length = 4;
+
+  {
+    char mocked_data[4] = "abcd";
+
+    will_return(__wrap_getrandom, false);
+    will_return(__wrap_getrandom, (void *) mocked_data);
+    will_return(__wrap_getrandom, length);
+
+    const f_status_t status = f_random_seed(0);
+
+    assert_int_equal(status, F_okay);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_random/tests/unit/c/test-random-seed.h b/level_0/f_random/tests/unit/c/test-random-seed.h
new file mode 100644 (file)
index 0000000..416ef34
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Random
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the seed function in the random project.
+ */
+#ifndef _TEST__F_random_seed_h
+#define _TEST__F_random_seed_h
+
+/**
+ * Test that the function fails.
+ *
+ * @see f_random_seed()
+ */
+extern void test__f_random_seed__fails(void **state);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_random_seed()
+ */
+extern void test__f_random_seed__works(void **state);
+
+#endif // _TEST__F_random_seed_h
diff --git a/level_0/f_random/tests/unit/c/test-random-seed_set.c b/level_0/f_random/tests/unit/c/test-random-seed_set.c
new file mode 100644 (file)
index 0000000..928c7bf
--- /dev/null
@@ -0,0 +1,19 @@
+#include "test-random.h"
+#include "test-random-seed_set.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_random_seed_set__works(void **state) {
+
+  {
+    const f_status_t status = f_random_seed_set(1);
+
+    assert_int_equal(status, F_okay);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_random/tests/unit/c/test-random-seed_set.h b/level_0/f_random/tests/unit/c/test-random-seed_set.h
new file mode 100644 (file)
index 0000000..62862f9
--- /dev/null
@@ -0,0 +1,20 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Random
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the seed function in the random project.
+ */
+#ifndef _TEST__F_random_seed_set_h
+#define _TEST__F_random_seed_set_h
+
+/**
+ * Test that the function works.
+ *
+ * @see f_random_seed_set()
+ */
+extern void test__f_random_seed_set__works(void **state);
+
+#endif // _TEST__F_random_seed_h
diff --git a/level_0/f_random/tests/unit/c/test-random.c b/level_0/f_random/tests/unit/c/test-random.c
new file mode 100644 (file)
index 0000000..f5d04b5
--- /dev/null
@@ -0,0 +1,44 @@
+#include "test-random.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[] = {
+    cmocka_unit_test(test__f_random_read__fails),
+    cmocka_unit_test(test__f_random_seed__fails),
+
+    cmocka_unit_test(test__f_random_get__works),
+    cmocka_unit_test(test__f_random_read__works),
+    cmocka_unit_test(test__f_random_seed__works),
+    cmocka_unit_test(test__f_random_seed_set__works),
+
+    #ifndef _di_level_0_parameter_checking_
+      cmocka_unit_test(test__f_random_get__parameter_checking),
+      cmocka_unit_test(test__f_random_read__parameter_checking),
+
+      // f_random_seed() doesn't use parameter checking.
+      // f_random_seed_set() doesn't use 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_random/tests/unit/c/test-random.h b/level_0/f_random/tests/unit/c/test-random.h
new file mode 100644 (file)
index 0000000..546118d
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Random
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the random project.
+ */
+#ifndef _TEST__F_random_h
+#define _TEST__F_random_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/random.h>
+
+// Mock includes.
+#include "mock-random.h"
+
+// Test includes.
+#include "test-random-get.h"
+#include "test-random-read.h"
+#include "test-random-seed.h"
+#include "test-random-seed_set.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_random_h