]> Kevux Git Server - fll/commitdiff
Feature: Add Turtle Kevux path support.
authorKevin Day <kevin@kevux.org>
Sun, 12 Feb 2023 16:22:20 +0000 (10:22 -0600)
committerKevin Day <kevin@kevux.org>
Sun, 12 Feb 2023 16:26:30 +0000 (10:26 -0600)
This does not break API or ABI because it requires macros to be defined that would break it.
These macros, when in use, should not break API (but does extend it) but may break ABI.
The return value may have additional results and might be considered an API but not ABI breaking change.

There is already Kevux-specific code in FLL.
Temporarily continue that process as a short term solution.
In the long term, separate functions or files may be used (or an entirely separate project).

level_0/f_path/c/path/common.c
level_0/f_path/c/path/common.h
level_0/f_path/data/build/defines
level_1/fl_environment/c/environment.c
level_1/fl_environment/c/environment.h
level_1/fl_environment/data/build/defines
level_2/fll_execute/c/execute.c
level_2/fll_execute/data/build/defines

index 9dc37f15ee65466603bb47b1d846016897e25a53..afdc3b0a2151d28835e129bfcab258239d76221f 100644 (file)
@@ -15,6 +15,12 @@ extern "C" {
   const f_string_static_t f_path_home_wildcard_s = macro_f_string_static_t_initialize(F_string_ascii_tilde_s, 0, F_string_ascii_tilde_s_length);
   const f_string_static_t f_path_present_working_s = macro_f_string_static_t_initialize(F_path_present_working_s, 0, F_path_present_working_s_length);
   const f_string_static_t f_path_present_working_old_s = macro_f_string_static_t_initialize(F_path_present_working_old_s, 0, F_path_present_working_old_s_length);
+
+  #ifdef _en_kevux_path_architecture_bits_
+    const f_string_static_t f_path_architecture_bits_s = macro_f_string_static_t_initialize(F_path_architecture_bits_s, 0, F_path_architecture_bits_s_length);
+    const f_string_static_t f_path_architecture_bits_default_s = macro_f_string_static_t_initialize(F_path_architecture_bits_default_s, 0, F_path_architecture_bits_default_s_length);
+    const f_string_static_t f_path_architecture_bits_scripts_s = macro_f_string_static_t_initialize(F_path_architecture_bits_scripts_s, 0, F_path_architecture_bits_scripts_s_length);
+  #endif // _en_kevux_path_architecture_bits_
 #endif // _di_f_path_defines_
 
 #if defined(_di_f_path_tree_s_) && !defined(_di_f_path_tree_hierarchy_standard_) && !defined(_di_f_path_tree_kevux_standard_)
index f266f9e2bb3305d196e4145b2a354cd58877e09a..e3da242918b98ecded22748753c8f3fadd70114f 100644 (file)
@@ -66,6 +66,67 @@ extern "C" {
   extern const f_string_static_t f_path_home_wildcard_s;
   extern const f_string_static_t f_path_present_working_s;
   extern const f_string_static_t f_path_present_working_old_s;
+
+  /**
+   * Provide Kevux ARCHITECTURE_BITS environment variable handling support.
+   *
+   * Non-Kevux systems should not need this and enabling this might cause problems.
+   *
+   * This uses the defines for customizing the architecture bits (and scripts) path:
+   *   - _en_kevux_path_architecture_bits_default_name_
+   *   - _en_kevux_path_architecture_bits_default_length_
+   *   - _en_kevux_path_architecture_bits_scripts_name_
+   *   - _en_kevux_path_architecture_bits_scripts_length_
+   *
+   * The path separator should not be specified for these defines because it is automatically appended.
+   * Disable either the default or scripts by setting the length to 0.
+   *
+   * F_path_*_s:
+   *   - architecture_bits:          The architecture bits environment variable (usually is "ARCHITECTURE_BITS").
+   *   - architecture_bits_default:  The default architecture bits string with a trailing path separator, such as "x64/".
+   *   - architecture_bits_scripts:  The default architecture bits string with a trailing path separator, such as "scripts/".
+   */
+  #ifdef _en_kevux_path_architecture_bits_
+    #define F_path_architecture_bits_s "ARCHITECTURE_BITS"
+
+    #define F_path_architecture_bits_s_length 17
+
+    #if defined(_en_kevux_path_architecture_bits_default_name_) && defined(_en_kevux_path_architecture_bits_default_length_)
+      #if _en_kevux_path_architecture_bits_default_length_ == 0
+        #define F_path_architecture_bits_default_s F_string_empty_s
+
+        #define F_path_architecture_bits_default_s_length F_string_empty_s_length
+      #else
+        #define F_path_architecture_bits_default_s _en_kevux_path_architecture_bits_default_name_
+
+        #define F_path_architecture_bits_default_s_length _en_kevux_path_architecture_bits_default_length_ + F_path_separator_s_length
+      #endif // _en_kevux_path_architecture_bits_default_length_ == 0
+    #else
+      #define F_path_architecture_bits_default_s "x64" F_path_separator_s
+
+      #define F_path_architecture_bits_default_s_length 3 + F_path_separator_s_length
+    #endif // !defined(_en_kevux_path_architecture_bits_default_name_) || !defined(_en_kevux_path_architecture_bits_default_length_)
+
+    #if defined(_en_kevux_path_architecture_bits_scripts_name_) && defined(_en_kevux_path_architecture_bits_scripts_length_)
+      #if _en_kevux_path_architecture_bits_scripts_length_ == 0
+        #define F_path_architecture_bits_scripts_s F_string_empty_s
+
+        #define F_path_architecture_bits_scripts_s_length F_string_empty_s_length
+      #else
+        #define F_path_architecture_bits_scripts_s _en_kevux_path_architecture_bits_scripts_name_
+
+        #define F_path_architecture_bits_scripts_s_length _en_kevux_path_architecture_bits_scripts_length_ + F_path_separator_s_length
+      #endif // _en_kevux_path_architecture_bits_scripts_length_ == 0
+    #else
+      #define F_path_architecture_bits_scripts_s "scripts" F_path_separator_s
+
+      #define F_path_architecture_bits_scripts_s_length 7 + F_path_separator_s_length
+    #endif // !defined(_en_kevux_path_architecture_bits_scripts_name_) || !defined(_en_kevux_path_architecture_bits_scripts_length_)
+
+    extern const f_string_static_t f_path_architecture_bits_s;
+    extern const f_string_static_t f_path_architecture_bits_default_s;
+    extern const f_string_static_t f_path_architecture_bits_scripts_s;
+  #endif // _en_kevux_path_architecture_bits_
 #endif // _di_f_path_defines_
 
 /**
index c6653172ef1e71eb1aff738b1cbad4300feeacd6..817f61a2dcbebd719b43836ef95314f5d4db6a6b 100644 (file)
@@ -1,2 +1,7 @@
 # fss-0000
 
+_en_kevux_path_architecture_bits_ Enable Kevux architecture bits handling in PATH.
+_en_kevux_path_architecture_bits_default_name_ If defined, then this is a string representing the architecture bits (without the path separator "/") such as "x64".
+_en_kevux_path_architecture_bits_default_length_ If _en_kevux_path_architecture_bits_default_name_ is defined, then this must be defined as the string length of _en_kevux_path_architecture_bits_default_name_ (without the trailing NULL character), such as 3 for "x64". Set to 0 to disable _en_kevux_path_architecture_bits_default_name_ (preventing default).
+_en_kevux_path_architecture_bits_scripts_name_ If defined, then this is a string representing the architecture bits (without the path separator "/") such as "script".
+_en_kevux_path_architecture_bits_scripts_length_ If _en_kevux_path_architecture_bits_scripts_name_ is defined, then this must be defined as the string length of _en_kevux_path_architecture_bits_scripts_name_ (without the trailing NULL character), such as 7 for "scripts". Set to 0 to disable _en_kevux_path_architecture_bits_scripts_name_ (preventing default).
index f2abc4a778c33d6680aaa43c580a12abe0b925f9..e395a4de72bafeddf70a86ded162a31592caf545 100644 (file)
@@ -104,11 +104,63 @@ extern "C" {
     f_array_length_t first = 0;
     f_array_length_t total = 0;
 
+    // Do a quick pre-process of PATH to approximate the amount of parts needed, reducing the number of allocations.
     for (; i <= path.used; ++i) {
+      if (path.string[i] == f_path_separator_variable_s.string[0]) ++total;
+    } // for
 
-      if (i == path.used || path.string[i] == f_path_separator_variable_s.string[0]) {
-        status = f_string_dynamics_increase(F_memory_default_allocation_small_d, paths);
+    #ifdef _en_kevux_path_architecture_bits_
+      total *= 3;
+    #endif // _en_kevux_path_architecture_bits_
+
+    if (total) {
+      status = f_string_dynamics_increase_by(total, paths);
+      if (F_status_is_error(status)) return status;
+
+      total = 0;
+    }
+
+    #ifdef _en_kevux_path_architecture_bits_
+      f_string_dynamic_t architecture_bits = f_string_dynamic_t_initialize;
+
+      if (f_path_architecture_bits_s.used) {
+        status = f_environment_get(f_path_architecture_bits_s, &architecture_bits);
         if (F_status_is_error(status)) return status;
+      }
+
+      if (architecture_bits.used) {
+        status = f_string_dynamic_append_assure(f_path_separator_s, &architecture_bits);
+
+        if (F_status_is_error(status)) {
+          f_string_dynamic_resize(0, &architecture_bits);
+
+          return status;
+        }
+      } else if (!architecture_bits.used && f_path_architecture_bits_default_s.used) {
+        architecture_bits.string = f_path_architecture_bits_default_s.string;
+        architecture_bits.used = f_path_architecture_bits_default_s.used;
+        architecture_bits.size = f_path_architecture_bits_default_s.size;
+      }
+    #endif // _en_kevux_path_architecture_bits_
+
+    for (i = 0; i <= path.used; ++i) {
+
+      if (i == path.used || path.string[i] == f_path_separator_variable_s.string[0]) {
+        #ifdef _en_kevux_path_architecture_bits_
+          if (paths->used + 3 > paths->size) {
+            status = f_string_dynamics_increase(F_memory_default_allocation_small_d + 2, paths);
+          }
+        #else
+          status = f_string_dynamics_increase(F_memory_default_allocation_small_d, paths);
+        #endif // _en_kevux_path_architecture_bits_
+
+        if (F_status_is_error(status)) {
+          #ifdef _en_kevux_path_architecture_bits_
+            f_string_dynamic_resize(0, &architecture_bits);
+          #endif // _en_kevux_path_architecture_bits_
+
+          return status;
+        }
 
         if (!i) {
           paths->array[paths->used++].used = 0;
@@ -136,8 +188,51 @@ extern "C" {
             buffer[k++] = f_path_separator_s.string[0];
           }
 
+          #ifdef _en_kevux_path_architecture_bits_
+            if (f_path_architecture_bits_s.used) {
+              status = f_string_dynamic_increase_by(k + f_path_architecture_bits_s.used, &paths->array[paths->used]);
+
+              if (F_status_is_error(status)) {
+                #ifdef _en_kevux_path_architecture_bits_
+                  f_string_dynamic_resize(0, &architecture_bits);
+                #endif // _en_kevux_path_architecture_bits_
+
+                return status;
+              }
+
+              memcpy(paths->array[paths->used].string, buffer, sizeof(f_char_t) * k);
+              memcpy(paths->array[paths->used].string + k, architecture_bits.string, sizeof(f_char_t) * architecture_bits.used);
+
+              paths->array[paths->used++].used = k + architecture_bits.used;
+            }
+
+            if (f_path_architecture_bits_scripts_s.used) {
+              status = f_string_dynamic_increase_by(k + f_path_architecture_bits_scripts_s.used, &paths->array[paths->used]);
+
+              if (F_status_is_error(status)) {
+                #ifdef _en_kevux_path_architecture_bits_
+                  f_string_dynamic_resize(0, &architecture_bits);
+                #endif // _en_kevux_path_architecture_bits_
+
+                return status;
+              }
+
+              memcpy(paths->array[paths->used].string, buffer, sizeof(f_char_t) * k);
+              memcpy(paths->array[paths->used].string + k, f_path_architecture_bits_scripts_s.string, sizeof(f_char_t) * f_path_architecture_bits_scripts_s.used);
+
+              paths->array[paths->used++].used = k + f_path_architecture_bits_scripts_s.used;
+            }
+          #endif // _en_kevux_path_architecture_bits_
+
           status = f_string_dynamic_increase_by(k, &paths->array[paths->used]);
-          if (F_status_is_error(status)) return status;
+
+          if (F_status_is_error(status)) {
+            #ifdef _en_kevux_path_architecture_bits_
+              f_string_dynamic_resize(0, &architecture_bits);
+            #endif // _en_kevux_path_architecture_bits_
+
+            return status;
+          }
 
           memcpy(paths->array[paths->used].string, buffer, sizeof(f_char_t) * k);
 
@@ -151,6 +246,10 @@ extern "C" {
       }
     } // for
 
+    #ifdef _en_kevux_path_architecture_bits_
+      f_string_dynamic_resize(0, &architecture_bits);
+    #endif // _en_kevux_path_architecture_bits_
+
     return F_none;
   }
 #endif // _di_fl_environment_path_explode_
@@ -182,11 +281,63 @@ extern "C" {
     f_array_length_t last = path.used;
     f_array_length_t total = 0;
 
+    // Do a quick pre-process of PATH to approximate the amount of parts needed, reducing the number of allocations.
+    for (; i <= path.used; ++i) {
+      if (path.string[i] == f_path_separator_variable_s.string[0]) ++total;
+    } // for
+
+    #ifdef _en_kevux_path_architecture_bits_
+      total *= 3;
+    #endif // _en_kevux_path_architecture_bits_
+
+    if (total) {
+      status = f_string_dynamics_increase_by(total, paths);
+      if (F_status_is_error(status)) return status;
+
+      total = 0;
+    }
+
+    #ifdef _en_kevux_path_architecture_bits_
+      f_string_dynamic_t architecture_bits = f_string_dynamic_t_initialize;
+
+      if (f_path_architecture_bits_s.used) {
+        status = f_environment_get(f_path_architecture_bits_s, &architecture_bits);
+        if (F_status_is_error(status)) return status;
+      }
+
+      if (architecture_bits.used) {
+        status = f_string_dynamic_append_assure(f_path_separator_s, &architecture_bits);
+
+        if (F_status_is_error(status)) {
+          f_string_dynamic_resize(0, &architecture_bits);
+
+          return status;
+        }
+      } else if (!architecture_bits.used && f_path_architecture_bits_default_s.used) {
+        architecture_bits.string = f_path_architecture_bits_default_s.string;
+        architecture_bits.used = f_path_architecture_bits_default_s.used;
+        architecture_bits.size = f_path_architecture_bits_default_s.size;
+      }
+    #endif // _en_kevux_path_architecture_bits_
+
     for (; i <= path.used; ++i, --r) {
 
       if (i == path.used || path.string[r] == f_path_separator_variable_s.string[0]) {
-        status = f_string_dynamics_increase(F_memory_default_allocation_small_d, paths);
-        if (F_status_is_error(status)) return status;
+        #ifdef _en_kevux_path_architecture_bits_
+          if (paths->used + 3 > paths->size) {
+            status = f_string_dynamics_increase(F_memory_default_allocation_small_d + 2, paths);
+          }
+        #else
+          status = f_string_dynamics_increase(F_memory_default_allocation_small_d, paths);
+        #endif // _en_kevux_path_architecture_bits_
+
+        if (F_status_is_error(status)) {
+          #ifdef _en_kevux_path_architecture_bits_
+            f_string_dynamic_resize(0, &architecture_bits);
+          #endif // _en_kevux_path_architecture_bits_
+
+          return status;
+        }
 
         if (!i) {
           paths->array[paths->used++].used = 0;
@@ -214,8 +365,51 @@ extern "C" {
             buffer[k++] = f_path_separator_s.string[0];
           }
 
+          #ifdef _en_kevux_path_architecture_bits_
+            if (f_path_architecture_bits_s.used) {
+              status = f_string_dynamic_increase_by(k + f_path_architecture_bits_s.used, &paths->array[paths->used]);
+
+              if (F_status_is_error(status)) {
+                #ifdef _en_kevux_path_architecture_bits_
+                  f_string_dynamic_resize(0, &architecture_bits);
+                #endif // _en_kevux_path_architecture_bits_
+
+                return status;
+              }
+
+              memcpy(paths->array[paths->used].string, buffer, sizeof(f_char_t) * k);
+              memcpy(paths->array[paths->used].string + k, architecture_bits.string, sizeof(f_char_t) * architecture_bits.used);
+
+              paths->array[paths->used++].used = k + architecture_bits.used;
+            }
+
+            if (f_path_architecture_bits_scripts_s.used) {
+              status = f_string_dynamic_increase_by(k + f_path_architecture_bits_scripts_s.used, &paths->array[paths->used]);
+
+              if (F_status_is_error(status)) {
+                #ifdef _en_kevux_path_architecture_bits_
+                  f_string_dynamic_resize(0, &architecture_bits);
+                #endif // _en_kevux_path_architecture_bits_
+
+                return status;
+              }
+
+              memcpy(paths->array[paths->used].string, buffer, sizeof(f_char_t) * k);
+              memcpy(paths->array[paths->used].string + k, f_path_architecture_bits_scripts_s.string, sizeof(f_char_t) * f_path_architecture_bits_scripts_s.used);
+
+              paths->array[paths->used++].used = k + f_path_architecture_bits_scripts_s.used;
+            }
+          #endif // _en_kevux_path_architecture_bits_
+
           status = f_string_dynamic_increase_by(k, &paths->array[paths->used]);
-          if (F_status_is_error(status)) return status;
+
+          if (F_status_is_error(status)) {
+            #ifdef _en_kevux_path_architecture_bits_
+              f_string_dynamic_resize(0, &architecture_bits);
+            #endif // _en_kevux_path_architecture_bits_
+
+            return status;
+          }
 
           memcpy(paths->array[paths->used].string, buffer, sizeof(f_char_t) * k);
 
@@ -229,6 +423,10 @@ extern "C" {
       }
     } // for
 
+    #ifdef _en_kevux_path_architecture_bits_
+      f_string_dynamic_resize(0, &architecture_bits);
+    #endif // _en_kevux_path_architecture_bits_
+
     return F_none;
   }
 #endif // _di_fl_environment_path_explode_reverse_
index 532b18b715fb416895a6f97fe20662425c32c434..d0fa4fa380d78041314834cbc640cff6db7342fa 100644 (file)
@@ -111,9 +111,11 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  *
+ *   Errors (with error bit) from: f_environment_get() (only when _en_kevux_path_architecture_bits_ is defined).
  *   Errors (with error bit) from: f_string_dynamics_increase().
  *   Errors (with error bit) from: f_string_dynamics_increase_by().
  *
+ * @see f_environment_get()
  * @see f_string_dynamics_increase()
  * @see f_string_dynamics_increase_by()
  */
@@ -143,9 +145,11 @@ extern "C" {
  *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
  *
+ *   Errors (with error bit) from: f_environment_get() (only when _en_kevux_path_architecture_bits_ is defined).
  *   Errors (with error bit) from: f_string_dynamics_increase().
  *   Errors (with error bit) from: f_string_dynamics_increase_by().
  *
+ * @see f_environment_get()
  * @see f_string_dynamics_increase()
  * @see f_string_dynamics_increase_by()
  */
index c6653172ef1e71eb1aff738b1cbad4300feeacd6..16f2bfcffd428cf78109ebf24e058127a8657c10 100644 (file)
@@ -1,2 +1,3 @@
 # fss-0000
 
+_en_kevux_path_architecture_bits_ Enable Kevux architecture bits handling in PATH.
index c5cf3cf363f2356abee9261e1c1e2f43796b32b3..36050ee3419ac9dac1361671a355745217b03b5a 100644 (file)
@@ -318,7 +318,7 @@ extern "C" {
 
         if (F_status_is_error(status)) {
 
-          // Do not consider PATH is not available (or not valid?) to be an error.
+          // Do not consider PATH to be not available (or not valid?) to be an error.
           if (F_status_set_fine(status) == F_valid_not || F_status_set_fine(status) == F_failure) {
             status = F_none;
           }
index 649b88bf2ad3a0ce74e17f1b9b2940ec4abcd364..34b48fd24182d93cdd4449b94bf151e0dfdd6b92 100644 (file)
@@ -2,5 +2,6 @@
 
 _di_libcap_ Disable libcap support, allow for compiling and linking without libcap (-lcap).
 _di_thread_support_ Disable support for compiling and depending on pthreads (and projects like f_thread).
+
 _pthread_attr_unsupported_ Disable non-portable functionality associated with pthread_attr.
 _pthread_sigqueue_unsupported_ Disable GNU specific sigqueue().