C-API: changed formatstr conversion to int to handle -1

Misc formatting
This commit is contained in:
Olof hagsand 2025-02-05 11:30:11 +01:00
parent 63f048115e
commit 74958d9114
11 changed files with 116 additions and 102 deletions

View file

@ -92,13 +92,13 @@ cli_notification_register(clixon_handle h,
int (*fn)(int, void*), int (*fn)(int, void*),
void *arg) void *arg)
{ {
int retval = -1; int retval = -1;
char *logname = NULL; char *logname = NULL;
void *p; void *p;
int s; int s;
clicon_hash_t *cdat = clicon_data(h); clicon_hash_t *cdat = clicon_data(h);
size_t len; size_t len;
int s_exist = -1; int s_exist = -1;
len = strlen("log_socket_") + strlen(stream) + 1; len = strlen("log_socket_") + strlen(stream) + 1;
if ((logname = malloc(len)) == NULL){ if ((logname = malloc(len)) == NULL){
@ -160,15 +160,18 @@ cli_signal_unblock(clixon_handle h)
clicon_signal_unblock (SIGINT); clicon_signal_unblock (SIGINT);
} }
/* /*! Flush pending signals for a given signal type
* Flush pending signals for a given signal type *
* @param[in] h Clixon handle
* XXX A bit rough. Use sigpending() and more clever logic ??
*/ */
void void
cli_signal_flush(clixon_handle h) cli_signal_flush(clixon_handle h)
{ {
/* XXX A bit rough. Use sigpending() and more clever logic ?? */ sigfn_t h1;
sigfn_t h2;
sigfn_t h1, h2, h3, h4; sigfn_t h3;
sigfn_t h4;
set_signal(SIGTSTP, SIG_IGN, &h1); set_signal(SIGTSTP, SIG_IGN, &h1);
set_signal(SIGQUIT, SIG_IGN, &h2); set_signal(SIGQUIT, SIG_IGN, &h2);
@ -195,8 +198,8 @@ cli_signal_flush(clixon_handle h)
* CLI variable vector element. * CLI variable vector element.
*/ */
int int
dbxml_body(cxobj *xbot, dbxml_body(cxobj *xbot,
cvec *cvv) cvec *cvv)
{ {
int retval = -1; int retval = -1;
char *str = NULL; char *str = NULL;
@ -636,8 +639,8 @@ cli_del(clixon_handle h,
*/ */
int int
cli_debug_show(clixon_handle h, cli_debug_show(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
cligen_output(stdout, "CLI debug:0x%x\n", clixon_debug_get()); cligen_output(stdout, "CLI debug:0x%x\n", clixon_debug_get());
return 0; return 0;
@ -655,8 +658,8 @@ cli_debug_show(clixon_handle h,
*/ */
int int
cli_debug_cli(clixon_handle h, cli_debug_cli(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int retval = -1; int retval = -1;
cg_var *cv; cg_var *cv;
@ -784,8 +787,8 @@ cli_set_mode(clixon_handle h,
*/ */
int int
cli_quit(clixon_handle h, cli_quit(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
cligen_exiting_set(cli_cligen(h), 1); cligen_exiting_set(cli_cligen(h), 1);
return 0; return 0;
@ -836,8 +839,8 @@ cli_commit(clixon_handle h,
*/ */
int int
cli_validate(clixon_handle h, cli_validate(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int retval = -1; int retval = -1;
@ -864,11 +867,11 @@ compare_db_names(clixon_handle h,
char *db1, char *db1,
char *db2) char *db2)
{ {
int retval = -1; int retval = -1;
cxobj *xc1 = NULL; cxobj *xc1 = NULL;
cxobj *xc2 = NULL; cxobj *xc2 = NULL;
cxobj *xerr = NULL; cxobj *xerr = NULL;
cbuf *cb = NULL; cbuf *cb = NULL;
if (clicon_rpc_get_config(h, NULL, db1, "/", NULL, NULL, &xc1) < 0) if (clicon_rpc_get_config(h, NULL, db1, "/", NULL, NULL, &xc1) < 0)
goto done; goto done;
@ -942,6 +945,7 @@ compare_dbs(clixon_handle h,
char *db1; char *db1;
char *db2; char *db2;
char *formatstr; char *formatstr;
int ret;
if (cvec_len(argv) != 3){ if (cvec_len(argv) != 3){
clixon_err(OE_PLUGIN, EINVAL, "Expected arguments: <db1> <db2> <format>"); clixon_err(OE_PLUGIN, EINVAL, "Expected arguments: <db1> <db2> <format>");
@ -950,17 +954,19 @@ compare_dbs(clixon_handle h,
db1 = cv_string_get(cvec_i(argv, 0)); db1 = cv_string_get(cvec_i(argv, 0));
db2 = cv_string_get(cvec_i(argv, 1)); db2 = cv_string_get(cvec_i(argv, 1));
formatstr = cv_string_get(cvec_i(argv, 2)); formatstr = cv_string_get(cvec_i(argv, 2));
if ((format = format_str2int(formatstr)) < 0){ if ((ret = format_str2int(formatstr)) < 0){
clixon_err(OE_XML, 0, "format not found %s", formatstr); clixon_err(OE_XML, 0, "format not found %s", formatstr);
goto done; goto done;
} }
format = ret;
/* Special default format handling */ /* Special default format handling */
if (format == FORMAT_DEFAULT){ if (format == FORMAT_DEFAULT){
formatstr = clicon_option_str(h, "CLICON_CLI_OUTPUT_FORMAT"); formatstr = clicon_option_str(h, "CLICON_CLI_OUTPUT_FORMAT");
if ((int)(format = format_str2int(formatstr)) < 0){ if ((ret = format_str2int(formatstr)) < 0){
clixon_err(OE_PLUGIN, 0, "Not valid format: %s", formatstr); clixon_err(OE_PLUGIN, 0, "Not valid format: %s", formatstr);
goto done; goto done;
} }
format = ret;
} }
if (compare_db_names(h, format, db1, db2) < 0) if (compare_db_names(h, format, db1, db2) < 0)
goto done; goto done;
@ -995,7 +1001,7 @@ load_config_file(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int ret = -1; int retval = -1;
struct stat st; struct stat st;
char *filename = NULL; char *filename = NULL;
int replace; int replace;
@ -1011,6 +1017,7 @@ load_config_file(clixon_handle h,
yang_stmt *yspec; yang_stmt *yspec;
cxobj *xerr = NULL; cxobj *xerr = NULL;
char *lineptr = NULL; char *lineptr = NULL;
int ret;
if (cvec_len(argv) < 2 || cvec_len(argv) > 4){ if (cvec_len(argv) < 2 || cvec_len(argv) > 4){
clixon_err(OE_PLUGIN, EINVAL, "Received %d arguments. Expected: <dbname>,<varname>[,<format>]", clixon_err(OE_PLUGIN, EINVAL, "Received %d arguments. Expected: <dbname>,<varname>[,<format>]",
@ -1023,10 +1030,11 @@ load_config_file(clixon_handle h,
} }
if (cvec_len(argv) > 2){ if (cvec_len(argv) > 2){
formatstr = cv_string_get(cvec_i(argv, 2)); formatstr = cv_string_get(cvec_i(argv, 2));
if ((int)(format = format_str2int(formatstr)) < 0){ if ((ret = format_str2int(formatstr)) < 0){
clixon_err(OE_PLUGIN, 0, "Not valid format: %s", formatstr); clixon_err(OE_PLUGIN, 0, "Not valid format: %s", formatstr);
goto done; goto done;
} }
format = ret;
} }
varstr = cv_string_get(cvec_i(argv, 0)); varstr = cv_string_get(cvec_i(argv, 0));
opstr = cv_string_get(cvec_i(argv, 1)); opstr = cv_string_get(cvec_i(argv, 1));
@ -1054,18 +1062,18 @@ load_config_file(clixon_handle h,
} }
switch (format){ switch (format){
case FORMAT_XML: case FORMAT_XML:
if ((ret = clixon_xml_parse_file(fp, YB_NONE, yspec, &xt, &xerr)) < 0) if ((retval = clixon_xml_parse_file(fp, YB_NONE, yspec, &xt, &xerr)) < 0)
goto done; goto done;
if (ret == 0){ if (retval == 0){
if (clixon_err_netconf(h, OE_NETCONF, 0, xerr, "Loading %s", filename) < 0) if (clixon_err_netconf(h, OE_NETCONF, 0, xerr, "Loading %s", filename) < 0)
goto done; goto done;
goto done; goto done;
} }
break; break;
case FORMAT_JSON: case FORMAT_JSON:
if ((ret = clixon_json_parse_file(fp, 1, YB_NONE, yspec, &xt, &xerr)) < 0) if ((retval = clixon_json_parse_file(fp, 1, YB_NONE, yspec, &xt, &xerr)) < 0)
goto done; goto done;
if (ret == 0){ if (retval == 0){
if (clixon_err_netconf(h, OE_NETCONF, 0, xerr, "Loading %s", filename) < 0) if (clixon_err_netconf(h, OE_NETCONF, 0, xerr, "Loading %s", filename) < 0)
goto done; goto done;
goto done; goto done;
@ -1075,9 +1083,9 @@ load_config_file(clixon_handle h,
/* text parser requires YANG and since load/save files have a "config" top-level /* text parser requires YANG and since load/save files have a "config" top-level
* the yang-bind parameter must be YB_MODULE_NEXT * the yang-bind parameter must be YB_MODULE_NEXT
*/ */
if ((ret = clixon_text_syntax_parse_file(fp, YB_MODULE_NEXT, yspec, &xt, &xerr)) < 0) if ((retval = clixon_text_syntax_parse_file(fp, YB_MODULE_NEXT, yspec, &xt, &xerr)) < 0)
goto done; goto done;
if (ret == 0){ if (retval == 0){
if (clixon_err_netconf(h, OE_NETCONF, 0, xerr, "Loading %s", filename) < 0) if (clixon_err_netconf(h, OE_NETCONF, 0, xerr, "Loading %s", filename) < 0)
goto done; goto done;
goto done; goto done;
@ -1135,7 +1143,7 @@ load_config_file(clixon_handle h,
cbuf_get(cbxml)) < 0) cbuf_get(cbxml)) < 0)
goto done; goto done;
ok: ok:
ret = 0; retval = 0;
done: done:
if (cbxml) if (cbxml)
cbuf_free(cbxml); cbuf_free(cbxml);
@ -1147,7 +1155,7 @@ load_config_file(clixon_handle h,
xml_free(xt); xml_free(xt);
if (fp) if (fp)
fclose(fp); fclose(fp);
return ret; return retval;
} }
/*! Copy database to local file as XMLn /*! Copy database to local file as XMLn
@ -1174,18 +1182,18 @@ save_config_file(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int retval = -1; int retval = -1;
char *filename = NULL; char *filename = NULL;
cg_var *cv; cg_var *cv;
char *dbstr; char *dbstr;
char *varstr; char *varstr;
cxobj *xt = NULL; cxobj *xt = NULL;
cxobj *xerr; cxobj *xerr;
FILE *f = NULL; FILE *f = NULL;
char *formatstr; char *formatstr;
enum format_enum format = FORMAT_XML; enum format_enum format = FORMAT_XML;
char *prefix = "set "; /* XXX hardcoded */ char *prefix = "set "; /* XXX hardcoded */
int pretty = 1; /* XXX hardcoded */ int pretty = 1; /* XXX hardcoded */
if (cvec_len(argv) < 2 || cvec_len(argv) > 4){ if (cvec_len(argv) < 2 || cvec_len(argv) > 4){
clixon_err(OE_PLUGIN, EINVAL, "Received %d arguments. Expected: <dbname>,<varname>[,<format>]", clixon_err(OE_PLUGIN, EINVAL, "Received %d arguments. Expected: <dbname>,<varname>[,<format>]",
@ -1284,8 +1292,8 @@ delete_all(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
char *dbstr; int retval = -1;
int retval = -1; char *dbstr;
if (cvec_len(argv) != 1){ if (cvec_len(argv) != 1){
clixon_err(OE_PLUGIN, EINVAL, "Requires one element: dbname"); clixon_err(OE_PLUGIN, EINVAL, "Requires one element: dbname");
@ -1345,11 +1353,11 @@ static int
cli_notification_cb(int s, cli_notification_cb(int s,
void *arg) void *arg)
{ {
int retval = -1; int retval = -1;
int eof = 0; int eof = 0;
cxobj *xt = NULL; cxobj *xt = NULL;
enum format_enum format = (enum format_enum)(uintptr_t)arg; enum format_enum format = (enum format_enum)(uintptr_t)arg;
cbuf *cb = NULL; cbuf *cb = NULL;
if (clixon_msg_rcv11(s, NULL, 0, &cb, &eof) < 0) if (clixon_msg_rcv11(s, NULL, 0, &cb, &eof) < 0)
goto done; goto done;
@ -1452,8 +1460,8 @@ cli_lock(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int retval = -1; int retval = -1;
char *db; char *db;
if (cvec_len(argv) != 1){ if (cvec_len(argv) != 1){
clixon_err(OE_PLUGIN, EINVAL, "Requires arguments: <db>"); clixon_err(OE_PLUGIN, EINVAL, "Requires arguments: <db>");
@ -1484,8 +1492,8 @@ cli_unlock(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int retval = -1; int retval = -1;
char *db; char *db;
if (cvec_len(argv) != 1){ if (cvec_len(argv) != 1){
clixon_err(OE_PLUGIN, EINVAL, "Requires arguments: <db>"); clixon_err(OE_PLUGIN, EINVAL, "Requires arguments: <db>");
@ -1566,26 +1574,26 @@ cli_copy_config(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int retval = -1; int retval = -1;
char *db; char *db;
cxobj *x1 = NULL; cxobj *x1 = NULL;
cxobj *x2 = NULL; cxobj *x2 = NULL;
cxobj *x; cxobj *x;
char *xpath; char *xpath;
char *namespace; char *namespace;
int i; int i;
int j; int j;
cbuf *cb = NULL; cbuf *cb = NULL;
char *keyname; char *keyname;
char *fromvar; char *fromvar;
cg_var *fromcv; cg_var *fromcv;
char *fromname = NULL; char *fromname = NULL;
char *tovar; char *tovar;
cg_var *tocv; cg_var *tocv;
char *toname; char *toname;
cxobj *xerr; cxobj *xerr;
cvec *nsc = NULL; cvec *nsc = NULL;
size_t len; size_t len;
if (cvec_len(argv) != 6){ if (cvec_len(argv) != 6){
clixon_err(OE_PLUGIN, EINVAL, "Requires 6 elements: <db> <xpath> <namespace> <keyname> <from> <to>"); clixon_err(OE_PLUGIN, EINVAL, "Requires 6 elements: <db> <xpath> <namespace> <keyname> <from> <to>");
@ -1820,12 +1828,12 @@ cli_process_control(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int retval = -1; int retval = -1;
char *name; char *name;
char *opstr; char *opstr;
cbuf *cb = NULL; cbuf *cb = NULL;
cxobj *xret = NULL; cxobj *xret = NULL;
cxobj *xerr; cxobj *xerr;
if (cvec_len(argv) != 2){ if (cvec_len(argv) != 2){
clixon_err(OE_PLUGIN, EINVAL, "Requires two element: process name and operation"); clixon_err(OE_PLUGIN, EINVAL, "Requires two element: process name and operation");
@ -1872,10 +1880,10 @@ cli_ping(clixon_handle h,
cvec *cvv, cvec *cvv,
cvec *argv) cvec *argv)
{ {
int retval = -1; int retval = -1;
cbuf *cb = NULL; cbuf *cb = NULL;
cxobj *xret = NULL; cxobj *xret = NULL;
cxobj *xerr; cxobj *xerr;
if ((cb = cbuf_new()) == NULL){ if ((cb = cbuf_new()) == NULL){
clixon_err(OE_UNIX, errno, "cbuf_new"); clixon_err(OE_UNIX, errno, "cbuf_new");

View file

@ -644,7 +644,7 @@ expand_dir(void *h,
cg_var *cv; cg_var *cv;
char *dir; char *dir;
char *regexp = NULL; char *regexp = NULL;
struct dirent *dp; struct dirent *dp = NULL;
int ndp; int ndp;
int i; int i;

View file

@ -74,7 +74,9 @@ static errmsg_t *_errmsg_callback_fn = NULL;
static char *_mount_yang = NULL; static char *_mount_yang = NULL;
static char *_mount_namespace = NULL; static char *_mount_namespace = NULL;
#ifndef CLIXON_STATIC_PLUGINS
static clixon_plugin_api api; static clixon_plugin_api api;
#endif
/*! Example cli function /*! Example cli function
*/ */

View file

@ -98,7 +98,7 @@ enum regexp_mode{
* Prototypes * Prototypes
*/ */
char *format_int2str(enum format_enum showas); char *format_int2str(enum format_enum showas);
enum format_enum format_str2int(char *str); int format_str2int(char *str);
/* Debug dump config options */ /* Debug dump config options */
int clicon_option_dump(clixon_handle h, int dblevel); int clicon_option_dump(clixon_handle h, int dblevel);

View file

@ -68,7 +68,7 @@ typedef int (proc_cb_t)(clixon_handle h,
int clixon_proc_socket(clixon_handle h, char **argv, int sock_flags, pid_t *pid, int *sock, int *sockerr); int clixon_proc_socket(clixon_handle h, char **argv, int sock_flags, pid_t *pid, int *sock, int *sockerr);
int clixon_proc_socket_close(pid_t pid, int sock); int clixon_proc_socket_close(pid_t pid, int sock);
int clixon_process_pid(clixon_handle h, const char *name, pid_t *pid); int clixon_process_pid(clixon_handle h, const char *name, pid_t *pid);
proc_operation clixon_process_op_str2int(char *opstr); int clixon_process_op_str2int(char *opstr);
int clixon_process_argv_get(clixon_handle h, const char *name, char ***argv, int *argc); int clixon_process_argv_get(clixon_handle h, const char *name, char ***argv, int *argc);
int clixon_process_register(clixon_handle h, const char *name, const char *descr, const char *netns, uid_t uid, gid_t gid, int fdkeep, proc_cb_t *callback, char **argv, int argc); int clixon_process_register(clixon_handle h, const char *name, const char *descr, const char *netns, uid_t uid, gid_t gid, int fdkeep, proc_cb_t *callback, char **argv, int argc);
int clixon_process_delete_all(clixon_handle h); int clixon_process_delete_all(clixon_handle h);

View file

@ -584,10 +584,11 @@ xmldb_readfile(clixon_handle h,
clixon_err(OE_CFG, ENOENT, "No CLICON_XMLDB_FORMAT"); clixon_err(OE_CFG, ENOENT, "No CLICON_XMLDB_FORMAT");
goto done; goto done;
} }
if ((format = format_str2int(formatstr)) < 0){ if ((ret = format_str2int(formatstr)) < 0){
clixon_err(OE_XML, 0, "format not found %s", formatstr); clixon_err(OE_XML, 0, "format not found %s", formatstr);
goto done; goto done;
} }
format = ret;
clixon_debug(CLIXON_DBG_DATASTORE, "Reading datastore %s using %s", dbfile, formatstr); clixon_debug(CLIXON_DBG_DATASTORE, "Reading datastore %s using %s", dbfile, formatstr);
/* Parse file into internal XML tree from different formats */ /* Parse file into internal XML tree from different formats */
if ((fp = fopen(dbfile, "r")) == NULL) { if ((fp = fopen(dbfile, "r")) == NULL) {

View file

@ -1703,6 +1703,7 @@ xmldb_write_cache2file(clixon_handle h,
int multi; int multi;
FILE *f = NULL; FILE *f = NULL;
char *dbfile = NULL; char *dbfile = NULL;
int ret;
if ((xt = xmldb_cache_get(h, db)) == NULL){ if ((xt = xmldb_cache_get(h, db)) == NULL){
clixon_err(OE_XML, 0, "XML cache not found"); clixon_err(OE_XML, 0, "XML cache not found");
@ -1711,10 +1712,11 @@ xmldb_write_cache2file(clixon_handle h,
pretty = clicon_option_bool(h, "CLICON_XMLDB_PRETTY"); pretty = clicon_option_bool(h, "CLICON_XMLDB_PRETTY");
multi = clicon_option_bool(h, "CLICON_XMLDB_MULTI"); multi = clicon_option_bool(h, "CLICON_XMLDB_MULTI");
if ((formatstr = clicon_option_str(h, "CLICON_XMLDB_FORMAT")) != NULL){ if ((formatstr = clicon_option_str(h, "CLICON_XMLDB_FORMAT")) != NULL){
if ((format = format_str2int(formatstr)) < 0){ if ((ret = format_str2int(formatstr)) < 0){
clixon_err(OE_XML, 0, "Format %s invalid", formatstr); clixon_err(OE_XML, 0, "Format %s invalid", formatstr);
goto done; goto done;
} }
format = ret;
} }
if (xmldb_db2file(h, db, &dbfile) < 0) if (xmldb_db2file(h, db, &dbfile) < 0)
goto done; goto done;

View file

@ -157,7 +157,7 @@ format_int2str(enum format_enum showas)
* @param[in] str String value * @param[in] str String value
* @retval enum Format value (see enum format_enum) * @retval enum Format value (see enum format_enum)
*/ */
enum format_enum int
format_str2int(char *str) format_str2int(char *str)
{ {
return clicon_str2int(_FORMATS, str); return clicon_str2int(_FORMATS, str);

View file

@ -477,7 +477,7 @@ static const map_str2int proc_operation_map[] = {
/* List of process callback entries XXX move to handle */ /* List of process callback entries XXX move to handle */
static process_entry_t *_proc_entry_list = NULL; static process_entry_t *_proc_entry_list = NULL;
proc_operation int
clixon_process_op_str2int(char *opstr) clixon_process_op_str2int(char *opstr)
{ {
return clicon_str2int(proc_operation_map, opstr); return clicon_str2int(proc_operation_map, opstr);

View file

@ -571,7 +571,7 @@ clixon_msg_rcv11(int s,
int eom = 0; int eom = 0;
cxobj *xtop = NULL; cxobj *xtop = NULL;
cxobj *xerr = NULL; cxobj *xerr = NULL;
sigset_t oldsigset = {0,}; sigset_t oldsigset = {{0,},};
struct sigaction oldsigaction[32] = {{{0,},},}; struct sigaction oldsigaction[32] = {{{0,},},};
eom = 0; eom = 0;

View file

@ -174,7 +174,7 @@ struct xml{
#endif #endif
int _x_vector_i; /* internal use: xml_child_each */ int _x_vector_i; /* internal use: xml_child_each */
int _x_i; /* internal use for stable sorting: int _x_i; /* internal use for stable sorting:
see xml_enumerate and xml_cmp */ see xml_enumerate_children and xml_cmp */
/*----- next is body/attribute only */ /*----- next is body/attribute only */
cbuf *x_value_cb; /* attribute and body nodes have values (XXX: this consumes cbuf *x_value_cb; /* attribute and body nodes have values (XXX: this consumes
memory) cv? */ memory) cv? */
@ -1152,7 +1152,7 @@ clixon_child_xvec_append(cxobj *xn,
return retval; return retval;
} }
/*! Create new xml node given a name and parent. Free with xml_free(). /*! Create new xml node given a name and append it to parent if given. Free with xml_free().
* *
* @param[in] name Name of XML node * @param[in] name Name of XML node
* @param[in] xp The parent where the new xml node will be appended * @param[in] xp The parent where the new xml node will be appended
@ -1228,6 +1228,7 @@ xml_new_body(char *name,
cxobj *body_node; cxobj *body_node;
if (!name || !parent || !val) { if (!name || !parent || !val) {
clixon_err(OE_XML, EINVAL, "name, parent or val is NULL");
return NULL; return NULL;
} }
if ((new_node = xml_new(name, parent, CX_ELMNT)) == NULL) { if ((new_node = xml_new(name, parent, CX_ELMNT)) == NULL) {