Simplify the code for determining which console parameter of some set of console parameters has priority.
Abstract this functionality into its own function so that other projects can leverage this.
The functions in fl_console should be prefixed with fl_console.
#endif // _di_f_console_parameter_
/**
+ * Provide a helper structure for references and processing parameters.
+ *
+ * The f_console_parameter_id is designed to be used for the enums to represent a any given parameter by the ID.
+ *
+ * The f_console_parameter_ids is designed for passing this to a function as a single argument.
+ * The "ids" property is intended to be populated with an aray of f_console_parameter_id whose size is defined by the "used" property.
+ * This follows the idea of f_string_dynamic and has a "used" instead of length, but because this is not intended to be dynamically allocated there is no "size" property.
+ */
+#ifndef _di_f_console_parameter_id_
+ typedef uint16_t f_console_parameter_id;
+
+ typedef struct {
+ f_console_parameter_id *ids;
+ f_array_length used;
+ } f_console_parameter_ids;
+
+ #define f_console_parameter_ids_initialize { 0, 0 }
+#endif // _di_f_console_parameter_id_
+
+/**
* Determine the type code the given input parameter represents.
*
* @param input
extern "C" {
#endif
-#ifndef _di_fl_process_parameters_
- f_return_status fl_process_parameters(const f_array_length argc, const f_string argv[], f_console_parameter parameters[], const f_array_length total_parameters, f_string_lengths *remaining) {
+#ifndef _di_fl_console_parameter_process_
+ f_return_status fl_console_parameter_process(const f_array_length argc, const f_string argv[], f_console_parameter parameters[], const f_array_length parameters_total, f_string_lengths *remaining) {
#ifndef _di_level_1_parameter_checking_
if (remaining == 0) return f_status_set_error(f_invalid_parameter);
#endif // _di_level_1_parameter_checking_
else if (console_short > f_console_none) {
// The sub_location is used on a per increment basis (such as 'tar -xcf', the '-' would have an increment of 1, therefore x, c, and f would all be three separate parameters).
while (sub_location < string_length) {
- for (parameter_counter = 0; parameter_counter < total_parameters; parameter_counter++) {
+ for (parameter_counter = 0; parameter_counter < parameters_total; parameter_counter++) {
if (parameters[parameter_counter].type != console_type) {
continue;
}
else {
found = f_false;
- for (parameter_counter = 0; parameter_counter < total_parameters; parameter_counter++) {
+ for (parameter_counter = 0; parameter_counter < parameters_total; parameter_counter++) {
if (parameters[parameter_counter].type != f_console_type_other) {
continue;
}
return status;
}
-#endif // _di_fl_process_parameters_
+#endif // _di_fl_console_parameter_process_
+
+#ifndef _di_fl_console_parameter_prioritize_
+ f_return_status fl_console_parameter_prioritize(const f_console_parameter parameters[], const f_array_length parameters_total, const f_console_parameter_ids choices, f_console_parameter_id *decision) {
+ #ifndef _di_level_1_parameter_checking_
+ if (decision == 0) return f_status_set_error(f_invalid_parameter);
+ if (parameters_total == 0) return f_status_set_error(f_invalid_parameter);
+ if (choices.ids == 0) return f_status_set_error(f_invalid_parameter);
+ if (choices.used == 0) return f_status_set_error(f_invalid_parameter);
+ #endif // _di_level_1_parameter_checking_
+
+ f_array_length location = 0;
+ f_array_length location_sub = 0;
+ f_console_parameter_id priority = 0;
+
+ for (f_array_length i = 0; i < choices.used; i++) {
+ if (choices.ids[i] > parameters_total) return f_status_set_error(f_invalid_parameter);
+
+ if (parameters[choices.ids[i]].result == f_console_result_found) {
+ if (parameters[choices.ids[i]].location > location) {
+ location = parameters[choices.ids[i]].location;
+ location_sub = parameters[choices.ids[i]].location_sub;
+ priority = choices.ids[i];
+ }
+ else if (parameters[choices.ids[i]].location == location && parameters[choices.ids[i]].location_sub > location_sub) {
+ location_sub = parameters[choices.ids[i]].location_sub;
+ priority = choices.ids[i];
+ }
+ }
+ } // for
+
+ // The first parameter location (argc = 0) is the program name, therefore if the location is 0, then no matches were found.
+ if (location == 0) {
+ return f_no_data;
+ }
+
+ *decision = priority;
+
+ return f_none;
+ }
+#endif // _di_fl_console_parameter_prioritize__
#ifdef __cplusplus
} // extern "C"
* The parameters passed to the process.
* @param parameters
* The console parameters to look for.
- * @param total_parameters
+ * @param parameters_total
* The used size of the parameters array.
* @param remaining
* A list of remaining parameters not associated with anything.
* f_invalid_parameter (with error bit) if a parameter is invalid.
* f_reallocation_error (with error bit) on memory reallocation error.
*/
-#ifndef _di_fl_process_parameters_
- extern f_return_status fl_process_parameters(const f_array_length argc, const f_string argv[], f_console_parameter parameters[], const f_array_length total_parameters, f_string_lengths *remaining);
-#endif // _di_fl_process_parameters_
+#ifndef _di_fl_console_parameter_process_
+ extern f_return_status fl_console_parameter_process(const f_array_length argc, const f_string argv[], f_console_parameter parameters[], const f_array_length parameters_total, f_string_lengths *remaining);
+#endif // _di_fl_console_parameter_process_
+
+/**
+ * Given a set of parameter choices, determine which one has the highest priority.
+ *
+ * The priority is determined by viewing the parameters from left to right.
+ * The right-most parameter defined in the set has the priority over others.
+ *
+ * For example, the color context modes override each other, so only one gets priority.
+ * If given, say "+l ++no_color +d", the "+d" would be the right-most parameter "+l" and "++no_color".
+ * The decision would be "+d".
+ *
+ * This also applies to short parameters combined into one, such as "+lnd", the "d" would again be the decision.
+ *
+ * @param parameters
+ * The parameters to process.
+ * @param parameters_total
+ * The used size of the parameters array.
+ * @param choices
+ * An array of numeric ids, each representing a parameter within the parameters variable.
+ * The order does not matter.
+ * @param decision
+ * The resulting decision.
+ * If none of the parameters are found, then this will not be updated (therefore it is safe to have it pre-initialized to the default).
+ *
+ * @return
+ * f_none on success.
+ * f_no_data if no parameters were found.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_console_parameter_prioritize__
+ extern f_return_status fl_console_parameter_prioritize(const f_console_parameter parameters[], const f_array_length parameters_total, const f_console_parameter_ids choices, f_console_parameter_id *decision);
+#endif // _di_fl_console_parameter_prioritize__
#ifdef __cplusplus
} // extern "C"
#endif // _di_fll_program_print_version_
#ifndef _di_fll_program_process_parameters_
- f_return_status fll_program_process_parameters(const f_array_length argc, const f_string argv[], f_console_parameter parameters[], const f_array_length total_parameters, const f_array_length parameter_no_color, const f_array_length parameter_light, const f_array_length parameter_dark, f_string_lengths *remaining, fl_color_context *context) {
+ f_return_status fll_program_process_parameters(const f_array_length argc, const f_string argv[], f_console_parameter parameters[], const f_array_length parameters_total, const f_array_length parameter_no_color, const f_array_length parameter_light, const f_array_length parameter_dark, f_string_lengths *remaining, fl_color_context *context) {
f_status status = f_none;
f_status allocation_status = f_none;
- status = fl_process_parameters(argc, argv, parameters, total_parameters, remaining);
+ status = fl_console_parameter_process(argc, argv, parameters, parameters_total, remaining);
- f_string_length color_mode = parameter_dark;
+ f_console_parameter_ids choices = f_console_parameter_ids_initialize;
+ f_console_parameter_id decision = parameter_dark;
+ f_console_parameter_id ids[3] = { parameter_no_color, parameter_light, parameter_dark};
- if (parameters[parameter_no_color].result == f_console_result_found) {
- if (parameters[parameter_light].result == f_console_result_none) {
- if (parameters[parameter_dark].result == f_console_result_none || parameters[parameter_no_color].location > parameters[parameter_dark].location) {
- color_mode = parameter_no_color;
- }
- else if (parameters[parameter_no_color].location == parameters[parameter_dark].location && parameters[parameter_no_color].location_sub > parameters[parameter_dark].location_sub) {
- color_mode = parameter_no_color;
- }
- }
- else {
- if (parameters[parameter_dark].result == f_console_result_none) {
- if (parameters[parameter_no_color].location > parameters[parameter_light].location) {
- color_mode = parameter_no_color;
- }
- else if (parameters[parameter_no_color].location == parameters[parameter_light].location && parameters[parameter_no_color].location_sub > parameters[parameter_light].location_sub) {
- color_mode = parameter_no_color;
- }
- else {
- color_mode = parameter_light;
- }
- }
- else if (parameters[parameter_no_color].location > parameters[parameter_dark].location) {
- if (parameters[parameter_no_color].location > parameters[parameter_light].location) {
- color_mode = parameter_no_color;
- }
- else if (parameters[parameter_no_color].location == parameters[parameter_light].location && parameters[parameter_no_color].location_sub > parameters[parameter_light].location_sub) {
- color_mode = parameter_no_color;
- }
- else {
- color_mode = parameter_light;
- }
- }
- else if (parameters[parameter_no_color].location == parameters[parameter_dark].location && parameters[parameter_no_color].location_sub > parameters[parameter_dark].location_sub) {
- if (parameters[parameter_no_color].location > parameters[parameter_light].location) {
- color_mode = parameter_no_color;
- }
- else if (parameters[parameter_no_color].location == parameters[parameter_light].location && parameters[parameter_no_color].location_sub > parameters[parameter_light].location_sub) {
- color_mode = parameter_no_color;
- }
- else {
- color_mode = parameter_light;
- }
- }
- else if (parameters[parameter_light].location > parameters[parameter_dark].location) {
- color_mode = parameter_light;
- }
- else if (parameters[parameter_light].location == parameters[parameter_dark].location && parameters[parameter_light].location_sub > parameters[parameter_dark].location_sub) {
- color_mode = parameter_light;
- }
- }
- }
- else if (parameters[parameter_light].result == f_console_result_found) {
- if (parameters[parameter_dark].result == f_console_result_none) {
- color_mode = parameter_light;
- }
- else if (parameters[parameter_light].location > parameters[parameter_dark].location) {
- color_mode = parameter_light;
- }
- else if (parameters[parameter_light].location == parameters[parameter_dark].location && parameters[parameter_light].location_sub > parameters[parameter_dark].location_sub) {
- color_mode = parameter_light;
- }
- }
+ choices.ids = ids;
+ choices.used = 3;
+
+ fl_console_parameter_prioritize(parameters, parameters_total, choices, &decision);
// load colors unless told not to.
- if (color_mode != parameter_no_color) {
+ if (decision != parameter_no_color) {
fl_macro_color_context_new(allocation_status, (*context));
if (f_status_is_error(allocation_status)) {
return allocation_status;
}
- fl_color_load_context(context, color_mode == parameter_light);
+ fl_color_load_context(context, decision == parameter_light);
}
if (f_status_is_error(status)) {
fl_color_print_line(f_standard_error, context->error, context->reset, "CRITICAL ERROR: unable to allocate memory.");
}
else if (status == f_invalid_parameter) {
- fl_color_print_line(f_standard_error, context->error, context->reset, "INTERNAL ERROR: Invalid parameter when calling fl_process_parameters().");
+ fl_color_print_line(f_standard_error, context->error, context->reset, "INTERNAL ERROR: Invalid parameter when calling fl_console_parameter_process().");
}
else {
- fl_color_print_line(f_standard_error, context->error, context->reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_process_parameters().", status);
+ fl_color_print_line(f_standard_error, context->error, context->reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_console_parameter_process().", status);
}
return f_status_set_error(status);
* The parameters passed to the process.
* @param parameters
* The console parameters to look for.
- * @param total_parameters
+ * @param parameters_total
* The used size of the parameters array.
* @param parameter_no_color
* The parameter in the parameters array representing the no-color option.
* f_reallocation_error (with error bit) on memory reallocation error.
*/
#ifndef _di_fll_program_process_parameters_
- extern f_return_status fll_program_process_parameters(const f_array_length argc, const f_string argv[], f_console_parameter parameters[], const f_array_length total_parameters, const f_array_length parameter_no_color, const f_array_length parameter_light, const f_array_length parameter_dark, f_string_lengths *remaining, fl_color_context *context);
+ extern f_return_status fll_program_process_parameters(const f_array_length argc, const f_string argv[], f_console_parameter parameters[], const f_array_length parameters_total, const f_array_length parameter_no_color, const f_array_length parameter_light, const f_array_length parameter_dark, f_string_lengths *remaining, fl_color_context *context);
#endif // _di_fll_program_process_parameters_
#ifdef __cplusplus
fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory.");
}
else if (status == f_invalid_parameter) {
- fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_process_parameters().");
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_console_parameter_process().");
}
else {
- fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_process_parameters().", f_status_set_error(status));
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_console_parameter_process().", f_status_set_error(status));
}
fss_extended_write_delete_data(data);