Refactored cli-syntax code to use cligen pt_head instead (long overdue)
This commit is contained in:
parent
e1a8e0d40b
commit
b39ee078c4
7 changed files with 124 additions and 274 deletions
|
|
@ -65,6 +65,7 @@ Developers may need to change their code
|
|||
|
||||
### Minor features
|
||||
|
||||
* Refactored cli-syntax code to use cligen pt_head instead (long overdue)
|
||||
* Modified backend exit strategy so that 2nd ^C actually exits
|
||||
* Performance: A change in the `merge` code made "co-located" config and non-config get retrieval go considerable faster. This is done by a specialized `xml_child_each_attr()` function.
|
||||
* CLI: Added `show statistics` example code for backend and CLI memory stats
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ struct cli_handle {
|
|||
/* ------ end of common handle ------ */
|
||||
|
||||
cligen_handle cl_cligen; /* cligen handle */
|
||||
cli_syntax_t *cl_stx; /* CLI syntax structure */
|
||||
};
|
||||
|
||||
/*! Return a clicon handle for other CLICON API calls
|
||||
|
|
@ -121,14 +120,9 @@ int
|
|||
cli_handle_exit(clicon_handle h)
|
||||
{
|
||||
cligen_handle ch = cligen(h);
|
||||
struct cli_handle *cl = handle(h);
|
||||
|
||||
if (cl->cl_stx)
|
||||
free(cl->cl_stx);
|
||||
clicon_handle_exit(h); /* frees h and options */
|
||||
|
||||
cligen_exit(ch);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -136,28 +130,6 @@ cli_handle_exit(clicon_handle h)
|
|||
* cli-specific handle access functions
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*! Get current syntax-group */
|
||||
cli_syntax_t *
|
||||
cli_syntax(clicon_handle h)
|
||||
{
|
||||
struct cli_handle *cl = handle(h);
|
||||
return cl->cl_stx;
|
||||
}
|
||||
|
||||
/*! Set current syntax-group */
|
||||
int
|
||||
cli_syntax_set(clicon_handle h,
|
||||
cli_syntax_t *stx)
|
||||
{
|
||||
struct cli_handle *cl = handle(h);
|
||||
|
||||
if (cl->cl_stx)
|
||||
free(cl->cl_stx);
|
||||
cl->cl_stx = stx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*! Return clicon handle */
|
||||
cligen_handle
|
||||
cli_cligen(clicon_handle h)
|
||||
|
|
|
|||
|
|
@ -57,9 +57,4 @@ int cli_prompt_set(clicon_handle h, char *prompt);
|
|||
|
||||
int cli_logsyntax_set(clicon_handle h, int status);
|
||||
|
||||
/* Internal functions for handling cli groups */
|
||||
cli_syntax_t *cli_syntax(clicon_handle h);
|
||||
|
||||
int cli_syntax_set(clicon_handle h, cli_syntax_t *stx);
|
||||
|
||||
#endif /* _CLI_HANDLE_H_ */
|
||||
|
|
|
|||
|
|
@ -239,13 +239,18 @@ cli_interactive(clicon_handle h)
|
|||
char *new_mode;
|
||||
cligen_result result;
|
||||
int ret;
|
||||
pt_head *ph;
|
||||
|
||||
/* Loop through all commands */
|
||||
while(!cligen_exiting(cli_cligen(h))) {
|
||||
new_mode = cli_syntax_mode(h);
|
||||
if ((ph = cligen_pt_head_active_get(cli_cligen(h))) == NULL){
|
||||
clicon_err(OE_UNIX, 0, "active tree not found");
|
||||
goto done;
|
||||
}
|
||||
new_mode = cligen_ph_name_get(ph);
|
||||
cmd = NULL;
|
||||
/* Read a CLI string, including expand handling */
|
||||
if ((ret = clicon_cliread(h, &cmd)) < 0)
|
||||
if ((ret = clicon_cliread(h, ph, &cmd)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
continue;
|
||||
|
|
@ -686,7 +691,7 @@ main(int argc,
|
|||
{
|
||||
char *dir;
|
||||
/* Load cli .so plugins before yangs are loaded (eg extension callbacks) and
|
||||
* before CLI is loaded by cli_syntax_load below */
|
||||
* before CLI is loaded by clispec_load below */
|
||||
if ((dir = clicon_cli_dir(h)) != NULL &&
|
||||
clixon_plugins_load(h, CLIXON_PLUGIN_INIT, dir, NULL) < 0)
|
||||
goto done;
|
||||
|
|
@ -752,7 +757,7 @@ main(int argc,
|
|||
|
||||
/* Initialize cli syntax.
|
||||
* Plugins have already been loaded by clixon_plugins_load above */
|
||||
if (cli_syntax_load(h) < 0)
|
||||
if (clispec_load(h) < 0)
|
||||
goto done;
|
||||
|
||||
/* Set syntax mode if specified from command-line or config-file. */
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
|
@ -80,117 +79,34 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/*! Find syntax mode named 'mode'. Create if specified
|
||||
*/
|
||||
static cli_syntaxmode_t *
|
||||
syntax_mode_find(cli_syntax_t *stx,
|
||||
const char *mode,
|
||||
int create)
|
||||
{
|
||||
cli_syntaxmode_t *csm;
|
||||
|
||||
csm = stx->stx_modes;
|
||||
if (csm) {
|
||||
do {
|
||||
if (strcmp(csm->csm_name, mode) == 0)
|
||||
return csm;
|
||||
csm = NEXTQ(cli_syntaxmode_t *, csm);
|
||||
} while (csm && csm != stx->stx_modes);
|
||||
}
|
||||
|
||||
if (create == 0)
|
||||
return NULL;
|
||||
|
||||
if ((csm = malloc(sizeof(cli_syntaxmode_t))) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
return NULL;
|
||||
}
|
||||
memset(csm, 0, sizeof(*csm));
|
||||
if ((csm->csm_name = strdup(mode)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "strdup");
|
||||
return NULL;
|
||||
}
|
||||
if ((csm->csm_prompt = strdup(CLI_DEFAULT_PROMPT)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "strdup");
|
||||
return NULL;
|
||||
}
|
||||
if ((csm->csm_pt = pt_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "pt_new");
|
||||
return NULL;
|
||||
}
|
||||
INSQ(csm, stx->stx_modes);
|
||||
stx->stx_nmodes++;
|
||||
|
||||
return csm;
|
||||
}
|
||||
|
||||
/*! Generate parse tree for syntax mode
|
||||
/*! Generate CLIgen parse tree for syntax mode
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] m Syntax mode struct
|
||||
*/
|
||||
static int
|
||||
gen_parse_tree(clicon_handle h,
|
||||
cli_syntaxmode_t *m)
|
||||
char *name,
|
||||
parse_tree *pt,
|
||||
pt_head **php)
|
||||
{
|
||||
int retval = -1;
|
||||
pt_head *ph;
|
||||
|
||||
if ((ph = cligen_ph_add(cli_cligen(h), m->csm_name)) == NULL)
|
||||
if ((ph = cligen_ph_add(cli_cligen(h), name)) == NULL)
|
||||
goto done;
|
||||
if (cligen_ph_parsetree_set(ph, m->csm_pt) < 0)
|
||||
if (cligen_ph_parsetree_set(ph, pt) < 0)
|
||||
goto done;
|
||||
if (cligen_ph_prompt_set(ph, CLI_DEFAULT_PROMPT) < 0){
|
||||
clicon_err(OE_UNIX, errno, "cligen_ph_prompt_set");
|
||||
goto done;
|
||||
}
|
||||
*php = ph;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Append syntax
|
||||
* @param[in] h Clicon handle
|
||||
*/
|
||||
static int
|
||||
syntax_append(clicon_handle h,
|
||||
cli_syntax_t *stx,
|
||||
const char *name,
|
||||
parse_tree *pt)
|
||||
{
|
||||
cli_syntaxmode_t *csm;
|
||||
|
||||
if ((csm = syntax_mode_find(stx, name, 1)) == NULL)
|
||||
return -1;
|
||||
if (cligen_parsetree_merge(csm->csm_pt, NULL, pt) < 0){
|
||||
clicon_err(OE_PLUGIN, errno, "cligen_parsetree_merge");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Remove all cligen syntax modes
|
||||
* @param[in] h Clicon handle
|
||||
*/
|
||||
static int
|
||||
cli_syntax_unload(clicon_handle h)
|
||||
{
|
||||
cli_syntax_t *stx = cli_syntax(h);
|
||||
cli_syntaxmode_t *csm;
|
||||
|
||||
if (stx == NULL)
|
||||
return 0;
|
||||
|
||||
while (stx->stx_nmodes > 0) {
|
||||
csm = stx->stx_modes;
|
||||
DELQ(csm, stx->stx_modes, cli_syntaxmode_t *);
|
||||
if (csm){
|
||||
if (csm->csm_name)
|
||||
free(csm->csm_name);
|
||||
if (csm->csm_prompt)
|
||||
free(csm->csm_prompt);
|
||||
free(csm);
|
||||
}
|
||||
stx->stx_nmodes--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Dynamic linking loader string to function mapper
|
||||
*
|
||||
* Maps strings from the CLI specification file to real funtions using dlopen
|
||||
|
|
@ -247,7 +163,7 @@ clixon_str2fn(char *name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*! Load a file containing syntax and append to specified modes, also load C plugin
|
||||
/*! Load a file containing clispec syntax and append to specified modes, also load C plugin
|
||||
*
|
||||
* First load CLIgen file,
|
||||
* Then find which .so to load by looking in the "CLICON_PLUGIN" variable in that file.
|
||||
|
|
@ -257,13 +173,15 @@ clixon_str2fn(char *name,
|
|||
* @param[in] filename Name of file where syntax is specified (in syntax-group dir)
|
||||
* @param[in] dir Name of dir, or NULL
|
||||
* @param[out] ptall Universal CLIgen parse tree: apply to all modes
|
||||
* @param[out] modes Keep track of all modes
|
||||
* @see clixon_plugins_load Where .so plugin code has been loaded prior to this
|
||||
*/
|
||||
static int
|
||||
cli_load_syntax_file(clicon_handle h,
|
||||
clispec_load_file(clicon_handle h,
|
||||
const char *filename,
|
||||
const char *dir,
|
||||
parse_tree *ptall)
|
||||
parse_tree *ptall,
|
||||
cvec *modes)
|
||||
{
|
||||
void *handle = NULL; /* Handle to plugin .so module */
|
||||
char *mode = NULL; /* Name of syntax mode to append new syntax */
|
||||
|
|
@ -274,8 +192,10 @@ cli_load_syntax_file(clicon_handle h,
|
|||
cvec *cvv = NULL;
|
||||
char *prompt = NULL;
|
||||
char **vec = NULL;
|
||||
int i, nvec;
|
||||
int i;
|
||||
int nvec;
|
||||
char *plgnam;
|
||||
pt_head *ph;
|
||||
#ifndef CLIXON_STATIC_PLUGINS
|
||||
clixon_plugin_t *cp;
|
||||
#endif
|
||||
|
|
@ -299,7 +219,7 @@ cli_load_syntax_file(clicon_handle h,
|
|||
}
|
||||
|
||||
/* Assuming this plugin is first in queue */
|
||||
if (cli_parse_file(h, f, filepath, pt, cvv) < 0){
|
||||
if (clispec_parse_file(h, f, filepath, NULL, pt, cvv) < 0){
|
||||
clicon_err(OE_PLUGIN, 0, "failed to parse cli file %s", filepath);
|
||||
fclose(f);
|
||||
goto done;
|
||||
|
|
@ -309,6 +229,7 @@ cli_load_syntax_file(clicon_handle h,
|
|||
* CLICON_MODE: which mode(s) this syntax applies to
|
||||
* CLICON_PROMPT: Cli prompt in this mode (see cli_prompt_get)
|
||||
* CLICON_PLUGIN: Name of C API plugin
|
||||
* CLICON_PIPETREE: terminals are automatically expanded with this tree
|
||||
* Note: the base case is that it is:
|
||||
* (1) a single mode or
|
||||
* (2) "*" all modes or "m1:m2" - a list of modes
|
||||
|
|
@ -330,6 +251,7 @@ cli_load_syntax_file(clicon_handle h,
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Resolve callback names to function pointers. */
|
||||
if (cligen_callbackv_str2fn(pt, (cgv_str2fn_t*)clixon_str2fn, handle) < 0){
|
||||
clicon_err(OE_PLUGIN, 0, "Mismatch between CLIgen file '%s' and CLI plugin file '%s'. Some possible errors:\n\t1. A function given in the CLIgen file does not exist in the plugin (ie link error)\n\t2. The CLIgen spec does not point to the correct plugin .so file (CLICON_PLUGIN=\"%s\" is wrong)",
|
||||
|
|
@ -366,17 +288,42 @@ cli_load_syntax_file(clicon_handle h,
|
|||
}
|
||||
else {
|
||||
for (i = 0; i < nvec; i++) {
|
||||
if (syntax_append(h,
|
||||
cli_syntax(h),
|
||||
vec[i],
|
||||
pt) < 0) {
|
||||
char *name = vec[i];
|
||||
parse_tree *ptnew = NULL;
|
||||
cg_var *cv;
|
||||
if ((ph = cligen_ph_find(cli_cligen(h), name)) == NULL){
|
||||
if ((ptnew = pt_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "pt_new");
|
||||
goto done;
|
||||
}
|
||||
if (prompt)
|
||||
cli_set_prompt(h, vec[i], prompt);
|
||||
if (gen_parse_tree(h, name, ptnew, &ph) < 0)
|
||||
goto done;
|
||||
if (ph == NULL)
|
||||
goto done;
|
||||
if ((cv = cv_new(CGV_STRING)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cv_new");
|
||||
goto done;
|
||||
}
|
||||
cv_string_set(cv, name);
|
||||
if (cvec_append_var(modes, cv) < 0){
|
||||
clicon_err(OE_UNIX, errno, "cvec_append_var");
|
||||
goto done;
|
||||
}
|
||||
if (cv)
|
||||
cv_free(cv);
|
||||
}
|
||||
if (cligen_parsetree_merge(cligen_ph_parsetree_get(ph), NULL, pt) < 0){
|
||||
clicon_err(OE_PLUGIN, errno, "cligen_parsetree_merge");
|
||||
goto done;
|
||||
}
|
||||
if (prompt){
|
||||
if (cligen_ph_prompt_set(ph, prompt) < 0){
|
||||
clicon_err(OE_UNIX, errno, "cligen_ph_prompt_set");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cligen_parsetree_free(pt, 1);
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -395,7 +342,7 @@ done:
|
|||
* XXX The parsetree loading needs a rewrite for multiple parse-trees
|
||||
*/
|
||||
int
|
||||
cli_syntax_load(clicon_handle h)
|
||||
clispec_load(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
char *clispec_dir = NULL;
|
||||
|
|
@ -403,37 +350,29 @@ cli_syntax_load(clicon_handle h)
|
|||
int ndp;
|
||||
int i;
|
||||
struct dirent *dp = NULL;
|
||||
cli_syntax_t *stx;
|
||||
cli_syntaxmode_t *m;
|
||||
cligen_susp_cb_t *fns = NULL;
|
||||
cligen_interrupt_cb_t *fni = NULL;
|
||||
clixon_plugin_t *cp;
|
||||
parse_tree *ptall = NULL; /* Universal CLIgen parse tree all modes */
|
||||
cvec *modes = NULL; /* Keep track of created modes */
|
||||
pt_head *ph;
|
||||
cg_var *cv = NULL;
|
||||
|
||||
/* Syntax already loaded. XXX should we re-load?? */
|
||||
if ((stx = cli_syntax(h)) != NULL)
|
||||
return 0;
|
||||
if ((ptall = pt_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "pt_new");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((modes = cvec_new(0)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||
goto done;
|
||||
}
|
||||
/* Format plugin directory path */
|
||||
clispec_dir = clicon_clispec_dir(h);
|
||||
clispec_file = clicon_option_str(h, "CLICON_CLISPEC_FILE");
|
||||
|
||||
/* Allocate plugin group object */
|
||||
if ((stx = malloc(sizeof(*stx))) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
memset(stx, 0, sizeof(*stx)); /* Zero out all */
|
||||
|
||||
cli_syntax_set(h, stx);
|
||||
|
||||
/* Load single specific clispec file */
|
||||
if (clispec_file){
|
||||
if (cli_load_syntax_file(h, clispec_file, NULL, ptall) < 0)
|
||||
if (clispec_load_file(h, clispec_file, NULL, ptall, modes) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* Load all clispec .cli files in directory */
|
||||
|
|
@ -443,33 +382,31 @@ cli_syntax_load(clicon_handle h)
|
|||
goto done;
|
||||
/* Load the syntax parse trees into cli_syntax stx structure */
|
||||
for (i = 0; i < ndp; i++) {
|
||||
clicon_debug(1, "DEBUG: Loading syntax '%.*s'",
|
||||
(int)strlen(dp[i].d_name)-4, dp[i].d_name);
|
||||
if (cli_load_syntax_file(h, dp[i].d_name, clispec_dir, ptall) < 0)
|
||||
clicon_debug(CLIXON_DBG_DEFAULT, "Loading clispec syntax: '%s/%s'",
|
||||
clispec_dir, dp[i].d_name);
|
||||
if (clispec_load_file(h, dp[i].d_name, clispec_dir, ptall, modes) < 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
/* Were any syntax modes successfully loaded? If not, leave */
|
||||
if (stx->stx_nmodes <= 0) {
|
||||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (cvec_len(modes) == 0)
|
||||
goto ok;
|
||||
/* Go thorugh all modes and :
|
||||
* 1) Add the universal syntax
|
||||
* 2) add syntax tree (of those modes - "activate" syntax from stx to CLIgen)
|
||||
*/
|
||||
m = stx->stx_modes;
|
||||
do {
|
||||
if (cligen_parsetree_merge(m->csm_pt, NULL, ptall) < 0){
|
||||
cv = NULL;
|
||||
while ((cv = cvec_each(modes, cv)) != NULL){
|
||||
if ((ph = cligen_ph_find(cli_cligen(h), cv_string_get(cv))) == NULL)
|
||||
continue;
|
||||
|
||||
if (cligen_parsetree_merge(cligen_ph_parsetree_get(ph),
|
||||
NULL,
|
||||
ptall) < 0){
|
||||
clicon_err(OE_PLUGIN, errno, "cligen_parsetree_merge");
|
||||
goto done;
|
||||
}
|
||||
if (gen_parse_tree(h, m) != 0)
|
||||
goto done;
|
||||
m = NEXTQ(cli_syntaxmode_t *, m);
|
||||
} while (m && m != stx->stx_modes);
|
||||
|
||||
}
|
||||
/* Set susp and interrupt callbacks into CLIgen */
|
||||
cp = NULL;
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
|
|
@ -480,29 +417,24 @@ cli_syntax_load(clicon_handle h)
|
|||
if (cli_interrupt_hook(h, fni) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
ok:
|
||||
/* All good. We can now proudly return a new group */
|
||||
retval = 0;
|
||||
done:
|
||||
if (retval != 0) {
|
||||
cli_syntax_unload(h);
|
||||
cli_syntax_set(h, NULL);
|
||||
}
|
||||
cligen_parsetree_free(ptall, 1);
|
||||
if (modes)
|
||||
cvec_free(modes);
|
||||
if (dp)
|
||||
free(dp);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Remove syntax modes and remove syntax
|
||||
/*! Free resources in plugin
|
||||
* @param[in] h Clicon handle
|
||||
*/
|
||||
int
|
||||
cli_plugin_finish(clicon_handle h)
|
||||
{
|
||||
/* Remove all cligen syntax modes */
|
||||
cli_syntax_unload(h);
|
||||
cli_syntax_set(h, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -556,8 +488,6 @@ clicon_parse(clicon_handle h,
|
|||
int retval = -1;
|
||||
char *modename;
|
||||
int ret;
|
||||
cli_syntax_t *stx = NULL;
|
||||
cli_syntaxmode_t *csm;
|
||||
parse_tree *pt; /* Orig */
|
||||
cg_obj *match_obj = NULL;
|
||||
cvec *cvv = NULL;
|
||||
|
|
@ -565,24 +495,16 @@ clicon_parse(clicon_handle h,
|
|||
FILE *f;
|
||||
char *reason = NULL;
|
||||
cligen_handle ch;
|
||||
pt_head *ph;
|
||||
|
||||
ch = cli_cligen(h);
|
||||
if (clicon_get_logflags()&CLICON_LOG_STDOUT)
|
||||
f = stdout;
|
||||
else
|
||||
f = stderr;
|
||||
stx = cli_syntax(h);
|
||||
if ((modename = *modenamep) == NULL) {
|
||||
csm = stx->stx_active_mode;
|
||||
modename = csm->csm_name;
|
||||
}
|
||||
else {
|
||||
if ((csm = syntax_mode_find(stx, modename, 0)) == NULL) {
|
||||
fprintf(f, "Can't find syntax mode '%s'\n", modename);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (csm != NULL){
|
||||
modename = *modenamep;
|
||||
ph = cligen_ph_find(cli_cligen(h), modename);
|
||||
if (ph != NULL){
|
||||
if (cligen_ph_active_set_byname(ch, modename) < 0){
|
||||
fprintf(f, "No such parse-tree registered: %s\n", modename);
|
||||
goto done;
|
||||
|
|
@ -743,7 +665,9 @@ cli_prompt_get(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Read command from CLIgen's cliread() using current syntax mode.
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] ph Parse-tree head
|
||||
* @param[out] stringp Pointer to command buffer or NULL on EOF
|
||||
* @retval 1 OK
|
||||
* @retval 0 Fail but continue
|
||||
|
|
@ -751,36 +675,35 @@ cli_prompt_get(clicon_handle h,
|
|||
*/
|
||||
int
|
||||
clicon_cliread(clicon_handle h,
|
||||
pt_head *ph,
|
||||
char **stringp)
|
||||
{
|
||||
int retval = -1;
|
||||
char *name;
|
||||
char *pfmt = NULL;
|
||||
cli_syntaxmode_t *mode;
|
||||
cli_syntax_t *stx;
|
||||
cli_prompthook_t *fn;
|
||||
clixon_plugin_t *cp;
|
||||
char *promptstr;
|
||||
|
||||
stx = cli_syntax(h);
|
||||
mode = stx->stx_active_mode;
|
||||
name = cligen_ph_name_get(ph);
|
||||
/* Get prompt from plugin callback? */
|
||||
cp = NULL;
|
||||
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_prompt) == NULL)
|
||||
continue;
|
||||
pfmt = fn(h, mode->csm_name);
|
||||
pfmt = fn(h, name);
|
||||
break;
|
||||
}
|
||||
if (clicon_quiet_mode(h))
|
||||
cli_prompt_set(h, "");
|
||||
else{
|
||||
if ((promptstr = cli_prompt_get(h, pfmt ? pfmt : mode->csm_prompt)) == NULL)
|
||||
if ((promptstr = cli_prompt_get(h,
|
||||
pfmt?pfmt:cligen_ph_prompt_get(ph)
|
||||
)) == NULL)
|
||||
goto done;
|
||||
cli_prompt_set(h, promptstr);
|
||||
free(promptstr);
|
||||
}
|
||||
cligen_ph_active_set_byname(cli_cligen(h), mode->csm_name);
|
||||
|
||||
clicon_err_reset();
|
||||
if (cliread(cli_cligen(h), stringp) < 0){
|
||||
cli_handler_err(stdout);
|
||||
|
|
@ -807,17 +730,19 @@ clicon_cliread(clicon_handle h,
|
|||
|
||||
/*! Set syntax mode mode for existing current plugin group.
|
||||
* @param[in] h Clicon handle
|
||||
* @retval 1 OK
|
||||
* @retval 0 Not found / error
|
||||
*/
|
||||
int
|
||||
cli_set_syntax_mode(clicon_handle h,
|
||||
const char *name)
|
||||
char *name)
|
||||
{
|
||||
cli_syntaxmode_t *mode;
|
||||
|
||||
if ((mode = syntax_mode_find(cli_syntax(h), name, 1)) == NULL)
|
||||
pt_head *ph;
|
||||
|
||||
if ((ph = cligen_ph_find(cli_cligen(h), name)) == NULL)
|
||||
return 0;
|
||||
|
||||
cli_syntax(h)->stx_active_mode = mode;
|
||||
cligen_pt_head_active_set(cli_cligen(h), ph);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -827,38 +752,10 @@ cli_set_syntax_mode(clicon_handle h,
|
|||
char *
|
||||
cli_syntax_mode(clicon_handle h)
|
||||
{
|
||||
cli_syntaxmode_t *csm;
|
||||
pt_head *ph;
|
||||
|
||||
if ((csm = cli_syntax(h)->stx_active_mode) == NULL)
|
||||
if ((ph = cligen_pt_head_active_get(cli_cligen(h))) == NULL)
|
||||
return NULL;
|
||||
return csm->csm_name;
|
||||
}
|
||||
|
||||
/*! Callback from cli_set_prompt(). Set prompt format for syntax mode
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] name Name of syntax mode
|
||||
* @param[in] prompt Prompt format
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
cli_set_prompt(clicon_handle h,
|
||||
const char *name,
|
||||
const char *prompt)
|
||||
{
|
||||
cli_syntaxmode_t *csm;
|
||||
|
||||
if ((csm = syntax_mode_find(cli_syntax(h), name, 1)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (csm->csm_prompt != NULL){
|
||||
free(csm->csm_prompt);
|
||||
csm->csm_prompt = NULL;
|
||||
}
|
||||
if ((csm->csm_prompt = strdup(prompt)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "strdup");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
return cligen_ph_name_get(ph);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,32 +45,12 @@
|
|||
/* clicon generic callback pointer */
|
||||
typedef void (clicon_callback_t)(clicon_handle h);
|
||||
|
||||
/* List of syntax modes
|
||||
* XXX: syntax modes seem not needed, could be replaced by existing (new) cligen structures, such
|
||||
* as pt_head and others. But code is arcane and difficult to modify.
|
||||
*/
|
||||
typedef struct {
|
||||
qelem_t csm_qelem; /* List header */
|
||||
char *csm_name; /* Syntax mode name */
|
||||
char *csm_prompt; /* Prompt for mode */
|
||||
int csm_nsyntax; /* Num syntax specs registered by plugin */
|
||||
parse_tree *csm_pt; /* CLIgen parse tree */
|
||||
} cli_syntaxmode_t;
|
||||
|
||||
/* Plugin group object. Just a single object, not list. part of cli_handle
|
||||
*/
|
||||
typedef struct {
|
||||
int stx_nmodes; /* Number of syntax modes */
|
||||
cli_syntaxmode_t *stx_active_mode; /* Current active syntax mode */
|
||||
cli_syntaxmode_t *stx_modes; /* List of syntax modes */
|
||||
} cli_syntax_t;
|
||||
|
||||
|
||||
void *clixon_str2fn(char *name, void *handle, char **error);
|
||||
|
||||
int clicon_parse(clicon_handle h, char *cmd, char **mode, cligen_result *result, int *evalres);
|
||||
|
||||
int clicon_cliread(clicon_handle h, char **stringp);
|
||||
int clicon_cliread(clicon_handle h, pt_head *ph, char **stringp);
|
||||
|
||||
int cli_plugin_finish(clicon_handle h);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ typedef enum autocli_listkw autocli_listkw_t;
|
|||
* Function Declarations
|
||||
*/
|
||||
/* cli_plugin.c */
|
||||
int cli_set_syntax_mode(clicon_handle h, const char *mode);
|
||||
int cli_set_syntax_mode(clicon_handle h, char *mode);
|
||||
char *cli_syntax_mode(clicon_handle h);
|
||||
int cli_syntax_load(clicon_handle h);
|
||||
int clispec_load(clicon_handle h);
|
||||
int cli_handler_err(FILE *fd);
|
||||
int cli_set_prompt(clicon_handle h, const char *mode, const char *prompt);
|
||||
int cli_set_prompt(clicon_handle h, char *mode, char *prompt);
|
||||
int cli_ptpush(clicon_handle h, char *mode, char *string, char *op);
|
||||
int cli_ptpop(clicon_handle h, char *mode, char *op);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue