Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ ifneq ($(LINKAGE),dynamic)
# -rdynamic for using -ldl
LDFLAGS += -rdynamic
endif
LIBS = @LIBS@
LIBS = @LIBS@ -ldl
INCLUDES = -I. -I@srcdir@ @INCLUDES@

HOST_VENDOR = @host_vendor@
Expand Down
44 changes: 44 additions & 0 deletions cligen_handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
*/
#define TREENAME_KEYWORD_DEFAULT "treename"

#include <dlfcn.h>

/* forward */
static int terminal_rows_set1(int rows);

Expand Down Expand Up @@ -153,6 +155,7 @@ cligen_init(void)
struct cligen_handle *ch;
cligen_handle h = NULL;
struct sigaction sigh;
void *lib_handle;

if ((ch = malloc(sizeof(*ch))) == NULL){
fprintf(stderr, "%s: malloc: %s\n", __FUNCTION__, strerror(errno));
Expand Down Expand Up @@ -186,6 +189,14 @@ cligen_init(void)
cligen_buf_init(h);
/* getline cant function without some history */
(void)cligen_hist_init(h, CLIGEN_HISTSIZE_DEFAULT);

lib_handle = dlopen("libcligen_ext.so", RTLD_LAZY);
if (lib_handle) {
cligen_ext_lib_handle_set(h, lib_handle);
}else {
cligen_ext_lib_handle_set(h, NULL);
}

done:
return h;
}
Expand Down Expand Up @@ -1448,3 +1459,36 @@ cligen_tree_resolve_wrapper_get(cligen_handle h,
*arg = ch->ch_tree_resolve_wrapper_arg;
return 0;
}


/*! Get extension library handle
*
* This handle is typically used to store a pointer to a dynamically loaded
* library (via dlopen) that provides additional functionality.
* @param[in] h CLIgen handle
* @retval ptr Pointer to the library handle or NULL if not set
*/
void *
cligen_ext_lib_handle_get(cligen_handle h)
{
struct cligen_handle *ch = handle(h);

return ch->ch_ext_lib_handle;
}

/*! Set extension library handle
*
* Store a handle to a loaded shared object in the CLIgen handle.
* @param[in] h CLIgen handle
* @param[in] data Pointer to store (e.g., dlopen handle)
* @retval 0 OK
*/
int
cligen_ext_lib_handle_set(cligen_handle h,
void *data)
{
struct cligen_handle *ch = handle(h);

ch->ch_ext_lib_handle = data;
return 0;
}
14 changes: 14 additions & 0 deletions cligen_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
*/
#define CLIGEN_TABMODE_SHOW 0x08

#include "cligen_result.h"

