This commit is contained in:
Olof hagsand 2020-05-01 17:09:56 +02:00
commit 442e96bdf0
9 changed files with 253 additions and 3 deletions

View file

@ -48,6 +48,8 @@ Expected: May 2020
### Minor changes ### Minor changes
* Compile-time option: `USE_CLIGEN44` for running clixon-45 with cligen-44.
* Temporary fix since cligen-45 have some non-backward compatible behaviour.
* Optimizations * Optimizations
* Reduced memory for attribute and body objects, see `XML_NEW_DIFFERENTIATE` compile-time option. * Reduced memory for attribute and body objects, see `XML_NEW_DIFFERENTIATE` compile-time option.
* Optimized prefix checks at xml parse time: using many prefixes slowed down parsing considerably * Optimized prefix checks at xml parse time: using many prefixes slowed down parsing considerably
@ -786,7 +788,7 @@ Olof Hagsand
* List ordering bug - lists with ints as keys behaved wrongly and slow. * List ordering bug - lists with ints as keys behaved wrongly and slow.
* NACM read default rule did not work properly if nacm was enabled AND no groups were defined * NACM read default rule did not work properly if nacm was enabled AND no groups were defined
* Re-inserted `cli_output_reset` for what was erroneuos thought to be an obsolete function * Re-inserted `cli_output_reset` for what was erroneuos thought to be an obsolete function
* See in 3.9.0 minro changes: Replaced all calls to (obsolete) `cli_output` with `fprintf` * See in 3.9.0 minor changes: Replaced all calls to (obsolete) `cli_output` with `fprintf`
* Allowed Yang extended Xpath functions (syntax only): * Allowed Yang extended Xpath functions (syntax only):
* re-match, deref, derived-from, derived-from-or-self, enum-value, bit-is-set * re-match, deref, derived-from, derived-from-or-self, enum-value, bit-is-set
* XSD regular expression handling of dash(`-`) * XSD regular expression handling of dash(`-`)

View file

@ -193,6 +193,15 @@ cli_interrupt_hook(clicon_handle h,
return cligen_interrupt_hook(ch, fn); return cligen_interrupt_hook(ch, fn);
} }
#ifdef USE_CLIGEN44
char *
cli_nomatch(clicon_handle h)
{
cligen_handle ch = cligen(h);
return cligen_nomatch(ch);
}
#endif
int int
cli_prompt_set(clicon_handle h, cli_prompt_set(clicon_handle h,
char *prompt) char *prompt)

View file

@ -53,6 +53,10 @@ int cli_susp_hook(clicon_handle h, cligen_susp_cb_t *fn);
int cli_interrupt_hook(clicon_handle h, cligen_interrupt_cb_t *fn); int cli_interrupt_hook(clicon_handle h, cligen_interrupt_cb_t *fn);
#ifdef USE_CLIGEN44
char *cli_nomatch(clicon_handle h);
#endif
int cli_prompt_set(clicon_handle h, char *prompt); int cli_prompt_set(clicon_handle h, char *prompt);
int cli_logsyntax_set(clicon_handle h, int status); int cli_logsyntax_set(clicon_handle h, int status);

View file

