* JSON errors are now labelled with JSON and not XML
* Fixed: [Performance issue when parsing large JSON param](https://github.com/clicon/clixon/issues/266) * Moved strlen() from for end condition * Fixed debugging of xpath parser
This commit is contained in:
parent
3cd3f7987d
commit
392e6679c5
17 changed files with 166 additions and 89 deletions
|
|
@ -68,6 +68,7 @@ Users may have to change how they access the system
|
||||||
|
|
||||||
### Minor features
|
### Minor features
|
||||||
|
|
||||||
|
* JSON errors are now labelled with JSON and not XML
|
||||||
* Restconf native HTTP/2:
|
* Restconf native HTTP/2:
|
||||||
* Added option `CLICON_RESTCONF_HTTP2_PLAIN` for non-TLS http
|
* Added option `CLICON_RESTCONF_HTTP2_PLAIN` for non-TLS http
|
||||||
* Default disabled, set to true to enable HTTP/2 direct and switch/upgrade HTTP/1->HTTP/2
|
* Default disabled, set to true to enable HTTP/2 direct and switch/upgrade HTTP/1->HTTP/2
|
||||||
|
|
@ -78,6 +79,7 @@ Users may have to change how they access the system
|
||||||
|
|
||||||
### Corrected Bugs
|
### Corrected Bugs
|
||||||
|
|
||||||
|
* Fixed: [Performance issue when parsing large JSON param](https://github.com/clicon/clixon/issues/266)
|
||||||
* Fixed: [Duplicate lines emitted by cli_show_config (cli output style) when yang list element has composite key](https://github.com/clicon/clixon/issues/258)
|
* Fixed: [Duplicate lines emitted by cli_show_config (cli output style) when yang list element has composite key](https://github.com/clicon/clixon/issues/258)
|
||||||
* Fixed: [JSON leaf-list output single element leaf-list does not use array](https://github.com/clicon/clixon/issues/261)
|
* Fixed: [JSON leaf-list output single element leaf-list does not use array](https://github.com/clicon/clixon/issues/261)
|
||||||
* Fixed: Netconf diff callback did not work with choice and same value replace
|
* Fixed: Netconf diff callback did not work with choice and same value replace
|
||||||
|
|
|
||||||
|
|
@ -521,6 +521,7 @@ cli_auto_up(clicon_handle h,
|
||||||
char *api_path = NULL;
|
char *api_path = NULL;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if (cvec_len(argv) != 1){
|
if (cvec_len(argv) != 1){
|
||||||
clicon_err(OE_PLUGIN, EINVAL, "Usage: %s(<treename>)", __FUNCTION__);
|
clicon_err(OE_PLUGIN, EINVAL, "Usage: %s(<treename>)", __FUNCTION__);
|
||||||
|
|
@ -551,7 +552,8 @@ cli_auto_up(clicon_handle h,
|
||||||
/* Find diff of 0 and 1 (how many variables differ?) and trunc cvv0 by that amount */
|
/* Find diff of 0 and 1 (how many variables differ?) and trunc cvv0 by that amount */
|
||||||
cvv0 = clicon_data_cvec_get(h, "cli-edit-cvv");
|
cvv0 = clicon_data_cvec_get(h, "cli-edit-cvv");
|
||||||
j=0; /* count diffs */
|
j=0; /* count diffs */
|
||||||
for (i=strlen(api_path_fmt1); i<strlen(api_path_fmt0); i++)
|
len = strlen(api_path_fmt0);
|
||||||
|
for (i=strlen(api_path_fmt1); i<len; i++)
|
||||||
if (api_path_fmt0[i] == '%')
|
if (api_path_fmt0[i] == '%')
|
||||||
j++;
|
j++;
|
||||||
cvv1 = cvec_new(0);
|
cvv1 = cvec_new(0);
|
||||||
|
|
|
||||||
|
|
@ -1210,6 +1210,7 @@ cli_copy_config(clicon_handle h,
|
||||||
char *toname;
|
char *toname;
|
||||||
cxobj *xerr;
|
cxobj *xerr;
|
||||||
cvec *nsc = NULL;
|
cvec *nsc = NULL;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if (cvec_len(argv) != 6){
|
if (cvec_len(argv) != 6){
|
||||||
clicon_err(OE_PLUGIN, EINVAL, "Requires 6 elements: <db> <xpath> <namespace> <keyname> <from> <to>");
|
clicon_err(OE_PLUGIN, EINVAL, "Requires 6 elements: <db> <xpath> <namespace> <keyname> <from> <to>");
|
||||||
|
|
@ -1241,8 +1242,9 @@ cli_copy_config(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Sanity check that xpath contains exactly two %s, ie [%s='%s'] */
|
/* Sanity check that xpath contains exactly two %s, ie [%s='%s'] */
|
||||||
|
len = strlen(xpath);
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i=0; i<strlen(xpath); i++){
|
for (i=0; i<len; i++){
|
||||||
if (xpath[i] == '%')
|
if (xpath[i] == '%')
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -404,6 +404,7 @@ yang2cli_var_sub(clicon_handle h,
|
||||||
int j;
|
int j;
|
||||||
char *cvtypestr;
|
char *cvtypestr;
|
||||||
char *arg;
|
char *arg;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if (cvtype == CGV_VOID){
|
if (cvtype == CGV_VOID){
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -428,7 +429,8 @@ yang2cli_var_sub(clicon_handle h,
|
||||||
cprintf(cb, "|");
|
cprintf(cb, "|");
|
||||||
/* Encode by escaping delimiters */
|
/* Encode by escaping delimiters */
|
||||||
arg = yang_argument_get(yi);
|
arg = yang_argument_get(yi);
|
||||||
for (j=0; j<strlen(arg); j++){
|
len = strlen(arg);
|
||||||
|
for (j=0; j<len; j++){
|
||||||
if (index(CLIGEN_DELIMITERS, arg[j]))
|
if (index(CLIGEN_DELIMITERS, arg[j]))
|
||||||
cprintf(cb, "\\");
|
cprintf(cb, "\\");
|
||||||
cprintf(cb, "%c", arg[j]);
|
cprintf(cb, "%c", arg[j]);
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,7 @@ restconf_convert_hdr(clicon_handle h,
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
int i;
|
int i;
|
||||||
char c;
|
char c;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
|
@ -294,7 +295,8 @@ restconf_convert_hdr(clicon_handle h,
|
||||||
}
|
}
|
||||||
/* convert key name */
|
/* convert key name */
|
||||||
cprintf(cb, "HTTP_");
|
cprintf(cb, "HTTP_");
|
||||||
for (i=0; i<strlen(name); i++){
|
len = strlen(name);
|
||||||
|
for (i=0; i<len; i++){
|
||||||
c = name[i] & 0xff;
|
c = name[i] & 0xff;
|
||||||
if (islower(c))
|
if (islower(c))
|
||||||
cprintf(cb, "%c", toupper(c));
|
cprintf(cb, "%c", toupper(c));
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ yang_patch_xml2json_modified_cbuf(cxobj *x_simple_patch)
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
char *json_simple_patch_tmp;
|
char *json_simple_patch_tmp;
|
||||||
int brace_count = 0;
|
int brace_count = 0;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
json_simple_patch = cbuf_new();
|
json_simple_patch = cbuf_new();
|
||||||
if (json_simple_patch == NULL)
|
if (json_simple_patch == NULL)
|
||||||
|
|
@ -122,7 +123,8 @@ yang_patch_xml2json_modified_cbuf(cxobj *x_simple_patch)
|
||||||
|
|
||||||
// Insert a '[' after the first '{' to get the JSON to match what api_data_post/write() expect
|
// Insert a '[' after the first '{' to get the JSON to match what api_data_post/write() expect
|
||||||
json_simple_patch_tmp = cbuf_get(cb);
|
json_simple_patch_tmp = cbuf_get(cb);
|
||||||
for (int l = 0; l < strlen(json_simple_patch_tmp); l++) {
|
len = strlen(json_simple_patch_tmp);
|
||||||
|
for (int l = 0; l < strlen(len); l++) {
|
||||||
char c = json_simple_patch_tmp[l];
|
char c = json_simple_patch_tmp[l];
|
||||||
if (c == '{') {
|
if (c == '{') {
|
||||||
brace_count++;
|
brace_count++;
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,8 @@ enum clicon_err{
|
||||||
OE_UNIX, /* unix/linux syscall error */
|
OE_UNIX, /* unix/linux syscall error */
|
||||||
OE_SYSLOG, /* syslog error */
|
OE_SYSLOG, /* syslog error */
|
||||||
OE_ROUTING, /* routing daemon error (eg quagga) */
|
OE_ROUTING, /* routing daemon error (eg quagga) */
|
||||||
OE_XML, /* xml parsing etc */
|
OE_XML, /* xml parsing */
|
||||||
|
OE_JSON, /* json parsing */
|
||||||
OE_RESTCONF, /* RESTCONF errors */
|
OE_RESTCONF, /* RESTCONF errors */
|
||||||
OE_PLUGIN, /* plugin loading, etc */
|
OE_PLUGIN, /* plugin loading, etc */
|
||||||
OE_YANG , /* Yang error */
|
OE_YANG , /* Yang error */
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,9 @@ typedef int (plgreset_t)(clicon_handle h, const char *db);
|
||||||
*/
|
*/
|
||||||
typedef int (plgstatedata_t)(clicon_handle h, cvec *nsc, char *xpath, cxobj *xtop);
|
typedef int (plgstatedata_t)(clicon_handle h, cvec *nsc, char *xpath, cxobj *xtop);
|
||||||
|
|
||||||
|
/* Transaction-data type
|
||||||
|
* @see clixon_backend_transaction.h for full transaction API
|
||||||
|
*/
|
||||||
typedef void *transaction_data;
|
typedef void *transaction_data;
|
||||||
|
|
||||||
/* Transaction callback */
|
/* Transaction callback */
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@ static struct errvec EV[] = {
|
||||||
{"Syslog error", OE_SYSLOG},
|
{"Syslog error", OE_SYSLOG},
|
||||||
{"Routing demon error", OE_ROUTING},
|
{"Routing demon error", OE_ROUTING},
|
||||||
{"XML error", OE_XML},
|
{"XML error", OE_XML},
|
||||||
|
{"JSON error", OE_JSON},
|
||||||
{"RESTCONF error", OE_RESTCONF},
|
{"RESTCONF error", OE_RESTCONF},
|
||||||
{"Plugins", OE_PLUGIN},
|
{"Plugins", OE_PLUGIN},
|
||||||
{"Yang error", OE_YANG},
|
{"Yang error", OE_YANG},
|
||||||
|
|
|
||||||
|
|
@ -257,8 +257,10 @@ json_str_escape_cdata(cbuf *cb,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int i;
|
int i;
|
||||||
int esc = 0; /* cdata escape */
|
int esc = 0; /* cdata escape */
|
||||||
|
size_t len;
|
||||||
|
|
||||||
for (i=0;i<strlen(str);i++)
|
len = strlen(str);
|
||||||
|
for (i=0; i<len; i++)
|
||||||
switch (str[i]){
|
switch (str[i]){
|
||||||
case '\n':
|
case '\n':
|
||||||
cprintf(cb, "\\n");
|
cprintf(cb, "\\n");
|
||||||
|
|
@ -372,7 +374,7 @@ json2xml_decode_identityref(cxobj *x,
|
||||||
/* Here prefix2 is valid and can be NULL
|
/* Here prefix2 is valid and can be NULL
|
||||||
Change body prefix to prefix2:id */
|
Change body prefix to prefix2:id */
|
||||||
if ((cbv = cbuf_new()) == NULL){
|
if ((cbv = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
clicon_err(OE_JSON, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (prefix2)
|
if (prefix2)
|
||||||
|
|
@ -1245,7 +1247,7 @@ _json_parse(char *str,
|
||||||
if (clixon_json_parseparse(&jy) != 0) { /* yacc returns 1 on error */
|
if (clixon_json_parseparse(&jy) != 0) { /* yacc returns 1 on error */
|
||||||
clicon_log(LOG_NOTICE, "JSON error: line %d", jy.jy_linenum);
|
clicon_log(LOG_NOTICE, "JSON error: line %d", jy.jy_linenum);
|
||||||
if (clicon_errno == 0)
|
if (clicon_errno == 0)
|
||||||
clicon_err(OE_XML, 0, "JSON parser error with no error code (should not happen)");
|
clicon_err(OE_JSON, 0, "JSON parser error with no error code (should not happen)");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Traverse new objects */
|
/* Traverse new objects */
|
||||||
|
|
@ -1361,7 +1363,7 @@ clixon_json_parse_string(char *str,
|
||||||
{
|
{
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
if (xt==NULL){
|
if (xt==NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "xt is NULL");
|
clicon_err(OE_JSON, EINVAL, "xt is NULL");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (*xt == NULL){
|
if (*xt == NULL){
|
||||||
|
|
@ -1422,18 +1424,18 @@ clixon_json_parse_file(FILE *fp,
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
if (xt==NULL){
|
if (xt==NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "xt is NULL");
|
clicon_err(OE_JSON, EINVAL, "xt is NULL");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((jsonbuf = malloc(jsonbuflen)) == NULL){
|
if ((jsonbuf = malloc(jsonbuflen)) == NULL){
|
||||||
clicon_err(OE_XML, errno, "malloc");
|
clicon_err(OE_JSON, errno, "malloc");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
memset(jsonbuf, 0, jsonbuflen);
|
memset(jsonbuf, 0, jsonbuflen);
|
||||||
ptr = jsonbuf;
|
ptr = jsonbuf;
|
||||||
while (1){
|
while (1){
|
||||||
if ((ret = fread(&ch, 1, 1, fp)) < 0){
|
if ((ret = fread(&ch, 1, 1, fp)) < 0){
|
||||||
clicon_err(OE_XML, errno, "read");
|
clicon_err(OE_JSON, errno, "read");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
|
@ -1454,7 +1456,7 @@ clixon_json_parse_file(FILE *fp,
|
||||||
oldjsonbuflen = jsonbuflen;
|
oldjsonbuflen = jsonbuflen;
|
||||||
jsonbuflen *= 2;
|
jsonbuflen *= 2;
|
||||||
if ((jsonbuf = realloc(jsonbuf, jsonbuflen)) == NULL){
|
if ((jsonbuf = realloc(jsonbuf, jsonbuflen)) == NULL){
|
||||||
clicon_err(OE_XML, errno, "realloc");
|
clicon_err(OE_JSON, errno, "realloc");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
memset(jsonbuf+oldjsonbuflen, 0, jsonbuflen-oldjsonbuflen);
|
memset(jsonbuf+oldjsonbuflen, 0, jsonbuflen-oldjsonbuflen);
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ object.
|
||||||
%union {
|
%union {
|
||||||
int intval;
|
int intval;
|
||||||
char *string;
|
char *string;
|
||||||
|
void *cbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
%token <string> J_FALSE
|
%token <string> J_FALSE
|
||||||
|
|
@ -89,8 +90,8 @@ object.
|
||||||
%token <string> J_CHAR
|
%token <string> J_CHAR
|
||||||
%token <string> J_NUMBER
|
%token <string> J_NUMBER
|
||||||
|
|
||||||
%type <string> string
|
%type <cbuf> string
|
||||||
%type <string> ustring
|
%type <cbuf> ustring
|
||||||
%type <string> number
|
%type <string> number
|
||||||
|
|
||||||
%lex-param {void *_jy} /* Add this argument to parse() and lex() function */
|
%lex-param {void *_jy} /* Add this argument to parse() and lex() function */
|
||||||
|
|
@ -102,7 +103,7 @@ object.
|
||||||
/* typecast macro */
|
/* typecast macro */
|
||||||
#define _JY ((clixon_json_yacc *)_jy)
|
#define _JY ((clixon_json_yacc *)_jy)
|
||||||
|
|
||||||
#define _YYERROR(msg) {clicon_err(OE_XML, 0, "YYERROR %s '%s' %d", (msg), clixon_json_parsetext, _JY->jy_linenum); YYERROR;}
|
#define _YYERROR(msg) {clicon_err(OE_JSON, 0, "YYERROR %s '%s' %d", (msg), clixon_json_parsetext, _JY->jy_linenum); YYERROR;}
|
||||||
|
|
||||||
/* add _yy to error parameters */
|
/* add _yy to error parameters */
|
||||||
#define YY_(msgid) msgid
|
#define YY_(msgid) msgid
|
||||||
|
|
@ -150,7 +151,7 @@ void
|
||||||
clixon_json_parseerror(void *_jy,
|
clixon_json_parseerror(void *_jy,
|
||||||
char *s)
|
char *s)
|
||||||
{
|
{
|
||||||
clicon_err(OE_XML, XMLPARSE_ERRNO, "json_parse: line %d: %s at or before: '%s'",
|
clicon_err(OE_JSON, XMLPARSE_ERRNO, "json_parse: line %d: %s at or before: '%s'",
|
||||||
_JY->jy_linenum ,
|
_JY->jy_linenum ,
|
||||||
s,
|
s,
|
||||||
clixon_json_parsetext);
|
clixon_json_parsetext);
|
||||||
|
|
@ -265,7 +266,7 @@ value : J_TRUE { json_current_body(_JY, "true"); _PARSE_DEBUG("va
|
||||||
| object { _PARSE_DEBUG("value->object"); }
|
| object { _PARSE_DEBUG("value->object"); }
|
||||||
| array { _PARSE_DEBUG("value->array"); }
|
| array { _PARSE_DEBUG("value->array"); }
|
||||||
| number { json_current_body(_JY, $1); free($1); _PARSE_DEBUG("value->number");}
|
| number { json_current_body(_JY, $1); free($1); _PARSE_DEBUG("value->number");}
|
||||||
| string { json_current_body(_JY, $1); free($1); _PARSE_DEBUG("value->string");}
|
| string { json_current_body(_JY, cbuf_get($1)); cbuf_free($1); _PARSE_DEBUG("value->string");}
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -277,7 +278,7 @@ objlist : pair { _PARSE_DEBUG("objlist->pair");}
|
||||||
| objlist ',' pair { _PARSE_DEBUG("objlist->objlist , pair");}
|
| objlist ',' pair { _PARSE_DEBUG("objlist->objlist , pair");}
|
||||||
;
|
;
|
||||||
|
|
||||||
pair : string { json_current_new(_JY, $1);free($1);} ':'
|
pair : string { json_current_new(_JY, cbuf_get($1));cbuf_free($1);} ':'
|
||||||
value { json_current_pop(_JY);}{ _PARSE_DEBUG("pair->string : value");}
|
value { json_current_pop(_JY);}{ _PARSE_DEBUG("pair->string : value");}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -292,19 +293,16 @@ valuelist : value { _PARSE_DEBUG("valuelist->value"); }
|
||||||
|
|
||||||
/* quoted string */
|
/* quoted string */
|
||||||
string : J_DQ ustring J_DQ { _PARSE_DEBUG("string->\" ustring \"");$$=$2; }
|
string : J_DQ ustring J_DQ { _PARSE_DEBUG("string->\" ustring \"");$$=$2; }
|
||||||
| J_DQ J_DQ { _PARSE_DEBUG("string->\" \"");$$=strdup(""); }
|
| J_DQ J_DQ { _PARSE_DEBUG("string->\" \"");$$=cbuf_new(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* unquoted string: can be optimized by reading whole string in lex */
|
/* unquoted string: can be optimized by reading whole string in lex */
|
||||||
ustring : ustring J_CHAR
|
ustring : ustring J_CHAR
|
||||||
{
|
{
|
||||||
int len = strlen($1);
|
cbuf_append_str($1,$2); $$=$1; free($2);
|
||||||
$$ = realloc($1, len+strlen($2) + 1);
|
|
||||||
sprintf($$+len, "%s", $2);
|
|
||||||
free($2);
|
|
||||||
}
|
}
|
||||||
| J_CHAR
|
| J_CHAR
|
||||||
{$$=$1;}
|
{ cbuf *cb = cbuf_new(); cbuf_append_str(cb,$1); $$=cb; free($1);}
|
||||||
;
|
;
|
||||||
|
|
||||||
number : J_NUMBER { $$ = $1; }
|
number : J_NUMBER { $$ = $1; }
|
||||||
|
|
|
||||||
|
|
@ -460,13 +460,15 @@ api_path_fmt2api_path(const char *api_path_fmt,
|
||||||
char *str;
|
char *str;
|
||||||
char *strenc=NULL;
|
char *strenc=NULL;
|
||||||
cg_var *cv;
|
cg_var *cv;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
j = 1; /* j==0 is cli string */
|
j = 1; /* j==0 is cli string */
|
||||||
for (i=0; i<strlen(api_path_fmt); i++){
|
len = strlen(api_path_fmt);
|
||||||
|
for (i=0; i<len; i++){
|
||||||
c = api_path_fmt[i];
|
c = api_path_fmt[i];
|
||||||
if (esc){
|
if (esc){
|
||||||
esc = 0;
|
esc = 0;
|
||||||
|
|
@ -546,13 +548,15 @@ api_path_fmt2xpath(char *api_path_fmt,
|
||||||
int j;
|
int j;
|
||||||
char *str;
|
char *str;
|
||||||
cg_var *cv;
|
cg_var *cv;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
j = 1; /* j==0 is cli string */
|
j = 1; /* j==0 is cli string */
|
||||||
for (i=0; i<strlen(api_path_fmt); i++){
|
len = strlen(api_path_fmt);
|
||||||
|
for (i=0; i<len; i++){
|
||||||
c = api_path_fmt[i];
|
c = api_path_fmt[i];
|
||||||
if (esc){
|
if (esc){
|
||||||
esc = 0;
|
esc = 0;
|
||||||
|
|
|
||||||
|
|
@ -102,13 +102,15 @@ regexp_xsd2posix(char *xsd,
|
||||||
int j; /* lookahead */
|
int j; /* lookahead */
|
||||||
int esc;
|
int esc;
|
||||||
int minus = 0;
|
int minus = 0;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
esc=0;
|
esc=0;
|
||||||
for (i=0; i<strlen(xsd); i++){
|
len = strlen(xsd);
|
||||||
|
for (i=0; i<len; i++){
|
||||||
x = xsd[i];
|
x = xsd[i];
|
||||||
if (esc){
|
if (esc){
|
||||||
esc = 0;
|
esc = 0;
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,7 @@ uri_percent_encode(char **encp,
|
||||||
char *str = NULL; /* Expanded format string w stdarg */
|
char *str = NULL; /* Expanded format string w stdarg */
|
||||||
char *enc = NULL;
|
char *enc = NULL;
|
||||||
int fmtlen;
|
int fmtlen;
|
||||||
int len;
|
size_t len;
|
||||||
int i, j;
|
int i, j;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
|
|
@ -276,8 +276,9 @@ uri_percent_encode(char **encp,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
memset(enc, 0, len);
|
memset(enc, 0, len);
|
||||||
|
len = strlen(str);
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i=0; i<strlen(str); i++){
|
for (i=0; i<len; i++){
|
||||||
if (uri_unreserved(str[i]))
|
if (uri_unreserved(str[i]))
|
||||||
enc[j++] = str[i];
|
enc[j++] = str[i];
|
||||||
else{
|
else{
|
||||||
|
|
@ -311,7 +312,7 @@ uri_percent_decode(char *enc,
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
int i, j;
|
int i, j;
|
||||||
char hstr[3];
|
char hstr[3];
|
||||||
int len;
|
size_t len;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
if (enc == NULL){
|
if (enc == NULL){
|
||||||
|
|
@ -325,8 +326,9 @@ uri_percent_decode(char *enc,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
memset(str, 0, len);
|
memset(str, 0, len);
|
||||||
|
len = strlen(enc);
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i=0; i<strlen(enc); i++){
|
for (i=0; i<len; i++){
|
||||||
if (enc[i] == '%' && strlen(enc)-i > 2 &&
|
if (enc[i] == '%' && strlen(enc)-i > 2 &&
|
||||||
isxdigit(enc[i+1]) && isxdigit(enc[i+2])){
|
isxdigit(enc[i+1]) && isxdigit(enc[i+2])){
|
||||||
hstr[0] = enc[i+1];
|
hstr[0] = enc[i+1];
|
||||||
|
|
@ -386,6 +388,7 @@ xml_chardata_encode(char **escp,
|
||||||
int i, j;
|
int i, j;
|
||||||
int cdata; /* when set, skip encoding */
|
int cdata; /* when set, skip encoding */
|
||||||
va_list args;
|
va_list args;
|
||||||
|
size_t slen;
|
||||||
|
|
||||||
/* Two steps: (1) read in the complete format string */
|
/* Two steps: (1) read in the complete format string */
|
||||||
va_start(args, fmt); /* dryrun */
|
va_start(args, fmt); /* dryrun */
|
||||||
|
|
@ -404,7 +407,8 @@ xml_chardata_encode(char **escp,
|
||||||
/* Step (2) encode and expand str --> enc */
|
/* Step (2) encode and expand str --> enc */
|
||||||
/* First compute length (do nothing) */
|
/* First compute length (do nothing) */
|
||||||
len = 0; cdata = 0;
|
len = 0; cdata = 0;
|
||||||
for (i=0; i<strlen(str); i++){
|
slen = strlen(str);
|
||||||
|
for (i=0; i<slen; i++){
|
||||||
if (cdata){
|
if (cdata){
|
||||||
if (strncmp(&str[i], "]]>", strlen("]]>")) == 0)
|
if (strncmp(&str[i], "]]>", strlen("]]>")) == 0)
|
||||||
cdata = 0;
|
cdata = 0;
|
||||||
|
|
@ -440,7 +444,8 @@ xml_chardata_encode(char **escp,
|
||||||
|
|
||||||
/* Same code again, but now actually encode into output buffer */
|
/* Same code again, but now actually encode into output buffer */
|
||||||
j = 0; cdata = 0;
|
j = 0; cdata = 0;
|
||||||
for (i=0; i<strlen(str); i++){
|
slen = strlen(str);
|
||||||
|
for (i=0; i<slen; i++){
|
||||||
if (cdata){
|
if (cdata){
|
||||||
if (strncmp(&str[i], "]]>", strlen("]]>")) == 0){
|
if (strncmp(&str[i], "]]>", strlen("]]>")) == 0){
|
||||||
cdata = 0;
|
cdata = 0;
|
||||||
|
|
@ -503,12 +508,15 @@ xml_chardata_cbuf_append(cbuf *cb,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int i;
|
int i;
|
||||||
int cdata; /* when set, skip encoding */
|
int cdata; /* when set, skip encoding */
|
||||||
|
size_t len;
|
||||||
|
|
||||||
/* The orignal of this code is in xml_chardata_encode */
|
/* The orignal of this code is in xml_chardata_encode */
|
||||||
/* Step: encode and expand str --> enc */
|
/* Step: encode and expand str --> enc */
|
||||||
/* Same code again, but now actually encode into output buffer */
|
/* Same code again, but now actually encode into output buffer */
|
||||||
cdata = 0;
|
cdata = 0;
|
||||||
for (i=0; i<strlen(str); i++){
|
|
||||||
|
len = strlen(str);
|
||||||
|
for (i=0; i<len; i++){
|
||||||
if (cdata){
|
if (cdata){
|
||||||
if (strncmp(&str[i], "]]>", strlen("]]>")) == 0){
|
if (strncmp(&str[i], "]]>", strlen("]]>")) == 0){
|
||||||
cdata = 0;
|
cdata = 0;
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
/* cligen */
|
/* cligen */
|
||||||
#include <cligen/cligen.h>
|
#include <cligen/cligen.h>
|
||||||
|
|
@ -538,6 +537,7 @@ xpath_parse(const char *xpath,
|
||||||
clicon_log(LOG_NOTICE, "XPATH error: on line %d", xpy.xpy_linenum);
|
clicon_log(LOG_NOTICE, "XPATH error: on line %d", xpy.xpy_linenum);
|
||||||
if (clicon_errno == 0)
|
if (clicon_errno == 0)
|
||||||
clicon_err(OE_XML, 0, "XPATH parser error with no error code (should not happen)");
|
clicon_err(OE_XML, 0, "XPATH parser error with no error code (should not happen)");
|
||||||
|
xpath_scan_exit(&xpy);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (clicon_debug_get() > 1){
|
if (clicon_debug_get() > 1){
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,20 @@
|
||||||
|
|
||||||
#include "clixon_xpath_parse.h"
|
#include "clixon_xpath_parse.h"
|
||||||
|
|
||||||
|
/* Best debugging is to enable PARSE_DEBUG below and add -d to the LEX compile statement in the Makefile
|
||||||
|
* And then run the testcase with -D 1
|
||||||
|
* Disable it to stop any calls to clicon_debug. Having it on by default would mean very large debug outputs.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
#define _PARSE_DEBUG(s) clicon_debug(1,(s))
|
||||||
|
#define _PARSE_DEBUG1(s, s1) clicon_debug(1,(s), (s1))
|
||||||
|
#define _PARSE_DEBUG2(s, s1, s2) clicon_debug(1,(s), (s1), (s2))
|
||||||
|
#else
|
||||||
|
#define _PARSE_DEBUG(s)
|
||||||
|
#define _PARSE_DEBUG1(s, s1)
|
||||||
|
#define _PARSE_DEBUG2(s, s1, s2)
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int clixon_xpath_parseget_lineno (void); /*XXX obsolete ? */
|
extern int clixon_xpath_parseget_lineno (void); /*XXX obsolete ? */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -366,92 +380,92 @@ xp_nodetest_function(clixon_xpath_yacc *xpy,
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
start : expr X_EOF { _XPY->xpy_top=$1;clicon_debug(3,"start->expr"); YYACCEPT; }
|
start : expr X_EOF { _XPY->xpy_top=$1;_PARSE_DEBUG("start->expr"); YYACCEPT; }
|
||||||
| locationpath X_EOF { _XPY->xpy_top=$1;clicon_debug(3,"start->locationpath"); YYACCEPT; }
|
| locationpath X_EOF { _XPY->xpy_top=$1;_PARSE_DEBUG("start->locationpath"); YYACCEPT; }
|
||||||
;
|
;
|
||||||
|
|
||||||
expr : expr LOGOP andexpr { $$=xp_new(XP_EXP,$2,NULL,NULL,NULL,$1, $3);clicon_debug(3,"expr->expr or andexpr"); }
|
expr : expr LOGOP andexpr { $$=xp_new(XP_EXP,$2,NULL,NULL,NULL,$1, $3);_PARSE_DEBUG("expr->expr or andexpr"); }
|
||||||
| andexpr { $$=xp_new(XP_EXP,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(3,"expr-> andexpr"); }
|
| andexpr { $$=xp_new(XP_EXP,A_NAN,NULL,NULL,NULL,$1, NULL);_XPY->xpy_top=$$;_PARSE_DEBUG("expr-> andexpr"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
andexpr : andexpr LOGOP relexpr { $$=xp_new(XP_AND,$2,NULL,NULL,NULL,$1, $3);clicon_debug(3,"andexpr-> andexpr and relexpr"); }
|
andexpr : andexpr LOGOP relexpr { $$=xp_new(XP_AND,$2,NULL,NULL,NULL,$1, $3);_PARSE_DEBUG("andexpr-> andexpr and relexpr"); }
|
||||||
| relexpr { $$=xp_new(XP_AND,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(3,"andexpr-> relexpr"); }
|
| relexpr { $$=xp_new(XP_AND,A_NAN,NULL,NULL,NULL,$1, NULL);_PARSE_DEBUG("andexpr-> relexpr"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
relexpr : relexpr RELOP addexpr { $$=xp_new(XP_RELEX,$2,NULL,NULL,NULL,$1, $3);clicon_debug(3,"relexpr-> relexpr relop addexpr"); }
|
relexpr : relexpr RELOP addexpr { $$=xp_new(XP_RELEX,$2,NULL,NULL,NULL,$1, $3);_PARSE_DEBUG("relexpr-> relexpr relop addexpr"); }
|
||||||
| addexpr { $$=xp_new(XP_RELEX,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(3,"relexpr-> addexpr"); }
|
| addexpr { $$=xp_new(XP_RELEX,A_NAN,NULL,NULL,NULL,$1, NULL);_PARSE_DEBUG("relexpr-> addexpr"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
addexpr : addexpr ADDOP unionexpr { $$=xp_new(XP_ADD,$2,NULL,NULL,NULL,$1, $3);clicon_debug(3,"addexpr-> addexpr ADDOP unionexpr"); }
|
addexpr : addexpr ADDOP unionexpr { $$=xp_new(XP_ADD,$2,NULL,NULL,NULL,$1, $3);_PARSE_DEBUG("addexpr-> addexpr ADDOP unionexpr"); }
|
||||||
| unionexpr { $$=xp_new(XP_ADD,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(3,"addexpr-> unionexpr"); }
|
| unionexpr { $$=xp_new(XP_ADD,A_NAN,NULL,NULL,NULL,$1, NULL);_PARSE_DEBUG("addexpr-> unionexpr"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* node-set */
|
/* node-set */
|
||||||
unionexpr : unionexpr '|' pathexpr { $$=xp_new(XP_UNION,XO_UNION,NULL,NULL,NULL,$1, $3);clicon_debug(3,"unionexpr-> unionexpr | pathexpr"); }
|
unionexpr : unionexpr '|' pathexpr { $$=xp_new(XP_UNION,XO_UNION,NULL,NULL,NULL,$1, $3);_PARSE_DEBUG("unionexpr-> unionexpr | pathexpr"); }
|
||||||
| pathexpr { $$=xp_new(XP_UNION,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(3,"unionexpr-> pathexpr"); }
|
| pathexpr { $$=xp_new(XP_UNION,A_NAN,NULL,NULL,NULL,$1, NULL);_PARSE_DEBUG("unionexpr-> pathexpr"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
pathexpr : locationpath { $$=xp_new(XP_PATHEXPR,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(3,"pathexpr-> locationpath"); }
|
pathexpr : locationpath { $$=xp_new(XP_PATHEXPR,A_NAN,NULL,NULL,NULL,$1, NULL);_PARSE_DEBUG("pathexpr-> locationpath"); }
|
||||||
| filterexpr { $$=xp_new(XP_PATHEXPR,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(3,"pathexpr-> filterexpr"); }
|
| filterexpr { $$=xp_new(XP_PATHEXPR,A_NAN,NULL,NULL,NULL,$1, NULL);_PARSE_DEBUG("pathexpr-> filterexpr"); }
|
||||||
| filterexpr '/' rellocpath { $$=xp_new(XP_PATHEXPR,A_NAN,NULL,strdup("/"),NULL,$1, $3);clicon_debug(3,"pathexpr-> filterexpr / rellocpath"); }
|
| filterexpr '/' rellocpath { $$=xp_new(XP_PATHEXPR,A_NAN,NULL,strdup("/"),NULL,$1, $3);_PARSE_DEBUG("pathexpr-> filterexpr / rellocpath"); }
|
||||||
| filterexpr DOUBLESLASH rellocpath { $$=xp_new(XP_PATHEXPR,A_NAN,NULL,strdup("//"),NULL,$1, $3);clicon_debug(3,"pathexpr-> filterexpr // rellocpath"); }
|
| filterexpr DOUBLESLASH rellocpath { $$=xp_new(XP_PATHEXPR,A_NAN,NULL,strdup("//"),NULL,$1, $3);_PARSE_DEBUG("pathexpr-> filterexpr // rellocpath"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
filterexpr : primaryexpr { $$=xp_new(XP_FILTEREXPR,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(3,"filterexpr-> primaryexpr"); }
|
filterexpr : primaryexpr { $$=xp_new(XP_FILTEREXPR,A_NAN,NULL,NULL,NULL,$1, NULL);_PARSE_DEBUG("filterexpr-> primaryexpr"); }
|
||||||
/* Filterexpr predicate */
|
/* Filterexpr predicate */
|
||||||
;
|
;
|
||||||
|
|
||||||
/* location path returns a node-set */
|
/* location path returns a node-set */
|
||||||
locationpath : rellocpath { $$=xp_new(XP_LOCPATH,A_NAN,NULL,NULL,NULL,$1, NULL); clicon_debug(3,"locationpath-> rellocpath"); }
|
locationpath : rellocpath { $$=xp_new(XP_LOCPATH,A_NAN,NULL,NULL,NULL,$1, NULL); _PARSE_DEBUG("locationpath-> rellocpath"); }
|
||||||
| abslocpath { $$=xp_new(XP_LOCPATH,A_NAN,NULL,NULL,NULL,$1, NULL); clicon_debug(3,"locationpath-> abslocpath"); }
|
| abslocpath { $$=xp_new(XP_LOCPATH,A_NAN,NULL,NULL,NULL,$1, NULL); _PARSE_DEBUG("locationpath-> abslocpath"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
abslocpath : '/' { $$=xp_new(XP_ABSPATH,A_ROOT,NULL,NULL,NULL,NULL, NULL);clicon_debug(3,"abslocpath-> /"); }
|
abslocpath : '/' { $$=xp_new(XP_ABSPATH,A_ROOT,NULL,NULL,NULL,NULL, NULL);_PARSE_DEBUG("abslocpath-> /"); }
|
||||||
| '/' rellocpath { $$=xp_new(XP_ABSPATH,A_ROOT,NULL,NULL,NULL,$2, NULL);clicon_debug(3,"abslocpath->/ rellocpath");}
|
| '/' rellocpath { $$=xp_new(XP_ABSPATH,A_ROOT,NULL,NULL,NULL,$2, NULL);_PARSE_DEBUG("abslocpath->/ rellocpath");}
|
||||||
/* // is short for /descendant-or-self::node()/ */
|
/* // is short for /descendant-or-self::node()/ */
|
||||||
| DOUBLESLASH rellocpath {$$=xp_new(XP_ABSPATH,A_DESCENDANT_OR_SELF,NULL,NULL,NULL,$2, NULL); clicon_debug(3,"abslocpath-> // rellocpath"); }
|
| DOUBLESLASH rellocpath {$$=xp_new(XP_ABSPATH,A_DESCENDANT_OR_SELF,NULL,NULL,NULL,$2, NULL); _PARSE_DEBUG("abslocpath-> // rellocpath"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
rellocpath : step { $$=xp_new(XP_RELLOCPATH,A_NAN,NULL,NULL,NULL,$1, NULL); clicon_debug(3,"rellocpath-> step"); }
|
rellocpath : step { $$=xp_new(XP_RELLOCPATH,A_NAN,NULL,NULL,NULL,$1, NULL); _PARSE_DEBUG("rellocpath-> step"); }
|
||||||
| rellocpath '/' step { $$=xp_new(XP_RELLOCPATH,A_NAN,NULL,NULL,NULL,$1, $3);clicon_debug(3,"rellocpath-> rellocpath / step"); }
|
| rellocpath '/' step { $$=xp_new(XP_RELLOCPATH,A_NAN,NULL,NULL,NULL,$1, $3);_PARSE_DEBUG("rellocpath-> rellocpath / step"); }
|
||||||
| rellocpath DOUBLESLASH step { $$=xp_new(XP_RELLOCPATH,A_DESCENDANT_OR_SELF,NULL,NULL,NULL,$1, $3); clicon_debug(3,"rellocpath-> rellocpath // step"); }
|
| rellocpath DOUBLESLASH step { $$=xp_new(XP_RELLOCPATH,A_DESCENDANT_OR_SELF,NULL,NULL,NULL,$1, $3); _PARSE_DEBUG("rellocpath-> rellocpath // step"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
step : axisspec nodetest predicates {$$=xp_new(XP_STEP,$1,NULL, NULL, NULL, $2, $3);clicon_debug(3,"step->axisspec(%d) nodetest", $1); }
|
step : axisspec nodetest predicates {$$=xp_new(XP_STEP,$1,NULL, NULL, NULL, $2, $3);_PARSE_DEBUG1("step->axisspec(%d) nodetest", $1); }
|
||||||
| '.' predicates { $$=xp_new(XP_STEP,A_SELF, NULL,NULL, NULL, NULL, $2); clicon_debug(3,"step-> ."); }
|
| '.' predicates { $$=xp_new(XP_STEP,A_SELF, NULL,NULL, NULL, NULL, $2); _PARSE_DEBUG("step-> ."); }
|
||||||
| DOUBLEDOT predicates { $$=xp_new(XP_STEP, A_PARENT, NULL,NULL, NULL, NULL, $2); clicon_debug(3,"step-> .."); }
|
| DOUBLEDOT predicates { $$=xp_new(XP_STEP, A_PARENT, NULL,NULL, NULL, NULL, $2); _PARSE_DEBUG("step-> .."); }
|
||||||
;
|
;
|
||||||
|
|
||||||
axisspec : AXISNAME { clicon_debug(3,"axisspec-> AXISNAME(%d) ::", $1); $$=$1;}
|
axisspec : AXISNAME { _PARSE_DEBUG1("axisspec-> AXISNAME(%d) ::", $1); $$=$1;}
|
||||||
| '@' { $$=A_ATTRIBUTE; clicon_debug(3,"axisspec-> @"); }
|
| '@' { $$=A_ATTRIBUTE; _PARSE_DEBUG("axisspec-> @"); }
|
||||||
| { clicon_debug(3,"axisspec-> "); $$=A_CHILD;}
|
| { _PARSE_DEBUG("axisspec-> "); $$=A_CHILD;}
|
||||||
;
|
;
|
||||||
|
|
||||||
nodetest : '*' { $$=xp_new(XP_NODE,A_NAN,NULL, NULL, NULL, NULL, NULL); clicon_debug(3,"nodetest-> *"); }
|
nodetest : '*' { $$=xp_new(XP_NODE,A_NAN,NULL, NULL, NULL, NULL, NULL); _PARSE_DEBUG("nodetest-> *"); }
|
||||||
| NAME { $$=xp_new(XP_NODE,A_NAN,NULL, NULL, $1, NULL, NULL); clicon_debug(3,"nodetest-> name(%s)",$1); }
|
| NAME { $$=xp_new(XP_NODE,A_NAN,NULL, NULL, $1, NULL, NULL); _PARSE_DEBUG1("nodetest-> name(%s)",$1); }
|
||||||
| NAME ':' NAME { $$=xp_new(XP_NODE,A_NAN,NULL, $1, $3, NULL, NULL);clicon_debug(3,"nodetest-> name(%s) : name(%s)", $1, $3); }
|
| NAME ':' NAME { $$=xp_new(XP_NODE,A_NAN,NULL, $1, $3, NULL, NULL);_PARSE_DEBUG2("nodetest-> name(%s) : name(%s)", $1, $3); }
|
||||||
| NAME ':' '*' { $$=xp_new(XP_NODE,A_NAN,NULL, $1, NULL, NULL, NULL);clicon_debug(3,"nodetest-> name(%s) : *", $1); }
|
| NAME ':' '*' { $$=xp_new(XP_NODE,A_NAN,NULL, $1, NULL, NULL, NULL);_PARSE_DEBUG1("nodetest-> name(%s) : *", $1); }
|
||||||
| FUNCTIONNAME ')' { if (($$ = xp_nodetest_function(_XPY, $1, NULL)) == NULL) YYERROR;; clicon_debug(3,"nodetest-> nodetype():%s", $1); }
|
| FUNCTIONNAME ')' { if (($$ = xp_nodetest_function(_XPY, $1, NULL)) == NULL) YYERROR;; _PARSE_DEBUG1("nodetest-> nodetype():%s", $1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* evaluates to boolean */
|
/* evaluates to boolean */
|
||||||
predicates : predicates '[' expr ']' { $$=xp_new(XP_PRED,A_NAN,NULL, NULL, NULL, $1, $3); clicon_debug(3,"predicates-> [ expr ]"); }
|
predicates : predicates '[' expr ']' { $$=xp_new(XP_PRED,A_NAN,NULL, NULL, NULL, $1, $3); _PARSE_DEBUG("predicates-> [ expr ]"); }
|
||||||
| { $$=xp_new(XP_PRED,A_NAN,NULL, NULL, NULL, NULL, NULL); clicon_debug(3,"predicates->"); }
|
| { $$=xp_new(XP_PRED,A_NAN,NULL, NULL, NULL, NULL, NULL); _PARSE_DEBUG("predicates->"); }
|
||||||
;
|
;
|
||||||
primaryexpr : '(' expr ')' { $$=xp_new(XP_PRI0,A_NAN,NULL, NULL, NULL, $2, NULL); clicon_debug(3,"primaryexpr-> ( expr )"); }
|
primaryexpr : '(' expr ')' { $$=xp_new(XP_PRI0,A_NAN,NULL, NULL, NULL, $2, NULL); _PARSE_DEBUG("primaryexpr-> ( expr )"); }
|
||||||
| NUMBER { $$=xp_new(XP_PRIME_NR,A_NAN, $1, NULL, NULL, NULL, NULL);clicon_debug(3,"primaryexpr-> NUMBER(%s)", $1); /*XXX*/}
|
| NUMBER { $$=xp_new(XP_PRIME_NR,A_NAN, $1, NULL, NULL, NULL, NULL);_PARSE_DEBUG1("primaryexpr-> NUMBER(%s)", $1); /*XXX*/}
|
||||||
| QUOTE string QUOTE { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, $2, NULL, NULL, NULL);clicon_debug(3,"primaryexpr-> \" string \""); }
|
| QUOTE string QUOTE { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, $2, NULL, NULL, NULL);_PARSE_DEBUG("primaryexpr-> \" string \""); }
|
||||||
| QUOTE QUOTE { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, strdup(""), NULL, NULL, NULL);clicon_debug(3,"primaryexpr-> \" \""); }
|
| QUOTE QUOTE { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, strdup(""), NULL, NULL, NULL);_PARSE_DEBUG("primaryexpr-> \" \""); }
|
||||||
| APOST string APOST { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, $2, NULL, NULL, NULL);clicon_debug(3,"primaryexpr-> ' string '"); }
|
| APOST string APOST { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, $2, NULL, NULL, NULL);_PARSE_DEBUG("primaryexpr-> ' string '"); }
|
||||||
| APOST APOST { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, strdup(""), NULL, NULL, NULL);clicon_debug(3,"primaryexpr-> ' '"); }
|
| APOST APOST { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, strdup(""), NULL, NULL, NULL);_PARSE_DEBUG("primaryexpr-> ' '"); }
|
||||||
| FUNCTIONNAME ')' { if (($$ = xp_primary_function(_XPY, $1, NULL)) == NULL) YYERROR; clicon_debug(3,"primaryexpr-> functionname ()"); }
|
| FUNCTIONNAME ')' { if (($$ = xp_primary_function(_XPY, $1, NULL)) == NULL) YYERROR; _PARSE_DEBUG("primaryexpr-> functionname ()"); }
|
||||||
| FUNCTIONNAME args ')' { if (($$ = xp_primary_function(_XPY, $1, $2)) == NULL) YYERROR; clicon_debug(3,"primaryexpr-> functionname (arguments)"); }
|
| FUNCTIONNAME args ')' { if (($$ = xp_primary_function(_XPY, $1, $2)) == NULL) YYERROR; _PARSE_DEBUG("primaryexpr-> functionname (arguments)"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
args : args ',' expr { $$=xp_new(XP_EXP,A_NAN,NULL,NULL,NULL,$1, $3);
|
args : args ',' expr { $$=xp_new(XP_EXP,A_NAN,NULL,NULL,NULL,$1, $3);
|
||||||
clicon_debug(3,"args -> args expr");}
|
_PARSE_DEBUG("args -> args expr");}
|
||||||
| expr { $$=xp_new(XP_EXP,A_NAN,NULL,NULL,NULL,$1, NULL);
|
| expr { $$=xp_new(XP_EXP,A_NAN,NULL,NULL,NULL,$1, NULL);
|
||||||
clicon_debug(3,"args -> expr "); }
|
_PARSE_DEBUG("args -> expr "); }
|
||||||
;
|
;
|
||||||
|
|
||||||
string : string CHARS {
|
string : string CHARS {
|
||||||
|
|
@ -459,9 +473,9 @@ string : string CHARS {
|
||||||
$$ = realloc($1, len+strlen($2) + 1);
|
$$ = realloc($1, len+strlen($2) + 1);
|
||||||
sprintf($$+len, "%s", $2);
|
sprintf($$+len, "%s", $2);
|
||||||
free($2);
|
free($2);
|
||||||
clicon_debug(3,"string-> string CHAR");
|
_PARSE_DEBUG("string-> string CHAR");
|
||||||
}
|
}
|
||||||
| CHARS { clicon_debug(3,"string-> "); }
|
| CHARS { _PARSE_DEBUG("string-> "); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
33
test/test_perf_json.sh
Executable file
33
test/test_perf_json.sh
Executable file
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# JSON performance test:
|
||||||
|
# 1. parse a long string
|
||||||
|
|
||||||
|
# Magic line must be first in script (see README.md)
|
||||||
|
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||||
|
|
||||||
|
: ${clixon_util_json:="clixon_util_json"}
|
||||||
|
|
||||||
|
# Number of list/leaf-list entries in file
|
||||||
|
: ${perfnr:=20000}
|
||||||
|
|
||||||
|
fjson=$dir/long.json
|
||||||
|
|
||||||
|
new "generate long file $fjson"
|
||||||
|
echo -n '{"foo": "' > $fjson
|
||||||
|
for (( i=0; i<$perfnr; i++ )); do
|
||||||
|
echo -n "a" >> $fjson
|
||||||
|
done
|
||||||
|
echo '"}' >> $fjson
|
||||||
|
echo "$fjson"
|
||||||
|
|
||||||
|
new "json parse long string"
|
||||||
|
expecteof_file "time -p $clixon_util_json" 0 "$fjson" 2>&1 | awk '/real/ {print $2}'
|
||||||
|
|
||||||
|
rm -rf $dir
|
||||||
|
|
||||||
|
# unset conditional parameters
|
||||||
|
unset clixon_util_xml
|
||||||
|
unset perfnr
|
||||||
|
|
||||||
|
new "endtest"
|
||||||
|
endtest
|
||||||
Loading…
Add table
Add a link
Reference in a new issue