Merge branch 'master' of https://github.com/clicon/clixon.
Added new API function `xpath_parse()` to split parsing and xml evaluation.
This commit is contained in:
commit
1f8c759f3d
64 changed files with 2282 additions and 1350 deletions
|
|
@ -73,7 +73,7 @@ SRC = clixon_sig.c clixon_log.c clixon_err.c clixon_event.c \
|
|||
clixon_yang_cardinality.c clixon_xml_changelog.c clixon_xml_nsctx.c \
|
||||
clixon_hash.c clixon_options.c clixon_data.c clixon_plugin.c \
|
||||
clixon_proto.c clixon_proto_client.c \
|
||||
clixon_xpath.c clixon_xpath_ctx.c clixon_sha1.c \
|
||||
clixon_xpath.c clixon_xpath_ctx.c clixon_xpath_eval.c clixon_sha1.c \
|
||||
clixon_datastore.c clixon_datastore_write.c clixon_datastore_read.c \
|
||||
clixon_datastore_tree.c \
|
||||
clixon_netconf_lib.c clixon_stream.c clixon_nacm.c
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ clicon_dbspec_yang(clicon_handle h)
|
|||
size_t len;
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "dbspec_yang", &len)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "dbspec_yang", &len)) != NULL)
|
||||
return *(yang_stmt **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -100,7 +100,7 @@ clicon_dbspec_yang_set(clicon_handle h,
|
|||
/* It is the pointer to ys that should be copied by hash,
|
||||
so we send a ptr to the ptr to indicate what to copy.
|
||||
*/
|
||||
if (hash_add(cdat, "dbspec_yang", &ys, sizeof(ys)) == NULL)
|
||||
if (clicon_hash_add(cdat, "dbspec_yang", &ys, sizeof(ys)) == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -118,7 +118,7 @@ clicon_nacm_ext(clicon_handle h)
|
|||
size_t len;
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "nacm_xml", &len)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "nacm_xml", &len)) != NULL)
|
||||
return *(cxobj **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ clicon_nacm_ext_set(clicon_handle h,
|
|||
/* It is the pointer to xn that should be copied by hash,
|
||||
so we send a ptr to the ptr to indicate what to copy.
|
||||
*/
|
||||
if (hash_add(cdat, "nacm_xml", &xn, sizeof(xn)) == NULL)
|
||||
if (clicon_hash_add(cdat, "nacm_xml", &xn, sizeof(xn)) == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -158,7 +158,7 @@ clicon_config_yang(clicon_handle h)
|
|||
size_t len;
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "control_yang", &len)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "control_yang", &len)) != NULL)
|
||||
return *(yang_stmt **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -175,7 +175,7 @@ clicon_config_yang_set(clicon_handle h,
|
|||
/* It is the pointer to ys that should be copied by hash,
|
||||
so we send a ptr to the ptr to indicate what to copy.
|
||||
*/
|
||||
if (hash_add(cdat, "control_yang", &ys, sizeof(ys)) == NULL)
|
||||
if (clicon_hash_add(cdat, "control_yang", &ys, sizeof(ys)) == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -192,7 +192,7 @@ clicon_conf_xml(clicon_handle h)
|
|||
size_t len;
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "clixon_conf", &len)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "clixon_conf", &len)) != NULL)
|
||||
return *(cxobj **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -209,7 +209,7 @@ clicon_conf_xml_set(clicon_handle h,
|
|||
/* It is the pointer to x that should be copied by hash,
|
||||
* so we send a ptr to the ptr to indicate what to copy.
|
||||
*/
|
||||
if (hash_add(cdat, "clixon_conf", &x, sizeof(x)) == NULL)
|
||||
if (clicon_hash_add(cdat, "clixon_conf", &x, sizeof(x)) == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -223,7 +223,7 @@ clicon_username_get(clicon_handle h)
|
|||
{
|
||||
clicon_hash_t *cdat = clicon_data(h);
|
||||
|
||||
return (char*)hash_value(cdat, "username", NULL);
|
||||
return (char*)clicon_hash_value(cdat, "username", NULL);
|
||||
}
|
||||
|
||||
/*! Set authorized user name
|
||||
|
|
@ -238,8 +238,8 @@ clicon_username_set(clicon_handle h,
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
|
||||
if (username == NULL)
|
||||
return hash_del(cdat, "username");
|
||||
return hash_add(cdat, "username", username, strlen(username)+1)==NULL?-1:0;
|
||||
return clicon_hash_del(cdat, "username");
|
||||
return clicon_hash_add(cdat, "username", username, strlen(username)+1)==NULL?-1:0;
|
||||
}
|
||||
|
||||
/*! Get backend daemon startup status
|
||||
|
|
@ -252,7 +252,7 @@ clicon_startup_status_get(clicon_handle h)
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "startup_status", NULL)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "startup_status", NULL)) != NULL)
|
||||
return *(enum startup_status *)p;
|
||||
return STARTUP_ERR;
|
||||
}
|
||||
|
|
@ -268,7 +268,7 @@ clicon_startup_status_set(clicon_handle h,
|
|||
enum startup_status status)
|
||||
{
|
||||
clicon_hash_t *cdat = clicon_data(h);
|
||||
if (hash_add(cdat, "startup_status", &status, sizeof(status))==NULL)
|
||||
if (clicon_hash_add(cdat, "startup_status", &status, sizeof(status))==NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ clicon_socket_get(clicon_handle h)
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "socket", NULL)) == NULL)
|
||||
if ((p = clicon_hash_value(cdat, "socket", NULL)) == NULL)
|
||||
return -1;
|
||||
return *(int*)p;
|
||||
}
|
||||
|
|
@ -302,8 +302,8 @@ clicon_socket_set(clicon_handle h,
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
|
||||
if (s == -1)
|
||||
return hash_del(cdat, "socket");
|
||||
return hash_add(cdat, "socket", &s, sizeof(int))==NULL?-1:0;
|
||||
return clicon_hash_del(cdat, "socket");
|
||||
return clicon_hash_add(cdat, "socket", &s, sizeof(int))==NULL?-1:0;
|
||||
}
|
||||
|
||||
/*! Get module state cache
|
||||
|
|
@ -319,7 +319,7 @@ clicon_modst_cache_get(clicon_handle h,
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, brief?"modst_brief":"modst_full", NULL)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, brief?"modst_brief":"modst_full", NULL)) != NULL)
|
||||
return *(cxobj **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -346,7 +346,7 @@ clicon_modst_cache_set(clicon_handle h,
|
|||
assert(strcmp(xml_name(xms),"modules-state")==0);
|
||||
if ((x = xml_dup(xms)) == NULL)
|
||||
return -1;
|
||||
if (hash_add(cdat, brief?"modst_brief":"modst_full", &x, sizeof(x))==NULL)
|
||||
if (clicon_hash_add(cdat, brief?"modst_brief":"modst_full", &x, sizeof(x))==NULL)
|
||||
return -1;
|
||||
ok:
|
||||
return 0;
|
||||
|
|
@ -363,7 +363,7 @@ clicon_xml_changelog_get(clicon_handle h)
|
|||
clicon_hash_t *cdat = clicon_data(h);
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, "xml-changelog", NULL)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, "xml-changelog", NULL)) != NULL)
|
||||
return *(cxobj **)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -381,7 +381,7 @@ clicon_xml_changelog_set(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *cdat = clicon_data(h);
|
||||
|
||||
if (hash_add(cdat, "xml-changelog", &xchlog, sizeof(xchlog))==NULL)
|
||||
if (clicon_hash_add(cdat, "xml-changelog", &xchlog, sizeof(xchlog))==NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -403,12 +403,12 @@ clicon_argv_get(clicon_handle h,
|
|||
void *p;
|
||||
|
||||
if (argc){
|
||||
if ((p = hash_value(cdat, "argc", NULL)) == NULL)
|
||||
if ((p = clicon_hash_value(cdat, "argc", NULL)) == NULL)
|
||||
return -1;
|
||||
*argc = *(int*)p;
|
||||
}
|
||||
if (argv){
|
||||
if ((p = hash_value(cdat, "argv", NULL)) == NULL)
|
||||
if ((p = clicon_hash_value(cdat, "argv", NULL)) == NULL)
|
||||
return -1;
|
||||
*argv = (char**)p;
|
||||
}
|
||||
|
|
@ -444,10 +444,10 @@ clicon_argv_set(clicon_handle h,
|
|||
memcpy(argvv+1, argv, argc*sizeof(char*));
|
||||
argvv[0] = prgm;
|
||||
/* Note the value is the argv vector (which is copied) */
|
||||
if (hash_add(cdat, "argv", argvv, len*sizeof(char*))==NULL)
|
||||
if (clicon_hash_add(cdat, "argv", argvv, len*sizeof(char*))==NULL)
|
||||
goto done;
|
||||
argc += 1;
|
||||
if (hash_add(cdat, "argc", &argc, sizeof(argc))==NULL)
|
||||
if (clicon_hash_add(cdat, "argc", &argc, sizeof(argc))==NULL)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -470,7 +470,7 @@ clicon_db_elmnt_get(clicon_handle h,
|
|||
clicon_hash_t *cdat = clicon_db_elmnt(h);
|
||||
void *p;
|
||||
|
||||
if ((p = hash_value(cdat, db, NULL)) != NULL)
|
||||
if ((p = clicon_hash_value(cdat, db, NULL)) != NULL)
|
||||
return (db_elmnt *)p;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -491,7 +491,7 @@ clicon_db_elmnt_set(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *cdat = clicon_db_elmnt(h);
|
||||
|
||||
if (hash_add(cdat, db, de, sizeof(*de))==NULL)
|
||||
if (clicon_hash_add(cdat, db, de, sizeof(*de))==NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,10 +161,10 @@ xmldb_disconnect(clicon_handle h)
|
|||
int i;
|
||||
db_elmnt *de;
|
||||
|
||||
if (hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0)
|
||||
if (clicon_hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0)
|
||||
goto done;
|
||||
for(i = 0; i < klen; i++)
|
||||
if ((de = hash_value(clicon_db_elmnt(h), keys[i], NULL)) != NULL){
|
||||
if ((de = clicon_hash_value(clicon_db_elmnt(h), keys[i], NULL)) != NULL){
|
||||
if (de->de_xml){
|
||||
xml_free(de->de_xml);
|
||||
de->de_xml = NULL;
|
||||
|
|
@ -311,7 +311,7 @@ xmldb_unlock_all(clicon_handle h,
|
|||
int i;
|
||||
db_elmnt *de;
|
||||
|
||||
if (hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0)
|
||||
if (clicon_hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0)
|
||||
goto done;
|
||||
for (i = 0; i < klen; i++)
|
||||
if ((de = clicon_db_elmnt_get(h, keys[i])) != NULL &&
|
||||
|
|
|
|||
|
|
@ -596,10 +596,6 @@ xmldb_get_zerocopy(clicon_handle h,
|
|||
db_elmnt *de = NULL;
|
||||
db_elmnt de0 = {0,};
|
||||
|
||||
if (!clicon_option_bool(h, "CLICON_XMLDB_CACHE")){
|
||||
clicon_err(OE_CFG, 0, "CLICON_XMLDB_CACHE must be set");
|
||||
goto done;
|
||||
}
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -111,15 +111,15 @@ clicon_handle_init0(int size)
|
|||
}
|
||||
memset(ch, 0, size);
|
||||
ch->ch_magic = CLICON_MAGIC;
|
||||
if ((ch->ch_copt = hash_init()) == NULL){
|
||||
if ((ch->ch_copt = clicon_hash_init()) == NULL){
|
||||
clicon_handle_exit((clicon_handle)ch);
|
||||
goto done;
|
||||
}
|
||||
if ((ch->ch_data = hash_init()) == NULL){
|
||||
if ((ch->ch_data = clicon_hash_init()) == NULL){
|
||||
clicon_handle_exit((clicon_handle)ch);
|
||||
goto done;
|
||||
}
|
||||
if ((ch->ch_db_elmnt = hash_init()) == NULL){
|
||||
if ((ch->ch_db_elmnt = clicon_hash_init()) == NULL){
|
||||
clicon_handle_exit((clicon_handle)ch);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -154,12 +154,12 @@ clicon_handle_exit(clicon_handle h)
|
|||
clicon_hash_t *ha;
|
||||
|
||||
if ((ha = clicon_options(h)) != NULL)
|
||||
hash_free(ha);
|
||||
clicon_hash_free(ha);
|
||||
if ((ha = clicon_data(h)) != NULL)
|
||||
hash_free(ha);
|
||||
clicon_hash_free(ha);
|
||||
|
||||
if ((ha = clicon_db_elmnt(h)) != NULL)
|
||||
hash_free(ha);
|
||||
clicon_hash_free(ha);
|
||||
stream_delete_all(h, 1);
|
||||
free(ch);
|
||||
retval = 0;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ hash_bucket(const char *str)
|
|||
* @see hash_free For freeing the hash-table
|
||||
*/
|
||||
clicon_hash_t *
|
||||
hash_init(void)
|
||||
clicon_hash_init(void)
|
||||
{
|
||||
clicon_hash_t *hash;
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ hash_init(void)
|
|||
* @retval void
|
||||
*/
|
||||
void
|
||||
hash_free(clicon_hash_t *hash)
|
||||
clicon_hash_free(clicon_hash_t *hash)
|
||||
{
|
||||
int i;
|
||||
clicon_hash_t tmp;
|
||||
|
|
@ -157,8 +157,8 @@ hash_free(clicon_hash_t *hash)
|
|||
* @retval NULL Not found
|
||||
*/
|
||||
clicon_hash_t
|
||||
hash_lookup(clicon_hash_t *hash,
|
||||
const char *key)
|
||||
clicon_hash_lookup(clicon_hash_t *hash,
|
||||
const char *key)
|
||||
{
|
||||
uint32_t bkt;
|
||||
clicon_hash_t h;
|
||||
|
|
@ -183,13 +183,13 @@ hash_lookup(clicon_hash_t *hash,
|
|||
* @retval NULL Key not found or value NULL
|
||||
*/
|
||||
void *
|
||||
hash_value(clicon_hash_t *hash,
|
||||
const char *key,
|
||||
size_t *vlen)
|
||||
clicon_hash_value(clicon_hash_t *hash,
|
||||
const char *key,
|
||||
size_t *vlen)
|
||||
{
|
||||
clicon_hash_t h;
|
||||
|
||||
h = hash_lookup(hash, key);
|
||||
h = clicon_hash_lookup(hash, key);
|
||||
if (h == NULL)
|
||||
return NULL; /* OK, key not found */
|
||||
|
||||
|
|
@ -209,10 +209,10 @@ hash_value(clicon_hash_t *hash,
|
|||
* @note special case val is NULL and vlen==0
|
||||
*/
|
||||
clicon_hash_t
|
||||
hash_add(clicon_hash_t *hash,
|
||||
const char *key,
|
||||
void *val,
|
||||
size_t vlen)
|
||||
clicon_hash_add(clicon_hash_t *hash,
|
||||
const char *key,
|
||||
void *val,
|
||||
size_t vlen)
|
||||
{
|
||||
void *newval = NULL;
|
||||
clicon_hash_t h;
|
||||
|
|
@ -225,7 +225,7 @@ hash_add(clicon_hash_t *hash,
|
|||
goto catch;
|
||||
}
|
||||
/* If variable exist, don't allocate a new. just replace value */
|
||||
h = hash_lookup(hash, key);
|
||||
h = clicon_hash_lookup(hash, key);
|
||||
if (h == NULL) {
|
||||
if ((new = (clicon_hash_t)malloc(sizeof(*new))) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc: %s", strerror(errno));
|
||||
|
|
@ -283,12 +283,12 @@ catch:
|
|||
* @retval -1 Key not found
|
||||
*/
|
||||
int
|
||||
hash_del(clicon_hash_t *hash,
|
||||
const char *key)
|
||||
clicon_hash_del(clicon_hash_t *hash,
|
||||
const char *key)
|
||||
{
|
||||
clicon_hash_t h;
|
||||
|
||||
h = hash_lookup(hash, key);
|
||||
h = clicon_hash_lookup(hash, key);
|
||||
if (h == NULL)
|
||||
return -1;
|
||||
|
||||
|
|
@ -311,9 +311,9 @@ hash_del(clicon_hash_t *hash,
|
|||
* @note: vector needs to be deallocated with free
|
||||
*/
|
||||
int
|
||||
hash_keys(clicon_hash_t *hash,
|
||||
char ***vector,
|
||||
size_t *nkeys)
|
||||
clicon_hash_keys(clicon_hash_t *hash,
|
||||
char ***vector,
|
||||
size_t *nkeys)
|
||||
{
|
||||
int retval = -1;
|
||||
int bkt;
|
||||
|
|
@ -357,8 +357,8 @@ catch:
|
|||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
hash_dump(clicon_hash_t *hash,
|
||||
FILE *f)
|
||||
clicon_hash_dump(clicon_hash_t *hash,
|
||||
FILE *f)
|
||||
{
|
||||
int retval = -1;
|
||||
int i;
|
||||
|
|
@ -369,10 +369,10 @@ hash_dump(clicon_hash_t *hash,
|
|||
|
||||
if (hash == NULL)
|
||||
goto ok;
|
||||
if (hash_keys(hash, &keys, &klen) < 0)
|
||||
if (clicon_hash_keys(hash, &keys, &klen) < 0)
|
||||
goto done;
|
||||
for(i = 0; i < klen; i++) {
|
||||
val = hash_value(hash, keys[i], &vlen);
|
||||
val = clicon_hash_value(hash, keys[i], &vlen);
|
||||
printf("%s =\t 0x%p , length %zu\n", keys[i], val, vlen);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,48 @@ netconf_in_use(cbuf *cb,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! Create Netconf invalid-value error XML tree according to RFC 6241 Appendix A
|
||||
*
|
||||
* The request specifies an unacceptable value for one or more parameters.
|
||||
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||
* @param[in] type Error type: "application" or "protocol"
|
||||
* @param[in] message Error message (will be XML encoded)
|
||||
*/
|
||||
int
|
||||
netconf_invalid_value_xml(cxobj **xret,
|
||||
char *type,
|
||||
char *message)
|
||||
{
|
||||
int retval =-1;
|
||||
cxobj *xerr;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (*xret == NULL){
|
||||
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if ((xerr = xml_new("rpc-error", *xret, NULL)) == NULL)
|
||||
goto done;
|
||||
if (xml_parse_va(&xerr, NULL, "<error-type>%s</error-type>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-severity>error</error-severity>", type) < 0)
|
||||
goto done;
|
||||
if (message){
|
||||
if (xml_chardata_encode(&encstr, "%s", message) < 0)
|
||||
goto done;
|
||||
if (xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
|
||||
encstr) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Create Netconf invalid-value error XML tree according to RFC 6241 Appendix A
|
||||
*
|
||||
* The request specifies an unacceptable value for one or more parameters.
|
||||
|
|
@ -120,6 +162,20 @@ netconf_invalid_value(cbuf *cb,
|
|||
char *type,
|
||||
char *message)
|
||||
{
|
||||
#if 1
|
||||
int retval = -1;
|
||||
cxobj *xret = NULL;
|
||||
|
||||
if (netconf_invalid_value_xml(&xret, type, message) < 0)
|
||||
goto done;
|
||||
if (clicon_xml2cbuf(cb, xret, 0, 0) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
if (xret)
|
||||
xml_free(xret);
|
||||
return retval;
|
||||
#else
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
|
|
@ -145,6 +201,7 @@ netconf_invalid_value(cbuf *cb,
|
|||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! Create Netconf too-big error XML tree according to RFC 6241 Appendix A
|
||||
|
|
|
|||
|
|
@ -112,10 +112,10 @@ clicon_option_dump(clicon_handle h,
|
|||
size_t vlen;
|
||||
cxobj *x = NULL;
|
||||
|
||||
if (hash_keys(hash, &keys, &klen) < 0)
|
||||
if (clicon_hash_keys(hash, &keys, &klen) < 0)
|
||||
goto done;
|
||||
for(i = 0; i < klen; i++) {
|
||||
val = hash_value(hash, keys[i], &vlen);
|
||||
val = clicon_hash_value(hash, keys[i], &vlen);
|
||||
if (vlen){
|
||||
if (((char*)val)[vlen-1]=='\0') /* assume string */
|
||||
clicon_debug(dbglevel, "%s =\t \"%s\"", keys[i], (char*)val);
|
||||
|
|
@ -234,7 +234,7 @@ parse_configfile(clicon_handle h,
|
|||
/* Used as an arg to this fn */
|
||||
if (strcmp(name,"CLICON_CONFIGFILE")==0)
|
||||
continue;
|
||||
if (hash_add(copt,
|
||||
if (clicon_hash_add(copt,
|
||||
name,
|
||||
body,
|
||||
strlen(body)+1) == NULL)
|
||||
|
|
@ -284,7 +284,7 @@ clicon_option_add(clicon_handle h,
|
|||
name, value, name) < 0)
|
||||
goto done;
|
||||
}
|
||||
if (hash_add(copt,
|
||||
if (clicon_hash_add(copt,
|
||||
name,
|
||||
value,
|
||||
strlen(value)+1) == NULL)
|
||||
|
|
@ -319,10 +319,10 @@ clicon_options_main(clicon_handle h,
|
|||
/*
|
||||
* Set configure file if not set by command-line above
|
||||
*/
|
||||
if (!hash_lookup(copt, "CLICON_CONFIGFILE")){
|
||||
if (!clicon_hash_lookup(copt, "CLICON_CONFIGFILE")){
|
||||
clicon_option_str_set(h, "CLICON_CONFIGFILE", CLIXON_DEFAULT_CONFIG);
|
||||
}
|
||||
configfile = hash_value(copt, "CLICON_CONFIGFILE", NULL);
|
||||
configfile = clicon_hash_value(copt, "CLICON_CONFIGFILE", NULL);
|
||||
clicon_debug(1, "CLICON_CONFIGFILE=%s", configfile);
|
||||
/* File must end with .xml */
|
||||
if ((suffix = rindex(configfile, '.')) != NULL){
|
||||
|
|
@ -385,7 +385,7 @@ clicon_option_exists(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *copt = clicon_options(h);
|
||||
|
||||
return (hash_lookup(copt, (char*)name) != NULL);
|
||||
return (clicon_hash_lookup(copt, (char*)name) != NULL);
|
||||
}
|
||||
|
||||
/*! Get a single string option string via handle
|
||||
|
|
@ -404,9 +404,9 @@ clicon_option_str(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *copt = clicon_options(h);
|
||||
|
||||
if (hash_lookup(copt, (char*)name) == NULL)
|
||||
if (clicon_hash_lookup(copt, (char*)name) == NULL)
|
||||
return NULL;
|
||||
return hash_value(copt, (char*)name, NULL);
|
||||
return clicon_hash_value(copt, (char*)name, NULL);
|
||||
}
|
||||
|
||||
/*! Set a single string option via handle
|
||||
|
|
@ -423,7 +423,7 @@ clicon_option_str_set(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *copt = clicon_options(h);
|
||||
|
||||
return hash_add(copt, (char*)name, val, strlen(val)+1)==NULL?-1:0;
|
||||
return clicon_hash_add(copt, (char*)name, val, strlen(val)+1)==NULL?-1:0;
|
||||
}
|
||||
|
||||
/*! Get options as integer but stored as string
|
||||
|
|
@ -518,7 +518,7 @@ clicon_option_del(clicon_handle h,
|
|||
{
|
||||
clicon_hash_t *copt = clicon_options(h);
|
||||
|
||||
return hash_del(copt, (char*)name);
|
||||
return clicon_hash_del(copt, (char*)name);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -343,11 +343,12 @@ validate_identityref(cxobj *xt,
|
|||
|
||||
{
|
||||
int retval = -1;
|
||||
char *node;
|
||||
char *node = NULL;
|
||||
yang_stmt *ybaseref; /* This is the type's base reference */
|
||||
yang_stmt *ybaseid;
|
||||
char *prefix = NULL;
|
||||
cbuf *cb = NULL;
|
||||
cbuf *cb2 = NULL;
|
||||
|
||||
/* Get idref value. Then see if this value is derived from ytype.
|
||||
* Always add default prefix because derived identifiers are stored with
|
||||
|
|
@ -380,10 +381,13 @@ validate_identityref(cxobj *xt,
|
|||
* The derived node list is a cvec computed XXX
|
||||
*/
|
||||
if (cvec_find(yang_cvec_get(ybaseid), node) == NULL){
|
||||
cbuf_reset(cb);
|
||||
cprintf(cb, "Identityref validation failed, %s not derived from %s",
|
||||
if ((cb2 = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cb2, "Identityref validation failed, %s not derived from %s",
|
||||
node, yang_argument_get(ybaseid));
|
||||
if (netconf_operation_failed_xml(xret, "application", cbuf_get(cb)) < 0)
|
||||
if (netconf_operation_failed_xml(xret, "application", cbuf_get(cb2)) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -391,6 +395,8 @@ validate_identityref(cxobj *xt,
|
|||
done:
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (cb2)
|
||||
cbuf_free(cb2);
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
|
|
@ -1221,19 +1227,20 @@ xml_yang_validate_all(clicon_handle h,
|
|||
/* Special case if leaf is leafref, then first check against
|
||||
current xml tree
|
||||
*/
|
||||
if ((yc = yang_find(ys, Y_TYPE, NULL)) != NULL){
|
||||
if (strcmp(yc->ys_argument, "leafref") == 0){
|
||||
if ((ret = validate_leafref(xt, yc, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
else if (strcmp(yc->ys_argument, "identityref") == 0){
|
||||
if ((ret = validate_identityref(xt, ys, yc, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
/* Get base type yc */
|
||||
if (yang_type_get(ys, NULL, &yc, NULL, NULL, NULL, NULL, NULL) < 0)
|
||||
goto done;
|
||||
if (strcmp(yang_argument_get(yc), "leafref") == 0){
|
||||
if ((ret = validate_leafref(xt, yc, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
else if (strcmp(yang_argument_get(yc), "identityref") == 0){
|
||||
if ((ret = validate_identityref(xt, ys, yc, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2557,7 +2564,7 @@ api_path2xml_vec(char **vec,
|
|||
else{
|
||||
if ((valvec = clicon_strsep(restval, ",", &nvalvec)) == NULL)
|
||||
goto done;
|
||||
if (nvalvec != cvec_len(cvk)){
|
||||
if ((nvalvec != cvec_len(cvk)) && strict){
|
||||
clicon_err(OE_XML, EINVAL, "List key %s length mismatch", name);
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -59,8 +59,9 @@
|
|||
#include "clixon_handle.h"
|
||||
#include "clixon_yang.h"
|
||||
#include "clixon_xml.h"
|
||||
#include "clixon_xpath_parse.h"
|
||||
#include "clixon_xpath_ctx.h"
|
||||
#include "clixon_xpath.h"
|
||||
#include "clixon_xpath_parse.h"
|
||||
|
||||
/*
|
||||
* Variables
|
||||
|
|
|
|||
1062
lib/src/clixon_xpath_eval.c
Normal file
1062
lib/src/clixon_xpath_eval.c
Normal file
File diff suppressed because it is too large
Load diff
49
lib/src/clixon_xpath_eval.h
Normal file
49
lib/src/clixon_xpath_eval.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
|
||||
|
||||
This file is part of CLIXON.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
the GNU General Public License Version 3 or later (the "GPL"),
|
||||
in which case the provisions of the GPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of the GPL, and not to allow others to
|
||||
use your version of this file under the terms of Apache License version 2,
|
||||
indicate your decision by deleting the provisions above and replace them with
|
||||
the notice and other provisions required by the GPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the Apache License version 2 or the GPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
* Clixon XML XPATH 1.0 according to https://www.w3.org/TR/xpath-10
|
||||
*/
|
||||
#ifndef _CLIXON_XPATH_EVAL_H
|
||||
#define _CLIXON_XPATH_EVAL_H
|
||||
|
||||
/*
|
||||
* Variables
|
||||
*/
|
||||
extern const map_str2int xpopmap[];
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
int xp_eval(xp_ctx *xc, xpath_tree *xs, cvec *nsc, xp_ctx **xrp);
|
||||
|
||||
#endif /* _CLIXON_XPATH_EVAL_H */
|
||||
|
|
@ -39,40 +39,6 @@
|
|||
/*
|
||||
* Types
|
||||
*/
|
||||
/* used as non-terminal type in yacc rules */
|
||||
enum xp_type{
|
||||
XP_EXP,
|
||||
XP_AND,
|
||||
XP_RELEX,
|
||||
XP_ADD,
|
||||
XP_UNION,
|
||||
XP_PATHEXPR,
|
||||
XP_LOCPATH,
|
||||
XP_ABSPATH,
|
||||
XP_RELLOCPATH,
|
||||
XP_STEP,
|
||||
XP_NODE, /* s0 is namespace prefix, s1 is name */
|
||||
XP_NODE_FN,
|
||||
XP_PRED,
|
||||
XP_PRI0,
|
||||
XP_PRIME_NR,
|
||||
XP_PRIME_STR,
|
||||
XP_PRIME_FN,
|
||||
};
|
||||
|
||||
/*! XPATH Parsing generates a tree of nodes that is later traversed
|
||||
*/
|
||||
struct xpath_tree{
|
||||
enum xp_type xs_type;
|
||||
int xs_int;
|
||||
double xs_double;
|
||||
char *xs_s0;
|
||||
char *xs_s1;
|
||||
struct xpath_tree *xs_c0; /* child 0 */
|
||||
struct xpath_tree *xs_c1; /* child 1 */
|
||||
};
|
||||
typedef struct xpath_tree xpath_tree;
|
||||
|
||||
struct clicon_xpath_yacc_arg{ /* XXX: mostly unrelevant */
|
||||
const char *xy_name; /* Name of syntax (for error string) */
|
||||
int xy_linenum; /* Number of \n in parsed buffer */
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include "clixon_xpath_ctx.h"
|
||||
#include "clixon_xpath.h"
|
||||
#include "clixon_xpath_parse.h"
|
||||
#include "clixon_xpath_eval.h"
|
||||
|
||||
/* Redefine main lex function so that you can send arguments to it: _yy is added to arg list */
|
||||
#define YY_DECL int clixon_xpath_parselex(void *_yy)
|
||||
|
|
|
|||
|
|
@ -588,6 +588,105 @@ cv_validate_pattern(clicon_handle h,
|
|||
(rmax && (i) > cv_##type##_get(rmax)))
|
||||
|
||||
|
||||
/*! Error messsage for int violating ranges
|
||||
* @note contains kludge - duplicate loop
|
||||
*/
|
||||
static int
|
||||
outofrange(cg_var *cv0,
|
||||
cvec *cvv,
|
||||
char **reason)
|
||||
{
|
||||
int retval = -1;
|
||||
cbuf *cb = NULL;
|
||||
cg_var *cv1;
|
||||
cg_var *cv2;
|
||||
int i;
|
||||
|
||||
if ((cb = cbuf_new()) == NULL)
|
||||
goto done;
|
||||
cprintf(cb, "Number ");
|
||||
cv2cbuf(cv0, cb);
|
||||
cprintf(cb, " out of range: ");
|
||||
/* Kludge: need to repeat the same loop as in the main function in
|
||||
cv_validate1 */
|
||||
i = 0;
|
||||
while (i<cvec_len(cvv)){
|
||||
cv1 = cvec_i(cvv, i++); /* Increment to check for max pair */
|
||||
if (strcmp(cv_name_get(cv1),"range_min") != 0){
|
||||
clicon_err(OE_YANG, EINVAL, "Internal error, expected range_min");
|
||||
goto done;
|
||||
}
|
||||
if (i<cvec_len(cvv) &&
|
||||
(cv2 = cvec_i(cvv, i)) != NULL &&
|
||||
strcmp(cv_name_get(cv2),"range_max") == 0){
|
||||
i++;
|
||||
}
|
||||
else
|
||||
cv2 = cv1;
|
||||
if (i>2)
|
||||
cprintf(cb, ", ");
|
||||
cv2cbuf(cv1, cb);
|
||||
cprintf(cb, " - ");
|
||||
cv2cbuf(cv2, cb);
|
||||
}
|
||||
if (reason && (*reason = strdup(cbuf_get(cb))) == NULL)
|
||||
goto done;
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Error messsage for string violating string limits
|
||||
* @note contains kludge - duplicate loop
|
||||
*/
|
||||
static int
|
||||
outoflength(uint64_t u64,
|
||||
cvec *cvv,
|
||||
char **reason)
|
||||
{
|
||||
int retval = -1;
|
||||
cbuf *cb = NULL;
|
||||
cg_var *cv1;
|
||||
cg_var *cv2;
|
||||
int i;
|
||||
|
||||
if ((cb = cbuf_new()) == NULL)
|
||||
goto done;
|
||||
cprintf(cb, "String length %" PRIu64 " out of range: ", u64);
|
||||
|
||||
/* Kludge: need to repeat the same loop as in the main function in
|
||||
cv_validate1 */
|
||||
i = 0;
|
||||
while (i<cvec_len(cvv)){
|
||||
cv1 = cvec_i(cvv, i++); /* Increment to check for max pair */
|
||||
if (strcmp(cv_name_get(cv1),"range_min") != 0){
|
||||
clicon_err(OE_YANG, EINVAL, "Internal error, expected range_min");
|
||||
goto done;
|
||||
}
|
||||
if (i<cvec_len(cvv) &&
|
||||
(cv2 = cvec_i(cvv, i)) != NULL &&
|
||||
strcmp(cv_name_get(cv2),"range_max") == 0){
|
||||
i++;
|
||||
}
|
||||
else
|
||||
cv2 = cv1;
|
||||
if (i>2)
|
||||
cprintf(cb, ", ");
|
||||
cv2cbuf(cv1, cb);
|
||||
cprintf(cb, " - ");
|
||||
cv2cbuf(cv2, cb);
|
||||
}
|
||||
if (reason && (*reason = strdup(cbuf_get(cb))) == NULL)
|
||||
goto done;
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Validate CLIgen variable
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] cv A cligen variable to validate. This is a correctly parsed cv.
|
||||
|
|
@ -600,6 +699,7 @@ cv_validate_pattern(clicon_handle h,
|
|||
* @retval 0 Validation not OK, malloced reason is returned. Free reason with free()
|
||||
* @retval 1 Validation OK
|
||||
* @note reason if given must be freed by caller
|
||||
* @see cv_validate Corresponding type check in cligen
|
||||
*/
|
||||
static int
|
||||
cv_validate1(clicon_handle h,
|
||||
|
|
@ -705,14 +805,13 @@ cv_validate1(clicon_handle h,
|
|||
/* Check fails */
|
||||
if (i==cvec_len(cvv)){ /* And it is last */
|
||||
if (reason){
|
||||
if (reti)
|
||||
*reason = cligen_reason("Number out of range: %"
|
||||
PRId64, ii);
|
||||
else if (retu)
|
||||
*reason = cligen_reason("Number out of range: %"
|
||||
PRIu64, uu);
|
||||
if (reti || retu){
|
||||
if (outofrange(cv, cvv, reason) < 0)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
*reason = cligen_reason("string length out of range: %" PRIu64, uu);
|
||||
if (outoflength(uu, cvv, reason) < 0)
|
||||
goto done;
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1317,13 +1416,14 @@ yang_type_resolve(yang_stmt *yorig,
|
|||
*
|
||||
* @code
|
||||
* yang_stmt *yrestype;
|
||||
* char *origtype = NULL;
|
||||
* int options;
|
||||
* cvec *cvv = NULL;
|
||||
* cvec *patterns = cvec_new(0);
|
||||
* cvec *regexps = cvec_new(0);
|
||||
* uint8_t fraction;
|
||||
*
|
||||
* if (yang_type_get(ys, &type, &yrestype, &options, &cvv,
|
||||
* if (yang_type_get(ys, &origtype, &yrestype, &options, &cvv,
|
||||
* patterns, regexps, &fraction) < 0)
|
||||
* goto err;
|
||||
* if (yrestype == NULL) # unresolved
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue