]> Kevux Git Server - fll/commitdiff
Feature: Add Turtle Kevux path support.
authorKevin Day <kevin@kevux.org>
Sun, 12 Feb 2023 16:34:25 +0000 (10:34 -0600)
committerKevin Day <kevin@kevux.org>
Sun, 12 Feb 2023 16:34:25 +0000 (10:34 -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 ac0ea557c11bec844f8fbd6702e964e8c3abd948..374b0e8d7f4c8b2df46892849aa085037506cd8e 100644 (file)
@@ -36,6 +36,12 @@ extern "C" {
   #ifndef _di_f_path_present_working_old_s_
     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);
   #endif // _di_f_path_present_working_old_s_
+
+  #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_d_
 
 #if defined(_di_f_path_tree_s_) && !defined(_di_f_path_tree_hierarchy_standard_d_) && !defined(_di_f_path_tree_kevux_standard_d_)
index 238f9a7b714c3e719abb2223b57fb45dc677a183..be969da1bff20419752936c95e6296f6dfcb67a2 100644 (file)
@@ -92,6 +92,67 @@ extern "C" {
   #ifndef _di_f_path_present_working_old_s_
     extern const f_string_static_t f_path_present_working_old_s;
   #endif // _di_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_s_
 
 /**
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 95325dcfeb5399c1d8d832b213007ab047b79f2a..53dd33929cc6f2fd74fd847a5a5cbe407877709c 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().