Refactoring for better performance of large auto-cli specs
* Fixed: [very slow execution of load_set_file #288](https://github.com/clicon/clixon/issues/288) * New `clixon-lib@2021-11-11.yang` revision * Modified option: RPC stats extended with YANG stats * Modified `clixon-config@2021-11-11.yang` revision * Added option: * CLICON_PLUGIN_CALLBACK_CHECK * Enable to make plugin context check before and after all callbacks. * Added statistics for YANG: number of objects and memory used * Use the treeref no-copy option of CLIgen to reduce memory * Refactored cli-generation/autocli-start code * Refactored cligen glue functions to use cligen_eval directly (remove clicon_eval,clixon_cligen_eval)
This commit is contained in:
parent
b91ce762d5
commit
5388aace12
29 changed files with 760 additions and 451 deletions
|
|
@ -198,9 +198,9 @@ backend_client_rm(clicon_handle h,
|
|||
* @retval -1 Error
|
||||
*/
|
||||
static int
|
||||
clixon_stats_get_db(clicon_handle h,
|
||||
char *dbname,
|
||||
cbuf *cb)
|
||||
clixon_stats_datastore_get(clicon_handle h,
|
||||
char *dbname,
|
||||
cbuf *cb)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xt = NULL;
|
||||
|
|
@ -234,6 +234,37 @@ clixon_stats_get_db(clicon_handle h,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Get clixon per datastore stats
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] dbname Datastore name
|
||||
* @param[in,out] cb Cligen buf
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
static int
|
||||
clixon_stats_module_get(clicon_handle h,
|
||||
yang_stmt *ys,
|
||||
cbuf *cb)
|
||||
{
|
||||
int retval = -1;
|
||||
uint64_t nr = 0;
|
||||
size_t sz = 0;
|
||||
cxobj *xn = NULL;
|
||||
|
||||
if (ys == NULL)
|
||||
return 0;
|
||||
if (yang_stats(ys, &nr, &sz) < 0)
|
||||
goto done;
|
||||
cprintf(cb, "<module xmlns=\"%s\"><name>%s</name><nr>%" PRIu64 "</nr>"
|
||||
"<size>%zu</size></module>",
|
||||
CLIXON_LIB_NS, yang_argument_get(ys), nr, sz);
|
||||
retval = 0;
|
||||
done:
|
||||
if (xn)
|
||||
xml_free(xn);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Loads all or part of a specified configuration to target configuration
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
|
|
@ -996,19 +1027,41 @@ from_client_stats(clicon_handle h,
|
|||
void *arg,
|
||||
void *regarg)
|
||||
{
|
||||
int retval = -1;
|
||||
uint64_t nr;
|
||||
int retval = -1;
|
||||
uint64_t nr;
|
||||
yang_stmt *ym;
|
||||
|
||||
cprintf(cbret, "<rpc-reply xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
|
||||
xml_stats_global(&nr);
|
||||
cprintf(cbret, "<global xmlns=\"%s\">", CLIXON_LIB_NS);
|
||||
nr=0;
|
||||
xml_stats_global(&nr);
|
||||
cprintf(cbret, "<global xmlns=\"%s\"><xmlnr>%" PRIu64 "</xmlnr></global>", CLIXON_LIB_NS, nr);
|
||||
if (clixon_stats_get_db(h, "running", cbret) < 0)
|
||||
cprintf(cbret, "<xmlnr>%" PRIu64 "</xmlnr>", nr);
|
||||
nr=0;
|
||||
yang_stats_global(&nr);
|
||||
cprintf(cbret, "<yangnr>%" PRIu64 "</yangnr>", nr);
|
||||
cprintf(cbret, "</global>");
|
||||
if (clixon_stats_datastore_get(h, "running", cbret) < 0)
|
||||
goto done;
|
||||
if (clixon_stats_get_db(h, "candidate", cbret) < 0)
|
||||
if (clixon_stats_datastore_get(h, "candidate", cbret) < 0)
|
||||
goto done;
|
||||
if (clixon_stats_get_db(h, "startup", cbret) < 0)
|
||||
if (clixon_stats_datastore_get(h, "startup", cbret) < 0)
|
||||
goto done;
|
||||
ym = NULL;
|
||||
while ((ym = yn_each(clicon_config_yang(h), ym)) != NULL) {
|
||||
if (clixon_stats_module_get(h, ym, cbret) < 0)
|
||||
goto done;
|
||||
}
|
||||
ym = NULL;
|
||||
while ((ym = yn_each(clicon_dbspec_yang(h), ym)) != NULL) {
|
||||
if (clixon_stats_module_get(h, ym, cbret) < 0)
|
||||
goto done;
|
||||
}
|
||||
ym = NULL;
|
||||
while ((ym = yn_each(clicon_nacm_ext_yang(h), ym)) != NULL) {
|
||||
if (clixon_stats_module_get(h, ym, cbret) < 0)
|
||||
goto done;
|
||||
}
|
||||
cprintf(cbret, "</rpc-reply>");
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
|
|||
|
|
@ -931,20 +931,21 @@ from_client_restart_one(clicon_handle h,
|
|||
yang_stmt *yspec;
|
||||
int i;
|
||||
cxobj *xn;
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
if (xmldb_db_reset(h, db) < 0)
|
||||
goto done;
|
||||
/* Application may define extra xml in its reset function*/
|
||||
if ((resetfn = clixon_plugin_api_get(cp)->ca_reset) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if ((retval = resetfn(h, db)) < 0) {
|
||||
clicon_debug(1, "plugin_start() failed");
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* 1. Start transaction */
|
||||
|
|
@ -998,7 +999,6 @@ from_client_restart_one(clicon_handle h,
|
|||
xml_flag_set(xn, XML_FLAG_CHANGE);
|
||||
xml_apply_ancestor(xn, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_CHANGE);
|
||||
}
|
||||
|
||||
/* Call plugin transaction start callbacks */
|
||||
if (plugin_transaction_begin_one(cp, h, td) < 0)
|
||||
goto fail;
|
||||
|
|
@ -1026,8 +1026,6 @@ from_client_restart_one(clicon_handle h,
|
|||
goto fail;
|
||||
retval = 1;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
if (td){
|
||||
xmldb_get0_free(h, &td->td_target);
|
||||
transaction_free(td);
|
||||
|
|
|
|||
|
|
@ -78,26 +78,27 @@ clixon_plugin_reset_one(clixon_plugin_t *cp,
|
|||
clicon_handle h,
|
||||
char *db)
|
||||
{
|
||||
int retval = -1;
|
||||
plgreset_t *fn; /* callback */
|
||||
plugin_context_t *pc = NULL;
|
||||
int retval = -1;
|
||||
plgreset_t *fn; /* callback */
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_reset) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h, db) < 0) {
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: Reset callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -138,26 +139,26 @@ clixon_plugin_pre_daemon_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
plgdaemon_t *fn; /* Daemonize plugin callback function */
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_pre_daemon) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
|
||||
if (fn(h) < 0) {
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: Pre-daemon callback in plugin:\
|
||||
%s returned -1 but did not make a clicon_err call",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -199,24 +200,25 @@ clixon_plugin_daemon_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
plgdaemon_t *fn; /* Daemonize plugin callback function */
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_daemon) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h) < 0) {
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: Daemon callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -283,28 +285,29 @@ clixon_plugin_statedata_one(clixon_plugin_t *cp,
|
|||
int retval = -1;
|
||||
plgstatedata_t *fn; /* Plugin statedata fn */
|
||||
cxobj *x = NULL;
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_statedata) != NULL){
|
||||
if ((x = xml_new(DATASTORE_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL)
|
||||
goto done;
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h, nsc, xpath, x) < 0){
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (clicon_errno < 0)
|
||||
clicon_log(LOG_WARNING, "%s: Internal error: State callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto fail; /* Dont quit here on user callbacks */
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (xp && x)
|
||||
*xp = x;
|
||||
retval = 1;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
|
|
@ -437,20 +440,19 @@ clixon_plugin_lockdb_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
plglockdb_t *fn; /* Plugin statedata fn */
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_lockdb) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h, db, lock, id) < 0)
|
||||
goto done;
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -613,24 +615,25 @@ plugin_transaction_begin_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_begin) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -673,24 +676,26 @@ plugin_transaction_validate_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_validate) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -731,24 +736,25 @@ plugin_transaction_complete_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_complete) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -821,24 +827,25 @@ plugin_transaction_commit_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_commit) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -872,7 +879,6 @@ plugin_transaction_commit_all(clicon_handle h,
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Call single plugin transaction_commit_done() in a commit transaction
|
||||
* @param[in] cp Plugin handle
|
||||
* @param[in] h Clixon handle
|
||||
|
|
@ -887,24 +893,25 @@ plugin_transaction_commit_done_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_commit_done) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -945,24 +952,25 @@ plugin_transaction_end_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_end) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -996,24 +1004,25 @@ plugin_transaction_abort_one(clixon_plugin_t *cp,
|
|||
{
|
||||
int retval = -1;
|
||||
trans_cb_t *fn;
|
||||
plugin_context_t *pc = NULL;
|
||||
void *wh = NULL;
|
||||
|
||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_abort) != NULL){
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
wh = NULL;
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (fn(h, (transaction_data)td) < 0){
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||
goto done;
|
||||
}
|
||||
if (plugin_context_check(pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
if (plugin_context_check(h, &wh, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc)
|
||||
free(pc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,9 +80,9 @@
|
|||
static char *
|
||||
co2apipath(cg_obj *co)
|
||||
{
|
||||
struct cg_callback *cb;
|
||||
cvec *cvv;
|
||||
cg_var *cv;
|
||||
cg_callback *cb;
|
||||
cvec *cvv;
|
||||
cg_var *cv;
|
||||
|
||||
if (co == NULL)
|
||||
return NULL;
|
||||
|
|
@ -467,10 +467,19 @@ cli_auto_edit(clicon_handle h,
|
|||
clicon_err(OE_PLUGIN, 0, "No such parsetree header: %s", treename);
|
||||
goto done;
|
||||
}
|
||||
/* Find the matching cligen object */
|
||||
if ((co = cligen_co_match(cli_cligen(h))) != NULL &&
|
||||
(coorig = co->co_treeref_orig) != NULL)
|
||||
cligen_ph_workpoint_set(ph, coorig);
|
||||
/* Find the matching cligen object
|
||||
* Note, is complictead: either an instantiated tree (co_treeref_orig)
|
||||
* or actual tree (co_ref)
|
||||
*/
|
||||
if ((co = cligen_co_match(cli_cligen(h))) != NULL){
|
||||
if ((coorig = co->co_treeref_orig) != NULL ||
|
||||
(coorig = co->co_ref) != NULL)
|
||||
cligen_ph_workpoint_set(ph, coorig);
|
||||
else {
|
||||
clicon_err(OE_YANG, EINVAL, "No workpoint found");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else{
|
||||
clicon_err(OE_YANG, EINVAL, "No workpoint found");
|
||||
goto done;
|
||||
|
|
@ -500,7 +509,7 @@ cli_auto_edit(clicon_handle h,
|
|||
/*! CLI callback: Working point tree up to parent
|
||||
* @param[in] h CLICON handle
|
||||
* @param[in] cvv Vector of variables from CLIgen command-line
|
||||
* @param[in] argv Vector oif user-supplied keywords
|
||||
* @param[in] argv Vector of user-supplied keywords
|
||||
* Format of argv:
|
||||
* <treename> Name of generated cligen parse-tree, eg "datamodel"
|
||||
*/
|
||||
|
|
@ -991,7 +1000,7 @@ cli_auto_sub_enter(clicon_handle h,
|
|||
}
|
||||
/* Find the point in the generated clispec tree where workpoint should be set */
|
||||
fa.fa_str = api_path_fmt;
|
||||
if (pt_apply(cligen_ph_parsetree_get(ph), cli_auto_findpt, &fa) < 0)
|
||||
if (pt_apply(cligen_ph_parsetree_get(ph), cli_auto_findpt, INT32_MAX, &fa) < 0)
|
||||
goto done;
|
||||
if (fa.fa_co == NULL){
|
||||
clicon_err(OE_PLUGIN, ENOENT, "No such cligen object found %s", api_path);
|
||||
|
|
|
|||
|
|
@ -1113,36 +1113,27 @@ yang2cli_stmt(clicon_handle h,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Generate CLI code for Yang specification
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] yn Create parse-tree from this yang node
|
||||
* @param[in] printgen Log generated CLIgen syntax
|
||||
* @param[in] state Set to include state syntax
|
||||
* @param[in] show_tree Is tree for show cli command
|
||||
* @param[out] pt CLIgen parse-tree (must be created on input)
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
yang2cli(clicon_handle h,
|
||||
yang_stmt *yn,
|
||||
int printgen,
|
||||
int state,
|
||||
int show_tree,
|
||||
parse_tree *pt)
|
||||
yang2cli_yspec(clicon_handle h,
|
||||
yang_stmt *yn,
|
||||
char *name0,
|
||||
int printgen,
|
||||
int state,
|
||||
int show_tree)
|
||||
{
|
||||
int retval = -1;
|
||||
cbuf *cb = NULL;
|
||||
yang_stmt *yc;
|
||||
cvec *globals; /* global variables from syntax */
|
||||
parse_tree *pt0 = NULL;
|
||||
cbuf *cb0 = NULL;
|
||||
genmodel_type gt;
|
||||
char *excludelist;
|
||||
char **exvec = NULL;
|
||||
int nexvec = 0;
|
||||
int e;
|
||||
yang_stmt *ym;
|
||||
pt_head *ph;
|
||||
|
||||
if (pt == NULL){
|
||||
clicon_err(OE_YANG, EINVAL, "pt is NULL");
|
||||
if ((pt0 = pt_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "pt_new");
|
||||
goto done;
|
||||
}
|
||||
/* List of modules that should not generate autocli */
|
||||
|
|
@ -1151,48 +1142,49 @@ yang2cli(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
gt = clicon_cli_genmodel_type(h);
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
if ((cb0 = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
/* Traverse YANG, loop through all modules and generate CLI */
|
||||
yc = NULL;
|
||||
while ((yc = yn_each(yn, yc)) != NULL){
|
||||
ym = NULL;
|
||||
while ((ym = yn_each(yn, ym)) != NULL){
|
||||
/* Check if module is in exclude list */
|
||||
for (e = 0; e < nexvec; e++){
|
||||
if (strcmp(yang_argument_get(yc), exvec[e]) == 0)
|
||||
if (strcmp(yang_argument_get(ym), exvec[e]) == 0)
|
||||
break;
|
||||
}
|
||||
if (e < nexvec)
|
||||
continue;
|
||||
if (yang2cli_stmt(h, yc, gt, 0, state, show_tree, cb) < 0)
|
||||
if (yang2cli_stmt(h, ym, gt, 0, state, show_tree, cb0) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (printgen)
|
||||
clicon_log(LOG_NOTICE, "%s: Generated CLI spec:\n%s", __FUNCTION__, cbuf_get(cb));
|
||||
clicon_log(LOG_NOTICE, "%s: Top-level api-spec %s:\n%s",
|
||||
__FUNCTION__, name0, cbuf_get(cb0));
|
||||
else
|
||||
clicon_debug(2, "%s: buf\n%s\n", __FUNCTION__, cbuf_get(cb));
|
||||
/* Parse the buffer using cligen parser. XXX why this?*/
|
||||
if ((globals = cvec_new(0)) == NULL)
|
||||
clicon_debug(2, "%s: Top-level api-spec %s:\n%s",
|
||||
__FUNCTION__, name0, cbuf_get(cb0));
|
||||
/* load top-level yangspec cli syntax (that point to modules) */
|
||||
if (cligen_parse_str(cli_cligen(h), cbuf_get(cb0), "yang2cli", pt0, NULL) < 0)
|
||||
goto done;
|
||||
/* load cli syntax */
|
||||
if (cligen_parse_str(cli_cligen(h), cbuf_get(cb), "yang2cli", pt, globals) < 0)
|
||||
goto done;
|
||||
cvec_free(globals);
|
||||
/* Resolve the expand callback functions in the generated syntax.
|
||||
* This "should" only be GENERATE_EXPAND_XMLDB
|
||||
* handle=NULL for global namespace, this means expand callbacks must be in
|
||||
* CLICON namespace, not in a cli frontend plugin.
|
||||
*/
|
||||
if (cligen_expandv_str2fn(pt, (expandv_str2fn_t*)clixon_str2fn, NULL) < 0)
|
||||
if (cligen_expandv_str2fn(pt0, (expandv_str2fn_t*)clixon_str2fn, NULL) < 0)
|
||||
goto done;
|
||||
/* Append cligen tree and name it */
|
||||
if ((ph = cligen_ph_add(cli_cligen(h), name0)) == NULL)
|
||||
goto done;
|
||||
if (cligen_ph_parsetree_set(ph, pt0) < 0)
|
||||
goto done;
|
||||
|
||||
retval = 0;
|
||||
done:
|
||||
if (exvec)
|
||||
free(exvec);
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (cb0)
|
||||
cbuf_free(cb0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
int yang2cli(clicon_handle h, yang_stmt *yspec,
|
||||
int printgen, int state, int show_tree, parse_tree *ptnew);
|
||||
int yang2cli_yspec(clicon_handle h, yang_stmt *yspec, char *name0,
|
||||
int printgen, int state, int show_tree);
|
||||
|
||||
#endif /* _CLI_GENERATE_H_ */
|
||||
|
|
|
|||
|
|
@ -107,7 +107,12 @@ cli_handle_init(void)
|
|||
goto done;
|
||||
}
|
||||
cligen_userhandle_set(clih, cl);
|
||||
cligen_eval_wrap_fn_set(clih, plugin_context_check, cl);
|
||||
/* To minimize memory, dont copy full treerefs on expand */
|
||||
cligen_reftree_copy_set(clih, 0);
|
||||
|
||||
cl->cl_cligen = clih;
|
||||
|
||||
h = (clicon_handle)cl;
|
||||
done:
|
||||
return h;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@
|
|||
#include "cli_handle.h"
|
||||
|
||||
/* Command line options to be passed to getopt(3) */
|
||||
#define CLI_OPTS "hD:f:E:l:F:1a:u:d:m:qp:GLy:c:U:o:"
|
||||
#define CLI_OPTS "+hD:f:E:l:F:1a:u:d:m:qp:GLy:c:U:o:"
|
||||
|
||||
/*! Check if there is a CLI history file and if so dump the CLI histiry to it
|
||||
* Just log if file does not exist or is not readable
|
||||
|
|
@ -242,57 +242,6 @@ cli_interactive(clicon_handle h)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Generate one autocli clispec tree
|
||||
*
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] name Name of tree
|
||||
* @param[in] gt genmodel-type, ie HOW to generate the CLI
|
||||
* @param[in] printgen Print CLI syntax to stderr
|
||||
* @param[in] show_tree Is tree for show cli command (1 - yes. 0 - no)
|
||||
*
|
||||
* Generate clispec (datamodel) from YANG dataspec and add to the set of cligen trees
|
||||
* (as a separate mode)
|
||||
* This tree is referenced from the main CLI spec (CLICON_CLISPEC_DIR) using the "tree reference"
|
||||
* syntax, ie @datamodel
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] state Set to include state syntax
|
||||
* @param[in] printgen Print CLI syntax generated from dbspec
|
||||
* @param[in] show_tree Is tree for show cli command
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*
|
||||
* @note that yang2cli generates syntax for ALL modules under the loaded yangspec.
|
||||
*/
|
||||
static int
|
||||
autocli_tree(clicon_handle h,
|
||||
char *name,
|
||||
int state,
|
||||
int printgen,
|
||||
int show_tree)
|
||||
{
|
||||
int retval = -1;
|
||||
parse_tree *pt = NULL; /* cli parse tree */
|
||||
yang_stmt *yspec;
|
||||
pt_head *ph;
|
||||
|
||||
if ((pt = pt_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "pt_new");
|
||||
goto done;
|
||||
}
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
/* Generate tree (this is where the action is) */
|
||||
if (yang2cli(h, yspec, printgen, state, show_tree, pt) < 0)
|
||||
goto done;
|
||||
/* Append cligen tree and name it */
|
||||
if ((ph = cligen_ph_add(cli_cligen(h), name)) == NULL)
|
||||
goto done;
|
||||
if (cligen_ph_parsetree_set(ph, pt) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Generate autocli, ie if enabled, generate clispec from YANG and add to cligen parse-trees
|
||||
*
|
||||
* Generate clispec (datamodel) from YANG dataspec and add to the set of cligen trees
|
||||
|
|
@ -310,13 +259,16 @@ static int
|
|||
autocli_start(clicon_handle h,
|
||||
int printgen)
|
||||
{
|
||||
int retval = -1;
|
||||
int autocli_model = 0;
|
||||
cbuf *show_treename = NULL, *treename = NULL;
|
||||
int retval = -1;
|
||||
int autocli_model = 0;
|
||||
cbuf *show_treename = NULL;
|
||||
cbuf *treename = NULL;
|
||||
yang_stmt *yspec;
|
||||
|
||||
/* If autocli disabled quit */
|
||||
if ((autocli_model = clicon_cli_genmodel(h)) == 0)
|
||||
goto ok;
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
/* Get the autocli type, ie HOW the cli is generated (could be much more here) */
|
||||
/* Create show_treename cbuf */
|
||||
if ((show_treename = cbuf_new()) == NULL){
|
||||
|
|
@ -330,23 +282,22 @@ autocli_start(clicon_handle h,
|
|||
}
|
||||
/* The tree name is by default @datamodel but can be changed by option (why would one do that?) */
|
||||
cprintf(treename, "%s", clicon_cli_model_treename(h));
|
||||
if (autocli_tree(h, cbuf_get(treename), 0, printgen, 0) < 0)
|
||||
if (yang2cli_yspec(h, yspec, cbuf_get(treename), printgen, 0, 0) < 0)
|
||||
goto done;
|
||||
|
||||
/* The tree name is by default @datamodelshow but can be changed by option (why would one do that?) */
|
||||
cprintf(show_treename, "%s", clicon_cli_model_treename(h));
|
||||
cprintf(show_treename, "show");
|
||||
if (autocli_tree(h, cbuf_get(show_treename), 0, printgen, 1) < 0)
|
||||
if (yang2cli_yspec(h, yspec, cbuf_get(show_treename), printgen, 0, 1) < 0)
|
||||
goto done;
|
||||
|
||||
/* Create a tree for config+state. This tree's name has appended "state" to @datamodel
|
||||
*/
|
||||
if (autocli_model > 1){
|
||||
cprintf(treename, "state");
|
||||
if (autocli_tree(h, cbuf_get(treename), 1, printgen, 1) < 0)
|
||||
if (yang2cli_yspec(h, yspec, cbuf_get(treename), printgen, 1, 1) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
|
|||
|
|
@ -522,105 +522,6 @@ cli_handler_err(FILE *f)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*! Variant of eval for context checking
|
||||
* @see cligen_eval
|
||||
*/
|
||||
static int
|
||||
clixon_cligen_eval(cligen_handle h,
|
||||
cg_obj *co,
|
||||
cvec *cvv)
|
||||
{
|
||||
struct cg_callback *cc;
|
||||
int retval = -1;
|
||||
cvec *argv;
|
||||
cvec *cvv1 = NULL; /* Modified */
|
||||
plugin_context_t *pc = NULL; /* Clixon-specific */
|
||||
|
||||
|
||||
/* Save matched object for plugin use */
|
||||
if (h)
|
||||
cligen_co_match_set(h, co);
|
||||
/* Make a copy of var argument for modifications */
|
||||
if ((cvv1 = cvec_dup(cvv)) == NULL)
|
||||
goto done;
|
||||
/* Make modifications to cvv */
|
||||
if (cligen_expand_first_get(h) &&
|
||||
cvec_expand_first(cvv1) < 0)
|
||||
goto done;
|
||||
if (cligen_exclude_keys_get(h) &&
|
||||
cvec_exclude_keys(cvv1) < 0)
|
||||
goto done;
|
||||
/* Traverse callbacks */
|
||||
for (cc = co->co_callbacks; cc; cc=cc->cc_next){
|
||||
/* Vector cvec argument to callback */
|
||||
if (cc->cc_fn_vec){
|
||||
argv = cc->cc_cvec ? cvec_dup(cc->cc_cvec) : NULL;
|
||||
cligen_fn_str_set(h, cc->cc_fn_str);
|
||||
/* Clixon-specific */
|
||||
if ((pc = plugin_context_get()) == NULL)
|
||||
break;
|
||||
if ((retval = (*cc->cc_fn_vec)(
|
||||
cligen_userhandle(h)?cligen_userhandle(h):h,
|
||||
cvv1,
|
||||
argv)) < 0){
|
||||
if (argv != NULL)
|
||||
cvec_free(argv);
|
||||
cligen_fn_str_set(h, NULL);
|
||||
goto done;
|
||||
}
|
||||
/* Clixon-specific */
|
||||
if (plugin_context_check(pc, "CLIgen", cc->cc_fn_str) < 0)
|
||||
break;
|
||||
if (pc){
|
||||
free(pc);
|
||||
pc = NULL;
|
||||
}
|
||||
if (argv != NULL)
|
||||
cvec_free(argv);
|
||||
cligen_fn_str_set(h, NULL);
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (pc) /* Clixon-specific */
|
||||
free(pc);
|
||||
if (cvv1)
|
||||
cvec_free(cvv1);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Evaluate a matched command
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] cmd The command string
|
||||
* @param[in] match_obj
|
||||
* @param[in] cvv
|
||||
* @retval int If there is a callback, the return value of the callback is returned,
|
||||
* @retval 0 otherwise
|
||||
*/
|
||||
int
|
||||
clicon_eval(clicon_handle h,
|
||||
char *cmd,
|
||||
cg_obj *match_obj,
|
||||
cvec *cvv)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
cli_output_reset();
|
||||
if (!cligen_exiting(cli_cligen(h))) {
|
||||
clicon_err_reset();
|
||||
|
||||
if ((retval = clixon_cligen_eval(cli_cligen(h), match_obj, cvv)) < 0) {
|
||||
#if 0 /* This is removed since we get two error messages on failure.
|
||||
But maybe only sometime?
|
||||
Both a real log when clicon_err is called, and the here again.
|
||||
(Before clicon_err was silent) */
|
||||
cli_handler_err(stdout);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Given a command string, parse and if match single command, eval it.
|
||||
* Parse and evaluate the string according to
|
||||
* the syntax parse tree of the syntax mode specified by *mode.
|
||||
|
|
@ -644,18 +545,20 @@ clicon_parse(clicon_handle h,
|
|||
cligen_result *result,
|
||||
int *evalres)
|
||||
{
|
||||
int retval = -1;
|
||||
char *modename;
|
||||
char *modename0;
|
||||
int r;
|
||||
cli_syntax_t *stx = NULL;
|
||||
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;
|
||||
FILE *f;
|
||||
char *reason = NULL;
|
||||
parse_tree *pt; /* Orig */
|
||||
cg_obj *match_obj = NULL;
|
||||
cvec *cvv = NULL;
|
||||
cg_callback *callbacks = NULL;
|
||||
FILE *f;
|
||||
char *reason = NULL;
|
||||
cligen_handle ch;
|
||||
|
||||
ch = cli_cligen(h);
|
||||
if (clicon_get_logflags()&CLICON_LOG_STDOUT)
|
||||
f = stdout;
|
||||
else
|
||||
|
|
@ -672,34 +575,18 @@ clicon_parse(clicon_handle h,
|
|||
}
|
||||
}
|
||||
if (csm != NULL){
|
||||
modename0 = NULL;
|
||||
if ((pt = cligen_pt_active_get(cli_cligen(h))) != NULL)
|
||||
modename0 = pt_name_get(pt);
|
||||
if (cligen_ph_active_set(cli_cligen(h), modename) < 0){
|
||||
if (cligen_ph_active_set_byname(ch, modename) < 0){
|
||||
fprintf(stderr, "No such parse-tree registered: %s\n", modename);
|
||||
goto done;
|
||||
}
|
||||
if ((pt = cligen_pt_active_get(cli_cligen(h))) == NULL){
|
||||
if ((pt = cligen_pt_active_get(ch)) == NULL){
|
||||
fprintf(stderr, "No such parse-tree registered: %s\n", modename);
|
||||
goto done;
|
||||
}
|
||||
#if 0 // switch after 5.4
|
||||
if (cliread_parse2(cli_cligen(h), cmd, pt, &match_obj, &cvv, result, &reason) < 0)
|
||||
if (cliread_parse(ch, cmd, pt, &match_obj, &cvv, &callbacks, result, &reason) < 0)
|
||||
goto done;
|
||||
#else
|
||||
if ((cvv = cvec_new(0)) == NULL)
|
||||
goto done;;
|
||||
if (cliread_parse(cli_cligen(h), cmd, pt, &match_obj, cvv, result, &reason) < 0)
|
||||
goto done;
|
||||
#endif
|
||||
/* Debug command and result code */
|
||||
clicon_debug(1, "%s result:%d command: \"%s\"", __FUNCTION__, *result, cmd);
|
||||
if (*result != CG_MATCH)
|
||||
pt_expand_cleanup(pt); /* XXX change to pt_expand_treeref_cleanup */
|
||||
if (modename0){
|
||||
cligen_ph_active_set(cli_cligen(h), modename0);
|
||||
modename0 = NULL;
|
||||
}
|
||||
switch (*result) {
|
||||
case CG_EOF: /* eof */
|
||||
case CG_ERROR:
|
||||
|
|
@ -713,12 +600,17 @@ clicon_parse(clicon_handle h,
|
|||
*modenamep = modename;
|
||||
cli_set_syntax_mode(h, modename);
|
||||
}
|
||||
if ((r = clicon_eval(h, cmd, match_obj, cvv)) < 0)
|
||||
cli_handler_err(stdout);
|
||||
pt_expand_cleanup(pt);
|
||||
pt_expand_treeref_cleanup(pt);
|
||||
cli_output_reset();
|
||||
if (!cligen_exiting(ch)) {
|
||||
clicon_err_reset();
|
||||
if ((ret = cligen_eval(ch, match_obj, cvv, callbacks)) < 0)
|
||||
cli_handler_err(stdout);
|
||||
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
if (evalres)
|
||||
*evalres = r;
|
||||
*evalres = ret;
|
||||
break;
|
||||
default:
|
||||
fprintf(f, "CLI syntax error: \"%s\" is ambiguous\n", cmd);
|
||||
|
|
@ -727,6 +619,8 @@ clicon_parse(clicon_handle h,
|
|||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (callbacks)
|
||||
co_callbacks_free(&callbacks);
|
||||
if (reason)
|
||||
free(reason);
|
||||
if (cvv)
|
||||
|
|
@ -829,7 +723,7 @@ clicon_cliread(clicon_handle h,
|
|||
cli_syntaxmode_t *mode;
|
||||
cli_syntax_t *stx;
|
||||
cli_prompthook_t *fn;
|
||||
clixon_plugin_t *cp;
|
||||
clixon_plugin_t *cp;
|
||||
char *promptstr;
|
||||
|
||||
stx = cli_syntax(h);
|
||||
|
|
@ -850,7 +744,7 @@ clicon_cliread(clicon_handle h,
|
|||
cli_prompt_set(h, promptstr);
|
||||
free(promptstr);
|
||||
}
|
||||
cligen_ph_active_set(cli_cligen(h), mode->csm_name);
|
||||
cligen_ph_active_set_byname(cli_cligen(h), mode->csm_name);
|
||||
|
||||
if (cliread(cli_cligen(h), stringp) < 0){
|
||||
clicon_err(OE_FATAL, errno, "CLIgen");
|
||||
|
|
|
|||
|
|
@ -45,7 +45,10 @@
|
|||
/* clicon generic callback pointer */
|
||||
typedef void (clicon_callback_t)(clicon_handle h);
|
||||
|
||||
/* List of syntax modes */
|
||||
/* 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 */
|
||||
|
|
@ -54,7 +57,8 @@ typedef struct {
|
|||
parse_tree *csm_pt; /* CLIgen parse tree */
|
||||
} cli_syntaxmode_t;
|
||||
|
||||
/* Plugin group object. Just a single object, not list. part of cli_handle */
|
||||
/* 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 */
|
||||
|
|
@ -64,8 +68,6 @@ typedef struct {
|
|||
|
||||
void *clixon_str2fn(char *name, void *handle, char **error);
|
||||
|
||||
int clicon_eval(clicon_handle h, char *cmd, cg_obj *match_obj, cvec *vr);
|
||||
|
||||
int clicon_parse(clicon_handle h, char *cmd, char **mode, cligen_result *result, int *evalres);
|
||||
|
||||
int clicon_cliread(clicon_handle h, char **stringp);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue