The realpath() function does not work on non-existent paths.
Provide an alternative, fll_path_canonical(), that works on paths without concern for some paths existence.
The f_environment_path* functions need f_path, so move them to a new fl_environment project.
build_linker ar
build_libraries -lc
build_libraries-level -lfll_0
-build_sources_library color.c console.c conversion.c directory.c private-directory.c private-fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c iki.c print.c status.c string.c private-string.c utf.c private-utf.c utf_file.c private-utf_file.c
+build_sources_library color.c console.c conversion.c directory.c private-directory.c environment.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c private-fss.c iki.c print.c status.c string.c private-string.c utf.c private-utf.c utf_file.c private-utf_file.c
build_sources_program
-build_sources_headers color.h console.h conversion.h directory.h fss.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_macro.h fss_status.h iki.h print.h status.h string.h utf.h utf_file.h
+build_sources_headers color.h console.h conversion.h directory.h environment.h fss.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_macro.h fss_status.h iki.h print.h status.h string.h utf.h utf_file.h
build_sources_script
build_sources_setting
build_script yes
build_linker ar
build_libraries -lc
build_libraries-level -lfll_1 -lfll_0
-build_sources_library execute.c private-execute.c file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c fss_status.c program.c status.c
+build_sources_library execute.c private-execute.c file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c fss_status.c path.c program.c status.c
build_sources_program
-build_sources_headers execute.h file.h fss.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_status.h program.h status.h
+build_sources_headers execute.h file.h fss.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_status.h path.c program.h status.h
build_sources_script
build_sources_setting
build_script yes
build_linker ar
build_libraries -lc
build_libraries-monolithic
-build_sources_library 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/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/serialize.c level_0/private-serialize.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/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/execute.c level_2/private-execute.c level_2/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_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/program.c level_2/status.c
+build_sources_library 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/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/serialize.c level_0/private-serialize.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/private-fss.c level_1/environment.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/execute.c level_2/private-execute.c level_2/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_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/path.c level_2/program.c level_2/status.c
build_sources_program
-build_sources_headers level_0/color.h level_0/console.h level_0/conversion.h level_0/directory.h level_0/directory_type.h level_0/environment.h level_0/file.h level_0/fss.h level_0/fss-common.h level_0/fss-named.h level_0/fss-nest.h level_0/fss-quoted.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/pipe.h level_0/print.h level_0/serialize.h level_0/socket.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/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/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.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_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/program.h level_2/status.h
+build_sources_headers level_0/color.h level_0/console.h level_0/conversion.h level_0/directory.h level_0/directory_type.h level_0/environment.h level_0/file.h level_0/fss.h level_0/fss-common.h level_0/fss-named.h level_0/fss-nest.h level_0/fss-quoted.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/pipe.h level_0/print.h level_0/serialize.h level_0/socket.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/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/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.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_extended.h level_2/fss_extended_list.h level_2/fss_status.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 build -i
if [[ $? -eq 0 ]] ; then
- for i in f_type f_status f_memory f_string f_utf f_color f_console f_conversion f_directory f_environment f_file f_fss f_iki f_path f_pipe f_print f_serialize f_socket fl_color fl_console fl_conversion fl_directory fl_fss fl_iki fl_print fl_status fl_string fl_utf fl_utf_file fll_execute fll_file fll_fss fll_program fll_status ; do
+ for i in f_type f_status f_memory f_string f_utf f_color f_console f_conversion f_directory f_environment f_file f_fss f_iki f_path f_pipe f_print f_serialize f_socket fl_color fl_console fl_conversion fl_directory fl_environment fl_fss fl_iki fl_print fl_status fl_string fl_utf fl_utf_file fll_execute fll_file fll_fss fll_path fll_program fll_status ; do
echo && echo "Processing $i." &&
cd package/individual/$i-$2/ &&
}
#endif // _di_f_environment_get_dynamic_
-#ifndef _di_f_environment_path_explode_
- f_return_status f_environment_path_explode(const f_string path, f_string_dynamics *paths) {
- #ifndef _di_level_0_parameter_checking_
- if (paths == 0) return F_status_set_error(F_parameter);
- if (paths->used > paths->size) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- f_status status = F_none;
- const f_string_length length = strnlen(path, PATH_MAX);
-
- if (length == 0) {
- // When PATH is "", this is actually a valid search path for PWD.
- // Therefore append an equivalent representation of PWD (string used length is 0).
- f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
- if (F_status_is_error(status)) return status;
-
- f_macro_string_dynamic_clear(paths->array[paths->used]);
- paths->used++;
-
- return F_none;
- }
-
- f_string_length i = length;
- f_string_length first = 0;
- f_string_length total = 0;
-
- for (i = 0; i <= length; i++) {
- if (i == length || path[i] == f_path_separator_variable[0]) {
- f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
- if (F_status_is_error(status)) return status;
-
- if (i == 0) {
- f_macro_string_dynamic_clear(paths->array[paths->used]);
- paths->used++;
-
- first = 1;
- continue;
- }
-
- f_string_dynamic part = f_string_dynamic_initialize;
-
- total = i - first;
-
- if (total > 0) {
- if (path[i - 1] == f_path_separator[0]) {
- f_macro_string_dynamic_new(status, part, total);
- if (F_status_is_error(status)) return status;
-
- part.used = total;
- }
- else {
- f_macro_string_dynamic_new(status, part, total + 1);
- if (F_status_is_error(status)) return status;
-
- part.string[total] = f_path_separator[0];
- part.used = total + 1;
- }
-
- memcpy(part.string, path + first, total);
- }
-
- paths->array[paths->used].string = part.string;
- paths->array[paths->used].used = part.used;
- paths->array[paths->used].size = part.size;
- paths->used++;
-
- first = i + 1;
- }
- } // for
-
- return F_none;
- }
-#endif // _di_f_environment_path_explode_
-
-#ifndef _di_f_environment_path_explode_dynamic_
- f_return_status f_environment_path_explode_dynamic(const f_string_static path, f_string_dynamics *paths) {
- #ifndef _di_level_0_parameter_checking_
- if (path.used > path.size) return F_status_set_error(F_parameter);
- if (paths == 0) return F_status_set_error(F_parameter);
- if (paths->used > paths->size) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- f_status status = F_none;
-
- if (path.used == 0) {
- // When PATH is "", this is actually a valid search path for PWD.
- // Therefore append an equivalent representation of PWD (string used length is 0).
- f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
- if (F_status_is_error(status)) return status;
-
- f_macro_string_dynamic_clear(paths->array[paths->used]);
- paths->used++;
-
- return F_none;
- }
-
- f_string_length i = 0;
- f_string_length j = 0;
- f_string_length first = 0;
- f_string_length total = 0;
-
- f_string_dynamic part = f_string_dynamic_initialize;
-
- for (i = 0; i <= path.used; i++) {
- if (i == path.used || path.string[i] == f_path_separator_variable[0]) {
- f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
- if (F_status_is_error(status)) return status;
-
- if (i == 0) {
- f_macro_string_dynamic_clear(paths->array[paths->used]);
- paths->used++;
-
- first = 1;
- continue;
- }
-
- total = i - first;
-
- if (total > 0) {
- f_macro_string_dynamic_new(status, part, total);
- if (F_status_is_error(status)) return status;
-
- for (j = 0; j < total; j++) {
- if (path.string[first + j] == 0) continue;
-
- part.string[part.used] = path.string[first + j];
- part.used++;
- } // for
-
- if (part.string[part.used - 1] != f_path_separator[0]) {
- f_macro_string_dynamic_resize(status, part, total + 1);
- if (F_status_is_error(status)) return status;
-
- part.string[part.used] = f_path_separator[0];
- part.used++;
- }
- }
-
- paths->array[paths->used].string = part.string;
- paths->array[paths->used].used = part.used;
- paths->array[paths->used].size = part.size;
- paths->used++;
-
- first = i + 1;
- }
- } // for
-
- return F_none;
- }
-#endif // _di_f_environment_path_explode_dynamic_
-
-#ifndef _di_f_environment_path_explode_reverse_
- f_return_status f_environment_path_explode_reverse(const f_string path, f_string_dynamics *paths) {
- #ifndef _di_level_0_parameter_checking_
- if (paths == 0) return F_status_set_error(F_parameter);
- if (paths->used > paths->size) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- f_status status = F_none;
- const f_string_length length = strnlen(path, PATH_MAX);
-
- if (length == 0) {
- // When PATH is "", this is actually a valid search path for PWD.
- // Therefore append an equivalent representation of PWD (string used length is 0).
- f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
- if (F_status_is_error(status)) return status;
-
- paths->array[paths->used].string = 0;
- paths->array[paths->used].used = 0;
- paths->array[paths->used].size = 0;
- paths->used++;
-
- return F_none;
- }
-
- f_string_length i = length;
- f_string_length j = length;
- f_string_length last = length;
- f_string_length total = 0;
-
- f_string_dynamic part = f_string_dynamic_initialize;
-
- for (; i > 0; i--) {
- j--;
-
- if (j == 0 || path[j] == f_path_separator_variable[0]) {
- f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
- if (F_status_is_error(status)) return status;
-
- if (path[j] == f_path_separator_variable[0]) {
- total = last - i;
-
- if (total > 0) {
- if (path[j + total] == f_path_separator[0]) {
- f_macro_string_dynamic_new(status, part, total);
- if (F_status_is_error(status)) return status;
-
- part.used = total;
- }
- else {
- f_macro_string_dynamic_new(status, part, total + 1);
- if (F_status_is_error(status)) return status;
-
- part.string[total] = f_path_separator[0];
- part.used = total + 1;
- }
-
- memcpy(part.string, path + i, total);
- }
-
- last = j;
- }
- else if (j == 0) {
- // when j = 0, the total is actually the entire length to max.
- total = last - j;
-
- if (total > 0) {
- if (path[last - 1] == f_path_separator[0]) {
- f_macro_string_dynamic_new(status, part, total);
- if (F_status_is_error(status)) return status;
-
- part.used = total;
- }
- else {
- f_macro_string_dynamic_new(status, part, total + 1);
- if (F_status_is_error(status)) return status;
-
- part.used = total + 1;
- part.string[total] = f_path_separator[0];
- }
-
- memcpy(part.string, path, total);
- }
- }
-
- paths->array[paths->used].string = part.string;
- paths->array[paths->used].used = part.used;
- paths->array[paths->used].size = part.size;
- paths->used++;
- }
- } // for
-
- return F_none;
- }
-#endif // _di_f_environment_path_explode_reverse_
-
-#ifndef _di_f_environment_path_explode_reverse_dynamic_
- f_return_status f_environment_path_explode_reverse_dynamic(const f_string_static path, f_string_dynamics *paths) {
- #ifndef _di_level_0_parameter_checking_
- if (path.used > path.size) return F_status_set_error(F_parameter);
- if (paths == 0) return F_status_set_error(F_parameter);
- if (paths->used > paths->size) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- f_status status = F_none;
-
- if (path.used == 0) {
- // When PATH is "", this is actually a valid search path for PWD.
- // Therefore append an equivalent representation of PWD (string used length is 0).
- f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
- if (F_status_is_error(status)) return status;
-
- f_macro_string_dynamic_clear(paths->array[paths->used]);
- paths->used++;
-
- return F_none;
- }
-
- f_string_length i = path.used;
- f_string_length j = path.used;
- f_string_length k = 0;
- f_string_length last = path.used;
- f_string_length total = 0;
-
- f_string_dynamic part = f_string_dynamic_initialize;
-
- for (; i > 0; i--) {
- j--;
-
- if (j == 0 || path.string[j] == f_path_separator_variable[0]) {
- f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
- if (F_status_is_error(status)) return status;
-
- if (path.string[j] == f_path_separator_variable[0]) {
- total = last - i;
-
- if (total > 0) {
- f_macro_string_dynamic_new(status, part, total);
- if (F_status_is_error(status)) return status;
-
- for (k = 0; k < total; k++) {
- if (path.string[i + k] == 0) continue;
-
- part.string[part.used] = path.string[i + k];
- part.used++;
- } // for
-
- if (part.string[part.used - 1] != f_path_separator[0]) {
- f_macro_string_dynamic_resize(status, part, total + 1);
- if (F_status_is_error(status)) return status;
-
- part.string[part.used] = f_path_separator[0];
- part.used++;
- }
- }
-
- last = j;
- }
- else if (j == 0) {
- // when j = 0, the total is actually the entire length to max.
- total = last - j;
-
- f_macro_string_dynamic_new(status, part, total);
- if (F_status_is_error(status)) return status;
-
- for (k = 0; k < total; k++) {
- if (path.string[i + k] == 0) continue;
-
- part.string[part.used] = path.string[i + k];
- part.used++;
- } // for
-
- if (part.string[part.used - 1] != f_path_separator[0]) {
- f_macro_string_dynamic_resize(status, part, total + 1);
- if (F_status_is_error(status)) return status;
-
- part.string[part.used - 1] = f_path_separator[0];
- part.used++;
- }
- }
-
- paths->array[paths->used].string = part.string;
- paths->array[paths->used].used = part.used;
- paths->array[paths->used].size = part.size;
- paths->used++;
- }
- } // for
-
- return F_none;
- }
-#endif // _di_f_environment_path_explode_reverse_dynamic_
-
#ifndef _di_f_environment_set_
f_return_status f_environment_set(const f_string name, const f_string value, const bool replace) {
return private_f_environment_set(name, value, replace);
#endif // _di_f_environment_get_dynamic_
/**
- * Separate a given PATH-style string into multiple separate paths.
- *
- * @param path
- * The string to process that is expected to follow the traditional Linux standard PATH environment variable.
- * Each seperate path is separated by a single ':'.
- * Must not contain NULLs except for the terminating NULL.
- * Must be NULL terminated.
- * @param paths
- * All of the strings exploded from PATH.
- * Each exploded path, when not empty, is guaranteed to have a trailing '/'.
- * Each exploded path is not NULL terminated.
- *
- * @return
- * F_none on success.
- * F_buffer_too_large (with error bit) if paths array is too large for further addressing.
- * F_memory_reallocation (with error bit) on reallocation error.
- * F_memory_allocation (with error bit) on allocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- */
-#ifndef _di_f_environment_path_explode_
- extern f_return_status f_environment_path_explode(const f_string path, f_string_dynamics *paths);
-#endif // _di_f_environment_path_explode_
-
-/**
- * Separate a given PATH-style string into multiple separate paths.
- *
- * @param path
- * The string to process that is expected to follow the traditional Linux standard PATH environment variable.
- * Each seperate path is separated by a single ':'.
- * Need not be NULL terminated.
- * NULLs are ignored and are not copied into the exploded paths.
- * @param paths
- * All of the strings exploded from PATH.
- * Each exploded path, when not empty, is guaranteed to have a trailing '/'.
- * Each exploded path is not NULL terminated.
- *
- * @return
- * F_none on success.
- * F_buffer_too_large (with error bit) if paths array is too large for further addressing.
- * F_memory_reallocation (with error bit) on reallocation error.
- * F_memory_allocation (with error bit) on allocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- */
-#ifndef _di_f_environment_path_explode_dynamic_
- extern f_return_status f_environment_path_explode_dynamic(const f_string_static path, f_string_dynamics *paths);
-#endif // _di_f_environment_path_explode_dynamic_
-
-/**
- * Separate a given PATH-style string into multiple separate paths.
- *
- * The paths are created in reverse order.
- *
- * @param path
- * The string to process that is expected to follow the traditional Linux standard PATH environment variable.
- * Each seperate path is separated by a single ':'.
- * Must not contain NULLs except for the terminating NULL.
- * Must be NULL terminated.
- * @param paths
- * All of the strings exploded from PATH.
- * Each exploded path, when not empty, is guaranteed to have a trailing '/'.
- * Each exploded path is not NULL terminated.
- *
- * @return
- * F_none on success.
- * F_buffer_too_large (with error bit) if paths array is too large for further addressing.
- * F_memory_reallocation (with error bit) on reallocation error.
- * F_memory_allocation (with error bit) on allocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- */
-#ifndef _di_f_environment_path_explode_reverse_
- extern f_return_status f_environment_path_explode_reverse(const f_string path, f_string_dynamics *paths);
-#endif // _di_f_environment_path_explode_reverse_
-
-/**
- * Separate a given PATH-style string into multiple separate paths.
- *
- * The paths are created in reverse order.
- *
- * @param path
- * The string to process that is expected to follow the traditional Linux standard PATH environment variable.
- * Each seperate path is separated by a single ':'.
- * Need not be NULL terminated.
- * NULLs are ignored and are not copied into the exploded paths.
- * @param paths
- * All of the strings exploded from PATH.
- * Each exploded path, when not empty, is guaranteed to have a trailing '/'.
- * Each exploded path is not NULL terminated.
- *
- * @return
- * F_none on success.
- * F_buffer_too_large (with error bit) if paths array is too large for further addressing.
- * F_memory_reallocation (with error bit) on reallocation error.
- * F_memory_allocation (with error bit) on allocation error.
- * F_parameter (with error bit) if a parameter is invalid.
- */
-#ifndef _di_f_environment_path_explode_reverse_dynamic_
- extern f_return_status f_environment_path_explode_reverse_dynamic(const f_string_static path, f_string_dynamics *paths);
-#endif // _di_f_environment_path_explode_reverse_dynamic_
-
-/**
* Assign the given value to the named environment variable.
*
* If the name does not exist, then it is created.
#endif // _di_f_path_current_
/**
- * Get the real path for some path.
+ * Get the real path for the given path.
*
- * All symbolic links and relative path parts are expanded to yield the real full path.
+ * This does check to see if the path exists or not (path must exist).
+ * This processes all relative parts.
+ * This processes all symbolic links.
+ * This has a max size of f_path_max + 1.
*
* @param path
* The source path to determine what the real path is.
+ * This is a NULL terminated string.
* @param real
* The (allocated) real file path.
* This will have a max size of f_path_max + 1.
--- /dev/null
+#include <level_1/environment.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fl_environment_path_explode_
+ f_return_status fl_environment_path_explode(const f_string path, f_string_dynamics *paths) {
+ #ifndef _di_level_0_parameter_checking_
+ if (paths == 0) return F_status_set_error(F_parameter);
+ if (paths->used > paths->size) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ f_status status = F_none;
+ const f_string_length length = strnlen(path, PATH_MAX);
+
+ if (length == 0) {
+ // When PATH is "", this is actually a valid search path for PWD.
+ // Append an equivalent representation of PWD (string used length is 0).
+ f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
+ if (F_status_is_error(status)) return status;
+
+ f_macro_string_dynamic_clear(paths->array[paths->used]);
+ paths->used++;
+
+ return F_none;
+ }
+
+ f_string_length i = length;
+ f_string_length first = 0;
+ f_string_length total = 0;
+
+ for (i = 0; i <= length; i++) {
+ if (i == length || path[i] == f_path_separator_variable[0]) {
+ f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
+ if (F_status_is_error(status)) return status;
+
+ if (i == 0) {
+ f_macro_string_dynamic_clear(paths->array[paths->used]);
+ paths->used++;
+
+ first = 1;
+ continue;
+ }
+
+ f_string_dynamic part = f_string_dynamic_initialize;
+
+ total = i - first;
+
+ if (total > 0) {
+ if (path[i - 1] == f_path_separator[0]) {
+ f_macro_string_dynamic_new(status, part, total);
+ if (F_status_is_error(status)) return status;
+
+ part.used = total;
+ }
+ else {
+ f_macro_string_dynamic_new(status, part, total + 1);
+ if (F_status_is_error(status)) return status;
+
+ part.string[total] = f_path_separator[0];
+ part.used = total + 1;
+ }
+
+ memcpy(part.string, path + first, total);
+ }
+
+ paths->array[paths->used].string = part.string;
+ paths->array[paths->used].used = part.used;
+ paths->array[paths->used].size = part.size;
+ paths->used++;
+
+ first = i + 1;
+ }
+ } // for
+
+ return F_none;
+ }
+#endif // _di_fl_environment_path_explode_
+
+#ifndef _di_fl_environment_path_explode_dynamic_
+ f_return_status fl_environment_path_explode_dynamic(const f_string_static path, f_string_dynamics *paths) {
+ #ifndef _di_level_0_parameter_checking_
+ if (path.used > path.size) return F_status_set_error(F_parameter);
+ if (paths == 0) return F_status_set_error(F_parameter);
+ if (paths->used > paths->size) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ f_status status = F_none;
+
+ if (path.used == 0) {
+ // When PATH is "", this is actually a valid search path for PWD.
+ // Therefore append an equivalent representation of PWD (string used length is 0).
+ f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
+ if (F_status_is_error(status)) return status;
+
+ f_macro_string_dynamic_clear(paths->array[paths->used]);
+ paths->used++;
+
+ return F_none;
+ }
+
+ f_string_length i = 0;
+ f_string_length j = 0;
+ f_string_length first = 0;
+ f_string_length total = 0;
+
+ f_string_dynamic part = f_string_dynamic_initialize;
+
+ for (i = 0; i <= path.used; i++) {
+ if (i == path.used || path.string[i] == f_path_separator_variable[0]) {
+ f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
+ if (F_status_is_error(status)) return status;
+
+ if (i == 0) {
+ f_macro_string_dynamic_clear(paths->array[paths->used]);
+ paths->used++;
+
+ first = 1;
+ continue;
+ }
+
+ total = i - first;
+
+ if (total > 0) {
+ f_macro_string_dynamic_new(status, part, total);
+ if (F_status_is_error(status)) return status;
+
+ for (j = 0; j < total; j++) {
+ if (path.string[first + j] == 0) continue;
+
+ part.string[part.used] = path.string[first + j];
+ part.used++;
+ } // for
+
+ if (part.string[part.used - 1] != f_path_separator[0]) {
+ f_macro_string_dynamic_resize(status, part, total + 1);
+ if (F_status_is_error(status)) return status;
+
+ part.string[part.used] = f_path_separator[0];
+ part.used++;
+ }
+ }
+
+ paths->array[paths->used].string = part.string;
+ paths->array[paths->used].used = part.used;
+ paths->array[paths->used].size = part.size;
+ paths->used++;
+
+ first = i + 1;
+ }
+ } // for
+
+ return F_none;
+ }
+#endif // _di_fl_environment_path_explode_dynamic_
+
+#ifndef _di_fl_environment_path_explode_reverse_
+ f_return_status fl_environment_path_explode_reverse(const f_string path, f_string_dynamics *paths) {
+ #ifndef _di_level_0_parameter_checking_
+ if (paths == 0) return F_status_set_error(F_parameter);
+ if (paths->used > paths->size) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ f_status status = F_none;
+ const f_string_length length = strnlen(path, PATH_MAX);
+
+ if (length == 0) {
+ // When PATH is "", this is actually a valid search path for PWD.
+ // Therefore append an equivalent representation of PWD (string used length is 0).
+ f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
+ if (F_status_is_error(status)) return status;
+
+ paths->array[paths->used].string = 0;
+ paths->array[paths->used].used = 0;
+ paths->array[paths->used].size = 0;
+ paths->used++;
+
+ return F_none;
+ }
+
+ f_string_length i = length;
+ f_string_length j = length;
+ f_string_length last = length;
+ f_string_length total = 0;
+
+ f_string_dynamic part = f_string_dynamic_initialize;
+
+ for (; i > 0; i--) {
+ j--;
+
+ if (j == 0 || path[j] == f_path_separator_variable[0]) {
+ f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
+ if (F_status_is_error(status)) return status;
+
+ if (path[j] == f_path_separator_variable[0]) {
+ total = last - i;
+
+ if (total > 0) {
+ if (path[j + total] == f_path_separator[0]) {
+ f_macro_string_dynamic_new(status, part, total);
+ if (F_status_is_error(status)) return status;
+
+ part.used = total;
+ }
+ else {
+ f_macro_string_dynamic_new(status, part, total + 1);
+ if (F_status_is_error(status)) return status;
+
+ part.string[total] = f_path_separator[0];
+ part.used = total + 1;
+ }
+
+ memcpy(part.string, path + i, total);
+ }
+
+ last = j;
+ }
+ else if (j == 0) {
+ // when j = 0, the total is actually the entire length to max.
+ total = last - j;
+
+ if (total > 0) {
+ if (path[last - 1] == f_path_separator[0]) {
+ f_macro_string_dynamic_new(status, part, total);
+ if (F_status_is_error(status)) return status;
+
+ part.used = total;
+ }
+ else {
+ f_macro_string_dynamic_new(status, part, total + 1);
+ if (F_status_is_error(status)) return status;
+
+ part.used = total + 1;
+ part.string[total] = f_path_separator[0];
+ }
+
+ memcpy(part.string, path, total);
+ }
+ }
+
+ paths->array[paths->used].string = part.string;
+ paths->array[paths->used].used = part.used;
+ paths->array[paths->used].size = part.size;
+ paths->used++;
+ }
+ } // for
+
+ return F_none;
+ }
+#endif // _di_fl_environment_path_explode_reverse_
+
+#ifndef _di_fl_environment_path_explode_reverse_dynamic_
+ f_return_status fl_environment_path_explode_reverse_dynamic(const f_string_static path, f_string_dynamics *paths) {
+ #ifndef _di_level_0_parameter_checking_
+ if (path.used > path.size) return F_status_set_error(F_parameter);
+ if (paths == 0) return F_status_set_error(F_parameter);
+ if (paths->used > paths->size) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ f_status status = F_none;
+
+ if (path.used == 0) {
+ // When PATH is "", this is actually a valid search path for PWD.
+ // Therefore append an equivalent representation of PWD (string used length is 0).
+ f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
+ if (F_status_is_error(status)) return status;
+
+ f_macro_string_dynamic_clear(paths->array[paths->used]);
+ paths->used++;
+
+ return F_none;
+ }
+
+ f_string_length i = path.used;
+ f_string_length j = path.used;
+ f_string_length k = 0;
+ f_string_length last = path.used;
+ f_string_length total = 0;
+
+ f_string_dynamic part = f_string_dynamic_initialize;
+
+ for (; i > 0; i--) {
+ j--;
+
+ if (j == 0 || path.string[j] == f_path_separator_variable[0]) {
+ f_macro_memory_structure_macro_increment(status, (*paths), 1, f_memory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large);
+ if (F_status_is_error(status)) return status;
+
+ if (path.string[j] == f_path_separator_variable[0]) {
+ total = last - i;
+
+ if (total > 0) {
+ f_macro_string_dynamic_new(status, part, total);
+ if (F_status_is_error(status)) return status;
+
+ for (k = 0; k < total; k++) {
+ if (path.string[i + k] == 0) continue;
+
+ part.string[part.used] = path.string[i + k];
+ part.used++;
+ } // for
+
+ if (part.string[part.used - 1] != f_path_separator[0]) {
+ f_macro_string_dynamic_resize(status, part, total + 1);
+ if (F_status_is_error(status)) return status;
+
+ part.string[part.used] = f_path_separator[0];
+ part.used++;
+ }
+ }
+
+ last = j;
+ }
+ else if (j == 0) {
+ // when j = 0, the total is actually the entire length to max.
+ total = last - j;
+
+ f_macro_string_dynamic_new(status, part, total);
+ if (F_status_is_error(status)) return status;
+
+ for (k = 0; k < total; k++) {
+ if (path.string[i + k] == 0) continue;
+
+ part.string[part.used] = path.string[i + k];
+ part.used++;
+ } // for
+
+ if (part.string[part.used - 1] != f_path_separator[0]) {
+ f_macro_string_dynamic_resize(status, part, total + 1);
+ if (F_status_is_error(status)) return status;
+
+ part.string[part.used - 1] = f_path_separator[0];
+ part.used++;
+ }
+ }
+
+ paths->array[paths->used].string = part.string;
+ paths->array[paths->used].used = part.used;
+ paths->array[paths->used].size = part.size;
+ paths->used++;
+ }
+ } // for
+
+ return F_none;
+ }
+#endif // _di_fl_environment_path_explode_reverse_dynamic_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 1
+ *
+ * Project: Environment
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * Provides environment processing functionality, such as environment variable handling.
+ */
+#ifndef _FL_environment_h
+#define _FL_environment_h
+
+#include <stdio.h>
+#include <sys/stat.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>
+#include <level_0/path.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Separate a given PATH-style string into multiple separate paths.
+ *
+ * @param path
+ * The string to process that is expected to follow the traditional Linux standard PATH environment variable.
+ * Each seperate path is separated by a single ':'.
+ * Must not contain NULLs except for the terminating NULL.
+ * Must be NULL terminated.
+ * @param paths
+ * All of the strings exploded from PATH.
+ * Each exploded path, when not empty, is guaranteed to have a trailing '/'.
+ * Each exploded path is not NULL terminated.
+ *
+ * @return
+ * F_none on success.
+ * F_buffer_too_large (with error bit) if paths array is too large for further addressing.
+ * F_memory_reallocation (with error bit) on reallocation error.
+ * F_memory_allocation (with error bit) on allocation error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_environment_path_explode_
+ extern f_return_status fl_environment_path_explode(const f_string path, f_string_dynamics *paths);
+#endif // _di_fl_environment_path_explode_
+
+/**
+ * Separate a given PATH-style string into multiple separate paths.
+ *
+ * @param path
+ * The string to process that is expected to follow the traditional Linux standard PATH environment variable.
+ * Each seperate path is separated by a single ':'.
+ * Need not be NULL terminated.
+ * NULLs are ignored and are not copied into the exploded paths.
+ * @param paths
+ * All of the strings exploded from PATH.
+ * Each exploded path, when not empty, is guaranteed to have a trailing '/'.
+ * Each exploded path is not NULL terminated.
+ *
+ * @return
+ * F_none on success.
+ * F_buffer_too_large (with error bit) if paths array is too large for further addressing.
+ * F_memory_reallocation (with error bit) on reallocation error.
+ * F_memory_allocation (with error bit) on allocation error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_environment_path_explode_dynamic_
+ extern f_return_status fl_environment_path_explode_dynamic(const f_string_static path, f_string_dynamics *paths);
+#endif // _di_fl_environment_path_explode_dynamic_
+
+/**
+ * Separate a given PATH-style string into multiple separate paths.
+ *
+ * The paths are created in reverse order.
+ *
+ * @param path
+ * The string to process that is expected to follow the traditional Linux standard PATH environment variable.
+ * Each seperate path is separated by a single ':'.
+ * Must not contain NULLs except for the terminating NULL.
+ * Must be NULL terminated.
+ * @param paths
+ * All of the strings exploded from PATH.
+ * Each exploded path, when not empty, is guaranteed to have a trailing '/'.
+ * Each exploded path is not NULL terminated.
+ *
+ * @return
+ * F_none on success.
+ * F_buffer_too_large (with error bit) if paths array is too large for further addressing.
+ * F_memory_reallocation (with error bit) on reallocation error.
+ * F_memory_allocation (with error bit) on allocation error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_environment_path_explode_reverse_
+ extern f_return_status fl_environment_path_explode_reverse(const f_string path, f_string_dynamics *paths);
+#endif // _di_fl_environment_path_explode_reverse_
+
+/**
+ * Separate a given PATH-style string into multiple separate paths.
+ *
+ * The paths are created in reverse order.
+ *
+ * @param path
+ * The string to process that is expected to follow the traditional Linux standard PATH environment variable.
+ * Each seperate path is separated by a single ':'.
+ * Need not be NULL terminated.
+ * NULLs are ignored and are not copied into the exploded paths.
+ * @param paths
+ * All of the strings exploded from PATH.
+ * Each exploded path, when not empty, is guaranteed to have a trailing '/'.
+ * Each exploded path is not NULL terminated.
+ *
+ * @return
+ * F_none on success.
+ * F_buffer_too_large (with error bit) if paths array is too large for further addressing.
+ * F_memory_reallocation (with error bit) on reallocation error.
+ * F_memory_allocation (with error bit) on allocation error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_environment_path_explode_reverse_dynamic_
+ extern f_return_status fl_environment_path_explode_reverse_dynamic(const f_string_static path, f_string_dynamics *paths);
+#endif // _di_fl_environment_path_explode_reverse_dynamic_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _FL_environment_h
--- /dev/null
+# fss-0000
+
--- /dev/null
+# fss-0000
+
+f_type
+f_status
+f_memory
+f_string
+f_utf
+f_environment
+f_path
--- /dev/null
+# fss-0001
+
+project_name fl_environment
+
+version_major 0
+version_minor 5
+version_micro 0
+version_target major
+
+environment
+
+process_pre
+process_post
+
+modes individual
+modes_default individual
+
+build_compiler gcc
+build_language c
+build_linker ar
+build_libraries -lc
+build_libraries-individual -lf_environment -lf_path -lf_utf -lf_memory
+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_1
+path_library_script script
+path_library_shared shared
+path_library_static static
+path_program_script script
+path_program_shared shared
+path_program_static static
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines_all
+defines_static
+defines_shared
+
+flags_all -z now -g
+flags_shared
+flags_static
+flags_library -fPIC
+flags_program -fPIE
}
}
else {
- status = f_environment_path_explode_dynamic(path, &paths);
+ status = fl_environment_path_explode_dynamic(path, &paths);
}
if (F_status_is_error(status)) {
#include <level_0/path.h>
// fll-1 includes
+#include <level_1/environment.h>
#include <level_1/string.h>
#ifdef __cplusplus
f_environment
f_file
f_path
+fl_environment
fl_string
build_language c
build_linker ar
build_libraries -lc
-build_libraries-individual -lfl_string -lf_utf -lf_path -lf_file -lf_environment -lf_memory
+build_libraries-individual -lfl_environment -lfl_string -lf_utf -lf_path -lf_file -lf_environment -lf_memory
build_sources_library execute.c private-execute.c
build_sources_program
build_sources_headers execute.h
--- /dev/null
+#include <level_2/path.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fll_path_canonical_
+ f_return_status fll_path_canonical(const f_string path, f_string_dynamic *canonical) {
+ #ifndef _di_level_2_parameter_checking_
+ if (canonical == 0) return F_status_set_error(F_parameter);
+ #endif // _di_level_2_parameter_checking_
+
+ f_status status = F_none;
+ f_string_length at = 0;
+
+ uint8_t previous_1 = 0;
+ uint8_t previous_2 = 0;
+
+ f_string_length size_chunk = 0;
+ f_string_length position = 0;
+
+ canonical->used = 0;
+
+ if (path[0] == '/') {
+ previous_1 = '/';
+ at = 1;
+ }
+ else {
+ status = f_path_current(F_true, canonical);
+ if (F_status_is_error(status)) return status;
+
+ if (!path[0]) {
+ return F_none;
+ }
+ }
+
+ status = fl_string_append_assure("/", 1, canonical);
+ if (F_status_is_error(status)) return status;
+
+ for (; path[at]; at++) {
+
+ if (!size_chunk && path[at] == '.') {
+ if (!previous_1 || previous_1 == '/') {
+ previous_1 = '.';
+ previous_2 = 0;
+ continue;
+ }
+
+ if (previous_1 == '.') {
+ if (previous_2) {
+ previous_1 = 0;
+ previous_2 = 0;
+ size_chunk = 3;
+ position = at - 2;
+ }
+ else {
+ previous_2 = '.';
+ }
+ }
+ }
+ else if (path[at] == '/') {
+ if (previous_1 == '/') {
+ size_chunk = 0;
+ position = 0;
+ continue;
+ }
+
+ if (previous_1 == '.') {
+ if (previous_2 == '.') {
+ if (canonical->used > 1) {
+ for (canonical->used--; canonical->used > 0; canonical->used--) {
+ if (canonical->string[canonical->used - 1] == '/') break;
+ } // for
+ }
+ }
+ }
+ else {
+ size_chunk++;
+
+ status = fl_string_append(path + position, size_chunk, canonical);
+ if (F_status_is_error(status)) return status;
+ }
+
+ previous_1 = '/';
+ previous_2 = 0;
+ size_chunk = 0;
+ position = 0;
+ }
+ else {
+ if (!size_chunk) {
+ position = at;
+
+ if (previous_2) {
+ position -= 2;
+ size_chunk = 2;
+ }
+ else if (previous_1) {
+ position--;
+ size_chunk = 1;
+ }
+ }
+
+ if (previous_1) {
+ previous_1 = 0;
+ previous_2 = 0;
+ }
+
+ size_chunk++;
+ }
+ } // for
+
+ if (previous_2 == '.') {
+ if (canonical->used > 1) {
+ for (canonical->used--; canonical->used > 0; canonical->used--) {
+ if (canonical->string[canonical->used - 1] == '/') break;
+ } // for
+ }
+ }
+ else if (!(previous_1 == '.' || previous_1 == '/')) {
+ if (size_chunk) {
+ status = fl_string_append(path + position, size_chunk, canonical);
+ if (F_status_is_error(status)) return status;
+ }
+ }
+
+ // assure there is no trailing forward slash, unless it is the first slash.
+ if (canonical->used > 1 && canonical->string[canonical->used - 1] == '/') {
+ canonical->used--;
+ }
+
+ status = fl_string_dynamic_terminate_after(canonical);
+ if (F_status_is_error(status)) return status;
+
+ return F_none;
+ }
+#endif // _di_fll_path_canonical_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 2
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * Provides path-related functionality.
+ */
+#ifndef _FLL_path_h
+#define _FLL_path_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/path.h>
+
+// fll-1 includes
+#include <level_1/string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Get the canonical (real) path for some path.
+ *
+ * This does not check if the path exists or not.
+ * This processes the relative parts: './', '../', and extra '/'.
+ * This does not process symbolic links.
+ * This has a max size of f_string_length_size.
+ *
+ * @param path
+ * The source path to determine what the canonical path is.
+ * This is a NULL terminated string.
+ * @param canonical
+ * The (allocated) canonical file path.
+ * The canonical->used is reset to 0 before processing.
+ * This will be NULL terminated at canonical->used + 1.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fll_path_canonical_
+ extern f_return_status fll_path_canonical(const f_string path, f_string_dynamic *canonical);
+#endif // _di_fll_path_canonical_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _FLL_path_h
--- /dev/null
+# fss-0000
+
--- /dev/null
+# fss-0000
+
+f_type
+f_status
+f_memory
+f_string
+f_path
+fl_string
--- /dev/null
+# fss-0001
+
+project_name fll_path
+
+version_major 0
+version_minor 5
+version_micro 0
+version_target major
+
+environment
+
+process_pre
+process_post
+
+modes individual
+modes_default individual
+
+build_compiler gcc
+build_language c
+build_linker ar
+build_libraries -lc
+build_libraries-individual -lfl_string -lf_path -lf_memory
+build_sources_library path.c
+build_sources_program
+build_sources_headers path.h
+build_sources_script
+build_sources_setting
+build_script yes
+build_shared yes
+build_static yes
+
+path_headers level_2
+path_library_script script
+path_library_shared shared
+path_library_static static
+path_program_script script
+path_program_shared shared
+path_program_static static
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines_all
+defines_static
+defines_shared
+
+flags_all -z now -g
+flags_shared
+flags_static
+flags_library -fPIC
+flags_program -fPIE
#include <level_2/fss.h>
#include <level_2/fss_basic_list.h>
#include <level_2/fss_extended.h>
+#include <level_2/path.h>
#include <level_2/program.h>
#ifdef __cplusplus
data_make->path_cache.used = 0;
- f_status status = f_path_real(path.string, &data_make->path_cache);
+ f_status status = fll_path_canonical(path.string, &data_make->path_cache);
if (F_status_is_error(status)) return status;
if (data_make->path_cache.used < data_make->path.stack.array[0].used) {
fake_make_operate_expand(data, section->name, operation, *operation_name, section->contents.array[i], section->quotedss.array[i], data_make, &arguments[i], status);
if (F_status_is_error(*status)) break;
- fake_make_operate_validate(data, section->name, operation, *operation_name, *data_make, arguments[i], operation_if, status);
+ fake_make_operate_validate(data, section->name, operation, *operation_name, arguments[i], operation_if, data_make, status);
if (operation_if) {
if (operation_if == fake_make_operation_if_type_if) {
*status = f_file_touch(arguments.array[1].string, mode.regular, F_false);
if (F_status_is_error(*status)) {
- fake_print_error(data, F_status_set_fine(*status), "f_file_touch", F_true);
+ if (F_status_is_fine(fll_path_canonical(arguments.array[1].string, &data_make->path_cache))) {
+ fake_print_error_file(data, F_status_set_fine(*status), "f_file_touch", data_make->path_cache.string, "touch", F_true, F_true);
+ }
+ else {
+ fake_print_error_file(data, F_status_set_fine(*status), "f_file_touch", arguments.array[1].string, "touch", F_true, F_true);
+ }
+
return;
}
}
*status = f_directory_touch(arguments.array[1].string, mode.directory);
if (F_status_is_error(*status)) {
- fake_print_error(data, F_status_set_fine(*status), "f_directory_touch", F_true);
+ if (F_status_is_fine(fll_path_canonical(arguments.array[1].string, &data_make->path_cache))) {
+ fake_print_error_file(data, F_status_set_fine(*status), "f_directory_touch", data_make->path_cache.string, "touch", F_false, F_true);
+ }
+ else {
+ fake_print_error_file(data, F_status_set_fine(*status), "f_directory_touch", arguments.array[1].string, "touch", F_false, F_true);
+ }
+
return;
}
}
#endif // _di_fake_make_operate_process_run_
#ifndef _di_fake_make_operate_validate_
- void fake_make_operate_validate(const fake_data data, const f_string_range section_name, const f_array_length operation, const f_string_static operation_name, const fake_make_data data_make, const f_string_dynamics arguments, const uint8_t operation_if, f_status *status) {
+ void fake_make_operate_validate(const fake_data data, const f_string_range section_name, const f_array_length operation, const f_string_static operation_name, const f_string_dynamics arguments, const uint8_t operation_if, fake_make_data *data_make, f_status *status) {
if (F_status_is_error(*status)) return;
if (operation == fake_make_operation_type_archive || operation == fake_make_operation_type_run || operation == fake_make_operation_type_shell) {
*status = F_status_set_error(F_failure);
}
else if (operation == fake_make_operation_type_pop) {
- if (data_make.path.stack.used == 1) {
+ if (data_make->path.stack.used == 1) {
printf("%c", f_string_eol[0]);
fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Must not attempt to pop project root off of path stack.");
}
}
- // @todo: fake_make_assure_inside_project
+ *status = fake_make_assure_inside_project(data, arguments.array[1], data_make);
+ if (F_status_is_error(*status)) {
+ fake_print_error_fakefile_section_operation_path_outside(data, F_status_set_fine(*status), "fake_make_assure_inside_project", arguments.array[1].string);
+
+ if (F_status_set_fine(*status) == F_false) {
+ *status = F_status_set_error(F_failure);
+ }
+ }
}
else {
printf("%c", f_string_eol[0]);
* The operation being performed.
* @param operation_name
* The operation name.
- * @param data_make
- * All make related setting data, including data from the fakefile and optionally build settings file.
* @param arguments
* The expanded arguments.
* @param operation_if
* The if-condition status for the current operation.
+ * @param data_make
+ * All make related setting data, including data from the fakefile and optionally build settings file.
* @param status
* The return status.
*
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_fake_make_operate_validate_
- extern void fake_make_operate_validate(const fake_data data, const f_string_range section_name, const f_array_length operation, const f_string_static operation_name, const fake_make_data data_make, const f_string_dynamics arguments, const uint8_t operation_if, f_status *status) f_gcc_attribute_visibility_internal;
+ extern void fake_make_operate_validate(const fake_data data, const f_string_range section_name, const f_array_length operation, const f_string_static operation_name, const f_string_dynamics arguments, const uint8_t operation_if, fake_make_data *data_make, f_status *status) f_gcc_attribute_visibility_internal;
#endif // _di_fake_make_operate_validate_
/**
fl_utf
fll_fss
fll_execute
+fll_path
fll_program
build_language c
build_linker ar
build_libraries -lc
-build_libraries-individual -lfll_program -lfll_execute -lfll_fss -lfl_utf -lfl_string -lfl_status -lfl_iki -lfl_fss -lfl_directory -lfl_conversion -lfl_console -lfl_color -lf_print -lf_path -lf_iki -lf_file -lf_fss -lf_environment -lf_directory -lf_conversion -lf_console -lf_utf -lf_memory
+build_libraries-individual -lfll_execute -lfll_fss -lfll_path -lfll_program -lfl_utf -lfl_string -lfl_status -lfl_iki -lfl_fss -lfl_directory -lfl_conversion -lfl_console -lfl_color -lf_print -lf_path -lf_iki -lf_file -lf_fss -lf_environment -lf_directory -lf_conversion -lf_console -lf_utf -lf_memory
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