/* * param.c * * This file provides the implementation of the "param" class */ #include "private.h" #include "lub/string.h" #include "clish/variable.h" #include #include #include #include /*--------------------------------------------------------- * PRIVATE METHODS *--------------------------------------------------------- */ static void clish_param_init(clish_param_t * this, const char *name, const char *text, clish_ptype_t * ptype) { /* initialise the help part */ this->name = lub_string_dup(name); this->text = lub_string_dup(text); this->ptype = ptype; /* set up defaults */ this->defval = NULL; this->mode = CLISH_PARAM_COMMON; this->optional = BOOL_FALSE; this->value = NULL; this->hidden = BOOL_FALSE; this->test = NULL; this->paramv = clish_paramv_new(); } /*--------------------------------------------------------- */ static void clish_param_fini(clish_param_t * this) { /* deallocate the memory for this instance */ lub_string_free(this->defval); this->defval = NULL; lub_string_free(this->name); this->name = NULL; lub_string_free(this->text); this->text = NULL; lub_string_free(this->value); this->value = NULL; lub_string_free(this->test); this->test = NULL; clish_paramv_delete(this->paramv); } /*--------------------------------------------------------- * PUBLIC META FUNCTIONS *--------------------------------------------------------- */ clish_param_t *clish_param_new(const char *name, const char *text, clish_ptype_t * ptype) { clish_param_t *this = malloc(sizeof(clish_param_t)); if (this) { clish_param_init(this, name, text, ptype); } return this; } /*--------------------------------------------------------- * PUBLIC METHODS *--------------------------------------------------------- */ void clish_param_delete(clish_param_t * this) { clish_param_fini(this); free(this); } /*--------------------------------------------------------- */ void clish_param_insert_param(clish_param_t * this, clish_param_t * param) { return clish_paramv_insert(this->paramv, param); } /*--------------------------------------------------------- * PUBLIC ATTRIBUTES *--------------------------------------------------------- */ const char *clish_param__get_name(const clish_param_t * this) { if (!this) return NULL; return this->name; } /*--------------------------------------------------------- */ const char *clish_param__get_text(const clish_param_t * this) { return this->text; } /*--------------------------------------------------------- */ const char *clish_param__get_range(const clish_param_t * this) { return clish_ptype__get_range(this->ptype); } /*--------------------------------------------------------- */ clish_ptype_t *clish_param__get_ptype(const clish_param_t * this) { return this->ptype; } /*--------------------------------------------------------- */ void clish_param__set_default(clish_param_t * this, const char *defval) { assert(NULL == this->defval); this->defval = lub_string_dup(defval); } /*--------------------------------------------------------- */ const char *clish_param__get_default(const clish_param_t * this) { return this->defval; } /*--------------------------------------------------------- */ void clish_param__set_mode(clish_param_t * this, clish_param_mode_e mode) { assert(this); this->mode = mode; } /*--------------------------------------------------------- */ clish_param_mode_e clish_param__get_mode(const clish_param_t * this) { return this->mode; } /*--------------------------------------------------------- */ char *clish_param_validate(const clish_param_t * this, const char *text) { if (CLISH_PARAM_SUBCOMMAND == clish_param__get_mode(this)) { if (lub_string_nocasecmp(clish_param__get_value(this), text)) return NULL; } return clish_ptype_translate(this->ptype, text); } /*--------------------------------------------------------- */ void clish_param_help(const clish_param_t * this, size_t offset) { const char *range = clish_ptype__get_range(this->ptype); const char *name; if (CLISH_PARAM_SWITCH == clish_param__get_mode(this)) { unsigned rec_paramc = clish_param__get_param_count(this); clish_param_t *cparam; unsigned i; for (i = 0; i < rec_paramc; i++) { cparam = clish_param__get_param(this, i); if (!cparam) break; clish_param_help(cparam, offset); } return; } if (CLISH_PARAM_SUBCOMMAND == clish_param__get_mode(this)) name = clish_param__get_value(this); else { if (!(name = clish_ptype__get_text(this->ptype))) name = clish_ptype__get_name(this->ptype); } fprintf(stderr, "%s %*c%s", name, (int)(offset - strlen(name)), ' ', this->text); if (NULL != range) { fprintf(stderr, " (%s)", range); } fprintf(stderr, "\n"); } /*--------------------------------------------------------- */ void clish_param_help_arrow(const clish_param_t * this, size_t offset) { fprintf(stderr, "%*c\n", (int)offset, '^'); } /*--------------------------------------------------------- */ clish_param_t *clish_param__get_param(const clish_param_t * this, unsigned index) { return clish_paramv__get_param(this->paramv, index); } /*--------------------------------------------------------- */ clish_paramv_t *clish_param__get_paramv(clish_param_t * this) { return this->paramv; } /*--------------------------------------------------------- */ const unsigned clish_param__get_param_count(const clish_param_t * this) { return clish_paramv__get_count(this->paramv); } /*--------------------------------------------------------- */ void clish_param__set_optional(clish_param_t * this, bool_t optional) { this->optional = optional; } /*--------------------------------------------------------- */ bool_t clish_param__get_optional(const clish_param_t * this) { return this->optional; } /*--------------------------------------------------------- */ /* paramv methods */ /*--------------------------------------------------------- */ static void clish_paramv_init(clish_paramv_t * this) { this->paramc = 0; this->paramv = NULL; } /*--------------------------------------------------------- */ static void clish_paramv_fini(clish_paramv_t * this) { unsigned i; /* finalize each of the parameter instances */ for (i = 0; i < this->paramc; i++) { clish_param_delete(this->paramv[i]); } /* free the parameter vector */ free(this->paramv); this->paramc = 0; } /*--------------------------------------------------------- */ clish_paramv_t *clish_paramv_new(void) { clish_paramv_t *this = malloc(sizeof(clish_paramv_t)); if (this) { clish_paramv_init(this); } return this; } /*--------------------------------------------------------- */ void clish_paramv_delete(clish_paramv_t * this) { clish_paramv_fini(this); free(this); } /*--------------------------------------------------------- */ void clish_paramv_insert(clish_paramv_t * this, clish_param_t * param) { size_t new_size = ((this->paramc + 1) * sizeof(clish_param_t *)); clish_param_t **tmp; /* resize the parameter vector */ tmp = realloc(this->paramv, new_size); if (NULL != tmp) { this->paramv = tmp; /* insert reference to the parameter */ this->paramv[this->paramc++] = param; } } /*--------------------------------------------------------- */ clish_param_t *clish_paramv__get_param(const clish_paramv_t * this, unsigned index) { clish_param_t *result = NULL; if (index < this->paramc) { result = this->paramv[index]; } return result; } /*--------------------------------------------------------- */ const unsigned clish_paramv__get_count(const clish_paramv_t * this) { return this->paramc; } /*--------------------------------------------------------- */ void clish_param__set_value(clish_param_t * this, const char * value) { assert(NULL == this->value); this->value = lub_string_dup(value); } /*--------------------------------------------------------- */ char *clish_param__get_value(const clish_param_t * this) { if (this->value) return this->value; return this->name; } /*--------------------------------------------------------- */ void clish_param__set_hidden(clish_param_t * this, bool_t hidden) { this->hidden = hidden; } /*--------------------------------------------------------- */ bool_t clish_param__get_hidden(const clish_param_t * this) { return this->hidden; } /*--------------------------------------------------------- */ void clish_param__set_test(clish_param_t * this, const char *test) { assert(NULL == this->test); this->test = lub_string_dup(test); } /*--------------------------------------------------------- */ char *clish_param__get_test(const clish_param_t * this, const char * viewid, const clish_command_t * cmd, clish_pargv_t * pargv) { if (!this->test) return NULL; return clish_variable_expand(this->test, viewid, cmd, pargv); }