#include "command.h" #include #include #include #include struct b_command_option *b_command_option_create(void) { struct b_command_option *out = malloc(sizeof *out); if (!out) { return out; } memset(out, 0x0, sizeof *out); return out; } void b_command_option_destroy(struct b_command_option *opt) { if (opt->opt_long_name) { free(opt->opt_long_name); } if (opt->opt_description) { free(opt->opt_description); } b_queue_iterator it = {0}; b_queue_iterator_begin(&opt->opt_args, &it); while (b_queue_iterator_is_valid(&it)) { struct b_command_arg *arg = b_unbox(struct b_command_arg, it.entry, arg_entry); if (!arg) { break; } b_queue_iterator_erase(&it); b_command_arg_destroy(arg); } free(opt); } b_status b_command_option_set_long_name( struct b_command_option *opt, const char *name) { char *n = b_strdup(name); if (!n) { return B_ERR_NO_MEMORY; } if (opt->opt_long_name) { free(opt->opt_long_name); opt->opt_long_name = NULL; } opt->opt_long_name = n; return B_SUCCESS; } b_status b_command_option_set_short_name(struct b_command_option *opt, char name) { opt->opt_short_name = name; return B_SUCCESS; } b_status b_command_option_set_description( struct b_command_option *opt, const char *description) { char *desc = b_strdup(description); if (!desc) { return B_ERR_NO_MEMORY; } if (opt->opt_description) { free(opt->opt_description); opt->opt_description = NULL; } opt->opt_description = desc; return B_SUCCESS; } struct b_command_arg *b_command_option_add_arg(struct b_command_option *opt, int id) { struct b_command_arg *arg = malloc(sizeof *arg); if (!arg) { return NULL; } memset(arg, 0x0, sizeof *arg); arg->arg_id = id; b_queue_push_back(&opt->opt_args, &arg->arg_entry); return arg; } void z__b_get_option_description(struct b_command_option *opt, b_string *out) { if (opt->opt_description) { b_string_append_cstr(out, opt->opt_description); } size_t nr_args = b_queue_length(&opt->opt_args); bool close_bracket = false; b_queue_iterator it; b_queue_foreach (&it, &opt->opt_args) { struct b_command_arg *arg = b_unbox(struct b_command_arg, it.entry, arg_entry); if (!arg || !arg->arg_allowed_values) { continue; } if (it.i > 0) { b_string_append_cstr(out, "; "); } else { b_string_append_cstr(out, " [["); close_bracket = true; } if (nr_args > 1) { b_string_append_cstrf( out, "values for `%s`:", arg->arg_name); } else { b_string_append_cstr(out, "values:"); } for (size_t i = 0; arg->arg_allowed_values[i]; i++) { if (i > 0) { b_string_append_cstr(out, ","); } b_string_append_cstrf( out, " " F_GREEN "%s" F_RESET, arg->arg_allowed_values[i]); } } if (close_bracket) { b_string_append_cstr(out, "]"); } } void z__b_get_option_usage_string( struct b_command_option *opt, enum cmd_string_flags flags, b_string *out) { if (flags & CMD_STR_DIRECT_USAGE) { b_string_append_cstr(out, "{"); } if (opt->opt_short_name) { b_string_append_cstrf( out, (flags & CMD_STR_COLOUR) ? F_GREEN "-%c" F_RESET : "-%c", opt->opt_short_name); } if (opt->opt_short_name && opt->opt_long_name) { b_string_append_cstr( out, (flags & CMD_STR_DIRECT_USAGE) ? "|" : ", "); } if (opt->opt_long_name) { b_string_append_cstrf( out, (flags & CMD_STR_COLOUR) ? F_GREEN "--%s" F_RESET : "--%s", opt->opt_long_name); } if (flags & CMD_STR_DIRECT_USAGE) { b_string_append_cstr(out, "}"); } b_queue_iterator it; b_queue_foreach (&it, &opt->opt_args) { struct b_command_arg *arg = b_unbox(struct b_command_arg, it.entry, arg_entry); if (!arg) { continue; } bool optional = false, multi = false; switch (arg->arg_nr_values) { case B_ARG_0_OR_1_VALUES: optional = true; multi = false; break; case B_ARG_0_OR_MORE_VALUES: optional = true; multi = true; break; case B_ARG_1_OR_MORE_VALUES: optional = false; multi = true; break; default: optional = false; multi = false; break; } if (optional) { b_string_append_cstrf( out, (flags & CMD_STR_COLOUR) ? " " F_GREEN "[%s]" : " [%s]", arg->arg_name); } else { b_string_append_cstrf( out, (flags & CMD_STR_COLOUR) ? " " F_GREEN "<%s>" : " <%s>", arg->arg_name); } for (int i = 1; i < arg->arg_nr_values; i++) { b_string_append_cstrf(out, " <%s>", arg->arg_name); } if (multi) { b_string_append_cstr(out, "..."); } if (flags & CMD_STR_COLOUR) { b_string_append_cstr(out, F_RESET); } } } struct b_command_arg *b_command_option_get_arg_with_id( struct b_command_option *opt, unsigned int id) { b_queue_iterator it; b_queue_foreach (&it, &opt->opt_args) { struct b_command_arg *arg = b_unbox(struct b_command_arg, it.entry, arg_entry); if (!arg) { continue; } if (arg->arg_id == id) { return arg; } } return NULL; }