The environment loading functionality is likely to be very common.
Create fll_environment (because it depends on fl_string) and provide the environment variable loading functionality.
Replace the related code from Featureless Make to use the code from fll_environment.
Instead of using two string arrays, use an array of string maps for the environment.
Make the appropriate changes in all affected projects.
Add the fll_execute_as() function to perform an execution without a fork() operation.
This will become important once I write the f_asynchronous and related projects.
A new execute parameter option fl_execute_parameter_option_fixated is introduced to allow for execution without automatically prepending the program name at index 0.
There are existing projects that have to reconstruct an array to meet the structure of the execute functions (which then reconstructs the array again...essentially back to how it started).
This is a bit ridiculous and an artifact of the previous design.
With this new execute parameter option, the array is not reconstructed and assumed to be correct.
The controller program now sets the environment variables on the executed process (which currently only script execution is written).
build_language c
build_libraries -lc
build_libraries-level -lfll_1 -lfll_0
-build_sources_library error.c private-error.c execute.c private-execute.c file.c private-file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_embedded_list.c fss_extended.c fss_extended_list.c fss_status.c iki.c private-iki.c path.c program.c status.c
+build_sources_library environment.c error.c private-error.c execute.c private-execute.c file.c private-file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_embedded_list.c fss_extended.c fss_extended_list.c fss_status.c iki.c private-iki.c path.c program.c status.c
build_sources_program
-build_sources_headers error.h error-common.h execute.h file.h fss.h fss_basic.h fss_basic_list.h fss_embedded_list.h fss_extended.h fss_extended_list.h fss_status.h iki.h path.h program.h status.h
+build_sources_headers environment.h error.h error-common.h execute.h file.h fss.h fss_basic.h fss_basic_list.h fss_embedded_list.h fss_extended.h fss_extended_list.h fss_status.h iki.h path.h program.h status.h
build_sources_script
build_sources_setting
build_script yes
build_language c
build_libraries -lc
build_libraries-monolithic
-build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/private-print.c level_0/process.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_embedded_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/private-print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/type.c level_1/private-type.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/error.c level_2/private-error.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_embedded_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/iki.c level_2/private-iki.c level_2/path.c level_2/program.c level_2/status.c
+build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/private-print.c level_0/process.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_embedded_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/private-print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/type.c level_1/private-type.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/environment.c level_2/error.c level_2/private-error.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_embedded_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/iki.c level_2/private-iki.c level_2/path.c level_2/program.c level_2/status.c
build_sources_program
-build_sources_headers level_0/account.h level_0/account-common.h level_0/color.h level_0/console.h level_0/console-common.h level_0/conversion.h level_0/conversion-common.h level_0/directory.h level_0/directory_type.h level_0/directory-common.h level_0/environment.h level_0/environment-common.h level_0/execute.h level_0/execute-common.h level_0/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.h level_0/fss_comment.h level_0/fss_delimit.h level_0/fss_named.h level_0/fss_nest.h level_0/fss_quote.h level_0/fss_set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory_structure.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.h level_0/process.h level_0/process-common.h level_0/serialize.h level_0/serialize-common.h level_0/signal.h level_0/signal-common.h level_0/socket.h level_0/socket-common.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string-common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/string_triple.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/execute.h level_1/execute-common.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_embedded_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/type.h level_1/utf.h level_1/utf_file.h level_2/error.h level_2/error-common.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_embedded_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/program.h level_2/status.h
+build_sources_headers level_0/account.h level_0/account-common.h level_0/color.h level_0/console.h level_0/console-common.h level_0/conversion.h level_0/conversion-common.h level_0/directory.h level_0/directory_type.h level_0/directory-common.h level_0/environment.h level_0/environment-common.h level_0/execute.h level_0/execute-common.h level_0/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.h level_0/fss_comment.h level_0/fss_delimit.h level_0/fss_named.h level_0/fss_nest.h level_0/fss_quote.h level_0/fss_set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory_structure.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.h level_0/process.h level_0/process-common.h level_0/serialize.h level_0/serialize-common.h level_0/signal.h level_0/signal-common.h level_0/socket.h level_0/socket-common.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string-common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/string_triple.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/execute.h level_1/execute-common.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_embedded_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/type.h level_1/utf.h level_1/utf_file.h level_2/environment.h level_2/error.h level_2/error-common.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_embedded_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/program.h level_2/status.h
build_sources_script
build_sources_setting
build_script yes
bash build/scripts/package.sh $verbose $color build -i
if [[ $? -eq 0 ]] ; then
- for i in f_type f_status f_memory f_string f_utf f_account f_color f_console f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_path f_pipe f_print f_process f_serialize f_signal f_socket fl_color fl_console fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_print fl_status fl_string fl_type fl_utf fl_utf_file fll_error fll_execute fll_file fll_fss fll_iki fll_path fll_program fll_status ; do
+ for i in f_type f_status f_memory f_string f_utf f_account f_color f_console f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_path f_pipe f_print f_process f_serialize f_signal f_socket fl_color fl_console fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_print fl_status fl_string fl_type fl_utf fl_utf_file fll_environment fll_error fll_execute fll_file fll_fss fll_iki fll_path fll_program fll_status ; do
echo && echo "Processing $i." &&
cd package/individual/$i-$2/ &&
* A structure for containing additional parameters for the execute functions that call the execv() family of functions.
*
* bitwise options:
- * fl_execute_parameter_option_exit: use to desginate to exit after calling child otherwise child process will return.
- * fl_execute_parameter_option_path: use to designate that this is a path to a program (such as '/bin/bash').
+ * fl_execute_parameter_option_exit: used to desginate to exit after calling child otherwise child process will return.
+ * fl_execute_parameter_option_fixated: used to designate that the program is already fixated in index 0 of the arguments array.
+ * fl_execute_parameter_option_path: used to designate that this is a path to a program (such as '/bin/bash').
*
- * option: accepts the bitwise options
- * names: the environment variable names, should have the same number of elements as values, set to 0 to not use.
- * values: the environment variable values, should have the same number of elements as names, set to 0 to not use.
- * signals: the set of signals the child process should or should block, set to 0 to not use.
- * data: the data to pipe to the child process, set to 0 to not use.
+ * option: accepts the bitwise options
+ * environment: the environment variable name and value pairs, set to 0 to not use.
+ * signals: the set of signals the child process should or should block, set to 0 to not use.
+ * data: the data to pipe to the child process, set to 0 to not use.
*/
#ifndef _di_fl_execute_parameter_t_
- #define fl_execute_parameter_option_exit 0x1
- #define fl_execute_parameter_option_path 0x2
+ #define fl_execute_parameter_option_exit 0x1
+ #define fl_execute_parameter_option_fixated 0x2
+ #define fl_execute_parameter_option_path 0x4
typedef struct {
uint8_t option;
- const f_string_statics_t *names;
- const f_string_statics_t *values;
+ const f_string_maps_t *environment;
const f_signal_how_t *signals;
const f_string_static_t *data;
} fl_execute_parameter_t;
- #define fl_execute_parameter_t_initialize { 0, 0, 0, 0, 0 }
+ #define fl_execute_parameter_t_initialize { 0, 0, 0, 0 }
- #define fl_macro_execute_parameter_t_initialize(option, names, values, signals, data) { option, names, values, signals, data }
+ #define fl_macro_execute_parameter_t_initialize(option, environment, signals, data) { option, environment, signals, data }
#define fl_execute_parameter_t_clear(set) \
set.option = 0; \
- set.names = 0; \
- set.values = 0; \
+ set.environment = 0; \
set.signals = 0; \
set.data = 0;
#endif // _di_fl_execute_parameter_t_
--- /dev/null
+#include "environment.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fll_environment_load_name_
+ f_return_status fll_environment_load_name(const f_string_t name, const f_string_length_t length, f_string_maps_t *environment) {
+ #ifndef _di_level_2_parameter_checking_
+ if (!name) return F_status_set_error(F_parameter);
+ if (!environment) return F_status_set_error(F_parameter);
+ #endif // _di_level_2_parameter_checking_
+
+ if (!length) {
+ return F_data_not;
+ }
+
+ f_status_t status = fl_string_maps_increase(environment);
+ if (F_status_is_error(status)) return status;
+
+ environment->array[environment->used].name.used = 0;
+ environment->array[environment->used].value.used = 0;
+
+ const f_string_static_t name_string = f_macro_string_static_t_initialize(name, length);
+
+ status = fl_string_dynamic_append_nulless(name_string, &environment->array[environment->used].name);
+ if (F_status_is_error(status)) return status;
+
+ status = f_environment_get_dynamic(name_string, &environment->array[environment->used].value);
+
+ if (F_status_is_error(status)) {
+ environment->array[environment->used].name.used = 0;
+ return status;
+ }
+
+ if (status == F_data_not || status == F_exist_not) {
+ environment->array[environment->used].name.used = 0;
+ return status;
+ }
+
+ environment->used++;
+
+ return F_none;
+ }
+#endif // _di_fll_environment_load_name_
+
+#ifndef _di_fll_environment_load_names_
+ f_return_status fll_environment_load_names(const f_string_dynamics_t names, f_string_maps_t *environment) {
+ #ifndef _di_level_2_parameter_checking_
+ if (!environment) return F_status_set_error(F_parameter);
+ #endif // _di_level_2_parameter_checking_
+
+ if (!names.used) {
+ return F_data_not;
+ }
+
+ f_status_t status = fl_string_maps_increase_by(names.used, environment);
+ if (F_status_is_error(status)) return status;
+
+ for (f_array_length_t i = 0; i < names.used; ++i) {
+
+ environment->array[environment->used].name.used = 0;
+ environment->array[environment->used].value.used = 0;
+
+ status = fl_string_dynamic_append_nulless(names.array[i], &environment->array[environment->used].name);
+ if (F_status_is_error(status)) return status;
+
+ status = f_environment_get_dynamic(names.array[i], &environment->array[environment->used].value);
+
+ if (F_status_is_error(status)) {
+ environment->array[environment->used].name.used = 0;
+ return status;
+ }
+
+ if (status == F_data_not || status == F_exist_not) {
+ environment->array[environment->used].name.used = 0;
+ continue;
+ }
+
+ environment->used++;
+ } // for
+
+ return F_none;
+ }
+#endif // _di_fll_environment_load_names_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 2
+ *
+ * Project: Environment
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * Provides environment-related functionality.
+ */
+#ifndef _FLL_environment_h
+#define _FLL_environment_h
+
+// libc includes
+#include <stdio.h>
+
+// fll-0 includes
+#include <level_0/type.h>
+#include <level_0/status.h>
+#include <level_0/memory.h>
+#include <level_0/string.h>
+#include <level_0/environment.h>
+
+// fll-1 includes
+#include <level_1/string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Append the given environment variable name and value pair into the given map.
+ *
+ * If the environment variable name is not found, then it is not added to the map.
+ * If the environment variable name is found but has an empty value, then it is added to the map with an empty value.
+ *
+ * This does not check for uniqueness in the map.
+ *
+ * @param name
+ * A string representing the environment variable name.
+ * @param length
+ * The length of the environment variable name string.
+ * @param environment
+ * An array of maps generated from the loaded environment variable names.
+ *
+ * @return
+ * F_none on success.
+ * F_data_not if name length is 0.
+ * F_exist_not if name does not exist.
+ *
+ * Errors (with error bit) from: f_environment_get_dynamic().
+ * Errors (with error bit) from: fl_string_dynamic_append_nulless().
+ * Errors (with error bit) from: fl_string_maps_increase_by().
+ *
+ * @see f_environment_get_dynamic()
+ * @see fl_string_dynamic_append_nulless()
+ * @see fl_string_maps_increase_by()
+ */
+#ifndef _di_fll_environment_load_name_
+ extern f_return_status fll_environment_load_name(const f_string_t name, const f_string_length_t length, f_string_maps_t *environment);
+#endif // _di_fll_environment_load_name_
+
+/**
+ * Append the given environment variable name and value pairs into the given map.
+ *
+ * If the environment variable name is not found, then it is not added to the map.
+ * If the environment variable name is found but has an empty value, then it is added to the map with an empty value.
+ *
+ * This does not check for uniqueness in the map.
+ *
+ * @param names
+ * An array of valid environment variable names.
+ * @param environment
+ * An array of maps generated from the loaded environment variable names.
+ * All environment names loaded are appended to this.
+ *
+ * @return
+ * F_none on success.
+ * F_data_not if names.used is 0.
+ *
+ * Errors (with error bit) from: f_environment_get_dynamic().
+ * Errors (with error bit) from: fl_string_dynamic_append_nulless().
+ * Errors (with error bit) from: fl_string_maps_increase_by().
+ *
+ * @see f_environment_get_dynamic()
+ * @see fl_string_dynamic_append_nulless()
+ * @see fl_string_maps_increase_by()
+ */
+#ifndef _di_fll_environment_load_names_
+ extern f_return_status fll_environment_load_names(const f_string_dynamics_t names, f_string_maps_t *environment);
+#endif // _di_fll_environment_load_names_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _FLL_environment_h
--- /dev/null
+# fss-0000
+
--- /dev/null
+# fss-0000
+
+f_type
+f_status
+f_memory
+f_string
+f_environment
+fl_string
--- /dev/null
+# fss-0001
+
+project_name fll_environment
+
+version_major 0
+version_minor 5
+version_micro 2
+version_target major
+
+environment
+
+process_pre
+process_post
+
+modes individual
+modes_default individual
+
+build_compiler gcc
+build_indexer ar
+build_language c
+build_libraries -lc
+build_libraries-individual -lfl_string -lf_environment -lf_memory -lf_utf
+build_sources_library environment.c
+build_sources_program
+build_sources_headers environment.h
+build_sources_script
+build_sources_setting
+build_script yes
+build_shared yes
+build_static yes
+
+path_headers level_2
+path_headers_preserve no
+path_library_script script
+path_library_shared shared
+path_library_static static
+path_program_script script
+path_program_shared shared
+path_program_static static
+path_sources
+path_standard yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines_all
+defines_static
+defines_shared
+
+flags_all -z now -g -fdiagnostics-color=always
+flags_shared
+flags_static
+flags_library -fPIC
+flags_program -fPIE
}
#endif // _di_fll_execute_arguments_dynamic_add_set_
+#ifndef _di_fll_execute_into_
+ f_return_status fll_execute_into(const f_string_t program, const f_string_statics_t arguments, const uint8_t option, int *result) {
+ #ifndef _di_level_2_parameter_checking_
+ if (!result) return F_status_set_error(F_parameter);
+ #endif // _di_level_2_parameter_checking_
+
+ // create a string array that is compatible with execv() calls.
+ f_string_t fixed_arguments[arguments.used + 2];
+
+ const f_string_t last_slash = strrchr(program, f_path_separator_s[0]);
+ const f_string_length_t name_size = last_slash ? strnlen(last_slash, f_path_max) : strnlen(program, f_path_max);
+
+ char program_name[name_size + 1];
+
+ program_name[name_size] = 0;
+
+ private_fll_execute_path_arguments_fixate(last_slash ? last_slash : program, arguments, option, name_size, program_name, fixed_arguments);
+
+ const int code = option & fl_execute_parameter_option_path ? execv(program, fixed_arguments) : execvp(program, fixed_arguments);
+
+ // generally this does not return, but in some cases (such as with scripts) this does return so handle the results.
+ if (result) {
+ *result = code;
+ }
+
+ if (option & fl_execute_parameter_option_exit) {
+ exit(code);
+ }
+
+ if (code) {
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_fll_execute_into_
+
#ifndef _di_fll_execute_program_
f_return_status fll_execute_program(const f_string_t program, const f_string_statics_t arguments, fl_execute_parameter_t * const parameter, int *result) {
#ifndef _di_level_2_parameter_checking_
if (!result) return F_status_set_error(F_parameter);
-
- if (parameter && parameter->names) {
- if (!parameter->values || parameter->names->used != parameter->values->used) {
- return F_status_set_error(F_parameter);
- }
- }
#endif // _di_level_2_parameter_checking_
// create a string array that is compatible with execv() calls.
program_name[name_size] = 0;
- private_fll_execute_path_arguments_fixate(last_slash ? last_slash : program, arguments, name_size, program_name, fixed_arguments);
+ private_fll_execute_path_arguments_fixate(last_slash ? last_slash : program, arguments, parameter->option, name_size, program_name, fixed_arguments);
// when the environment is to be cleared, a full path must be used.
- if (parameter && !(parameter->option & fl_execute_parameter_option_path) && parameter->names) {
+ if (parameter && !(parameter->option & fl_execute_parameter_option_path) && parameter->environment) {
f_string_dynamic_t path = f_string_dynamic_t_initialize;
f_string_dynamics_t paths = f_string_dynamics_t_initialize;
return status;
}
- f_macro_string_dynamic_t_delete(status, path);
+ status = fl_string_dynamic_delete(&path);
if (F_status_is_error(status)) {
f_macro_string_dynamics_t_delete_simple(paths);
/**
* Execute a program given by program name found in the PATH environment (such as "bash") or program path (such as "/bin/bash").
*
+ * The program will be executed directly and not via a child process.
+ *
+ * Because this directly executes a program, it potentially may not return.
+ * If and when it does, the executed program is finished executing (be it failure or success).
+ * Often times scripts may return and binaries may not.
+ *
+ * @param program
+ * The name or path of the program.
+ * @param arguments
+ * An array of strings representing the arguments.
+ * @param option
+ * A bitwise set of options, such as: fl_execute_parameter_option_exit, and fl_execute_parameter_option_path.
+ * If fl_execute_parameter_option_exit: this will call exit() at the end of execution (be it success or failure).
+ * If fl_execute_parameter_option_path: this is a program path (such as "/bin/bash"), otherwise this is a program (such as "bash").
+ * If fl_execute_parameter_option_fixated: this is a program path is already in the arguments at index 0.
+ * @param result
+ * The code returned after finishing execution of program.
+ *
+ * @return
+ * F_none on success.
+ * F_failure (with error bit) on execution failure.
+ *
+ * @see execv()
+ * @see execvp()
+ * @see exit()
+ * @see memcpy()
+ * @see strnlen()
+ */
+#ifndef _di_fll_execute_into_
+ extern f_return_status fll_execute_into(const f_string_t program, const f_string_statics_t arguments, const uint8_t option, int *result);
+#endif // _di_fll_execute_into_
+
+/**
+ * Execute a program given by program name found in the PATH environment (such as "bash") or program path (such as "/bin/bash").
+ *
+ * The program will be executed via a forked child process.
+ *
* If parameter.names is specified:
* Uses the provided environment array to designate the environment for the program being executed.
* The environment is defined by the names and values pair.
* @param arguments
* An array of strings representing the arguments.
* @param parameter
- * (optional) This and each of its fields are optional and are disabled when set to 0.
+ * (optional) This and most of its fields are optional and are disabled when set to 0.
+ * option:
+ * A bitwise set of options, such as: fl_execute_parameter_option_exit, and fl_execute_parameter_option_path.
* names:
* An array of strings representing the environment variable names.
* At most names.used variables are created.
*
* Errors (with error bit) from: f_environment_get().
* Errors (with error bit) from: f_file_exists().
- * Errors (with error bit) from: f_macro_string_dynamic_t_delete().
* Errors (with error bit) from: f_macro_string_dynamics_t_delete().
* Errors (with error bit) from: f_signal_set_handle().
* Errors (with error bit) from: fl_environment_path_explode_dynamic().
* Errors (with error bit) from: fl_string_append().
+ * Errors (with error bit) from: fl_string_dynamic_delete().
* Errors (with error bit) from: fl_string_dynamic_terminate().
*
* @see close()
if (F_status_is_error(status)) {
fl_string_dynamic_delete(&argument);
+
return status;
}
}
if (F_status_is_error(status)) {
fl_string_dynamic_delete(&argument);
+
return status;
}
}
if (F_status_is_error(status)) {
fl_string_dynamic_delete(&argument);
+
return status;
}
if (F_status_is_error(status)) {
fl_string_dynamic_delete(&argument);
+
return status;
}
}
if (F_status_is_error(status)) {
fl_string_dynamic_delete(&argument);
+
return status;
}
if (F_status_is_error(status)) {
fl_string_dynamic_delete(&argument);
+
return status;
}
f_signal_set_handle(SIG_UNBLOCK, ¶meter->signals->block_not);
}
- if (parameter && parameter->names) {
+ if (parameter && parameter->environment) {
clearenv();
- for (f_array_length_t i = 0; i < parameter->names->used && i < parameter->values->used; i++) {
- f_environment_set_dynamic(parameter->names->array[i], parameter->values->array[i], F_true);
+ for (f_array_length_t i = 0; i < parameter->environment->used; i++) {
+ f_environment_set_dynamic(parameter->environment->array[i].name, parameter->environment->array[i].value, F_true);
} // for
}
f_signal_set_handle(SIG_UNBLOCK, ¶meter->signals->block_not);
}
- if (parameter && parameter->names) {
+ if (parameter && parameter->environment) {
clearenv();
- for (f_array_length_t i = 0; i < parameter->names->used && i < parameter->values->used; i++) {
- f_environment_set_dynamic(parameter->names->array[i], parameter->values->array[i], F_true);
+ for (f_array_length_t i = 0; i < parameter->environment->used; i++) {
+ f_environment_set_dynamic(parameter->environment->array[i].name, parameter->environment->array[i].value, F_true);
} // for
}
#endif // !defined(_di_fll_execute_program_)
#if !defined(_di_fll_execute_program_)
- void private_fll_execute_path_arguments_fixate(const f_string_t program_path, const f_string_statics_t arguments, const f_string_length_t name_size, char program_name[], f_string_t fixed_arguments[]) {
+ void private_fll_execute_path_arguments_fixate(const f_string_t program_path, const f_string_statics_t arguments, const uint8_t option, const f_string_length_t name_size, char program_name[], f_string_t fixed_arguments[]) {
+
+ if (option & fl_execute_parameter_option_fixated) {
- memcpy(program_name, program_path, name_size);
- program_name[name_size] = 0;
+ for (f_string_length_t i = 0; i < arguments.used; i++) {
+ fixed_arguments[i] = arguments.array[i].string;
+ } // for
- if (name_size) {
- fixed_arguments[0] = program_name;
+ // insert the required end of array designator.
+ fixed_arguments[arguments.used] = 0;
}
else {
- fixed_arguments[0] = 0;
- }
+ memcpy(program_name, program_path, name_size);
+ program_name[name_size] = 0;
- for (f_string_length_t i = 0; i < arguments.used; i++) {
- fixed_arguments[i + 1] = arguments.array[i].string;
- } // for
+ if (name_size) {
+ fixed_arguments[0] = program_name;
+ }
+ else {
+ fixed_arguments[0] = 0;
+ }
+
+ for (f_string_length_t i = 0; i < arguments.used; i++) {
+ fixed_arguments[i + 1] = arguments.array[i].string;
+ } // for
+ }
// insert the required end of array designator.
fixed_arguments[arguments.used + 1] = 0;
* @param arguments
* An array of strings representing the arguments.
* @param parameter
- * (optional) This and each of its fields are optional and are disabled when set to 0.
+ * (optional) This and most of its fields are optional and are disabled when set to 0.
+ * option:
+ * A bitwise set of options, such as: fl_execute_parameter_option_exit, and fl_execute_parameter_option_path.
* names:
* An array of strings representing the environment variable names.
* At most names.used variables are created.
* @param arguments
* An array of strings representing the arguments.
* @param parameter
- * (optional) This and each of its fields are optional and are disabled when set to 0.
+ * (optional) This and most of its fields are optional and are disabled when set to 0.
+ * option:
+ * A bitwise set of options, such as: fl_execute_parameter_option_exit, and fl_execute_parameter_option_path.
* names:
* An array of strings representing the environment variable names.
* At most names.used variables are created.
* The part of the path to the program representing the program name to copy from.
* @param arguments
* An array of strings representing the arguments.
+ * @param option
+ * The bitwise option from fl_execute_parameter_t.option.
+ * This only cares about fl_execute_parameter_option_fixated.
* @param name_size
* The size of the program_path to copy.
* @param program_name
* @see fll_execute_program()
*/
#if !defined(_di_fll_execute_program_)
- extern void private_fll_execute_path_arguments_fixate(const f_string_t program_path, const f_string_statics_t arguments, const f_string_length_t name_size, char program_name[], f_string_t fixed_arguments[]) f_gcc_attribute_visibility_internal;
+ extern void private_fll_execute_path_arguments_fixate(const f_string_t program_path, const f_string_statics_t arguments, const uint8_t option, const f_string_length_t name_size, char program_name[], f_string_t fixed_arguments[]) f_gcc_attribute_visibility_internal;
#endif // !defined(_di_fll_execute_program_)
#ifdef __cplusplus
} // for
if (ripped.size) {
- f_macro_string_dynamic_t_delete(status, ripped);
+ status = fl_string_dynamic_delete(&ripped);
}
if (status == F_none && start == destination->used) {
#include <level_0/color.h>
#include <level_0/console.h>
#include <level_0/directory.h>
+#include <level_0/environment.h>
#include <level_0/execute.h>
#include <level_0/file.h>
#include <level_0/fss.h>
#include <level_1/type.h>
// fll-2 includes
+#include <level_2/environment.h>
#include <level_2/error.h>
#include <level_2/execute.h>
#include <level_2/fss.h>
#define controller_string_parameter "parameter"
#define controller_string_path "path"
#define controller_string_pid "pid"
+ #define controller_string_program "program"
#define controller_string_ready "ready"
#define controller_string_reload "reload"
#define controller_string_require "require"
#define controller_string_parameter_length 9
#define controller_string_path_length 4
#define controller_string_pid_length 3
+ #define controller_string_program_length 7
#define controller_string_ready_length 5
#define controller_string_reload_length 6
#define controller_string_require_length 7
}
#endif // _di_controller_rule_error_print_
-#ifndef _di_controller_rule_error_need_want_wish_print_
- void controller_rule_error_need_want_wish_print(const fll_error_print_t output, const f_string_t need_want_wish, const f_string_t value, const f_string_t why) {
+#ifndef _di_controller_rule_error_print_execute_
+ void controller_rule_error_print_execute(const fll_error_print_t output, const bool program_is, const f_string_t name, const int code) {
+
+ if (output.verbosity != f_console_verbosity_quiet) {
+ fprintf(output.to.stream, "%c", f_string_eol_s[0]);
+ fprintf(output.to.stream, "%s%sThe %s '", output.context.before->string, output.prefix ? output.prefix : f_string_empty_s, program_is ? controller_string_program : controller_string_script);
+ fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, name ? name : f_string_empty_s, output.notable.after->string);
+ fprintf(output.to.stream, "%s' failed with the exit code '", output.context.before->string);
+ fprintf(output.to.stream, "%s%s%d%s", output.context.after->string, output.notable.before->string, code, output.notable.after->string);
+ fprintf(output.to.stream, "%s'.%s%c", output.context.before->string, output.context.after->string, f_string_eol_s[0]);
+ }
+ }
+#endif // _di_controller_rule_error_print_execute_
+
+#ifndef _di_controller_rule_error_print_need_want_wish_
+ void controller_rule_error_print_need_want_wish(const fll_error_print_t output, const f_string_t need_want_wish, const f_string_t value, const f_string_t why) {
if (output.verbosity != f_console_verbosity_quiet) {
fprintf(output.to.stream, "%c", f_string_eol_s[0]);
fprintf(output.to.stream, "%s' %s.%s%c", output.context.before->string, why, output.context.after->string, f_string_eol_s[0]);
}
}
-#endif // _di_controller_rule_error_need_want_wish_print_
+#endif // _di_controller_rule_error_print_need_want_wish_
#ifndef _di_controller_rule_execute_
f_return_status controller_rule_execute(const controller_cache_t cache, const f_array_length_t index, const uint8_t type, controller_data_t *data, controller_setting_t *setting) {
controller_rule_item_t *item = 0;
controller_rule_action_t *action = 0;
+ // child processes should receive all signals, without blocking.
+ f_signal_how_t signals = f_signal_how_t_initialize;
+ f_signal_set_empty(&signals.block);
+ f_signal_set_fill(&signals.block_not);
+
+ f_string_maps_t environment = f_string_maps_t_initialize;
+
+ const f_string_dynamics_t arguments_none = f_string_dynamics_t_initialize;
+ fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(0, &environment, &signals, 0);
+
+ status = fll_environment_load_names(setting->rules.array[index].environment, &environment);
+
+ if (F_status_is_error(status)) {
+ fll_error_print(data->error, F_status_set_fine(status), "fll_environment_load_names", F_true);
+ return status;
+ }
+
for (i = 0; i < setting->rules.array[index].items.used; ++i) {
if (setting->rules.array[index].items.array[i].type == controller_rule_item_type_setting) continue;
action = &item->actions.array[j];
status = F_none;
+ parameter.data = 0;
+ parameter.option = 0;
+
if (item->type == controller_rule_item_type_command) {
if (action->method == controller_rule_action_method_extended) {
// @todo
}
}
else if (item->type == controller_rule_item_type_script) {
- status = controller_rule_execute_script(*action, 0, data);
+ parameter.data = &action->parameters.array[0];
+
+ status = controller_rule_execute_script(*action, 0, arguments_none, ¶meter, data);
if (F_status_is_error(status)) break;
}
else if (item->type == controller_rule_item_type_service) {
if (action->method == controller_rule_action_method_extended) {
- // @todo
+ // @todo
}
else {
// @todo extended list execution.
#endif // _di_controller_rule_execute_
#ifndef _di_controller_rule_execute_script_
- f_return_status controller_rule_execute_script(const controller_rule_action_t action, const uint8_t options, controller_data_t *data) {
-
- // child processes should receive all signals, without blocking.
- f_signal_how_t signals = f_signal_how_t_initialize;
- f_signal_set_empty(&signals.block);
- f_signal_set_fill(&signals.block_not);
-
+ f_return_status controller_rule_execute_script(const controller_rule_action_t action, const uint8_t options, const f_string_dynamics_t arguments, fl_execute_parameter_t * const parameter, controller_data_t *data) {
int result = 0;
- const f_string_dynamics_t arguments = f_string_dynamics_t_initialize;
- fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(0, 0, 0, &signals, action.parameters.used ? &action.parameters.array[0] : 0);
-
// @todo script program (such as: "bash") should be configurable somehow (a new entry setting? a new rule setting? both?).
- // @todo have the environment variables built before executing the script and then instead call fll_execute_program_environment() for all execute functions (with environment.names, environment.values).
- f_status_t status = fll_execute_program(controller_string_bash, arguments, ¶meter, &result);
+ f_status_t status = fll_execute_program(controller_string_bash, arguments, parameter, &result);
if (status == F_child) {
data->child = result;
return F_child;
}
- // @todo handle errors, print messages, etc..
if (result != 0) {
+ controller_rule_error_print_execute(data->error, F_false, controller_string_bash, result);
+
status = F_status_set_error(F_failure);
}
else if (F_status_is_error(status)) {
fll_error_print(data->error, F_status_set_fine(status), "fll_execute_program_environment", F_true);
- return status;
}
data->child = 0;
if (at == setting->rules.used) {
if (i == 0) {
- controller_rule_error_need_want_wish_print(data->error, strings[i], dynamics[i]->array[j].string, "was not found");
+ controller_rule_error_print_need_want_wish(data->error, strings[i], dynamics[i]->array[j].string, "was not found");
status = F_status_set_error(F_found_not);
controller_rule_error_print(data->error, *cache, F_true);
}
else {
if (data->warning.verbosity == f_console_verbosity_debug) {
- controller_rule_error_need_want_wish_print(data->warning, strings[i], dynamics[i]->array[j].string, "was not found");
+ controller_rule_error_print_need_want_wish(data->warning, strings[i], dynamics[i]->array[j].string, "was not found");
controller_rule_error_print(data->warning, *cache, F_true);
}
}
if (F_status_is_error(status)) {
if (i == 0 || i == 1 || F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
- controller_rule_error_need_want_wish_print(data->error, strings[i], dynamics[i]->array[j].string, "failed during execution");
+ controller_rule_error_print_need_want_wish(data->error, strings[i], dynamics[i]->array[j].string, "failed during execution");
controller_rule_error_print(data->error, *cache, F_true);
if (!(options & controller_rule_option_simulate) || F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
}
else {
if (data->warning.verbosity == f_console_verbosity_debug) {
- controller_rule_error_need_want_wish_print(data->warning, strings[i], dynamics[i]->array[j].string, "failed during execution");
+ controller_rule_error_print_need_want_wish(data->warning, strings[i], dynamics[i]->array[j].string, "failed during execution");
controller_rule_error_print(data->warning, *cache, F_true);
}
}
else if (F_status_is_error(setting->rules.array[at].status)) {
if (i == 0 || i == 1) {
- controller_rule_error_need_want_wish_print(data->error, strings[i], dynamics[i]->array[j].string, "is in a failed state");
+ controller_rule_error_print_need_want_wish(data->error, strings[i], dynamics[i]->array[j].string, "is in a failed state");
status = F_status_set_error(F_found_not);
controller_rule_error_print(data->error, *cache, F_true);
}
else {
if (data->warning.verbosity == f_console_verbosity_debug) {
- controller_rule_error_need_want_wish_print(data->warning, strings[i], dynamics[i]->array[j].string, "is in a failed state");
+ controller_rule_error_print_need_want_wish(data->warning, strings[i], dynamics[i]->array[j].string, "is in a failed state");
controller_rule_error_print(data->warning, *cache, F_true);
}
}
#endif // _di_controller_rule_error_print_
/**
+ * Print an error or warning message related to the failed execution of some program or script.
+ *
+ * @param output
+ * The error or warning output structure.
+ * @param program_is
+ * If TRUE, then this represents a program.
+ * If FALSE, then this represents a script.
+ * @param name
+ * The name of the program or script.
+ * @param code
+ * The code returned by the executed program or script.
+ */
+#ifndef _di_controller_rule_error_print_execute_
+ extern void controller_rule_error_print_execute(const fll_error_print_t output, const bool program_is, const f_string_t name, const int code) f_gcc_attribute_visibility_internal;
+#endif // _di_controller_rule_error_print_execute_
+
+/**
* Print an error or warning message related to need/want/wish settings of some rule.
*
* @param output
* @param why
* A short explanation on why this is an error or warning.
*/
-#ifndef _di_controller_rule_error_need_want_wish_print_
- extern void controller_rule_error_need_want_wish_print(const fll_error_print_t output, const f_string_t need_want_wish, const f_string_t value, const f_string_t why) f_gcc_attribute_visibility_internal;
-#endif // _di_controller_rule_error_need_want_wish_print_
+#ifndef _di_controller_rule_error_print_need_want_wish_
+ extern void controller_rule_error_print_need_want_wish(const fll_error_print_t output, const f_string_t need_want_wish, const f_string_t value, const f_string_t why) f_gcc_attribute_visibility_internal;
+#endif // _di_controller_rule_error_print_need_want_wish_
/**
* Perform an execution of the given rule.
* - controller_rule_action_type_start
* - controller_rule_action_type_stop
* @param options
- * The execute options.
+ * The controller execute options (and not fl_execute_parameter_t.option).
+ * This is for designating asynchronous and other controller specific execution options.
+ * @todo this is not yet implemented.
+ * @param arguments
+ * The arguments to pass to the script.
+ * @param parameter
+ * The execute parameter settings.
* @param data
* The program data.
*
* @see fll_execute_program()
*/
#ifndef _di_controller_rule_execute_script_
- extern f_return_status controller_rule_execute_script(const controller_rule_action_t action, const uint8_t options, controller_data_t *data) f_gcc_attribute_visibility_internal;
+ extern f_return_status controller_rule_execute_script(const controller_rule_action_t action, const uint8_t options, const f_string_dynamics_t arguments, fl_execute_parameter_t * const parameter, controller_data_t *data) f_gcc_attribute_visibility_internal;
#endif // _di_controller_rule_execute_script_
/**
f_console
f_conversion
f_directory
+f_environment
f_execute
f_file
f_fss
fl_iki
fl_string
fl_type
+fll_environment
fll_error
fll_execute
fll_fss
build_indexer ar
build_language c
build_libraries -lc
-build_libraries-individual -lfll_error -lfll_execute -lfll_fss -lfll_path -lfll_program -lfll_status -lfl_color -lfl_console -lfl_conversion -lfl_environment -lfl_fss -lfl_iki -lfl_status -lfl_string -lfl_type -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_utf
+build_libraries-individual -lfll_environment -lfll_error -lfll_execute -lfll_fss -lfll_path -lfll_program -lfll_status -lfl_color -lfl_console -lfl_conversion -lfl_environment -lfl_fss -lfl_iki -lfl_status -lfl_string -lfl_type -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_utf
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
build_sources_library controller.c private-control.c private-controller.c private-entry.c private-rule.c
#include <level_1/string.h>
// fll-2 includes
+#include <level_2/environment.h>
#include <level_2/error.h>
#include <level_2/execute.h>
#include <level_2/file.h>
f_signal_set_empty(&signals.block);
f_signal_set_fill(&signals.block_not);
- fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(fl_execute_parameter_option_path, &data_build.environment.names, &data_build.environment.values, &signals, 0);
+ fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(fl_execute_parameter_option_path, &data_build.environment, &signals, 0);
*status = fll_execute_program(path.string, arguments, ¶meter, &return_code);
#endif // _di_fake_build_library_static_
#ifndef _di_fake_build_load_environment_
- void fake_build_load_environment(const fake_data_t data, const fake_build_data_t data_build, fake_environment_t *environment, f_status_t *status) {
+ void fake_build_load_environment(const fake_data_t data, const fake_build_data_t data_build, f_string_maps_t *environment, f_status_t *status) {
if (F_status_is_error(*status)) return;
- f_string_dynamics_t names = f_string_dynamics_t_initialize;
+ // reset the environment.
+ for (f_array_length_t i = 0; i < environment->used; i++) {
+ environment->array[i].name.used = 0;
+ environment->array[i].value.used = 0;
+ } // for
+
+ environment->used = 0;
{
// add the guaranteed environment variables.
f_path_present_working_length
};
- f_macro_string_dynamics_new(*status, names, 2);
-
- if (F_status_is_error(*status)) {
- fll_error_print(data.error, F_status_set_fine(*status), "f_macro_string_dynamics_new", F_true);
-
- fl_string_dynamics_delete(&names);
- return;
- }
-
- f_string_dynamic_t part = f_string_dynamic_t_initialize;
-
for (uint8_t i = 0; i < 2; i++) {
- *status = fl_string_append(variables_name[i], variables_length[i], &part);
- if (F_status_is_error(*status)) break;
-
- names.array[names.used].string = part.string;
- names.array[names.used].used = part.used;
- names.array[names.used].size = part.size;
- names.used++;
-
- f_macro_string_dynamic_t_clear(part);
- } // for
-
- if (F_status_is_error_not(*status)) {
- if (names.used + data_build.setting.environment.used > names.size) {
- if (names.used + data_build.setting.environment.used > f_array_length_t_size) {
- if (data.error.verbosity != f_console_verbosity_quiet) {
- fprintf(data.error.to.stream, "%c", f_string_eol[0]);
- fl_color_print(data.error.to.stream, data.context.set.error, "%sThe values for the setting '", fll_error_print_error);
- fl_color_print(data.error.to.stream, data.context.set.notable, "%s", fake_build_setting_name_environment);
- fl_color_print(data.error.to.stream, data.context.set.error, "' of setting file '");
- fl_color_print(data.error.to.stream, data.context.set.notable, "%s", data.file_data_build_settings.string);
- fl_color_print(data.error.to.stream, data.context.set.error, "' is too large.");
- fprintf(data.error.to.stream, "%c", f_string_eol[0]);
- }
+ *status = fll_environment_load_name(variables_name[i], variables_length[i], environment);
- fl_string_dynamic_delete(&part);
- fl_string_dynamics_delete(&names);
- *status = F_status_set_error(F_array_too_large);
- return;
- }
-
- f_macro_string_dynamics_t_resize(*status, names, names.used + data_build.setting.environment.used);
-
- if (F_status_is_error(*status)) {
- fll_error_print(data.error, F_status_set_fine(*status), "f_macro_string_dynamics_t_resize", F_true);
-
- fl_string_dynamic_delete(&part);
- fl_string_dynamics_delete(&names);
- return;
- }
+ if (F_status_is_error(*status)) {
+ fll_error_print(data.error, F_status_set_fine(*status), "fll_environment_load_name", F_true);
+ break;
}
-
- for (f_string_length_t i = 0; i < data_build.setting.environment.used; i++) {
-
- *status = fl_string_dynamic_append_nulless(data_build.setting.environment.array[i], &part);
- if (F_status_is_error(*status)) break;
-
- names.array[names.used].string = part.string;
- names.array[names.used].used = part.used;
- names.array[names.used].size = part.size;
- names.used++;
-
- f_macro_string_dynamic_t_clear(part);
- } // for
- }
-
- fl_string_dynamic_delete(&part);
+ } // for
if (F_status_is_error(*status)) {
- fll_error_print(data.error, F_status_set_fine(*status), "fl_string_append", F_true);
-
- fl_string_dynamics_delete(&names);
return;
}
}
- f_string_t function = f_string_t_initialize;
- f_string_dynamic_t variable_name = f_string_dynamic_t_initialize;
- f_string_dynamic_t variable_value = f_string_dynamic_t_initialize;
-
- for (f_string_length_t i = 0; i < names.used; i++) {
-
- if (fake_signal_received(data)) {
- *status = F_status_set_error(F_signal);
- break;
- }
-
- *status = f_environment_get_dynamic(names.array[i], &variable_value);
-
- if (F_status_is_error(*status)) {
- if (F_status_set_fine(*status) == F_memory_reallocation) {
- function = "f_macro_string_dynamics_t_resize";
- break;
- }
- }
-
- if (F_status_is_error_not(*status) && environment->names.used + 1 > environment->names.size) {
- if (environment->names.size + f_memory_default_allocation_step > f_array_length_t_size) {
- if (environment->names.size + 1 > f_array_length_t_size) {
- *status = F_status_set_error(F_array_too_large);
- }
- else {
- f_macro_string_dynamics_t_resize(*status, environment->names, environment->names.size + 1);
- }
- }
- else {
- f_macro_string_dynamics_t_resize(*status, environment->names, environment->names.size + f_memory_default_allocation_step);
- }
-
- if (F_status_is_error(*status)) {
- function = "f_macro_string_dynamics_t_resize";
- break;
- }
-
- f_macro_string_dynamics_t_resize(*status, environment->values, environment->names.size);
- if (F_status_is_error(*status)) {
- function = "f_macro_string_dynamics_t_resize";
- break;
+ if (environment->used + data_build.setting.environment.used > environment->size) {
+ if (environment->used + data_build.setting.environment.used > f_array_length_t_size) {
+ if (data.error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data.error.to.stream, data.context.set.error, "%sThe values for the setting '", fll_error_print_error);
+ fl_color_print(data.error.to.stream, data.context.set.notable, "%s", fake_build_setting_name_environment);
+ fl_color_print(data.error.to.stream, data.context.set.error, "' of setting file '");
+ fl_color_print(data.error.to.stream, data.context.set.notable, "%s", data.file_data_build_settings.string);
+ fl_color_print(data.error.to.stream, data.context.set.error, "' is too large.");
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
}
- }
-
- *status = fl_string_dynamic_append(names.array[i], &variable_name);
- if (F_status_is_error(*status)) {
- function = "fl_string_append";
- break;
+ *status = F_status_set_error(F_array_too_large);
+ return;
}
+ }
- environment->names.array[environment->names.used].string = variable_name.string;
- environment->names.array[environment->names.used].used = variable_name.used;
- environment->names.array[environment->names.used].size = variable_name.size;
- environment->names.used++;
-
- environment->values.array[environment->values.used].string = variable_value.string;
- environment->values.array[environment->values.used].used = variable_value.used;
- environment->values.array[environment->values.used].size = variable_value.size;
- environment->values.used++;
-
- f_macro_string_dynamic_t_clear(variable_name);
- f_macro_string_dynamic_t_clear(variable_value);
- } // for
-
- fl_string_dynamics_delete(&names);
- fl_string_dynamic_delete(&variable_name);
- fl_string_dynamic_delete(&variable_value);
+ *status = fll_environment_load_names(data_build.setting.environment, environment);
- if (F_status_is_error(*status) && F_status_set_fine(*status) != F_signal) {
- fll_error_print(data.error, *status, function, F_true);
+ if (F_status_is_error(*status)) {
+ fll_error_print(data.error, F_status_set_fine(*status), "fll_environment_load_names", F_true);
}
}
#endif // _di_fake_build_load_environment_
#ifndef _di_fake_build_data_t_
typedef struct {
fake_build_setting_t setting;
- fake_environment_t environment;
+ f_string_maps_t environment;
} fake_build_data_t;
#define fake_build_data_t_initialize { \
fake_build_setting_t_initialize, \
- fake_environment_t_initialize, \
+ f_string_maps_t_initialize, \
}
#define fake_macro_build_data_delete_simple(build) \
fake_macro_build_setting_t_delete_simple(build.setting) \
- fake_macro_environment_t_delete_simple(build.environment)
+ fl_string_maps_delete(&build.environment);
#endif // _di_fake_build_data_t_
#ifndef _di_fake_build_parameter_
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_fake_build_load_environment_
- extern void fake_build_load_environment(const fake_data_t data, const fake_build_data_t data_build, fake_environment_t *environment, f_status_t *status) f_gcc_attribute_visibility_internal;
+ extern void fake_build_load_environment(const fake_data_t data, const fake_build_data_t data_build, f_string_maps_t *environment, f_status_t *status) f_gcc_attribute_visibility_internal;
#endif // _di_fake_build_load_environment_
/**
#endif
#ifndef _di_fake_execute_
- int fake_execute(const fake_data_t data, const fake_environment_t environment, const f_string_static_t program, const f_string_statics_t arguments, f_status_t *status) {
+ int fake_execute(const fake_data_t data, const f_string_maps_t environment, const f_string_static_t program, const f_string_statics_t arguments, f_status_t *status) {
if (F_status_is_error(*status)) return 1;
if (data.error.verbosity == f_console_verbosity_verbose) {
f_signal_set_empty(&signals.block);
f_signal_set_fill(&signals.block_not);
- fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(0, &environment.names, &environment.values, &signals, 0);
+ fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(0, &environment, &signals, 0);
*status = fll_execute_program(program.string, arguments, ¶meter, &return_code);
#define fake_common_setting_bool_no_length 2
#endif // _di_fake_common_
-#ifndef _di_fake_environment_t_
- typedef struct {
- f_string_dynamics_t names;
- f_string_dynamics_t values;
- } fake_environment_t;
-
- #define fake_environment_t_initialize { \
- f_string_dynamics_t_initialize, \
- f_string_dynamics_t_initialize, \
- }
-
- #define fake_macro_environment_t_delete_simple(environment) \
- fl_string_dynamics_delete(&environment.names); \
- fl_string_dynamics_delete(&environment.values);
-#endif // _di_fake_environment_t_
-
/**
* Execute the given command and arguments.
*
* A value of 1 is returned if status has the error bit set.
*/
#ifndef _di_fake_execute_
- extern int fake_execute(const fake_data_t data, const fake_environment_t environment, const f_string_static_t program, const f_string_statics_t arguments, f_status_t *status) f_gcc_attribute_visibility_internal;
+ extern int fake_execute(const fake_data_t data, const f_string_maps_t environment, const f_string_static_t program, const f_string_statics_t arguments, f_status_t *status) f_gcc_attribute_visibility_internal;
#endif // _di_fake_execute_
/**
f_status_t status = F_none;
// reset the environment.
- for (f_array_length_t i = 0; i < data_make->environment.names.used; i++) {
- data_make->environment.names.array[i].used = 0;
- data_make->environment.values.array[i].used = 0;
+ for (f_array_length_t i = 0; i < data_make->environment.used; i++) {
+ data_make->environment.array[i].name.used = 0;
+ data_make->environment.array[i].value.used = 0;
} // for
- data_make->environment.names.used = 0;
- data_make->environment.values.used = 0;
+ data_make->environment.used = 0;
- // load all environment variables found.
- for (f_array_length_t i = 0; i < data_make->setting_build.environment.used; i++) {
+ status = fll_environment_load_names(data_make->setting_build.environment, &data_make->environment);
- // pre-allocate name and value if necessary.
- if (data_make->environment.names.used + 1 > data_make->environment.names.size) {
- f_macro_string_dynamics_t_resize(status, data_make->environment.names, data_make->environment.names.size + f_memory_default_allocation_step);
-
- if (F_status_is_error_not(status)) {
- f_macro_string_dynamics_t_resize(status, data_make->environment.values, data_make->environment.values.size + f_memory_default_allocation_step);
- }
-
- if (F_status_is_error(status)) {
- fll_error_print(data_make->error, F_status_set_fine(status), "f_macro_string_dynamics_t_resize", F_true);
- return status;
- }
- }
-
- status = f_environment_get(data_make->setting_build.environment.array[i].string, &data_make->environment.values.array[data_make->environment.values.used]);
-
- if (F_status_is_error(status)) {
- fll_error_print(data_make->error, F_status_set_fine(status), "f_environment_get", F_true);
- return status;
- }
-
- if (status == F_exist_not) continue;
-
- fl_string_dynamic_append(data_make->setting_build.environment.array[i], &data_make->environment.names.array[data_make->environment.names.used]);
-
- if (F_status_is_error(status)) {
- fll_error_print(data_make->error, F_status_set_fine(status), "f_environment_get", F_true);
- return status;
- }
+ if (F_status_is_error(status)) {
+ fll_error_print(data_make->error, F_status_set_fine(status), "fll_environment_load_names", F_true);
- data_make->environment.names.used++;
- data_make->environment.values.used++;
- } // for
+ return status;
+ }
if (data.error.verbosity == f_console_verbosity_verbose) {
fprintf(data.output.stream, "%s", program.string);
f_signal_set_empty(&signals.block);
f_signal_set_fill(&signals.block_not);
- fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(as_shell ? 0 : fl_execute_parameter_option_path, &data_make->environment.names, &data_make->environment.values, &signals, 0);
+ fl_execute_parameter_t parameter = fl_macro_execute_parameter_t_initialize(as_shell ? 0 : fl_execute_parameter_option_path, &data_make->environment, &signals, 0);
status = fll_execute_program(program.string, arguments, ¶meter, &return_code);
fake_build_setting_t setting_build;
fake_make_setting_t setting_make;
- fake_environment_t environment;
+ f_string_maps_t environment;
fake_make_parameter_t parameter;
fake_make_path_t path; // @todo review this, check if path.current is used anymore.
#define fake_make_data_t_initialize { \
fake_build_setting_t_initialize, \
fake_make_setting_t_initialize, \
- fake_environment_t_initialize, \
+ f_string_maps_t_initialize, \
fake_make_parameter_t_initialize, \
fake_make_path_t_initialize, \
fll_error_print_t_initialize, \
#define fake_macro_make_data_t_delete_simple(data) \
fake_macro_build_setting_t_delete_simple(data.setting_build) \
fake_macro_make_setting_t_delete_simple(data.setting_make) \
- fake_macro_environment_t_delete_simple(data.environment) \
+ fl_string_maps_delete(&data.environment); \
fake_macro_make_parameter_delete_simple(data.parameter) \
fake_macro_make_path_delete_simple(data.path) \
f_macro_fss_nameds_t_delete_simple(data.fakefile) \
fl_status
fl_string
fl_utf
+fll_environment
fll_error
fll_execute
fll_file
build_indexer ar
build_language c
build_libraries -lc
-build_libraries-individual -lfll_error -lfll_execute -lfll_file -lfll_fss -lfll_path -lfll_program -lfl_color -lfl_console -lfl_conversion -lfl_directory -lfl_environment -lfl_fss -lfl_iki -lfl_status -lfl_string -lfl_utf -lf_account -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_print -lf_signal -lf_utf
+build_libraries-individual -lfll_environment -lfll_error -lfll_execute -lfll_file -lfll_fss -lfll_path -lfll_program -lfl_color -lfl_console -lfl_conversion -lfl_directory -lfl_environment -lfl_fss -lfl_iki -lfl_status -lfl_string -lfl_utf -lf_account -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_iki -lf_memory -lf_path -lf_print -lf_signal -lf_utf
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
build_sources_library fake.c private-fake.c private-clean.c private-build.c private-make.c private-print.c private-skeleton.c
}
#define firewall_macro_delete_fss_buffers(status, buffer, objects, contents) \
- f_macro_string_dynamic_t_delete(status, buffer); \
+ fl_string_dynamic_delete(&buffer); \
f_macro_fss_objects_t_delete(status, objects); \
f_macro_fss_contents_t_delete(status, contents);
structure.value_at = 0; \
f_macro_string_dynamic_t_clear(structure.value_name)
- #define fss_basic_list_read_macro_depth_t_delete(status, structure) f_macro_string_dynamic_t_delete(status, structure.value_name)
- #define fss_basic_list_read_macro_depth_t_destroy(status, structure) f_macro_string_dynamic_t_destroy(status, structure.value_name)
-
- #define fss_basic_list_read_macro_depth_t_delete_simple(structure) f_macro_string_dynamic_t_delete_simple(structure.value_name)
- #define fss_basic_list_read_macro_depth_t_destroy_simple(structure) f_macro_string_dynamic_t_destroy_simple(structure.value_name)
+ #define fss_basic_list_read_macro_depth_t_delete(status, structure) status = fl_string_dynamic_delete(&structure.value_name);
+ #define fss_basic_list_read_macro_depth_t_delete_simple(structure) fl_string_dynamic_delete(&structure.value_name);
#endif // _di_fss_basic_list_read_depth_t_
/**
} \
if (status == F_none) f_macro_memory_structure_t_delete(depths, fss_basic_list_read_depth_t)
- #define fss_basic_list_read_macro_depths_t_destroy(status, depths) \
- status = F_none; \
- depths.used = depths.size; \
- while (depths.used > 0) { \
- depths.used--; \
- fss_basic_list_read_macro_depth_t_destroy(status, depths.array[depths.used]); \
- if (status != F_none) break; \
- } \
- if (status == F_none) f_macro_memory_structure_t_destroy(depths, fss_basic_list_read_depth_t)
-
#define fss_basic_list_read_macro_depths_t_delete_simple(depths) \
depths.used = depths.size; \
while (depths.used > 0) { \
} \
if (!depths.used) f_macro_memory_structure_t_delete_simple(depths, fss_basic_list_read_depth_t)
- #define fss_basic_list_read_macro_depths_t_destroy_simple(depths) \
- depths.used = depths.size; \
- while (depths.used > 0) { \
- depths.used--; \
- fss_basic_list_read_macro_depth_t_destroy_simple(depths.array[depths.used]); \
- } \
- if (!depths.used) f_macro_memory_structure_t_destroy_simple(depths, fss_basic_list_read_depth_t)
-
#define fss_basic_list_read_macro_depths_t_resize(status, depths, new_length) \
status = F_none; \
if (new_length < depths.size) { \
structure.value_at = 0; \
f_macro_string_dynamic_t_clear(structure.value_name)
- #define fss_basic_read_macro_depth_t_delete(status, structure) f_macro_string_dynamic_t_delete(status, structure.value_name)
- #define fss_basic_read_macro_depth_t_destroy(status, structure) f_macro_string_dynamic_t_destroy(status, structure.value_name)
-
- #define fss_basic_read_macro_depth_t_delete_simple(structure) f_macro_string_dynamic_t_delete_simple(structure.value_name)
- #define fss_basic_read_macro_depth_t_destroy_simple(structure) f_macro_string_dynamic_t_destroy_simple(structure.value_name)
+ #define fss_basic_read_macro_depth_t_delete(status, structure) status = fl_string_dynamic_delete(&structure.value_name);
+ #define fss_basic_read_macro_depth_t_delete_simple(structure) fl_string_dynamic_delete(&structure.value_name);
#endif // _di_fss_basic_read_depth_t_
/**
} \
if (status == F_none) f_macro_memory_structure_t_delete(depths, fss_basic_read_depth_t)
- #define fss_basic_read_macro_depths_t_destroy(status, depths) \
- status = F_none; \
- depths.used = depths.size; \
- while (depths.used > 0) { \
- depths.used--; \
- fss_basic_read_macro_depth_t_destroy(status, depths.array[depths.used]); \
- if (status != F_none) break; \
- } \
- if (status == F_none) f_macro_memory_structure_t_destroy(depths, fss_basic_read_depth_t)
-
#define fss_basic_read_macro_depths_t_delete_simple(depths) \
depths.used = depths.size; \
while (depths.used > 0) { \
} \
if (!depths.used) f_macro_memory_structure_t_delete_simple(depths, fss_basic_read_depth_t)
- #define fss_basic_read_macro_depths_t_destroy_simple(depths) \
- depths.used = depths.size; \
- while (depths.used > 0) { \
- depths.used--; \
- fss_basic_read_macro_depth_t_destroy_simple(depths.array[depths.used]); \
- } \
- if (!depths.used) f_macro_memory_structure_t_destroy_simple(depths, fss_basic_read_depth_t)
-
#define fss_basic_read_macro_depths_t_resize(status, depths, new_length) \
status = F_none; \
if (new_length < depths.size) { \
structure.value_at = 0; \
f_macro_string_dynamic_t_clear(structure.value_name)
- #define fss_embedded_list_read_macro_depth_t_delete(status, structure) f_macro_string_dynamic_t_delete(status, structure.value_name)
- #define fss_embedded_list_read_macro_depth_t_destroy(status, structure) f_macro_string_dynamic_t_destroy(status, structure.value_name)
-
- #define fss_embedded_list_read_macro_depth_t_delete_simple(structure) f_macro_string_dynamic_t_delete_simple(structure.value_name)
- #define fss_embedded_list_read_macro_depth_t_destroy_simple(structure) f_macro_string_dynamic_t_destroy_simple(structure.value_name)
+ #define fss_embedded_list_read_macro_depth_t_delete(status, structure) status = fl_string_dynamic_delete(&structure.value_name)
+ #define fss_embedded_list_read_macro_depth_t_delete_simple(structure) fl_string_dynamic_delete(&structure.value_name)
#endif // _di_fss_embedded_list_read_depth_t_
/**
} \
if (status == F_none) f_macro_memory_structure_t_delete(depths, fss_embedded_list_read_depth_t)
- #define fss_embedded_list_read_macro_depths_t_destroy(status, depths) \
- status = F_none; \
- depths.used = depths.size; \
- while (depths.used > 0) { \
- depths.used--; \
- fss_embedded_list_read_macro_depth_t_destroy(status, depths.array[depths.used]); \
- if (status != F_none) break; \
- } \
- if (status == F_none) f_macro_memory_structure_t_destroy(depths, fss_embedded_list_read_depth_t)
-
#define fss_embedded_list_read_macro_depths_t_delete_simple(depths) \
depths.used = depths.size; \
while (depths.used > 0) { \
} \
if (!depths.used) f_macro_memory_structure_t_delete_simple(depths, fss_embedded_list_read_depth_t)
- #define fss_embedded_list_read_macro_depths_t_destroy_simple(depths) \
- depths.used = depths.size; \
- while (depths.used > 0) { \
- depths.used--; \
- fss_embedded_list_read_macro_depth_t_destroy_simple(depths.array[depths.used]); \
- } \
- if (!depths.used) f_macro_memory_structure_t_destroy_simple(depths, fss_embedded_list_read_depth_t)
-
#define fss_embedded_list_read_macro_depths_t_resize(status, depths, new_length) \
status = F_none; \
if (new_length < depths.size) { \
structure.value_at = 0; \
f_macro_string_dynamic_t_clear(structure.value_name)
- #define fss_extended_list_read_macro_depth_t_delete(status, structure) f_macro_string_dynamic_t_delete(status, structure.value_name)
- #define fss_extended_list_read_macro_depth_t_destroy(status, structure) f_macro_string_dynamic_t_destroy(status, structure.value_name)
-
- #define fss_extended_list_read_macro_depth_t_delete_simple(structure) f_macro_string_dynamic_t_delete_simple(structure.value_name)
- #define fss_extended_list_read_macro_depth_t_destroy_simple(structure) f_macro_string_dynamic_t_destroy_simple(structure.value_name)
+ #define fss_extended_list_read_macro_depth_t_delete(status, structure) status = fl_string_dynamic_delete(&structure.value_name)
+ #define fss_extended_list_read_macro_depth_t_delete_simple(structure) fl_string_dynamic_delete(&structure.value_name)
#endif // _di_fss_extended_list_read_depth_t_
/**
} \
if (status == F_none) f_macro_memory_structure_t_delete(depths, fss_extended_list_read_depth_t)
- #define fss_extended_list_read_macro_depths_t_destroy(status, depths) \
- status = F_none; \
- depths.used = depths.size; \
- while (depths.used > 0) { \
- depths.used--; \
- fss_extended_list_read_macro_depth_t_destroy(status, depths.array[depths.used]); \
- if (status != F_none) break; \
- } \
- if (status == F_none) f_macro_memory_structure_t_destroy(depths, fss_extended_list_read_depth_t)
-
#define fss_extended_list_read_macro_depths_t_delete_simple(depths) \
depths.used = depths.size; \
while (depths.used > 0) { \
} \
if (!depths.used) f_macro_memory_structure_t_delete_simple(depths, fss_extended_list_read_depth_t)
- #define fss_extended_list_read_macro_depths_t_destroy_simple(depths) \
- depths.used = depths.size; \
- while (depths.used > 0) { \
- depths.used--; \
- fss_extended_list_read_macro_depth_t_destroy_simple(depths.array[depths.used]); \
- } \
- if (!depths.used) f_macro_memory_structure_t_destroy_simple(depths, fss_extended_list_read_depth_t)
-
#define fss_extended_list_read_macro_depths_t_resize(status, depths, new_length) \
status = F_none; \
if (new_length < depths.size) { \
structure.value_at = 0; \
f_macro_string_dynamic_t_clear(structure.value_name)
- #define fss_extended_read_macro_depth_t_delete(status, structure) f_macro_string_dynamic_t_delete(status, structure.value_name)
- #define fss_extended_read_macro_depth_t_destroy(status, structure) f_macro_string_dynamic_t_destroy(status, structure.value_name)
-
- #define fss_extended_read_macro_depth_t_delete_simple(structure) f_macro_string_dynamic_t_delete_simple(structure.value_name)
- #define fss_extended_read_macro_depth_t_destroy_simple(structure) f_macro_string_dynamic_t_destroy_simple(structure.value_name)
+ #define fss_extended_read_macro_depth_t_delete(status, structure) status = fl_string_dynamic_delete(structure.value_name)
+ #define fss_extended_read_macro_depth_t_delete_simple(structure) fl_string_dynamic_delete(structure.value_name)
#endif // _di_fss_extended_read_depth_t_
/**
} \
if (status == F_none) f_macro_memory_structure_t_delete(depths, fss_extended_read_depth_t)
- #define fss_extended_read_macro_depths_t_destroy(status, depths) \
- status = F_none; \
- depths.used = depths.size; \
- while (depths.used > 0) { \
- depths.used--; \
- fss_extended_read_macro_depth_t_destroy(status, depths.array[depths.used]); \
- if (status != F_none) break; \
- } \
- if (status == F_none) f_macro_memory_structure_t_destroy(depths, fss_extended_read_depth_t)
-
#define fss_extended_read_macro_depths_t_delete_simple(depths) \
depths.used = depths.size; \
while (depths.used > 0) { \
} \
if (!depths.used) f_macro_memory_structure_t_delete_simple(depths, fss_extended_read_depth_t)
- #define fss_extended_read_macro_depths_t_destroy_simple(depths) \
- depths.used = depths.size; \
- while (depths.used > 0) { \
- depths.used--; \
- fss_extended_read_macro_depth_t_destroy_simple(depths.array[depths.used]); \
- } \
- if (!depths.used) f_macro_memory_structure_t_destroy_simple(depths, fss_extended_read_depth_t)
-
#define fss_extended_read_macro_depths_t_resize(status, depths, new_length) \
status = F_none; \
if (new_length < depths.size) { \