From ff5462ecac4dc300aab48af389a3bd270d7a71cf Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Tue, 9 Jun 2020 16:04:49 +0200 Subject: [PATCH] Replaced the global variable `debug` with access function: `clicon_debug_get()`. --- CHANGELOG.md | 1 + apps/backend/backend_client.c | 4 +- apps/backend/backend_commit.c | 2 +- apps/backend/backend_main.c | 16 ++-- apps/backend/backend_plugin.c | 2 +- apps/cli/cli_main.c | 11 +-- apps/cli/clixon_cli_api.h | 13 +--- apps/netconf/netconf_lib.c | 2 +- apps/netconf/netconf_main.c | 11 +-- apps/restconf/restconf_fcgi_main.c | 11 +-- apps/restconf/restconf_methods.c | 2 +- apps/restconf/restconf_methods_get.c | 2 +- apps/restconf/restconf_methods_post.c | 12 +-- example/main/example_backend.c | 2 +- lib/clixon/clixon_log.h | 7 +- lib/src/clixon_datastore_read.c | 6 +- lib/src/clixon_log.c | 23 ++++-- lib/src/clixon_path.c | 4 +- lib/src/clixon_proto.c | 4 +- lib/src/clixon_stream.c | 2 +- lib/src/clixon_xml_map.c | 2 +- lib/src/clixon_xpath.c | 2 +- lib/src/clixon_xpath_eval.c | 4 +- lib/src/clixon_yang_parse.y | 7 -- test/test_cli_gen.sh | 106 ++++++++++++++++++++++++++ util/clixon_util_datastore.c | 7 +- util/clixon_util_json.c | 7 +- util/clixon_util_path.c | 5 +- util/clixon_util_regexp.c | 11 ++- util/clixon_util_socket.c | 7 +- util/clixon_util_stream.c | 4 +- util/clixon_util_xml.c | 9 ++- util/clixon_util_xml_mod.c | 8 +- util/clixon_util_xpath.c | 5 +- util/clixon_util_yang.c | 6 +- 35 files changed, 227 insertions(+), 100 deletions(-) create mode 100755 test/test_cli_gen.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 16267558..eb09c81d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ Expected: July 2020 ### C-API changes on existing features (For developers) +* Replaced the global variable `debug` with access function: `clicon_debug_get()`. * Due to name collision with libevent, all clixon event functions prepended with `clixon_`. You need to rename your event functions as follows: * event_reg_fd() -> clixon_event_reg_fd() * event_unreg_fd() -> clixon_event_unreg_fd() diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 43c4f6b2..43b7d61a 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -1066,7 +1066,7 @@ from_client_get(clicon_handle h, (ret = xml_yang_validate_add(h, xret, &xerr)) < 0) goto done; if (ret == 0){ - if (debug) + if (clicon_debug_get()) clicon_log_xml(LOG_DEBUG, xret, "VALIDATE_STATE"); if (clixon_netconf_internal_error(xerr, ". Internal error, state callback returned invalid XML", @@ -1362,7 +1362,7 @@ from_client_debug(clicon_handle h, clicon_debug_init(level, NULL); /* 0: dont debug, 1:debug */ setlogmask(LOG_UPTO(level?LOG_DEBUG:LOG_INFO)); /* for syslog */ - clicon_log(LOG_NOTICE, "%s debug:%d", __FUNCTION__, debug); + clicon_log(LOG_NOTICE, "%s debug:%d", __FUNCTION__, clicon_debug_get()); cprintf(cbret, ""); ok: retval = 0; diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index c020dc90..823eb878 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -453,7 +453,7 @@ from_validate_common(clicon_handle h, &td->td_tcvec, /* changed: wanted values */ &td->td_clen) < 0) goto done; - if (debug>1) + if (clicon_debug_get()>1) transaction_print(stderr, td); /* Mark as changed in tree */ for (i=0; itd_dlen; i++){ /* Also down */ diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index 55fb6ac9..7afe54af 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -461,6 +461,7 @@ main(int argc, cvec *nsctx_global = NULL; /* Global namespace context */ size_t cligen_buflen; size_t cligen_bufthreshold; + int dbg; /* In the startup, logs to stderr & syslog and debug flag set later */ clicon_log_init(__PROGRAM__, LOG_INFO, logdst); @@ -472,6 +473,7 @@ main(int argc, once = 0; zap = 0; extraxml_file = NULL; + dbg = 0; /* * Command-line options for help, debug, and config-file @@ -489,7 +491,7 @@ main(int argc, help = 1; break; case 'D' : /* debug */ - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(h, argv[0]); break; case 'f': /* config file */ @@ -513,8 +515,8 @@ main(int argc, * XXX: if started in a start-daemon script, there will be irritating * double syslogs until fork below. */ - clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst); - clicon_debug_init(debug, NULL); + clicon_log_init(__PROGRAM__, dbg?LOG_DEBUG:LOG_INFO, logdst); + clicon_debug_init(dbg, NULL); /* Find and read configfile */ if (clicon_options_main(h) < 0){ @@ -622,7 +624,7 @@ main(int argc, /* Access the remaining argv/argc options (after --) w clicon-argv_get() */ clicon_argv_set(h, argv0, argc, argv); - clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst); + clicon_log_init(__PROGRAM__, dbg?LOG_DEBUG:LOG_INFO, logdst); /* Defer: Wait to the last minute to print help message */ if (help) @@ -880,7 +882,7 @@ main(int argc, demonized errors OK. Before this stage, errors are logged on stderr also */ if (foreground==0){ - clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, + clicon_log_init(__PROGRAM__, dbg?LOG_DEBUG:LOG_INFO, logdst==CLICON_LOG_FILE?CLICON_LOG_FILE:CLICON_LOG_SYSLOG); if (daemon(0, 0) < 0){ fprintf(stderr, "config: daemon"); @@ -911,8 +913,8 @@ main(int argc, goto done; if (clicon_socket_set(h, ss) < 0) goto done; - if (debug) - clicon_option_dump(h, debug); + if (dbg) + clicon_option_dump(h, dbg); /* Depending on configure setting, privileges may be dropped here after * initializations */ if (check_drop_priv(h, gid) < 0) diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index 1eaceee1..e2b3bcc3 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -246,7 +246,7 @@ clixon_plugin_statedata_all(clicon_handle h, continue; } #if 1 - if (debug) + if (clicon_debug_get()) clicon_log_xml(LOG_DEBUG, x, "%s STATE:", __FUNCTION__); #endif /* XXX: ret == 0 invalid yang binding should be handled as internal error */ diff --git a/apps/cli/cli_main.c b/apps/cli/cli_main.c index 622a6023..881f14d6 100644 --- a/apps/cli/cli_main.c +++ b/apps/cli/cli_main.c @@ -294,6 +294,7 @@ main(int argc, cvec *nsctx_global = NULL; /* Global namespace context */ size_t cligen_buflen; size_t cligen_bufthreshold; + int dbg=0; /* Defaults */ once = 0; @@ -332,7 +333,7 @@ main(int argc, help = 1; break; case 'D' : /* debug */ - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(h, argv[0]); break; case 'f': /* config file */ @@ -352,9 +353,9 @@ main(int argc, /* * Logs, error and debug to stderr or syslog, set debug level */ - clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst); + clicon_log_init(__PROGRAM__, dbg?LOG_DEBUG:LOG_INFO, logdst); - clicon_debug_init(debug, NULL); + clicon_debug_init(dbg, NULL); /* Find, read and parse configfile */ if (clicon_options_main(h) < 0){ @@ -588,8 +589,8 @@ main(int argc, if (logclisyntax) cli_logsyntax_set(h, logclisyntax); - if (debug) - clicon_option_dump(h, debug); + if (dbg) + clicon_option_dump(h, dbg); /* Join rest of argv to a single command */ restarg = clicon_strjoin(argc, argv, " "); diff --git a/apps/cli/clixon_cli_api.h b/apps/cli/clixon_cli_api.h index 80653f66..c7c31040 100644 --- a/apps/cli/clixon_cli_api.h +++ b/apps/cli/clixon_cli_api.h @@ -69,54 +69,44 @@ int cli_notification_register(clicon_handle h, char *stream, enum format_enum fo /* cli_common.c: CLIgen new vector callbacks */ - int cli_set(clicon_handle h, cvec *vars, cvec *argv); int cli_merge(clicon_handle h, cvec *vars, cvec *argv); int cli_create(clicon_handle h, cvec *vars, cvec *argv); + int cli_remove(clicon_handle h, cvec *vars, cvec *argv); int cli_del(clicon_handle h, cvec *vars, cvec *argv); int cli_debug_cli(clicon_handle h, cvec *vars, cvec *argv); - int cli_debug_backend(clicon_handle h, cvec *vars, cvec *argv); - int cli_debug_restconf(clicon_handle h, cvec *vars, cvec *argv); int cli_set_mode(clicon_handle h, cvec *vars, cvec *argv); - int cli_start_shell(clicon_handle h, cvec *vars, cvec *argv); - int cli_quit(clicon_handle h, cvec *vars, cvec *argv); - int cli_commit(clicon_handle h, cvec *vars, cvec *argv); int cli_validate(clicon_handle h, cvec *vars, cvec *argv); - int compare_dbs(clicon_handle h, cvec *vars, cvec *argv); int load_config_file(clicon_handle h, cvec *vars, cvec *argv); int save_config_file(clicon_handle h, cvec *vars, cvec *argv); - int delete_all(clicon_handle h, cvec *vars, cvec *argv); - int discard_changes(clicon_handle h, cvec *vars, cvec *argv); - int cli_notify(clicon_handle h, cvec *cvv, cvec *argv); - int db_copy(clicon_handle h, cvec *cvv, cvec *argv); int cli_lock(clicon_handle h, cvec *cvv, cvec *argv); @@ -133,7 +123,6 @@ int expand_dbvar(void *h, char *name, cvec *cvv, cvec *argv, /* cli_show.c: CLIgen new vector arg callbacks */ int show_yang(clicon_handle h, cvec *vars, cvec *argv); - int show_conf_xpath(clicon_handle h, cvec *cvv, cvec *argv); int cli_show_config(clicon_handle h, cvec *cvv, cvec *argv); diff --git a/apps/netconf/netconf_lib.c b/apps/netconf/netconf_lib.c index a42dde08..995fa69e 100644 --- a/apps/netconf/netconf_lib.c +++ b/apps/netconf/netconf_lib.c @@ -197,7 +197,7 @@ netconf_output(int s, int retval = -1; clicon_debug(1, "SEND %s", msg); - if (debug > 1){ /* XXX: below only works to stderr, clicon_debug may log to syslog */ + if (clicon_debug_get() > 1){ /* XXX: below only works to stderr, clicon_debug may log to syslog */ cxobj *xt = NULL; if (clixon_xml_parse_string(buf, YB_NONE, NULL, &xt, NULL) == 0){ clicon_xml2file(stderr, xml_child_i(xt, 0), 0, 0); diff --git a/apps/netconf/netconf_main.c b/apps/netconf/netconf_main.c index 376edd89..5d30ec02 100644 --- a/apps/netconf/netconf_main.c +++ b/apps/netconf/netconf_main.c @@ -401,6 +401,7 @@ main(int argc, cvec *nsctx_global = NULL; /* Global namespace context */ size_t cligen_buflen; size_t cligen_bufthreshold; + int dbg = 0; /* Create handle */ if ((h = clicon_handle_init()) == NULL) @@ -421,7 +422,7 @@ main(int argc, usage(h, argv[0]); break; case 'D' : /* debug */ - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(h, argv[0]); break; case 'f': /* override config file */ @@ -442,8 +443,8 @@ main(int argc, /* * Logs, error and debug to stderr or syslog, set debug level */ - clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst); - clicon_debug_init(debug, NULL); + clicon_log_init(__PROGRAM__, dbg?LOG_DEBUG:LOG_INFO, logdst); + clicon_debug_init(dbg, NULL); /* Find, read and parse configfile */ if (clicon_options_main(h) < 0) @@ -592,8 +593,8 @@ main(int argc, send_hello(h, 1, id); if (clixon_event_reg_fd(0, netconf_input_cb, h, "netconf socket") < 0) goto done; - if (debug) - clicon_option_dump(h, debug); + if (dbg) + clicon_option_dump(h, dbg); if (tv.tv_sec || tv.tv_usec){ struct timeval t; gettimeofday(&t, NULL); diff --git a/apps/restconf/restconf_fcgi_main.c b/apps/restconf/restconf_fcgi_main.c index f5f07c23..24f45c7c 100644 --- a/apps/restconf/restconf_fcgi_main.c +++ b/apps/restconf/restconf_fcgi_main.c @@ -551,6 +551,7 @@ main(int argc, cvec *nsctx_global = NULL; /* Global namespace context */ size_t cligen_buflen; size_t cligen_bufthreshold; + int dbg = 0; /* In the startup, logs to stderr & debug flag set later */ clicon_log_init(__PROGRAM__, LOG_INFO, logdst); @@ -567,7 +568,7 @@ main(int argc, usage(h, argv[0]); break; case 'D' : /* debug */ - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(h, argv[0]); break; case 'f': /* override config file */ @@ -587,9 +588,9 @@ main(int argc, /* * Logs, error and debug to stderr or syslog, set debug level */ - clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst); + clicon_log_init(__PROGRAM__, dbg?LOG_DEBUG:LOG_INFO, logdst); - clicon_debug_init(debug, NULL); + clicon_debug_init(dbg, NULL); clicon_log(LOG_NOTICE, "%s: %u Started", __PROGRAM__, getpid()); if (set_signal(SIGTERM, restconf_sig_term, NULL) < 0){ clicon_err(OE_DAEMON, errno, "Setting signal"); @@ -737,8 +738,8 @@ main(int argc, goto done; /* Dump configuration options on debug */ - if (debug) - clicon_option_dump(h, debug); + if (dbg) + clicon_option_dump(h, dbg); /* Call start function in all plugins before we go interactive */ diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c index 83b45906..e646fbad 100644 --- a/apps/restconf/restconf_methods.c +++ b/apps/restconf/restconf_methods.c @@ -306,7 +306,7 @@ api_data_write(clicon_handle h, } #if 0 - if (debug) + if (clicon_debug_get()) clicon_log_xml(LOG_DEBUG, xret, "%s xret:", __FUNCTION__); #endif if (xml_child_nr(xret) == 0){ /* Object does not exist */ diff --git a/apps/restconf/restconf_methods_get.c b/apps/restconf/restconf_methods_get.c index deb7e94e..43b36414 100644 --- a/apps/restconf/restconf_methods_get.c +++ b/apps/restconf/restconf_methods_get.c @@ -221,7 +221,7 @@ api_data_get2(clicon_handle h, * We need to cut that tree to only the object. */ #if 0 /* DEBUG */ - if (debug) + if (clicon_debug_get()) clicon_log_xml(LOG_DEBUG, xret, "%s xret:", __FUNCTION__); #endif /* Check if error return */ diff --git a/apps/restconf/restconf_methods_post.c b/apps/restconf/restconf_methods_post.c index 60d535ec..9a384a82 100644 --- a/apps/restconf/restconf_methods_post.c +++ b/apps/restconf/restconf_methods_post.c @@ -307,7 +307,7 @@ api_data_post(clicon_handle h, if (restconf_insert_attributes(xdata, qvec) < 0) goto done; #if 1 - if (debug) + if (clicon_debug_get()) clicon_log_xml(LOG_DEBUG, xdata, "%s xdata:", __FUNCTION__); #endif @@ -512,7 +512,7 @@ api_operations_post_input(clicon_handle h, * ... */ #if 1 - if (debug) + if (clicon_debug_get()) clicon_log_xml(LOG_DEBUG, xdata, "%s xdata:", __FUNCTION__); #endif /* Validate that exactly only tag */ @@ -614,7 +614,7 @@ api_operations_post_output(clicon_handle h, xml_name_set(xoutput, "output"); /* xoutput should now look: 0 */ #if 1 - if (debug) + if (clicon_debug_get()) clicon_log_xml(LOG_DEBUG, xoutput, "%s xoutput:", __FUNCTION__); #endif @@ -843,7 +843,7 @@ api_operations_post(clicon_handle h, /* Here xtop is: 42 */ #if 1 - if (debug) + if (clicon_debug_get()) clicon_log_xml(LOG_DEBUG, xtop, "%s 5. Translate input args:", __FUNCTION__); #endif /* 6. Validate outgoing RPC and fill in defaults */ @@ -874,7 +874,7 @@ api_operations_post(clicon_handle h, * 4299 */ #if 0 - if (debug) + if (clicon_debug_get()) clicon_log_xml(LOG_DEBUG, xtop, "%s 6. Validate and defaults:", __FUNCTION__); #endif /* 7. Send to RPC handler, either local or backend @@ -909,7 +909,7 @@ api_operations_post(clicon_handle h, * 0 */ #if 1 - if (debug) + if (clicon_debug_get()) clicon_log_xml(LOG_DEBUG, xret, "%s Receive reply:", __FUNCTION__); #endif youtput = yang_find(yrpc, Y_OUTPUT, NULL); diff --git a/example/main/example_backend.c b/example/main/example_backend.c index bbb8c48c..832a0c73 100644 --- a/example/main/example_backend.c +++ b/example/main/example_backend.c @@ -159,7 +159,7 @@ main_commit(clicon_handle h, /* Get all added i/fs */ if (xpath_vec_flag(target, nsc, "//interface", XML_FLAG_ADD, &vec, &len) < 0) return -1; - if (debug) + if (clicon_debug_get()) for (i=0; i1) + if (clicon_debug_get()>1) clicon_xml2file(stderr, xt, 0, 1); *xtop = xt; xt = NULL; @@ -565,7 +565,7 @@ xmldb_get_cache(clicon_handle h, /* Copy the matching parts of the (relevant) XML tree. * If cache was empty, also update to datastore cache */ - if (debug>1) + if (clicon_debug_get()>1) clicon_xml2file(stderr, x1t, 0, 1); *xtop = x1t; retval = 0; @@ -639,7 +639,7 @@ xmldb_get_zerocopy(clicon_handle h, /* Apply default values (removed in clear function) */ if (xml_default_recurse(x0t) < 0) goto done; - if (debug>1) + if (clicon_debug_get()>1) clicon_xml2file(stderr, x0t, 0, 1); *xtop = x0t; retval = 0; diff --git a/lib/src/clixon_log.c b/lib/src/clixon_log.c index 74c19b36..c3a752e0 100644 --- a/lib/src/clixon_log.c +++ b/lib/src/clixon_log.c @@ -58,8 +58,12 @@ #include "clixon_err.h" #include "clixon_log.h" -/* The global debug level. 0 means no debug */ -int debug = 0; +/* The global debug level. 0 means no debug + * @note There are pros and cons in having the debug state as a global variable. The + * alternative to bind it to the clicon handle (h) was considered but it limits its + * usefulness, since not all functions have h + */ +static int _clixon_debug = 0; /* Bitmask whether to log to syslog or stderr: CLICON_LOG_STDERR | CLICON_LOG_SYSLOG */ static int _logflags = 0x0; @@ -67,6 +71,7 @@ static int _logflags = 0x0; /* Set to open file to write debug messages directly to file */ static FILE *_logfile = NULL; + /*! Initialize system logger. * * Make syslog(3) calls with specified ident and gates calls of level upto specified level (upto). @@ -217,7 +222,7 @@ clicon_log_str(int level, /* syslog makes own filtering, we do it here: * if normal (not debug) then filter loglevels >= debug */ - if (debug == 0 && level >= LOG_DEBUG) + if (_clixon_debug == 0 && level >= LOG_DEBUG) goto done; if (_logflags & CLICON_LOG_STDERR){ flogtime(stderr); @@ -231,6 +236,7 @@ clicon_log_str(int level, flogtime(_logfile); fprintf(_logfile, "%s\n", msg); fflush(_logfile); + } /* Enable this if you want syslog in a stream. But there are problems with @@ -288,7 +294,6 @@ clicon_log(int level, return retval; } - /*! Initialize debug messages. Set debug level. * * Initialize debug module. The level is used together with clicon_debug(dbglevel) calls as follows: @@ -309,10 +314,16 @@ int clicon_debug_init(int dbglevel, FILE *f) { - debug = dbglevel; /* Global variable */ + _clixon_debug = dbglevel; /* Global variable */ return 0; } +int +clicon_debug_get(void) +{ + return _clixon_debug; +} + /*! Print a debug message with debug-level. Settings determine where msg appears. * * If the dbglevel passed in the function is equal to or lower than the one set by @@ -335,7 +346,7 @@ clicon_debug(int dbglevel, char *msg = NULL; int retval = -1; - if (dbglevel > debug) /* debug mask */ + if (dbglevel > _clixon_debug) /* compare debug mask with global variable */ return 0; /* first round: compute length of debug message */ va_start(args, format); diff --git a/lib/src/clixon_path.c b/lib/src/clixon_path.c index 539747a5..ff17384c 100644 --- a/lib/src/clixon_path.c +++ b/lib/src/clixon_path.c @@ -1559,7 +1559,7 @@ clixon_xml_find_api_path(cxobj *xt, /* Parse api-path string to structured clixon-path data */ if (api_path_parse(api_path, &cplist) < 0) goto done; - if (debug) + if (clicon_debug_get()) clixon_path_print(stderr, cplist); /* Resolve module:name to yang-stmt, fail if not successful */ if ((ret = api_path_resolve(cplist, yt)) < 0) @@ -1652,7 +1652,7 @@ clixon_xml_find_instance_id(cxobj *xt, va_end(ap); if (instance_id_parse(path, &cplist) < 0) goto done; - if (debug) + if (clicon_debug_get()) clixon_path_print(stderr, cplist); /* Resolve module:name to pointer to yang-stmt, fail if not successful */ if ((ret = instance_id_resolve(cplist, yt)) < 0) diff --git a/lib/src/clixon_proto.c b/lib/src/clixon_proto.c index 1c24dcc3..84082877 100644 --- a/lib/src/clixon_proto.c +++ b/lib/src/clixon_proto.c @@ -326,7 +326,7 @@ clicon_msg_send(int s, clicon_debug(2, "%s: send msg len=%d", __FUNCTION__, ntohl(msg->op_len)); - if (debug > 2) + if (clicon_debug_get() > 2) msg_dump(msg); if (atomicio((ssize_t (*)(int, void *, size_t))write, s, msg, ntohl(msg->op_len)) < 0){ @@ -400,7 +400,7 @@ clicon_msg_rcv(int s, clicon_err(OE_CFG, errno, "body too short"); goto done; } - if (debug > 1) + if (clicon_debug_get() > 1) msg_dump(*msg); retval = 0; done: diff --git a/lib/src/clixon_stream.c b/lib/src/clixon_stream.c index c43b3048..1e6c7bab 100644 --- a/lib/src/clixon_stream.c +++ b/lib/src/clixon_stream.c @@ -927,7 +927,7 @@ url_post(char *url, curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postfields); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(postfields)); - if (debug) + if (clicon_debug_get()) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); if ((errcode = curl_easy_perform(curl)) != CURLE_OK){ clicon_debug(1, "%s: curl: %s(%d)", __FUNCTION__, err, errcode); diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 3f1428da..47ee536e 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -358,7 +358,7 @@ xml2cvec(cxobj *xt, } } } - if (debug > 1){ + if (clicon_debug_get() > 1){ clicon_debug(2, "%s cvv:\n", __FUNCTION__); cvec_print(stderr, cvv); } diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index 8a6f7076..70a72361 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -504,7 +504,7 @@ xpath_parse(char *xpath, clicon_err(OE_XML, 0, "XPATH parser error with no error code (should not happen)"); goto done; } - if (debug > 1){ + if (clicon_debug_get() > 1){ if ((cb = cbuf_new()) == NULL){ clicon_err(OE_XML, errno, "cbuf_new"); goto done; diff --git a/lib/src/clixon_xpath_eval.c b/lib/src/clixon_xpath_eval.c index 69b547f6..8d155ffc 100644 --- a/lib/src/clixon_xpath_eval.c +++ b/lib/src/clixon_xpath_eval.c @@ -940,7 +940,7 @@ xp_eval(xp_ctx *xc, xp_ctx *xr2 = NULL; int use_xr0 = 0; /* In 2nd child use transitively result of 1st child */ - if (debug > 1) + if (clicon_debug_get() > 1) ctx_print(stderr, xc, xpath_tree_int2str(xs->xs_type)); /* Pre-actions before check first child c0 */ @@ -1096,7 +1096,7 @@ xp_eval(xp_ctx *xc, xr0 = NULL; } ok: - if (debug>1) + if (clicon_debug_get() > 1) ctx_print(stderr, *xrp, xpath_tree_int2str(xs->xs_type)); retval = 0; done: diff --git a/lib/src/clixon_yang_parse.y b/lib/src/clixon_yang_parse.y index de147a03..7e3add06 100644 --- a/lib/src/clixon_yang_parse.y +++ b/lib/src/clixon_yang_parse.y @@ -195,13 +195,6 @@ extern int clixon_yang_parseget_lineno (void); -int -clicon_yang_debug(int d) -{ - debug = d; - return 0; -} - /* clixon_yang_parseerror also called from yacc generated code * diff --git a/test/test_cli_gen.sh b/test/test_cli_gen.sh new file mode 100755 index 00000000..4d78fa77 --- /dev/null +++ b/test/test_cli_gen.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# Tests for using the generated cli. +# In particular setting a config, displaying as cli commands and reconfigure it using that. +# Tests: +# Make a config in CLI. Show output as CLI, save it and ensure it is the same + +# Magic line must be first in script (see README.md) +s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi + +APPNAME=example + +# include err() and new() functions and creates $dir + +cfg=$dir/conf_yang.xml +fyang=$dir/$APPNAME.yang +clidir=$dir/cli +if [ -d $clidir ]; then + rm -rf $clidir/* +else + mkdir $clidir +fi + +# Use yang in example + +cat < $cfg + + $cfg + /usr/local/share/clixon + $dir + $fyang + $clidir + /usr/local/lib/$APPNAME/cli + $APPNAME + ALL + /usr/local/var/$APPNAME/$APPNAME.sock + /usr/local/var/$APPNAME/$APPNAME.pidfile + /usr/local/var/$APPNAME + +EOF + +cat < $fyang +module $APPNAME { + namespace "urn:example:clixon"; + prefix ex; + container table{ + list parameter{ + key name; + leaf name{ + type string; + } + leaf value{ + type string; + } + } + } +} +EOF + +cat < $clidir/ex.cli +CLICON_MODE="example"; +CLICON_PROMPT="%U@%H> "; + +set @datamodel, cli_set(); +merge @datamodel, cli_merge(); +create @datamodel, cli_create(); +delete @datamodel, cli_del(); +show config @datamodel, cli_show_auto("candidate", "cli"); + +EOF + +new "test params: -f $cfg" +if [ $BE -ne 0 ]; then + new "kill old backend" + sudo clixon_backend -z -f $cfg + if [ $? -ne 0 ]; then + err + fi + new "start backend -s init -f $cfg" + start_backend -s init -f $cfg + + new "waiting" + wait_backend +fi + +# Set a config in CLI +new "set a" +expectfn "$clixon_cli -1 -f $cfg set table parameter name a value x" 0 "" + +new "set b" +expectfn "$clixon_cli -1 -f $cfg set table parameter name b value y" 0 "" + +new "set b" +expectfn "$clixon_cli -1 -f $cfg set table parameter name b value y" 0 "" + + + +new "Kill backend" +# Check if premature kill +pid=$(pgrep -u root -f clixon_backend) +if [ -z "$pid" ]; then + err "backend already dead" +fi +# kill backend +stop_backend -f $cfg + +rm -rf $dir diff --git a/util/clixon_util_datastore.c b/util/clixon_util_datastore.c index 037f2298..c29131c9 100644 --- a/util/clixon_util_datastore.c +++ b/util/clixon_util_datastore.c @@ -118,6 +118,7 @@ main(int argc, char **argv) int i; char *xpath; cbuf *cbret = NULL; + int dbg = 0; /* In the startup, logs to stderr & debug flag set later */ clicon_log_init(__FILE__, LOG_INFO, CLICON_LOG_STDERR); @@ -135,7 +136,7 @@ main(int argc, char **argv) usage(argv0); break; case 'D' : /* debug */ - debug = 1; + dbg = 1; break; case 'd': /* db symbolic: running|candidate|startup */ if (!optarg) @@ -166,8 +167,8 @@ main(int argc, char **argv) /* * Logs, error and debug to stderr, set debug level */ - clicon_log_init(__FILE__, debug?LOG_DEBUG:LOG_INFO, CLICON_LOG_STDERR); - clicon_debug_init(debug, NULL); + clicon_log_init(__FILE__, dbg?LOG_DEBUG:LOG_INFO, CLICON_LOG_STDERR); + clicon_debug_init(dbg, NULL); argc -= optind; argv += optind; diff --git a/util/clixon_util_json.c b/util/clixon_util_json.c index 18a43fea..1d40cf8d 100644 --- a/util/clixon_util_json.c +++ b/util/clixon_util_json.c @@ -96,6 +96,7 @@ main(int argc, cxobj *xerr = NULL; /* malloced must be freed */ int ret; int pretty = 0; + int dbg = 0; optind = 1; opterr = 0; @@ -105,7 +106,7 @@ main(int argc, usage(argv[0]); break; case 'D': - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(argv[0]); break; case 'j': @@ -125,7 +126,9 @@ main(int argc, usage(argv[0]); break; } - clicon_log_init(__FILE__, debug?LOG_DEBUG:LOG_INFO, logdst); + clicon_log_init(__FILE__, dbg?LOG_DEBUG:LOG_INFO, logdst); + clicon_debug_init(dbg, NULL); + if (yang_filename){ if ((yspec = yspec_new()) == NULL) goto done; diff --git a/util/clixon_util_path.c b/util/clixon_util_path.c index 5d3f9961..2805b5c8 100644 --- a/util/clixon_util_path.c +++ b/util/clixon_util_path.c @@ -109,6 +109,7 @@ main(int argc, cxobj *xcfg = NULL; cxobj *xerr = NULL; /* malloced must be freed */ int nr = 1; + int dbg = 0; /* In the startup, logs to stderr & debug flag set later */ clicon_log_init("api-path", LOG_DEBUG, CLICON_LOG_STDERR); @@ -129,7 +130,7 @@ main(int argc, usage(argv0); break; case 'D': - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(argv0); break; case 'f': /* XML file */ @@ -159,6 +160,8 @@ main(int argc, usage(argv[0]); break; } + clicon_debug_init(dbg, NULL); + /* Parse yang */ if (yang_file_dir){ if ((yspec = yspec_new()) == NULL) diff --git a/util/clixon_util_regexp.c b/util/clixon_util_regexp.c index 997df129..e8413986 100644 --- a/util/clixon_util_regexp.c +++ b/util/clixon_util_regexp.c @@ -163,6 +163,7 @@ main(int argc, int ret = 0; int nr = 1; int mode = 0; /* 0 is posix, 1 is libxml */ + int dbg = 0; optind = 1; opterr = 0; @@ -172,7 +173,7 @@ main(int argc, usage(argv0); break; case 'D': - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(argv0); break; case 'p': /* xsd->posix */ @@ -195,7 +196,9 @@ main(int argc, usage(argv[0]); break; } - clicon_log_init(__FILE__, debug?LOG_DEBUG:LOG_INFO, CLICON_LOG_STDERR); + clicon_log_init(__FILE__, dbg?LOG_DEBUG:LOG_INFO, CLICON_LOG_STDERR); + clicon_debug_init(dbg, NULL); + if (regexp == NULL){ fprintf(stderr, "-r mandatory\n"); usage(argv0); @@ -211,12 +214,12 @@ main(int argc, clicon_debug(1, "regexp:%s", regexp); clicon_debug(1, "content:%s", content); if (mode == 0){ - if ((ret = regex_posix(regexp, content, nr, debug)) < 0) + if ((ret = regex_posix(regexp, content, nr, dbg)) < 0) goto done; } else if (mode == 1){ - if ((ret = regex_libxml2(regexp, content, nr, debug)) < 0) + if ((ret = regex_libxml2(regexp, content, nr, dbg)) < 0) goto done; } else diff --git a/util/clixon_util_socket.c b/util/clixon_util_socket.c index 101221a2..e51238e2 100644 --- a/util/clixon_util_socket.c +++ b/util/clixon_util_socket.c @@ -95,6 +95,7 @@ main(int argc, int ret; cbuf *cb = cbuf_new(); clicon_handle h; + int dbg = 0; /* In the startup, logs to stderr & debug flag set later */ clicon_log_init(__FILE__, LOG_INFO, CLICON_LOG_STDERR); @@ -110,7 +111,7 @@ main(int argc, usage(argv[0]); break; case 'D': - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(argv[0]); break; case 's': @@ -129,7 +130,9 @@ main(int argc, usage(argv[0]); break; } - clicon_log_init(__FILE__, debug?LOG_DEBUG:LOG_INFO, logdst); + clicon_log_init(__FILE__, dbg?LOG_DEBUG:LOG_INFO, logdst); + clicon_debug_init(dbg, NULL); + if (sockpath == NULL){ fprintf(stderr, "Mandatory option missing: -s \n"); usage(argv[0]); diff --git a/util/clixon_util_stream.c b/util/clixon_util_stream.c index 48dbecf7..38c1ff19 100644 --- a/util/clixon_util_stream.c +++ b/util/clixon_util_stream.c @@ -219,6 +219,7 @@ main(int argc, char **argv) int c; char *argv0 = argv[0]; struct timeval now; + int dbg = 0; clicon_log_init("xpath", LOG_DEBUG, CLICON_LOG_STDERR); gettimeofday(&now, NULL); @@ -230,7 +231,7 @@ main(int argc, char **argv) usage(argv0); break; case 'D': - debug++; + dbg = 1; break; case 'u': /* URL */ url = optarg; @@ -264,6 +265,7 @@ main(int argc, char **argv) usage(argv[0]); break; } + clicon_debug_init(dbg, NULL); if (url == NULL) usage(argv[0]); curl_global_init(0); diff --git a/util/clixon_util_xml.c b/util/clixon_util_xml.c index ddc8d3cd..6693df8c 100644 --- a/util/clixon_util_xml.c +++ b/util/clixon_util_xml.c @@ -163,6 +163,7 @@ main(int argc, cxobj *xbot; /* Place in xtop where base cxobj is parsed */ cvec *nsc = NULL; yang_bind yb; + int dbg = 0; /* In the startup, logs to stderr & debug flag set later */ clicon_log_init(__FILE__, LOG_INFO, CLICON_LOG_STDERR); @@ -184,7 +185,7 @@ main(int argc, usage(argv[0]); break; case 'D': - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(argv[0]); break; case 'f': @@ -239,7 +240,9 @@ main(int argc, fprintf(stderr, "-t requires -T\n"); usage(argv[0]); } - clicon_log_init(__FILE__, debug?LOG_DEBUG:LOG_INFO, logdst); + clicon_log_init(__FILE__, dbg?LOG_DEBUG:LOG_INFO, logdst); + clicon_debug_init(dbg, NULL); + /* 1. Parse yang */ if (yang_file_dir){ if ((yspec = yspec_new()) == NULL) @@ -319,7 +322,7 @@ main(int argc, } /* Dump data structures (for debug) */ - if (debug){ + if (clicon_debug_get()){ cbuf_reset(cb); xmltree2cbuf(cb, xt, 0); fprintf(stderr, "%s\n", cbuf_get(cb)); diff --git a/util/clixon_util_xml_mod.c b/util/clixon_util_xml_mod.c index f2eae659..010f64ea 100644 --- a/util/clixon_util_xml_mod.c +++ b/util/clixon_util_xml_mod.c @@ -129,6 +129,7 @@ main(int argc, char **argv) clicon_handle h; enum opx opx = OPX_ERROR; char *reason = NULL; + int dbg = 0; clicon_log_init("clixon_insert", LOG_DEBUG, CLICON_LOG_STDERR); if ((h = clicon_handle_init()) == NULL) @@ -141,7 +142,7 @@ main(int argc, char **argv) usage(argv0); break; case 'D': - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(argv0); break; case 'o': /* Operation */ @@ -171,6 +172,7 @@ main(int argc, char **argv) usage(argv0); if (opx == OPX_ERROR) usage(argv0); + clicon_debug_init(dbg, NULL); if ((yspec = yspec_new()) == NULL) goto done; if (yang_spec_parse_file(h, yangfile, yspec) < 0) @@ -189,7 +191,7 @@ main(int argc, char **argv) clicon_err(OE_XML, 0, "xpath: %s not found in x0", xpath); goto done; } - if (debug){ + if (clicon_debug_get()){ clicon_debug(1, "xb:"); xml_print(stderr, xb); } @@ -256,7 +258,7 @@ main(int argc, char **argv) default: usage(argv0); } - if (debug){ + if (clicon_debug_get()){ clicon_debug(1, "x0:"); xml_print(stderr, x0); } diff --git a/util/clixon_util_xpath.c b/util/clixon_util_xpath.c index f8afdb71..1513633d 100644 --- a/util/clixon_util_xpath.c +++ b/util/clixon_util_xpath.c @@ -140,6 +140,7 @@ main(int argc, cxobj *xcfg = NULL; cbuf *cbret = NULL; cxobj *xerr = NULL; /* malloced must be freed */ + int dbg = 0; /* In the startup, logs to stderr & debug flag set later */ clicon_log_init("xpath", LOG_DEBUG, CLICON_LOG_STDERR); @@ -160,7 +161,7 @@ main(int argc, usage(argv0); break; case 'D': - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(argv0); break; case 'f': /* XML file */ @@ -210,6 +211,8 @@ main(int argc, usage(argv[0]); break; } + clicon_debug_init(dbg, NULL); + /* Parse yang */ if (yang_file_dir){ if ((yspec = yspec_new()) == NULL) diff --git a/util/clixon_util_yang.c b/util/clixon_util_yang.c index 7918cac3..d3261ab6 100644 --- a/util/clixon_util_yang.c +++ b/util/clixon_util_yang.c @@ -81,6 +81,7 @@ main(int argc, char **argv) yang_stmt *yspec = NULL; int c; int logdst = CLICON_LOG_STDERR; + int dbg = 0; optind = 1; opterr = 0; @@ -90,7 +91,7 @@ main(int argc, char **argv) usage(argv[0]); break; case 'D': - if (sscanf(optarg, "%d", &debug) != 1) + if (sscanf(optarg, "%d", &dbg) != 1) usage(argv[0]); break; case 'l': /* Log destination: s|e|o|f */ @@ -101,7 +102,8 @@ main(int argc, char **argv) usage(argv[0]); break; } - clicon_log_init("clixon_util_yang", debug?LOG_DEBUG:LOG_INFO, logdst); + clicon_log_init("clixon_util_yang", dbg?LOG_DEBUG:LOG_INFO, logdst); + clicon_debug_init(dbg, NULL); if ((yspec = yspec_new()) == NULL) goto done; if (yang_parse_file(0, "yang test", yspec) == NULL){