extern "C" {
#endif
+#ifndef _fl_console_parameter_to_string_dynamic_directory_
+ f_return_status fl_console_parameter_to_string_dynamic_directory(const f_string argument, f_string_dynamic *directory) {
+ f_status status = f_none;
+ f_string_length length = strlen(argument);
+
+ if (length == 0) {
+ directory->used = 0;
+ return f_none;
+ }
+
+ if (length > 1) {
+ while (length > 1 && argument[length - 1] == '/') {
+ length--;
+ } // while
+
+ if (argument[0] == '/') {
+ f_string_length begin = 1;
+
+ while (begin < length && argument[begin] == '/') {
+ begin++;
+ } // while
+
+ length -= begin;
+
+ if (length > 0) {
+ length += 2;
+
+ f_macro_string_dynamic_new(status, (*directory), length);
+ if (f_status_is_error(status)) return status;
+
+ memcpy(directory->string + 1, argument + begin, length - 2);
+
+ directory->used = length;
+ directory->size = length;
+ directory->string[0] = '/';
+ directory->string[length - 1] = '/';
+ }
+ else {
+ f_macro_string_dynamic_new(status, (*directory), 1);
+ if (f_status_is_error(status)) return status;
+
+ directory->used = 1;
+ directory->size = 1;
+ directory->string[0] = '/';
+ }
+ }
+ else if (length > 3 && argument[0] == '.' && argument[1] == '.' && argument[2] == '/') {
+ f_string_length begin = 3;
+
+ while (begin < length && argument[begin] == '/') {
+ begin++;
+ } // while
+
+ length -= begin;
+
+ if (length > 0) {
+ length += 4;
+
+ f_macro_string_dynamic_new(status, (*directory), length);
+ if (f_status_is_error(status)) return status;
+
+ memcpy(directory->string + 3, argument + begin, length - 4);
+
+ directory->used = length;
+ directory->size = length;
+ directory->string[0] = '.';
+ directory->string[1] = '.';
+ directory->string[2] = '/';
+ directory->string[length - 1] = '/';
+ }
+ else {
+ f_macro_string_dynamic_new(status, (*directory), 3);
+ if (f_status_is_error(status)) return status;
+
+ directory->used = 3;
+ directory->size = 3;
+ directory->string[0] = '.';
+ directory->string[1] = '.';
+ directory->string[2] = '/';
+ }
+ }
+ else if (length > 2 && argument[0] == '.' && argument[1] == '/') {
+ f_string_length begin = 2;
+
+ while (begin < length && argument[begin] == '/') {
+ begin++;
+ } // while
+
+ length -= begin;
+
+ if (length > 0) {
+ length += 3;
+
+ f_macro_string_dynamic_new(status, (*directory), length);
+ if (f_status_is_error(status)) return status;
+
+ memcpy(directory->string + 2, argument + begin, length - 3);
+
+ directory->used = length;
+ directory->size = length;
+ directory->string[0] = '.';
+ directory->string[1] = '/';
+ directory->string[length - 1] = '/';
+ }
+ else {
+ f_macro_string_dynamic_new(status, (*directory), 2);
+ if (f_status_is_error(status)) return status;
+
+ directory->used = 2;
+ directory->size = 2;
+ directory->string[0] = '.';
+ directory->string[1] = '/';
+ }
+ }
+ else {
+ length++;
+
+ f_macro_string_dynamic_new(status, (*directory), length);
+ if (f_status_is_error(status)) return status;
+
+ memcpy(directory->string, argument, length - 1);
+
+ directory->used = length;
+ directory->size = length;
+ directory->string[length - 1] = '/';
+ }
+ }
+ else if (argument[0] != '/') {
+ f_macro_string_dynamic_new(status, (*directory), 2);
+ if (f_status_is_error(status)) return status;
+
+ memcpy(directory->string, argument, 2);
+
+ directory->used = 2;
+ directory->size = 2;
+ directory->string[1] = '/';
+ }
+ else {
+ f_macro_string_dynamic_new(status, (*directory), 1);
+ if (f_status_is_error(status)) return status;
+
+ memcpy(directory->string, argument, 1);
+
+ directory->used = 1;
+ directory->size = 1;
+ }
+
+ return f_none;
+ }
+#endif // _fl_console_parameter_to_string_dynamic_directory_
+
#ifndef _fl_console_parameter_to_number_signed_
f_return_status fl_console_parameter_to_number_signed(const f_string argument, f_number_signed *number) {
#ifndef _di_level_0_parameter_checking_
// libc include
#include <limits.h>
#include <string.h>
+#include <sys/stat.h>
// fll-0 includes
#include <level_0/console.h>
#endif
/**
+ * Validate and convert a console parameter additional argument to a file directory in a dynamic string.
+ *
+ * The directory path is validated to exist.
+ *
+ * The path to a directy has the following very basic cleanup operations performed:
+ * - Ensures that it always ends in a '/'.
+ * - Ensures that multiple '/' in front or multiple '/' at end of string is reduced to a single '/' in front and a single '/' at end.
+ * - Ensures that multiple '/' following './' at the start of the string is reduced to only './' ('.////' would become './').
+ * - Ensures that multiple '/' following '../' at the start of the string is reduced to only '../' ('..////' would become '../').
+ *
+ * This does not perform complex cleanup, such as '..///..///' to '../../'.
+ *
+ * The purpose of the cleanups is to ensure/enforce a consistent beginning and ending of the path strings.
+ * These path strings can then, very simply, be checked to see how to join them with another string, such as a filename.
+ *
+ * @param argv
+ * The argument string expected to be a number.
+ * This is generally passed from the argv[].
+ * @param directory
+ * The dynamically allocated processed directory string.
+ *
+ * @return
+ * f_none on success.
+ * f_error_allocation (with error bit) on allocation error.
+ */
+#ifndef _fl_console_parameter_to_string_dynamic_directory_
+ extern f_return_status fl_console_parameter_to_string_dynamic_directory(const f_string argument, f_string_dynamic *directory);
+#endif // _fl_console_parameter_to_string_dynamic_directory_
+
+/**
* Convert a console parameter additional argument to a signed integer.
*
* This will detect based types as follows:
* @see f_conversion_string_to_number_signed()
*/
#ifndef _fl_console_parameter_to_number_signed_
- f_return_status fl_console_parameter_to_number_signed(const f_string argument, f_number_signed *number);
+ extern f_return_status fl_console_parameter_to_number_signed(const f_string argument, f_number_signed *number);
#endif // _fl_console_parameter_to_number_signed_
/**
* @see f_conversion_string_to_number_unsigned()
*/
#ifndef _fl_console_parameter_to_number_unsigned_
- f_return_status fl_console_parameter_to_number_unsigned(const f_string argument, f_number_unsigned *number);
+ extern f_return_status fl_console_parameter_to_number_unsigned(const f_string argument, f_number_unsigned *number);
#endif // _fl_console_parameter_to_number_unsigned_
#ifdef __cplusplus