/*
* Types
*/
Expand Down Expand Up @@ -108,6 +110,15 @@ typedef int (cligen_tree_resolve_wrapper_fn)(cligen_handle h, const char *name,
*/
typedef int (cligen_hist_fn)(cligen_handle h, const char *cmd, void *arg);

/*! Function type for injecting custom data into match results.
* @param[in] mr Match results to be modified
* @param[in] cvt Tokenized string vector providing context
* @param[in] string Original input string
* @retval 0 OK
* @retval -1 Error
*/
typedef int (cligen_match_inject_fn)(match_result *mr, cvec *cvt, const char *string);

/*
* Prototypes
*/
Expand Down Expand Up @@ -221,4 +232,7 @@ int cligen_eval_wrap_fn_get(cligen_handle h, cligen_eval_wrap_fn **fn, void **
int cligen_tree_resolve_wrapper_set(cligen_handle h, cligen_tree_resolve_wrapper_fn *fn, void *arg);
int cligen_tree_resolve_wrapper_get(cligen_handle h, cligen_tree_resolve_wrapper_fn **fn, void **arg);

void *cligen_ext_lib_handle_get(cligen_handle h);
int cligen_ext_lib_handle_set(cligen_handle h, void *data);

#endif /* _CLIGEN_HANDLE_H_ */
1 change: 1 addition & 0 deletions cligen_handle_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ struct cligen_handle{
void *ch_eval_wrap_arg; /* Argument to eval wrap function */
cligen_tree_resolve_wrapper_fn *ch_tree_resolve_wrapper_fn; /* Wrap function for treeref lookup */
void *ch_tree_resolve_wrapper_arg; /* Argument to treeref wrap function */
void *ch_ext_lib_handle; /* Handle to dynamically loaded extension library (dlopen) */
};

#endif /* _CLIGEN_HANDLE_INTERNAL_H_ */
80 changes: 56 additions & 24 deletions cligen_read.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dlfcn.h>
#ifdef WIN32
#include <winsock2.h>
#else
Expand Down Expand Up @@ -285,22 +286,24 @@ show_help_columns(cligen_handle h,
parse_tree *pt,
cvec *cvv)
{
int retval = -1;
int level;
int i;
int nrcmd = 0;
struct cligen_help *chvec = NULL;
struct cligen_help *ch;
cg_obj *co;
cbuf *cb = NULL;
char *cmd;
int maxlen = 0;
int column_width;
int column_nr;
int rest;
cvec *cvt = NULL; /* Tokenized string: vector of tokens */
cvec *cvr = NULL; /* Rest variant, eg remaining string in each step */
match_result *mr = NULL;
int retval = -1;
int level;
int i;
int nrcmd = 0;
struct cligen_help *chvec = NULL;
struct cligen_help *ch;
cg_obj *co;
cbuf *cb = NULL;
char *cmd;
int maxlen = 0;
int column_width;
int column_nr;
int rest;
cvec *cvt = NULL; /* Tokenized string: vector of tokens */
cvec *cvr = NULL; /* Rest variant, eg remaining string in each step */
match_result *mr = NULL;
void *lib_handle = NULL;
cligen_match_inject_fn *inject_func = NULL;

if (string == NULL){
errno = EINVAL;
Expand All @@ -319,6 +322,20 @@ show_help_columns(cligen_handle h,
cvv,
&mr) < 0)
goto done;

lib_handle = cligen_ext_lib_handle_get(h);
if (lib_handle) {
dlerror();
inject_func = (cligen_match_inject_fn*)dlsym(lib_handle, "cligen_ext_match_inject");
if (inject_func){
if (inject_func(mr, cvt, string) < 0) {
goto done;
}
}else {
fprintf(stderr, "CLIgen extension error (dlsym): %s\n", dlerror());
}
}

if ((level = cligen_cvv_levels(cvt)) < 0)
goto done;
if (mr_pt_len_get(mr) > 0){ /* min, max only defined if matchlen > 0 */
Expand Down Expand Up @@ -425,14 +442,16 @@ show_help_line(cligen_handle h,
parse_tree *pt,
cvec *cvv)
{
int retval = -1;
int level;
cvec *cvt = NULL; /* Tokenized string: vector of tokens */
cvec *cvr = NULL; /* Rest variant, eg remaining string in each step */
cg_var *cvlastt; /* Last element in cvt */
cg_var *cvlastr; /* Last element in cvr */
cligen_result result;
match_result *mr = NULL;
int retval = -1;
int level;
cvec *cvt = NULL; /* Tokenized string: vector of tokens */
cvec *cvr = NULL; /* Rest variant, eg remaining string in each step */
cg_var *cvlastt; /* Last element in cvt */
cg_var *cvlastr; /* Last element in cvr */
cligen_result result;
match_result *mr = NULL;
void *lib_handle = NULL;
cligen_match_inject_fn *inject_func = NULL;

if (string == NULL){
errno = EINVAL;
Expand All @@ -448,6 +467,19 @@ show_help_line(cligen_handle h,
cvv,
&mr) < 0)
goto done;

lib_handle = cligen_ext_lib_handle_get(h);
if (lib_handle) {
inject_func = (cligen_match_inject_fn*)dlsym(lib_handle, "cligen_ext_match_inject");
if (inject_func){
if (inject_func(mr, cvt, string) < 0) {
goto done;
}
}else {
fprintf(stderr, "CLIgen extension error (dlsym): %s\n", dlerror());
}
}

if ((level = cligen_cvv_levels(cvt)) < 0)
goto done;

Expand Down