]> Kevux Git Server - fll/commitdiff
Progress: Wrap up most of the directory do related changes in Featureless Make.
authorKevin Day <kevin@kevux.org>
Mon, 17 Apr 2023 02:36:04 +0000 (21:36 -0500)
committerKevin Day <kevin@kevux.org>
Mon, 17 Apr 2023 02:36:04 +0000 (21:36 -0500)
I am hoping this is the last progress on Featureless Make to get it fully up to date with all of the changes.
While I won't be surprised if I missed something this feels like its ready.

Remove the directory recurse copy flags.

Use more caches in Featureless Make.
Move the directory do as a cache to better allow for reusing the path and path_custom strings.
Update the documentation comments regarding the caching.

The regression mentioned in commit 61a348ba714e41467da803f8220a31c126581a01 is resolved.
The regression is that I appended the path separator out of scope (outside of a relevant condition check).

I noticed another regression where when source.used is 0 the action is not performed.
This is incorrect because the source may be 0 and the paths being used are just relative paths.

Fix a mistake where the f_file_copy() and f_file_clone() are passed invalid flags.
Make sure to pass the appropriate flags to the f_file_clone() calls in the directory do handle callback.

15 files changed:
level_0/f_directory/c/directory/common.h
level_3/fake/c/main/build.c
level_3/fake/c/main/build.h
level_3/fake/c/main/build/library.c
level_3/fake/c/main/build/library.h
level_3/fake/c/main/build/object.c
level_3/fake/c/main/build/object.h
level_3/fake/c/main/build/objects.c
level_3/fake/c/main/build/objects.h
level_3/fake/c/main/build/program.c
level_3/fake/c/main/build/program.h
level_3/fake/c/main/common/type.c
level_3/fake/c/main/common/type.h
level_3/fake/c/main/fake/do.c
level_3/fake/c/main/make/operate_process_type.c