@ -209,6 +209,32 @@ cli_signal_init (clicon_handle h)
* @retval -1 * @retval -1
* @see cligen_loop * @see cligen_loop
*/ */
#ifdef USE_CLIGEN44
static int
cli_interactive(clicon_handle h)
{
int retval = -1;
int res;
char *cmd;
char *new_mode;
int eval;
/* Loop through all commands */
while(!cligen_exiting(cli_cligen(h))) {
new_mode = cli_syntax_mode(h);
if ((cmd = clicon_cliread(h)) == NULL) {
cligen_exiting_set(cli_cligen(h), 1); /* EOF */
goto ok; /* EOF should not be -1 error? */
}
if ((res = clicon_parse(h, cmd, &new_mode, &eval)) < 0)
goto done;
}
ok:
retval = 0;
done:
return retval;
}
#else /* USE_CLIGEN44 */
static int static int
cli_interactive(clicon_handle h) cli_interactive(clicon_handle h)
{ {
@ -235,7 +261,7 @@ cli_interactive(clicon_handle h)
done: done:
return retval; return retval;
} }
#endif /* USE_CLIGEN44 */
static void static void
usage(clicon_handle h, usage(clicon_handle h,
@ -608,6 +634,15 @@ main(int argc, char **argv)
/* Launch interfactive event loop, unless -1 */ /* Launch interfactive event loop, unless -1 */
if (restarg != NULL && strlen(restarg)){ if (restarg != NULL && strlen(restarg)){
char *mode = cli_syntax_mode(h); char *mode = cli_syntax_mode(h);
#ifdef USE_CLIGEN44
int result;
/* */
if (clicon_parse(h, restarg, &mode, &result) != 1)
goto done;
if (result < 0)
goto done;
#else /* USE_CLIGEN44 */
cligen_result result; /* match result */ cligen_result result; /* match result */
int evalresult = 0; /* if result == 1, calback result */ int evalresult = 0; /* if result == 1, calback result */
@ -617,6 +652,7 @@ main(int argc, char **argv)
goto done; goto done;
if (evalresult < 0) if (evalresult < 0)
goto done; goto done;
#endif /* USE_CLIGEN44 */
} }
/* Go into event-loop unless -1 command-line */ /* Go into event-loop unless -1 command-line */

View file

@ -511,6 +511,94 @@ clicon_eval(clicon_handle h,
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
*/ */
#ifdef USE_CLIGEN44
int
clicon_parse(clicon_handle h,
char *cmd,
char **modenamep,
int *evalres)
{
int retval = -1;
char *modename;
char *modename0;
int r;
cli_syntax_t *stx = NULL;
cli_syntaxmode_t *smode;
parse_tree *pt; /* Orig */
cg_obj *match_obj;
cvec *cvv = NULL;
FILE *f;
if (clicon_get_logflags()&CLICON_LOG_STDOUT)
f = stdout;
else
f = stderr;
stx = cli_syntax(h);
if ((modename = *modenamep) == NULL) {
smode = stx->stx_active_mode;
modename = smode->csm_name;
}
else {
if ((smode = syntax_mode_find(stx, modename, 0)) == NULL) {
fprintf(f, "Can't find syntax mode '%s'\n", modename);
goto done;
}
}
if (smode){
modename0 = NULL;
if ((pt = cligen_tree_active_get(cli_cligen(h))) != NULL)
modename0 = pt->pt_name;
if (cligen_tree_active_set(cli_cligen(h), modename) < 0){
fprintf(stderr, "No such parse-tree registered: %s\n", modename);
goto done;
}
if ((pt = cligen_tree_active_get(cli_cligen(h))) == NULL){
fprintf(stderr, "No such parse-tree registered: %s\n", modename);
goto done;
}
if ((cvv = cvec_new(0)) == NULL){
clicon_err(OE_UNIX, errno, "cvec_new");
goto done;;
}
retval = cliread_parse(cli_cligen(h), cmd, pt, &match_obj, cvv);
if (retval != CG_MATCH)
pt_expand_cleanup_1(pt); /* XXX change to pt_expand_treeref_cleanup */
if (modename0){
cligen_tree_active_set(cli_cligen(h), modename0);
modename0 = NULL;
}
switch (retval) {
case CG_EOF: /* eof */
case CG_ERROR:
fprintf(f, "CLI parse error: %s\n", cmd);
break;
case CG_NOMATCH: /* no match */
/* clicon_err(OE_CFG, 0, "CLI syntax error: \"%s\": %s",
cmd, cli_nomatch(h));*/
fprintf(f, "CLI syntax error: \"%s\": %s\n", cmd, cli_nomatch(h));
break;
case CG_MATCH:
if (strcmp(modename, *modenamep)){ /* Command in different mode */
*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_1(pt); /* XXX change to pt_expand_treeref_cleanup */
if (evalres)
*evalres = r;
break;
default:
fprintf(f, "CLI syntax error: \"%s\" is ambiguous\n", cmd);
break;
} /* switch retval */
}
done:
if (cvv)
cvec_free(cvv);
return retval;
}
#else /* USE_CLIGEN44 */
int int
clicon_parse(clicon_handle h, clicon_parse(clicon_handle h,
char *cmd, char *cmd,
@ -601,6 +689,7 @@ done:
cvec_free(cvv); cvec_free(cvv);
return retval; return retval;
} }
#endif /* USE_CLIGEN44 */
/*! Read command from CLIgen's cliread() using current syntax mode. /*! Read command from CLIgen's cliread() using current syntax mode.
* @param[in] h Clicon handle * @param[in] h Clicon handle
@ -608,6 +697,38 @@ done:
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
*/ */
#ifdef USE_CLIGEN44
char *
clicon_cliread(clicon_handle h)
{
char *ret;
char *pfmt = NULL;
cli_syntaxmode_t *mode;
cli_syntax_t *stx;
cli_prompthook_t *fn;
clixon_plugin *cp;
stx = cli_syntax(h);
mode = stx->stx_active_mode;
/* Get prompt from plugin callback? */
cp = NULL;
while ((cp = clixon_plugin_each(h, cp)) != NULL) {
if ((fn = cp->cp_api.ca_prompt) == NULL)
continue;
pfmt = fn(h, mode->csm_name);
break;
}
if (clicon_quiet_mode(h))
cli_prompt_set(h, "");
else
cli_prompt_set(h, cli_prompt(pfmt ? pfmt : mode->csm_prompt));
cligen_tree_active_set(cli_cligen(h), mode->csm_name);
ret = cliread(cli_cligen(h));
if (pfmt)
free(pfmt);
return ret;
}
#else
int int
clicon_cliread(clicon_handle h, clicon_cliread(clicon_handle h,
char **stringp) char **stringp)
@ -634,6 +755,7 @@ clicon_cliread(clicon_handle h,
else else
cli_prompt_set(h, cli_prompt(pfmt ? pfmt : mode->csm_prompt)); cli_prompt_set(h, cli_prompt(pfmt ? pfmt : mode->csm_prompt));
cligen_tree_active_set(cli_cligen(h), mode->csm_name); cligen_tree_active_set(cli_cligen(h), mode->csm_name);
if (cliread(cli_cligen(h), stringp) < 0){ if (cliread(cli_cligen(h), stringp) < 0){
clicon_err(OE_FATAL, errno, "CLIgen"); clicon_err(OE_FATAL, errno, "CLIgen");
goto done; goto done;
@ -644,6 +766,7 @@ clicon_cliread(clicon_handle h,
free(pfmt); free(pfmt);
return retval; return retval;
} }
#endif /* USE_CLIGEN44 */
/* /*
* *

View file

@ -66,9 +66,13 @@ 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_eval(clicon_handle h, char *cmd, cg_obj *match_obj, cvec *vr);
#ifdef USE_CLIGEN44
int clicon_parse(clicon_handle h, char *cmd, char **modenamep, int *evalres);
char *clicon_cliread(clicon_handle h);
#else
int clicon_parse(clicon_handle h, char *cmd, char **mode, cligen_result *result, int *evalres); 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, char **stringp);
#endif
int cli_plugin_finish(clicon_handle h); int cli_plugin_finish(clicon_handle h);

View file

@ -119,3 +119,9 @@
* Primarily for large lists * Primarily for large lists
*/ */
#undef OPTIMIZE_45_SORT #undef OPTIMIZE_45_SORT
/*! Use cligen 4.4 instead of master / cligen 4.5.pre
* Temporary fix
*/
#undef USE_CLIGEN44

View file

@ -107,6 +107,9 @@ char *clixon_trim(char *str);
char *clixon_trim2(char *str, char *trims); char *clixon_trim2(char *str, char *trims);
int clicon_strcmp(char *s1, char *s2); int clicon_strcmp(char *s1, char *s2);
#ifdef USE_CLIGEN44
int cbuf_append_str(cbuf *cb, char *str);
#endif
#ifndef HAVE_STRNDUP #ifndef HAVE_STRNDUP
char *clicon_strndup (const char *, size_t); char *clicon_strndup (const char *, size_t);
#endif /* ! HAVE_STRNDUP */ #endif /* ! HAVE_STRNDUP */

View file

@ -814,6 +814,69 @@ clicon_strndup(const char *str,
} }
#endif /* ! HAVE_STRNDUP */ #endif /* ! HAVE_STRNDUP */
#ifdef USE_CLIGEN44
#define CBUFLEN_THRESHOLD 65536
struct cbuf {
char *cb_buffer; /* pointer to buffer */
size_t cb_buflen; /* allocated bytes of buffer */
size_t cb_strlen; /* length of string in buffer (< buflen) */
};
static int
cbuf_realloc(cbuf *cb,
size_t sz)
{
int retval = -1;
int diff;
diff = cb->cb_buflen - (cb->cb_strlen + sz + 1);
if (diff <= 0){
while (diff <= 0){
if (cb->cb_buflen < CBUFLEN_THRESHOLD)
cb->cb_buflen *= 2; /* Double the space - exponential */
else
cb->cb_buflen += CBUFLEN_THRESHOLD; /* Add - linear growth*/
diff = cb->cb_buflen - (cb->cb_strlen + sz + 1);
}
if ((cb->cb_buffer = realloc(cb->cb_buffer, cb->cb_buflen)) == NULL)
goto done;
}
retval = 0;
done:
return retval;
}
/*! Append a string to a cbuf
*
* An optimized special case of cprintf
* @param [in] cb cligen buffer allocated by cbuf_new(), may be reallocated.
* @param [in] str string
* @retval 0 OK
* @retval -1 Error
* @see cprintf for the generic function
*/
int
cbuf_append_str(cbuf *cb,
char *str)
{
size_t len0;
size_t len;
if (str == NULL){
errno = EINVAL;
return -1;
}
len0 = strlen(str);
len = cb->cb_strlen + len0;
/* Ensure buffer is large enough */
if (cbuf_realloc(cb, len) < 0)
return -1;
strncpy(cb->cb_buffer+cb->cb_strlen, str, len0+1);
cb->cb_strlen = len;;
return 0;
}
#endif
/* /*
* Turn this on for uni-test programs * Turn this on for uni-test programs