index 85a4251782e7f5761298f8601eece241cf3a2fd4..4a79b0edeebd0581423192abfed674bf267ee5e0 100644 (file)
@@ -103,30 +103,6 @@ extern "C" {
 #endif // _di_f_directory_max_d_
 
 /**
- * Directory recurse copy flags.
- *
- * f_directory_recurse_copy_flag_*_e:
- *   - none:        No flags are set.
- *   - clone:       Operate as clone instead of as copy, if applicable.
- *   - dereference: Dereference symbolic links rather than operating on the link itself.
- *   - exclusive:   File flag requiring that a file does not already exist.
- *   - group:       File flag representing copying the group.
- *   - owner:       File flag representing copying the owner.
- *   - top:         Operate on top directory and not just inside the directory.
- */
-#ifndef _di_f_directory_recurse_copy_flag_e_
-  enum {
-    f_directory_recurse_copy_flag_none_e        = 0,
-    f_directory_recurse_copy_flag_clone_e       = 0x1,
-    f_directory_recurse_copy_flag_dereference_e = 0x2,
-    f_directory_recurse_copy_flag_exclusive_e   = 0x4,
-    f_directory_recurse_copy_flag_group_e       = 0x8,
-    f_directory_recurse_copy_flag_owner_e       = 0x10,
-    f_directory_recurse_copy_flag_top_e         = 0x20,
-  }; // enum
-#endif // _di_f_directory_recurse_copy_flag_e_
-
-/**
  * Directory recurse do flags.
  *
  * f_directory_recurse_do_flag_*_e:
index ceee017663855e551ccd1c126e5437faaebbf28a..18ae30e9d393af32e219ce2b647447e94c26ff0e 100644 (file)
@@ -12,85 +12,67 @@ extern "C" {
 
     fake_main_t * const main = data->main;
 
-    {
-      f_array_length_t build_libraries_length = fake_build_parameter_library_link_path_s.used + data->path_build_libraries_shared.used;
-
-      f_char_t build_libraries[build_libraries_length + 1];
-      build_libraries[build_libraries_length] = 0;
-
-      memcpy(build_libraries, fake_build_parameter_library_link_path_s.string, sizeof(f_char_t) * fake_build_parameter_library_link_path_s.used);
-
-      if (is_shared) {
-        memcpy(build_libraries + fake_build_parameter_library_link_path_s.used, data->path_build_libraries_shared.string, sizeof(f_char_t) * data->path_build_libraries_shared.used);
-      }
-      else {
-        memcpy(build_libraries + fake_build_parameter_library_link_path_s.used, data->path_build_libraries_static.string, sizeof(f_char_t) * data->path_build_libraries_static.used);
-      }
+    fake_string_dynamic_reset(&main->cache_argument);
 
-      f_array_length_t build_includes_length = fake_build_parameter_library_include_s.used + data->path_build_includes.used;
+    main->setting.state.status = f_string_dynamic_append_nulless(fake_build_parameter_library_link_path_s, &main->cache_argument);
+    if (F_status_is_error(main->setting.state.status)) return;
 
-      f_char_t build_includes[build_includes_length + 1];
-      build_includes[build_includes_length] = 0;
+    main->setting.state.status = f_string_dynamic_append_nulless(is_shared ? data->path_build_libraries_shared : data->path_build_libraries_static, &main->cache_argument);
+    if (F_status_is_error(main->setting.state.status)) return;
 
-      memcpy(build_includes, fake_build_parameter_library_include_s.string, sizeof(f_char_t) * fake_build_parameter_library_include_s.used);
-      memcpy(build_includes + fake_build_parameter_library_include_s.used, data->path_build_includes.string, sizeof(f_char_t) * data->path_build_includes.used);
+    if (main->cache_argument.used) {
+      main->setting.state.status = fll_execute_arguments_add(main->cache_argument, &main->cache_arguments);
+      if (F_status_is_error(main->setting.state.status)) return;
+    }
 
-      const f_string_static_t values[] = {
-        macro_f_string_static_t_initialize(build_libraries, 0, build_libraries_length),
-        macro_f_string_static_t_initialize(build_includes, 0, build_includes_length),
-      };
+    fake_string_dynamic_reset(&main->cache_argument);
 
-      for (uint8_t i = 0; i < 2; ++i) {
+    main->setting.state.status = f_string_dynamic_append_nulless(fake_build_parameter_library_include_s, &main->cache_argument);
+    if (F_status_is_error(main->setting.state.status)) return;
 
-        if (!values[i].used) continue;
+    main->setting.state.status = f_string_dynamic_append_nulless(data->path_build_includes, &main->cache_argument);
+    if (F_status_is_error(main->setting.state.status)) return;
 
-        main->setting.state.status = fll_execute_arguments_add(values[i], &main->cache_arguments);
-        if (F_status_is_error(main->setting.state.status)) return;
-      } // for
+    if (main->cache_argument.used) {
+      main->setting.state.status = fll_execute_arguments_add(main->cache_argument, &main->cache_arguments);
+      if (F_status_is_error(main->setting.state.status)) return;
     }
 
     if (main->setting.work.used) {
-      f_string_static_t buffer = f_string_static_t_initialize;
-
-      {
-        buffer.used = fake_build_parameter_library_include_s.used + data->path_work_includes.used;
+      fake_string_dynamic_reset(&main->cache_argument);
 
-        f_char_t buffer_string[buffer.used + 1];
-        buffer.string = buffer_string;
-        buffer_string[buffer.used] = 0;
+      main->setting.state.status = f_string_dynamic_append_nulless(fake_build_parameter_library_include_s, &main->cache_argument);
+      if (F_status_is_error(main->setting.state.status)) return;
 
-        memcpy(buffer_string, fake_build_parameter_library_include_s.string, sizeof(f_char_t) * fake_build_parameter_library_include_s.used);
-        memcpy(buffer_string + fake_build_parameter_library_include_s.used, data->path_work_includes.string, sizeof(f_char_t) * data->path_work_includes.used);
+      main->setting.state.status = f_string_dynamic_append_nulless(data->path_work_includes, &main->cache_argument);
+      if (F_status_is_error(main->setting.state.status)) return;
 
-        main->setting.state.status = fll_execute_arguments_add(buffer, &main->cache_arguments);
-        if (F_status_is_error(main->setting.state.status)) return;
-      }
+      main->setting.state.status = fll_execute_arguments_add(main->cache_argument, &main->cache_arguments);
+      if (F_status_is_error(main->setting.state.status)) return;
 
       if (data_build->setting.search_shared && (is_shared || !data_build->setting.search_exclusive)) {
-        buffer.used = fake_build_parameter_library_link_path_s.used + data->path_work_libraries_shared.used;
+        fake_string_dynamic_reset(&main->cache_argument);
 
-        f_char_t buffer_string[buffer.used + 1];
-        buffer.string = buffer_string;
-        buffer_string[buffer.used] = 0;
+        main->setting.state.status = f_string_dynamic_append_nulless(fake_build_parameter_library_link_path_s, &main->cache_argument);
+        if (F_status_is_error(main->setting.state.status)) return;
 
-        memcpy(buffer_string, fake_build_parameter_library_link_path_s.string, sizeof(f_char_t) * fake_build_parameter_library_link_path_s.used);
-        memcpy(buffer_string + fake_build_parameter_library_link_path_s.used, data->path_work_libraries_shared.string, sizeof(f_char_t) * data->path_work_libraries_shared.used);
+        main->setting.state.status = f_string_dynamic_append_nulless(data->path_work_libraries_shared, &main->cache_argument);
+        if (F_status_is_error(main->setting.state.status)) return;
 
-        main->setting.state.status = fll_execute_arguments_add(buffer, &main->cache_arguments);
+        main->setting.state.status = fll_execute_arguments_add(main->cache_argument, &main->cache_arguments);
         if (F_status_is_error(main->setting.state.status)) return;
       }
 
       if (data_build->setting.search_static && (!is_shared || !data_build->setting.search_exclusive)) {
-        buffer.used = fake_build_parameter_library_link_path_s.used + data->path_work_libraries_static.used;
+        fake_string_dynamic_reset(&main->cache_argument);
 
-        f_char_t buffer_string[buffer.used + 1];
-        buffer.string = buffer_string;
-        buffer_string[buffer.used] = 0;
+        main->setting.state.status = f_string_dynamic_append_nulless(fake_build_parameter_library_link_path_s, &main->cache_argument);
+        if (F_status_is_error(main->setting.state.status)) return;
 
-        memcpy(buffer_string, fake_build_parameter_library_link_path_s.string, sizeof(f_char_t) * fake_build_parameter_library_link_path_s.used);
-        memcpy(buffer_string + fake_build_parameter_library_link_path_s.used, data->path_work_libraries_static.string, sizeof(f_char_t) * data->path_work_libraries_static.used);
+        main->setting.state.status = f_string_dynamic_append_nulless(data->path_work_libraries_static, &main->cache_argument);
+        if (F_status_is_error(main->setting.state.status)) return;
 
-        main->setting.state.status = fll_execute_arguments_add(buffer, &main->cache_arguments);
+        main->setting.state.status = fll_execute_arguments_add(main->cache_argument, &main->cache_arguments);
         if (F_status_is_error(main->setting.state.status)) return;
       }
     }
@@ -171,29 +153,17 @@ extern "C" {
     f_status_t failed = F_none;
     fake_local_t local = macro_fake_local_t_initialize_1(main, &main->cache_map, &failed);
 
-    f_directory_recurse_do_t recurse = f_directory_recurse_do_t_initialize;
-    recurse.action = &fake_do_copy_action;
-    recurse.handle = &fake_do_copy_handle;
-    recurse.state.custom = (void *) &local;
-    recurse.state.code = fake_state_code_local_e;
-    recurse.flag = f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_before_e | f_directory_recurse_do_flag_after_e;
-    recurse.mode = mode;
+    main->cache_recurse_do.action = &fake_do_copy_action;
+    main->cache_recurse_do.handle = &fake_do_copy_handle;
+    main->cache_recurse_do.state.custom = (void *) &local;
+    main->cache_recurse_do.state.code = fake_state_code_local_e;
+    main->cache_recurse_do.flag = f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_before_e | f_directory_recurse_do_flag_after_e;
+    main->cache_recurse_do.mode = mode;
 
-    fake_build_print_message_copying(&main->program.message, label);
-
-    main->setting.state.status = f_file_exists(source, F_false);
-
-    if (F_status_is_error(main->setting.state.status)) {
-      fake_print_error(&main->program.error, macro_fake_f(f_file_exists));
-
-      return;
-    }
-
-    if (main->setting.state.status != F_true) {
-      fake_build_touch(data, file_stage);
+    fake_string_dynamic_reset(&main->cache_recurse_do.path);
+    fake_string_dynamic_reset(&main->cache_recurse_do.path_cache);
 
-      return;
-    }
+    fake_build_print_message_copying(&main->program.message, label);
 
     fake_string_dynamic_reset(&main->cache_2);
     fake_string_dynamic_reset(&main->cache_map.name);
@@ -210,8 +180,6 @@ extern "C" {
       return;
     }
 
-    // @todo Consider binding the (non-existent) cache_3 for the recurse.path for more memory saving.
-
     for (f_array_length_t i = 0; i < files.used; ++i) {
 
       if (fake_signal_check(main)) break;
@@ -246,7 +214,7 @@ extern "C" {
 
         main->cache_map.name.string[main->cache_map.name.used] = 0;
 
-        fl_directory_do(main->cache_2, &recurse);
+        fl_directory_do(main->cache_2, &main->cache_recurse_do);
         if (F_status_set_fine(main->setting.state.status) == F_interrupt) break;
 
         // Always provide a finall error message to the copy message.
@@ -337,7 +305,7 @@ extern "C" {
           if (F_status_is_error(main->setting.state.status)) {
             fake_print_error(&main->program.error, macro_fake_f(f_string_dynamic_append_nulless));
 
-            return;
+            break;
           }
         }
       }
@@ -350,8 +318,6 @@ extern "C" {
       main->setting.state.status = F_none;
     } // for
 
-    f_directory_recurse_do_delete(&recurse);
-
     fake_build_touch(data, file_stage);
   }
 #endif // _di_fake_build_copy_
@@ -603,14 +569,13 @@ extern "C" {
 
         if (!sources[i]->array[j].used) continue;
 
-        source.used = path->used + sources[i]->array[j].used;
+        fake_string_dynamic_reset(&main->cache_argument);
 
-        f_char_t source_string[source.used + 1];
-        source.string = source_string;
-        source_string[source.used] = 0;
+        main->setting.state.status = f_string_dynamic_append_nulless(*path, &main->cache_argument);
+        if (F_status_is_error(main->setting.state.status)) return;
 
-        memcpy(source_string, path->string, sizeof(f_char_t) * path->used);
-        memcpy(source_string + path->used, sources[i]->array[j].string, sizeof(f_char_t) * sources[i]->array[j].used);
+        main->setting.state.status = f_string_dynamic_append_nulless(sources[i]->array[j], &main->cache_argument);
+        if (F_status_is_error(main->setting.state.status)) return;
 
         main->setting.state.status = fll_execute_arguments_add(source, &main->cache_arguments);
         if (F_status_is_error(main->setting.state.status)) return;
@@ -774,10 +739,10 @@ extern "C" {
       else if (data_build->setting.build_language == fake_build_language_bash_e) {
         main->setting.state.status = f_string_dynamic_append_nulless(fake_build_language_bash_s, source);
       }
-    }
 
-    if (F_status_is_error_not(main->setting.state.status)) {
-      main->setting.state.status = f_string_dynamic_append_assure(f_path_separator_s, source);
+      if (F_status_is_error_not(main->setting.state.status)) {
+        main->setting.state.status = f_string_dynamic_append_assure(f_path_separator_s, source);
+      }
     }
 
     if (F_status_is_error(main->setting.state.status)) {
@@ -807,6 +772,8 @@ extern "C" {
 
         if (!sources[i]->array[j].used) continue;
 
+        fake_string_dynamic_reset(&main->cache_argument);
+
         fake_build_path_source_string(data, data_build, &data_build->setting.path_sources, &main->cache_argument);
         if (F_status_is_error(main->setting.state.status)) return;
 
@@ -840,6 +807,8 @@ extern "C" {
 
     fake_main_t * const main = data->main;
 
+    fake_string_dynamic_reset(&main->cache_argument);
+
     fake_build_path_source_string(data, data_build, &data_build->setting.path_sources_object, &main->cache_argument);
     if (F_status_is_error(main->setting.state.status)) return;
 
@@ -852,7 +821,12 @@ extern "C" {
     }
 
     main->setting.state.status = fll_execute_arguments_add(main->cache_argument, &main->cache_arguments);
-    if (F_status_is_error(main->setting.state.status)) return;
+
+    if (F_status_is_error(main->setting.state.status)) {
+      fake_print_error(&main->program.error, macro_fake_f(f_string_dynamic_append_nulless));
+
+      return;
+    }
 
     main->setting.state.status = F_none;
   }
index f8c49855c9973e361bfd2e34c11d075b79f14a87..c4685968750dc1ae478014613719a57dba3d4993 100644 (file)
@@ -22,6 +22,9 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
@@ -48,6 +51,7 @@ extern "C" {
  *
  *   This modifies data.main.cache_2.
  *   This modifies data.main.cache_map.
+ *   This modifies data.main.cache_recurse_do.
  *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
@@ -109,6 +113,9 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
@@ -170,6 +177,9 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
@@ -195,6 +205,9 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
@@ -291,6 +304,9 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
@@ -314,6 +330,9 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
index bb26111fbcad7c1ec834f2676bc1aa59d2e0ee7d..90adaeaab3e592cc7ffaa363a22cba385b75e813 100644 (file)
@@ -103,9 +103,9 @@ extern "C" {
       &parameter_file_name_nano,
     };
 
-    {
-      uint8_t i = 0;
+    uint8_t i = 0;
 
+    {
       for (; i < strings_length; ++i) {
 
         memcpy(strings[i]->string, fake_build_parameter_library_name_prefix_s.string, sizeof(f_char_t) * fake_build_parameter_library_name_prefix_s.used);
@@ -207,92 +207,75 @@ extern "C" {
     }
 
     {
-      f_string_static_t parameter_file_path = f_string_static_t_initialize;
-      f_string_static_t parameter_linker = f_string_static_t_initialize;
+      main->setting.state.status = fll_execute_arguments_add(fake_build_parameter_library_shared_s, &main->cache_arguments);
 
-      parameter_file_path.used = data->path_build_libraries_shared.used;
-      parameter_linker.used = fake_build_parameter_library_shared_prefix_s.used;
-
-      if (data_build->setting.version_file == fake_build_version_major_e) {
-        parameter_file_path.used += parameter_file_name_major.used;
-      }
-      else if (data_build->setting.version_file == fake_build_version_minor_e) {
-        parameter_file_path.used += parameter_file_name_minor.used;
-      }
-      else if (data_build->setting.version_file == fake_build_version_micro_e) {
-        parameter_file_path.used += parameter_file_name_micro.used;
-      }
-      else if (data_build->setting.version_file == fake_build_version_nano_e) {
-        parameter_file_path.used += parameter_file_name_nano.used;
-      }
+      if (F_status_is_error(main->setting.state.status)) {
+        fake_print_error(&main->program.error, macro_fake_f(fll_execute_arguments_add));
 
-      if (data_build->setting.version_target == fake_build_version_major_e) {
-        parameter_linker.used += parameter_file_name_major.used;
-      }
-      else if (data_build->setting.version_target == fake_build_version_minor_e) {
-        parameter_linker.used += parameter_file_name_minor.used;
-      }
-      else if (data_build->setting.version_target == fake_build_version_micro_e) {
-        parameter_linker.used += parameter_file_name_micro.used;
-      }
-      else if (data_build->setting.version_target == fake_build_version_nano_e) {
-        parameter_linker.used += parameter_file_name_nano.used;
+        return 0;
       }
 
-      f_char_t parameter_file_path_string[parameter_file_path.used + 1];
-      f_char_t parameter_linker_string[parameter_linker.used + 1];
+      fake_string_dynamic_reset(&main->cache_argument);
 
-      parameter_file_path.string = parameter_file_path_string;
-      parameter_linker.string = parameter_linker_string;
+      main->setting.state.status = f_string_dynamic_append_nulless(fake_build_parameter_library_shared_prefix_s, &main->cache_argument);
 
-      parameter_file_path_string[parameter_file_path.used] = 0;
-      parameter_linker_string[parameter_linker.used] = 0;
+      if (F_status_is_error_not(main->setting.state.status)) {
+        if (data_build->setting.version_target == fake_build_version_major_e) {
+          main->setting.state.status = f_string_dynamic_append_nulless(parameter_file_name_major, &main->cache_argument);
+        }
+        else if (data_build->setting.version_target == fake_build_version_minor_e) {
+          main->setting.state.status = f_string_dynamic_append_nulless(parameter_file_name_minor, &main->cache_argument);
+        }
+        else if (data_build->setting.version_target == fake_build_version_micro_e) {
+          main->setting.state.status = f_string_dynamic_append_nulless(parameter_file_name_micro, &main->cache_argument);
+        }
+        else if (data_build->setting.version_target == fake_build_version_nano_e) {
+          main->setting.state.status = f_string_dynamic_append_nulless(parameter_file_name_nano, &main->cache_argument);
+        }
+      }
 
-      memcpy(parameter_file_path_string, data->path_build_libraries_shared.string, sizeof(f_char_t) * data->path_build_libraries_shared.used);
-      memcpy(parameter_linker_string, fake_build_parameter_library_shared_prefix_s.string, sizeof(f_char_t) * fake_build_parameter_library_shared_prefix_s.used);
+      if (F_status_is_error(main->setting.state.status)) {
+        fake_print_error(&main->program.error, macro_fake_f(f_string_dynamic_append_nulless));
 
-      if (data_build->setting.version_file == fake_build_version_major_e) {
-        memcpy(parameter_file_path_string + data->path_build_libraries_shared.used, parameter_file_name_major_string, sizeof(f_char_t) * parameter_file_name_major.used);
-      }
-      else if (data_build->setting.version_file == fake_build_version_minor_e) {
-        memcpy(parameter_file_path_string + data->path_build_libraries_shared.used, parameter_file_name_minor_string, sizeof(f_char_t) * parameter_file_name_minor.used);
-      }
-      else if (data_build->setting.version_file == fake_build_version_micro_e) {
-        memcpy(parameter_file_path_string + data->path_build_libraries_shared.used, parameter_file_name_micro_string, sizeof(f_char_t) * parameter_file_name_micro.used);
-      }
-      else if (data_build->setting.version_file == fake_build_version_nano_e) {
-        memcpy(parameter_file_path_string + data->path_build_libraries_shared.used, parameter_file_name_nano_string, sizeof(f_char_t) * parameter_file_name_nano.used);
+        return 0;
       }
 
-      if (data_build->setting.version_target == fake_build_version_major_e) {
-        memcpy(parameter_linker_string + fake_build_parameter_library_shared_prefix_s.used, parameter_file_name_major_string, sizeof(f_char_t) * parameter_file_name_major.used);
-      }
-      else if (data_build->setting.version_target == fake_build_version_minor_e) {
-        memcpy(parameter_linker_string + fake_build_parameter_library_shared_prefix_s.used, parameter_file_name_minor_string, sizeof(f_char_t) * parameter_file_name_minor.used);
-      }
-      else if (data_build->setting.version_target == fake_build_version_micro_e) {
-        memcpy(parameter_linker_string + fake_build_parameter_library_shared_prefix_s.used, parameter_file_name_micro_string, sizeof(f_char_t) * parameter_file_name_micro.used);
+      main->setting.state.status = fll_execute_arguments_add(main->cache_argument, &main->cache_arguments);
+
+      if (F_status_is_error_not(main->setting.state.status)) {
+        main->setting.state.status = fll_execute_arguments_add(fake_build_parameter_library_output_s, &main->cache_arguments);
       }
-      else if (data_build->setting.version_target == fake_build_version_nano_e) {
-        memcpy(parameter_linker_string + fake_build_parameter_library_shared_prefix_s.used, parameter_file_name_nano_string, sizeof(f_char_t) * parameter_file_name_nano.used);
+
+      if (F_status_is_error(main->setting.state.status)) {
+        fake_print_error(&main->program.error, macro_fake_f(fll_execute_arguments_add));
+
+        return 0;
       }
 
-      const f_string_static_t values[] = {
-        fake_build_parameter_library_shared_s,
-        parameter_linker,
-        fake_build_parameter_library_output_s,
-        parameter_file_path,
-      };
+      fake_string_dynamic_reset(&main->cache_argument);
 
-      for (uint8_t i = 0; i < 4; ++i) {
+      main->setting.state.status = f_string_dynamic_append_nulless(data->path_build_libraries_shared, &main->cache_argument);
 
-        if (!values[i].used) continue;
+      if (F_status_is_error_not(main->setting.state.status)) {
+        if (data_build->setting.version_file == fake_build_version_major_e) {
+          main->setting.state.status = f_string_dynamic_append_nulless(parameter_file_name_major, &main->cache_argument);
+        }
+        else if (data_build->setting.version_file == fake_build_version_minor_e) {
+          main->setting.state.status = f_string_dynamic_append_nulless(parameter_file_name_minor, &main->cache_argument);
+        }
+        else if (data_build->setting.version_file == fake_build_version_micro_e) {
+          main->setting.state.status = f_string_dynamic_append_nulless(parameter_file_name_micro, &main->cache_argument);
+        }
+        else if (data_build->setting.version_file == fake_build_version_nano_e) {
+          main->setting.state.status = f_string_dynamic_append_nulless(parameter_file_name_nano, &main->cache_argument);
+        }
+      }
 
-        main->setting.state.status = fll_execute_arguments_add(values[i], &main->cache_arguments);
-        if (F_status_is_error(main->setting.state.status)) break;
-      } // for
+      main->setting.state.status = fll_execute_arguments_add(main->cache_argument, &main->cache_arguments);
 
-      fake_build_arguments_standard_add(data, data_build, F_true, fake_build_type_library_e);
+      if (F_status_is_error_not(main->setting.state.status)) {
+        fake_build_arguments_standard_add(data, data_build, F_true, fake_build_type_library_e);
+      }
 
       if (F_status_is_error(main->setting.state.status)) {
         fake_print_error(&main->program.error, macro_fake_f(fll_execute_arguments_add));
@@ -308,117 +291,62 @@ extern "C" {
       if (main->setting.state.status == F_child) return result;
     }
 
-    if (parameter_file_name_major.used) {
-      f_string_static_t parameter_file_path = f_string_static_t_initialize;
-      parameter_file_path.used = data->path_build_libraries_shared.used + parameter_file_name.used;
-
-      f_char_t parameter_file_path_string[parameter_file_path.used + 1];
-      parameter_file_path.string = parameter_file_path_string;
-      parameter_file_path_string[parameter_file_path.used] = 0;
-
-      memcpy(parameter_file_path_string, data->path_build_libraries_shared.string, sizeof(f_char_t) * data->path_build_libraries_shared.used);
-      memcpy(parameter_file_path_string + data->path_build_libraries_shared.used, parameter_file_name.string, sizeof(f_char_t) * parameter_file_name.used);
-
-      main->setting.state.status = f_file_link(parameter_file_name_major, parameter_file_path);
-
-      if (F_status_is_error_not(main->setting.state.status)) {
-        fake_build_print_verbose_linked_file(&main->program.message, parameter_file_path, parameter_file_name_major);
-      }
-      else {
-        if (F_status_set_fine(main->setting.state.status) == F_file_found) {
-          fake_print_error_file(&main->program.error, macro_fake_f(f_file_link), parameter_file_path, f_file_operation_link_s, fll_error_file_type_file_e);
-
-          return 0;
-        }
-
-        fake_print_error_file(&main->program.error, macro_fake_f(f_file_link), parameter_file_name_major, f_file_operation_link_s, fll_error_file_type_file_e);
+    {
+      bool dont_links[] = {
+        !parameter_file_name_major.used,
+        data_build->setting.version_file == fake_build_version_major_e || !parameter_file_name_major.used,
+        data_build->setting.version_file == fake_build_version_minor_e || !parameter_file_name_minor.used,
+        data_build->setting.version_file == fake_build_version_micro_e || !parameter_file_name_micro.used,
+      };
 
-        return 0;
-      }
-    }
+      const f_string_static_t points[] = {
+        parameter_file_name,
+        parameter_file_name_major,
+        parameter_file_name_minor,
+        parameter_file_name_micro,
+      };
 
-    if (data_build->setting.version_file != fake_build_version_major_e && parameter_file_name_major.used) {
-      f_string_static_t parameter_file_path = f_string_static_t_initialize;
+      const f_string_static_t targets[] = {
+        parameter_file_name_major,
+        parameter_file_name_minor,
+        parameter_file_name_micro,
+        parameter_file_name_nano,
+      };
 
-      {
-        parameter_file_path.used = data->path_build_libraries_shared.used + parameter_file_name_major.used;
+      for (i = 0; i < 4; ++i) {
 
-        f_char_t parameter_file_path_string[parameter_file_path.used + 1];
-        parameter_file_path.string = parameter_file_path_string;
-        parameter_file_path_string[parameter_file_path.used] = 0;
+        if (dont_links[i]) break;
 
-        memcpy(parameter_file_path_string, data->path_build_libraries_shared.string, sizeof(f_char_t) * data->path_build_libraries_shared.used);
-        memcpy(parameter_file_path_string + data->path_build_libraries_shared.used, parameter_file_name_major.string, sizeof(f_char_t) * parameter_file_name_major.used);
+        fake_string_dynamic_reset(&main->cache_argument);
 
-        main->setting.state.status = f_file_link(parameter_file_name_minor, parameter_file_path);
+        main->setting.state.status = f_string_dynamic_append_nulless(data->path_build_libraries_shared, &main->cache_argument);
 
         if (F_status_is_error_not(main->setting.state.status)) {
-          fake_build_print_verbose_linked_file(&main->program.message, parameter_file_path, parameter_file_name_minor);
+          main->setting.state.status = f_string_dynamic_append_nulless(points[i], &main->cache_argument);
         }
-        else {
-          fake_print_error_file(&main->program.error, macro_fake_f(f_file_link), F_status_set_fine(main->setting.state.status) == F_file_found ? parameter_file_path : parameter_file_name_minor, f_file_operation_link_s, fll_error_file_type_file_e);
+
+        if (F_status_is_error(main->setting.state.status)) {
+          fake_print_error(&main->program.error, macro_fake_f(f_string_dynamic_append_nulless));
 
           return 0;
         }
-      }
-
-      if (data_build->setting.version_file != fake_build_version_minor_e && parameter_file_name_minor.used) {
-        {
-          parameter_file_path.used = data->path_build_libraries_shared.used + parameter_file_name_minor.used;
-
-          f_char_t parameter_file_path_string[parameter_file_path.used + 1];
-          parameter_file_path.string = parameter_file_path_string;
-          parameter_file_path_string[parameter_file_path.used] = 0;
-
-          memcpy(parameter_file_path_string, data->path_build_libraries_shared.string, sizeof(f_char_t) * data->path_build_libraries_shared.used);
-          memcpy(parameter_file_path_string + data->path_build_libraries_shared.used, parameter_file_name_minor.string, sizeof(f_char_t) * parameter_file_name_minor.used);
-
-          main->setting.state.status = f_file_link(parameter_file_name_micro, parameter_file_path);
 
-          if (F_status_is_error_not(main->setting.state.status)) {
-            fake_build_print_verbose_linked_file(&main->program.message, parameter_file_path, parameter_file_name_micro);
-          }
-          else {
-            if (F_status_set_fine(main->setting.state.status) == F_file_found) {
-              fake_print_error_file(&main->program.error, macro_fake_f(f_file_link), parameter_file_path, f_file_operation_link_s, fll_error_file_type_file_e);
-
-              return 0;
-            }
-
-            fake_print_error_file(&main->program.error, macro_fake_f(f_file_link), parameter_file_name_micro, f_file_operation_link_s, fll_error_file_type_file_e);
+        main->setting.state.status = f_file_link(targets[i], main->cache_argument);
 
-            return 0;
-          }
+        if (F_status_is_error_not(main->setting.state.status)) {
+          fake_build_print_verbose_linked_file(&main->program.message, main->cache_argument, targets[i]);
         }
-
-        if (data_build->setting.version_file != fake_build_version_micro_e && parameter_file_name_micro.used) {
-          parameter_file_path.used = data->path_build_libraries_shared.used + parameter_file_name_micro.used;
-
-          f_char_t parameter_file_path_string[parameter_file_path.used + 1];
-          parameter_file_path.string = parameter_file_path_string;
-          parameter_file_path_string[parameter_file_path.used] = 0;
-
-          memcpy(parameter_file_path_string, data->path_build_libraries_shared.string, sizeof(f_char_t) * data->path_build_libraries_shared.used);
-          memcpy(parameter_file_path_string + data->path_build_libraries_shared.used, parameter_file_name_micro.string, sizeof(f_char_t) * parameter_file_name_micro.used);
-
-          main->setting.state.status = f_file_link(parameter_file_name_nano, parameter_file_path);
-
-          if (F_status_is_error_not(main->setting.state.status)) {
-            fake_build_print_verbose_linked_file(&main->program.message, parameter_file_path, parameter_file_name_nano);
+        else {
+          if (F_status_set_fine(main->setting.state.status) == F_file_found) {
+            fake_print_error_file(&main->program.error, macro_fake_f(f_file_link), main->cache_argument, f_file_operation_link_s, fll_error_file_type_file_e);
           }
           else {
-            if (F_status_set_fine(main->setting.state.status) == F_file_found) {
-              fake_print_error_file(&main->program.error, macro_fake_f(f_file_link), parameter_file_path, f_file_operation_link_s, fll_error_file_type_file_e);
-
-              return 0;
-            }
-
-            fake_print_error_file(&main->program.error, macro_fake_f(f_file_link), parameter_file_name_nano, f_file_operation_link_s, fll_error_file_type_file_e);
-
-            return 0;
+            fake_print_error_file(&main->program.error, macro_fake_f(f_file_link), targets[i], f_file_operation_link_s, fll_error_file_type_file_e);
           }
+
+          return 0;
         }
-      }
+      } // for
     }
 
     fake_build_touch(data, file_stage);
@@ -450,7 +378,12 @@ extern "C" {
       if (!data_build->setting.build_indexer_arguments.array[i].used) continue;
 
       main->setting.state.status = fll_execute_arguments_add(data_build->setting.build_indexer_arguments.array[i], &main->cache_arguments);
-      if (F_status_is_error(main->setting.state.status)) break;
+
+      if (F_status_is_error(main->setting.state.status)) {
+        fake_print_error(&main->program.error, macro_fake_f(fll_execute_arguments_add));
+
+        return 0;
+      }
     } // for
 
     if (F_status_is_error_not(main->setting.state.status)) {
@@ -473,6 +406,12 @@ extern "C" {
       }
       else {
         main->setting.state.status = fll_execute_arguments_add(main->cache_2, &main->cache_arguments);
+
+        if (F_status_is_error(main->setting.state.status)) {
+          fake_print_error(&main->program.error, macro_fake_f(fll_execute_arguments_add));
+
+          return 0;
+        }
       }
     }
 
index 564f6585fff4d21b0b305eaa604d630c072a3a9e..9f6189e016845561ea82fd9b622ad68752095a43 100644 (file)
@@ -70,6 +70,9 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
@@ -109,6 +112,11 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_1.
+ *   This modifies data.main.cache_2.
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
index 75bf30a397a6418331da7e41e3861b95c4f6c984..b374e74842d55c77c6f23b64cdcd856a2eaa75e3 100644 (file)
@@ -72,6 +72,7 @@ extern "C" {
       } // for
     }
 
+    // The cache_argument should be safe at this point to be reset and reused by this function.
     fake_build_arguments_standard_add(data, data_build, F_true, fake_build_type_object_e);
 
     if (F_status_is_error(main->setting.state.status)) {
@@ -145,6 +146,7 @@ extern "C" {
       } // for
     }
 
+    // The cache_argument should be safe at this point to be reset and reused by this function.
     fake_build_arguments_standard_add(data, data_build, F_false, fake_build_type_object_e);
 
     if (F_status_is_error(main->setting.state.status)) {
index bef1f589a37f921fcc3d55b006ad937a5ef57084..f65e8ec6f42f84325c021d24fb121a9fe59515f4 100644 (file)
@@ -57,6 +57,9 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
@@ -93,6 +96,9 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
index d1cf612673b88558349d0ab6d6c1aaa391388ffe..ddc81757ccc6cd0c4717bf12eaaecf18d817e000 100644 (file)
@@ -162,6 +162,7 @@ extern "C" {
           if (F_status_is_error(main->setting.state.status)) break;
         } // for
 
+        // The cache_argument should be safe at this point to be reset and reused by this function.
         fake_build_arguments_standard_add(data, data_build, F_false, fake_build_type_library_e);
 
         if (F_status_is_error(main->setting.state.status)) {
index de065638a65fd27adab551a0ab9c734caa87f606..1d0a0df6b1f14f91d07e46eb83d5286d1d0edb93 100644 (file)
@@ -25,6 +25,11 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_1.
+ *   This modifies data.main.cache_2.
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->settings.state.status:
  *     F_none on success.
  *
index 4745987a12de76cb8446d8fcd88f4916c7267b22..c55d3c36d572bc5897d964c04b872fd34aef58e3 100644 (file)
@@ -144,55 +144,76 @@ extern "C" {
     }
 
     if (F_status_is_error_not(main->setting.state.status)) {
-      f_string_static_t source_library = f_string_static_t_initialize;
-      source_library.used = data->path_build_libraries_static.used + fake_build_parameter_library_name_prefix_s.used + data_build->setting.build_name.used + fake_build_parameter_library_name_suffix_static_s.used;
-
-      f_char_t source_library_string[source_library.used + 1];
-      source_library.string = source_library_string;
-      source_library_string[source_library.used] = 0;
-      source_library.used = 0;
 
       // Only include the library if there are sources that would result in it being built.
       if (data_build->setting.build_sources_library.used) {
-        memcpy(source_library_string, data->path_build_libraries_static.string, sizeof(f_char_t) * data->path_build_libraries_static.used);
-        source_library.used += data->path_build_libraries_static.used;
+        fake_string_dynamic_reset(&main->cache_argument);
+
+        main->setting.state.status = f_string_dynamic_append_nulless(fake_build_parameter_library_name_prefix_s, &main->cache_argument);
+
+        if (F_status_is_error_not(main->setting.state.status)) {
+          main->setting.state.status = f_string_dynamic_append_nulless(fake_build_parameter_library_name_prefix_s, &main->cache_argument);
+        }
+
+        if (F_status_is_error_not(main->setting.state.status)) {
+          main->setting.state.status = f_string_dynamic_append_nulless(data_build->setting.build_name, &main->cache_argument);
+        }
+
+        if (F_status_is_error_not(main->setting.state.status)) {
+          main->setting.state.status = f_string_dynamic_append_nulless(fake_build_parameter_library_name_suffix_static_s, &main->cache_argument);
+        }
 
-        memcpy(source_library_string + source_library.used, fake_build_parameter_library_name_prefix_s.string, sizeof(f_char_t) * fake_build_parameter_library_name_prefix_s.used);
-        source_library.used += fake_build_parameter_library_name_prefix_s.used;
+        if (F_status_is_error(main->setting.state.status)) {
+          fake_print_error(&main->program.error, macro_fake_f(f_string_dynamic_append_nulless));
 
-        memcpy(source_library_string + source_library.used, data_build->setting.build_name.string, sizeof(f_char_t) * data_build->setting.build_name.used);
-        source_library.used += data_build->setting.build_name.used;
+          return 0;
+        }
 
-        memcpy(source_library_string + source_library.used, fake_build_parameter_library_name_suffix_static_s.string, sizeof(f_char_t) * fake_build_parameter_library_name_suffix_static_s.used);
-        source_library.used += fake_build_parameter_library_name_suffix_static_s.used;
+        main->setting.state.status = fll_execute_arguments_add(main->cache_argument, &main->cache_arguments);
+
+        if (F_status_is_error(main->setting.state.status)) {
+          fake_print_error(&main->program.error, macro_fake_f(fll_execute_arguments_add));
+
+          return 0;
+        }
       }
 
-      f_string_static_t parameter_file_name_path = f_string_static_t_initialize;
-      parameter_file_name_path.used = data->path_build_programs_static.used + data_build->setting.build_name.used;
+      main->setting.state.status = fll_execute_arguments_add(fake_build_parameter_library_static_s, &main->cache_arguments);
 
-      f_char_t parameter_file_name_path_string[parameter_file_name_path.used + 1];
-      parameter_file_name_path.string = parameter_file_name_path_string;
-      parameter_file_name_path_string[parameter_file_name_path.used] = 0;
+      if (F_status_is_error_not(main->setting.state.status)) {
+        main->setting.state.status = fll_execute_arguments_add(fake_build_parameter_library_output_s, &main->cache_arguments);
+      }
 
-      memcpy(parameter_file_name_path_string, data->path_build_programs_static.string, sizeof(f_char_t) * data->path_build_programs_static.used);
-      memcpy(parameter_file_name_path_string + data->path_build_programs_static.used, data_build->setting.build_name.string, sizeof(f_char_t) * data_build->setting.build_name.used);
+      if (F_status_is_error(main->setting.state.status)) {
+        fake_print_error(&main->program.error, macro_fake_f(fll_execute_arguments_add));
 
-      const f_string_static_t values[] = {
-        source_library,
-        fake_build_parameter_library_static_s,
-        fake_build_parameter_library_output_s,
-        parameter_file_name_path,
-      };
+        return 0;
+      }
 
-      for (uint8_t i = 0; i < 4; ++i) {
+      fake_string_dynamic_reset(&main->cache_argument);
 
-        if (!values[i].used) continue;
+      main->setting.state.status = f_string_dynamic_append_nulless(data->path_build_programs_static, &main->cache_argument);
 
-        main->setting.state.status = fll_execute_arguments_add(values[i], &main->cache_arguments);
-        if (F_status_is_error(main->setting.state.status)) break;
-      } // for
+      if (F_status_is_error_not(main->setting.state.status)) {
+        main->setting.state.status = f_string_dynamic_append_nulless(data_build->setting.build_name, &main->cache_argument);
+      }
+
+      if (F_status_is_error(main->setting.state.status)) {
+        fake_print_error(&main->program.error, macro_fake_f(f_string_dynamic_append_nulless));
+
+        return 0;
+      }
+
+      main->setting.state.status = fll_execute_arguments_add(main->cache_argument, &main->cache_arguments);
+
+      if (F_status_is_error(main->setting.state.status)) {
+        fake_print_error(&main->program.error, macro_fake_f(fll_execute_arguments_add));
+
+        return 0;
+      }
     }
 
+    // The cache_argument should be safe at this point to be reset and reused by this function.
     fake_build_arguments_standard_add(data, data_build, F_false, fake_build_type_program_e);
 
     if (F_status_is_error(main->setting.state.status)) {
index 0fa8fa25d148929b10839da09060e6202874895a..956068a75dc751dbb2145a41822c723f92ea63bf 100644 (file)
@@ -55,6 +55,9 @@ extern "C" {
  * @param data
  *   The program data.
  *
+ *   This modifies data.main.cache_argument.
+ *   This modifies data.main.cache_arguments.
+ *
  *   This alters data.main->setting.state.status:
  *     F_none on success.
  *
index 3f2aa0d104a999fb81157e1a309fac23a2785dfa..1b698be8a8a3c15c520b5c6ddeb658c8f16a6e68 100644 (file)
@@ -197,6 +197,8 @@ extern "C" {
     f_string_dynamic_resize(0, &main->cache_map.value);
 
     f_iki_data_delete(&main->cache_iki);
+
+    f_directory_recurse_do_delete(&main->cache_recurse_do);
   }
 #endif // _di_fake_main_data_delete_
 
index cdf05a19201edbb45c22d12c8477e5c71255ecc3..99e74dd038b8f8a2d4f80fde5f11bd1d27904ca3 100644 (file)
@@ -125,14 +125,15 @@ extern "C" {
  * program: The main program data.
  * setting: The settings data.
  *
- * buffer:          A string buffer cache often used for files and often held longe than other caches.
- * cache_1:         A string cache.
- * cache_2:         A string cache.
- * cache_argument:  A string cache for some argument.
- * cache_argument:  A string cache for some path.
- * cache_arguments: An array of strings cache for arguments.
- * cache_map:       A string map cache.
- * cach_iki:        IKI data cache.
+ * buffer:           A string buffer cache often used for files and often held longe than other caches.
+ * cache_1:          A string cache.
+ * cache_2:          A string cache.
+ * cache_argument:   A string cache for some argument.
+ * cache_argument:   A string cache for some path.
+ * cache_arguments:  An array of strings cache for arguments.
+ * cache_map:        A string map cache.
+ * cache_iki:        IKI data cache.
+ * cache_recurse_do: A cache for the directory recursion do function.
  */
 #ifndef _di_fake_main_t_
   typedef struct {
@@ -146,6 +147,7 @@ extern "C" {
     f_string_dynamics_t cache_arguments;
     f_string_map_t cache_map;
     f_iki_data_t cache_iki;
+    f_directory_recurse_do_t cache_recurse_do;
   } fake_main_t;
 
   #define fake_main_t_initialize \
@@ -159,6 +161,7 @@ extern "C" {
       f_string_dynamics_t_initialize, \
       f_string_map_t_initialize, \
       f_iki_data_t_initialize, \
+      f_directory_recurse_do_t_initialize, \
     }
 #endif // _di_fake_main_t_
 
index a94c044c007e3a44c7fbcf85d19acad0e5541711..8365f41cf87709ec16ac7ece7286ba01fd5cf755 100644 (file)
@@ -28,12 +28,12 @@ extern "C" {
         if (recurse->state.code & fake_state_code_clone_e) {
           fake_print_verbose_cloning(&local->main->program.message, *recurse->path_top, map->name);
 
-          recurse->state.status = f_file_clone(*recurse->path_top, map->name, F_file_default_write_size_d, F_file_flag_write_only_d);
+          recurse->state.status = f_file_clone(*recurse->path_top, map->name, F_file_default_write_size_d, f_file_stat_flag_group_e | f_file_stat_flag_owner_e | (f_directory_recurse_do_flag_dereference_e ? 0 : f_file_stat_flag_reference_e));
         }
         else {
           fake_print_verbose_copying(&local->main->program.message, *recurse->path_top, map->name);
 
-          recurse->state.status = f_file_copy(*recurse->path_top, map->name, recurse->mode, F_file_default_write_size_d, F_file_flag_write_only_d);
+          recurse->state.status = f_file_copy(*recurse->path_top, map->name, recurse->mode, F_file_default_write_size_d, f_directory_recurse_do_flag_dereference_e ? 0 : f_file_stat_flag_reference_e);
         }
 
         if (F_status_is_error(recurse->state.status)) {
@@ -86,12 +86,12 @@ extern "C" {
         if (recurse->state.code & fake_state_code_clone_e) {
           fake_print_verbose_cloning(&local->main->program.message, recurse->path, recurse->path_cache);
 
-          recurse->state.status = f_file_clone(recurse->path, recurse->path_cache, F_file_default_write_size_d, F_file_flag_write_only_d);
+          recurse->state.status = f_file_clone(recurse->path, recurse->path_cache, F_file_default_write_size_d, f_file_stat_flag_group_e | f_file_stat_flag_owner_e | (f_directory_recurse_do_flag_dereference_e ? 0 : f_file_stat_flag_reference_e));
         }
         else {
           fake_print_verbose_copying(&local->main->program.message, recurse->path, recurse->path_cache);
 
-          recurse->state.status = f_file_copy(recurse->path, recurse->path_cache, recurse->mode, F_file_default_write_size_d, F_file_flag_write_only_d);
+          recurse->state.status = f_file_copy(recurse->path, recurse->path_cache, recurse->mode, F_file_default_write_size_d, f_directory_recurse_do_flag_dereference_e ? 0 : f_file_stat_flag_reference_e);
         }
 
         if (F_status_is_error(recurse->state.status)) {
@@ -146,12 +146,12 @@ extern "C" {
     if (recurse->state.code & fake_state_code_clone_e) {
       fake_print_verbose_cloning(&local->main->program.message, recurse->path, map->value);
 
-      recurse->state.status = f_file_clone(recurse->path, map->value, F_file_default_write_size_d, F_file_flag_write_only_d);
+      recurse->state.status = f_file_clone(recurse->path, map->value, F_file_default_write_size_d, f_file_stat_flag_group_e | f_file_stat_flag_owner_e | (f_directory_recurse_do_flag_dereference_e ? 0 : f_file_stat_flag_reference_e));
     }
     else {
       fake_print_verbose_copying(&local->main->program.message, recurse->path, map->value);
 
-      recurse->state.status = f_file_copy(recurse->path, map->value, recurse->mode, F_file_default_write_size_d, F_file_flag_write_only_d);
+      recurse->state.status = f_file_copy(recurse->path, map->value, recurse->mode, F_file_default_write_size_d, f_directory_recurse_do_flag_dereference_e ? 0 : f_file_stat_flag_reference_e);
     }
 
     if (F_status_is_error(recurse->state.status)) {
index 41b0859cb48cc1e9a4488aadeec287fa3bc73423..5733db8a60e10ac2b2488e9cfe9e8a7c6d95a45a 100644 (file)
@@ -213,21 +213,22 @@ extern "C" {
     f_status_t failed = F_none;
     fake_local_t local = macro_fake_local_t_initialize_1(main, &main->cache_map, &failed);
 
-    f_directory_recurse_do_t recurse = f_directory_recurse_do_t_initialize;
-    recurse.action = &fake_do_copy_action;
-    recurse.handle = &fake_do_copy_handle;
-    recurse.state.custom = (void *) &local;
-    recurse.state.code = fake_state_code_local_e;
-    recurse.flag = f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_before_e | f_directory_recurse_do_flag_after_e;
+    main->cache_recurse_do.action = &fake_do_copy_action;
+    main->cache_recurse_do.handle = &fake_do_copy_handle;
+    main->cache_recurse_do.state.custom = (void *) &local;
+    main->cache_recurse_do.state.code = fake_state_code_local_e;
+    main->cache_recurse_do.flag = f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_before_e | f_directory_recurse_do_flag_after_e;
 
     if (clone) {
-      recurse.state.code |= fake_state_code_clone_e;
-      recurse.flag = f_file_stat_flag_group_e | f_file_stat_flag_owner_e | f_directory_recurse_copy_flag_clone_e;
+      main->cache_recurse_do.state.code |= fake_state_code_clone_e;
     }
     else {
-      macro_f_mode_t_set_default_umask(recurse.mode, main->program.umask);
+      macro_f_mode_t_set_default_umask(main->cache_recurse_do.mode, main->program.umask);
     }
 
+    fake_string_dynamic_reset(&main->cache_recurse_do.path);
+    fake_string_dynamic_reset(&main->cache_recurse_do.path_cache);
+
     bool existing = F_true;
     f_array_length_t i = 0;
     const f_string_t *function = 0;
@@ -237,7 +238,7 @@ extern "C" {
     // The first argument may designate not to dereference links.
     if (f_compare_dynamic(fake_make_operation_argument_no_dereference_s, main->cache_arguments.array[i]) == F_equal_to) {
       ++i;
-      recurse.flag |= f_file_stat_flag_reference_e;
+      main->cache_recurse_do.flag |= f_file_stat_flag_reference_e;
     }
 
     // Confirm if the destination is a file when there are three or more arguments (after the potential no dereference argument).
@@ -290,10 +291,10 @@ extern "C" {
         main->setting.state.status = f_directory_is(main->cache_arguments.array[i]);
 
         if (main->setting.state.status == F_true) {
-          fl_directory_do(main->cache_arguments.array[i], &recurse);
+          fl_directory_do(main->cache_arguments.array[i], &main->cache_recurse_do);
 
-          if (F_status_is_error(recurse.state.status)) {
-            main->setting.state.status = recurse.state.status;
+          if (F_status_is_error(main->cache_recurse_do.state.status)) {
+            main->setting.state.status = main->cache_recurse_do.state.status;
 
             function = &macro_fake_f(fl_directory_do);
             operation = clone ? &f_file_operation_clone_s : &f_file_operation_copy_s;
@@ -304,10 +305,10 @@ extern "C" {
         }
         else if (main->setting.state.status == F_false) {
           if (clone) {
-            main->setting.state.status = f_file_clone(main->cache_arguments.array[i], main->cache_map.name, F_file_default_write_size_d, F_file_flag_write_only_d);
+            main->setting.state.status = f_file_clone(main->cache_arguments.array[i], main->cache_map.name, F_file_default_write_size_d, f_file_stat_flag_group_e | f_file_stat_flag_owner_e | (f_directory_recurse_do_flag_dereference_e ? 0 : f_file_stat_flag_reference_e));
           }
           else {
-            main->setting.state.status = f_file_copy(main->cache_arguments.array[i], main->cache_map.name, recurse.mode, F_file_default_write_size_d, F_file_flag_write_only_d);
+            main->setting.state.status = f_file_copy(main->cache_arguments.array[i], main->cache_map.name, main->cache_recurse_do.mode, F_file_default_write_size_d, f_directory_recurse_do_flag_dereference_e ? 0 : f_file_stat_flag_reference_e);
           }
 
           if (F_status_is_error(main->setting.state.status)) {
@@ -330,8 +331,6 @@ extern "C" {
       } // for
     }
 
-    f_directory_recurse_do_delete(&recurse);
-
     if (F_status_is_error(main->setting.state.status)) {
       fake_print_error_file(&main->program.error, *function, main->cache_arguments.array[1], *operation, fll_error_file_type_path_e);