From 6fc8a69dff014fd78cc0473857dd4db364db9e7f Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 27 Nov 2019 22:02:39 +0100 Subject: [PATCH] Fixed: [xpath_tree2cbuf() changes integers into floating point representations #99](https://github.com/clicon/clixon/issues/99) --- CHANGELOG.md | 3 +- lib/clixon/clixon_xpath.h | 1 + lib/src/clixon_xpath | Bin 25708 -> 0 bytes lib/src/clixon_xpath.c | 8 +-- lib/src/clixon_xpath_parse.l | 2 +- lib/src/clixon_xpath_parse.y | 98 +++++++++++++++++++---------------- 6 files changed, 61 insertions(+), 51 deletions(-) delete mode 100644 lib/src/clixon_xpath diff --git a/CHANGELOG.md b/CHANGELOG.md index bd58463e7..d92916e92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,12 +14,13 @@ ### API changes on existing features (you may need to change your code) * Yang files reorganized into three classes: clixon, mandatory, optional (previous "standard" split into mandatory and optional). * Clixon and mandatory yang spec are always installed - * Optional yang files are loaded only if configured with `--enable-optyangs` (flipped lofgic and changed from `disable-stdyangs`). NOTE: you must do this to run examples and tests. + * Optional yang files are loaded only if configured with `--enable-optyangs` (flipped logic and changed from `disable-stdyangs`). NOTE: you must do this to run examples and tests. * Optional yang files can be installed in a separate dir with `--with-opt-yang-installdir=DIR` (renamed from `with-std-yang-installdir`) * The multi-namespace augment state may rearrange the XML namespace attributes. * Main example yang changed to incorporate augmented state, new revision is 2019-11-15. ### Corrected Bugs +* [xpath_tree2cbuf() changes integers into floating point representations #99](https://github.com/clicon/clixon/issues/99) * [xml_parse_string() is slow for a long XML string #96](https://github.com/clicon/clixon/issues/96) * Mandatory variables can no longer be deleted. * [Add missing includes](https://github.com/clicon/clixon/pulls) diff --git a/lib/clixon/clixon_xpath.h b/lib/clixon/clixon_xpath.h index 0998da16e..338dc0021 100644 --- a/lib/clixon/clixon_xpath.h +++ b/lib/clixon/clixon_xpath.h @@ -106,6 +106,7 @@ struct xpath_tree{ enum xp_type xs_type; int xs_int; /* step-> axis-type */ double xs_double; + char *xs_strnr; /* original string xs_double: numeric value */ char *xs_s0; char *xs_s1; struct xpath_tree *xs_c0; /* child 0 */ diff --git a/lib/src/clixon_xpath b/lib/src/clixon_xpath deleted file mode 100644 index 472df3d5d30e5620c9625a568090f163f158d92c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25708 zcmeHvdw5jUx%b{PN!a0%NeGt!fsEWl+T6GaDmnoMCK@h{i3JrW$z*cTBopTngW?Ho zz~dNGiM1Y%hgS6S^rKczX=^P7tnpHV7Hw*+a9Ue)thO^ok5Q;6Ui1Clcda$qGs&E< z&vTyV{M8MawchJ`*Sp?z*?aB1I-F%2ExN9$%c5Pb5p*ca!6@;oY4$4_l(^Mey5`Up zXm%|Pm{j~Zm_n(@sdQMXR;eNRtVmPvx7s2Qt1S-Bs5DogHI*t0DW&p8FNe&EboWvL zsuY$pg5=27fqVv$R&hq9?PL(H!!lKJWFE;4OSxewr_v#5m`YXssBZLEA?sIRaR4IN zL5a43e@9c|rEA;U!CK1SeIbKL9h`}!0y;@P%Vl}V{9>2(t5jB3 zD{N}4S+%0DsW!iNwOtqTuoHR4@BD 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 diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index 33b094f93..3a9b48d09 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -180,8 +180,8 @@ xpath_tree_print0(cbuf *cb, cprintf(cb, "%d ", xs->xs_int); break; } - if (xs->xs_double) - cprintf(cb,"%lf ", xs->xs_double); + if (xs->xs_strnr) + cprintf(cb,"%s ", xs->xs_strnr); cprintf(cb, "\n"); if (xs->xs_c0) xpath_tree_print0(cb, xs->xs_c0,level+1); @@ -253,7 +253,7 @@ xpath_tree2cbuf(xpath_tree *xs, cprintf(xcb, "'%s'", xs->xs_s0); break; case XP_PRIME_NR: - cprintf(xcb, "%lf", xs->xs_double); + cprintf(xcb, "%s", xs->xs_strnr?xs->xs_strnr:"0"); break; case XP_STEP: switch (xs->xs_int){ @@ -313,6 +313,8 @@ xpath_tree2cbuf(xpath_tree *xs, int xpath_tree_free(xpath_tree *xs) { + if (xs->xs_strnr) + free(xs->xs_strnr); if (xs->xs_s0) free(xs->xs_s0); if (xs->xs_s1) diff --git a/lib/src/clixon_xpath_parse.l b/lib/src/clixon_xpath_parse.l index 31699443c..8676b9d1f 100644 --- a/lib/src/clixon_xpath_parse.l +++ b/lib/src/clixon_xpath_parse.l @@ -140,7 +140,7 @@ real ({digit}+[.]{digit}*)|({digit}*[.]{digit}+) \" { BEGIN(QLITERAL); return QUOTE; } \' { BEGIN(ALITERAL); return APOST; } -\-?({integer}|{real}) { sscanf(yytext,"%lf",&clixon_xpath_parselval.dval); return NUMBER;} +\-?({integer}|{real}) { clixon_xpath_parselval.string = strdup(yytext); return NUMBER; } [0-9A-Za-z_\-]+ { clixon_xpath_parselval.string = strdup(yytext); return NAME; /* rather be catch-all */ } diff --git a/lib/src/clixon_xpath_parse.y b/lib/src/clixon_xpath_parse.y index 0fdeac5ec..a5050aaac 100644 --- a/lib/src/clixon_xpath_parse.y +++ b/lib/src/clixon_xpath_parse.y @@ -44,7 +44,6 @@ %union { int intval; - double dval; char *string; void *stack; /* xpath_tree */ } @@ -54,8 +53,7 @@ %token ADDOP %token RELOP -%token NUMBER - +%token NUMBER %token X_EOF %token QUOTE %token APOST @@ -161,13 +159,13 @@ xpath_parse_exit(struct clicon_xpath_yacc_arg *xy) static xpath_tree * xp_new(enum xp_type type, int i0, - double d0, + char *numstr, char *s0, char *s1, xpath_tree *c0, xpath_tree *c1) { - xpath_tree *xs = NULL; + xpath_tree *xs = NULL; if ((xs = malloc(sizeof(xpath_tree))) == NULL){ clicon_err(OE_XML, errno, "malloc"); @@ -176,7 +174,15 @@ xp_new(enum xp_type type, memset(xs, 0, sizeof(*xs)); xs->xs_type = type; xs->xs_int = i0; - xs->xs_double = d0; + if (numstr){ + xs->xs_strnr = numstr; + if (sscanf(numstr, "%lf", &xs->xs_double) == EOF){ + clicon_err(OE_XML, errno, "sscanf"); + goto done; + } + } + else + xs->xs_double = 0.0; xs->xs_s0 = s0; xs->xs_s1 = s1; xs->xs_c0 = c0; @@ -196,50 +202,50 @@ start : expr X_EOF { _XY->xy_top=$1;clicon_debug(2,"start->expr"); | locationpath X_EOF { _XY->xy_top=$1;clicon_debug(2,"start->locationpath"); YYACCEPT; } ; -expr : expr LOGOP andexpr { $$=xp_new(XP_EXP,$2,0.0,NULL,NULL,$1, $3);clicon_debug(2,"expr->expr or andexpr"); } - | andexpr { $$=xp_new(XP_EXP,A_NAN,0.0,NULL,NULL,$1, NULL);clicon_debug(2,"expr-> andexpr"); } +expr : expr LOGOP andexpr { $$=xp_new(XP_EXP,$2,NULL,NULL,NULL,$1, $3);clicon_debug(2,"expr->expr or andexpr"); } + | andexpr { $$=xp_new(XP_EXP,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(2,"expr-> andexpr"); } ; -andexpr : andexpr LOGOP relexpr { $$=xp_new(XP_AND,$2,0.0,NULL,NULL,$1, $3);clicon_debug(2,"andexpr-> andexpr and relexpr"); } - | relexpr { $$=xp_new(XP_AND,A_NAN,0.0,NULL,NULL,$1, NULL);clicon_debug(2,"andexpr-> relexpr"); } +andexpr : andexpr LOGOP relexpr { $$=xp_new(XP_AND,$2,NULL,NULL,NULL,$1, $3);clicon_debug(2,"andexpr-> andexpr and relexpr"); } + | relexpr { $$=xp_new(XP_AND,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(2,"andexpr-> relexpr"); } ; -relexpr : relexpr RELOP addexpr { $$=xp_new(XP_RELEX,$2,0.0,NULL,NULL,$1, $3);clicon_debug(2,"relexpr-> relexpr relop addexpr"); } - | addexpr { $$=xp_new(XP_RELEX,A_NAN,0.0,NULL,NULL,$1, NULL);clicon_debug(2,"relexpr-> addexpr"); } +relexpr : relexpr RELOP addexpr { $$=xp_new(XP_RELEX,$2,NULL,NULL,NULL,$1, $3);clicon_debug(2,"relexpr-> relexpr relop addexpr"); } + | addexpr { $$=xp_new(XP_RELEX,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(2,"relexpr-> addexpr"); } ; -addexpr : addexpr ADDOP unionexpr { $$=xp_new(XP_ADD,$2,0.0,NULL,NULL,$1, $3);clicon_debug(2,"addexpr-> addexpr ADDOP unionexpr"); } - | unionexpr { $$=xp_new(XP_ADD,A_NAN,0.0,NULL,NULL,$1, NULL);clicon_debug(2,"addexpr-> unionexpr"); } +addexpr : addexpr ADDOP unionexpr { $$=xp_new(XP_ADD,$2,NULL,NULL,NULL,$1, $3);clicon_debug(2,"addexpr-> addexpr ADDOP unionexpr"); } + | unionexpr { $$=xp_new(XP_ADD,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(2,"addexpr-> unionexpr"); } ; /* node-set */ -unionexpr : unionexpr '|' pathexpr { $$=xp_new(XP_UNION,A_NAN,0.0,NULL,NULL,$1, $3);clicon_debug(2,"unionexpr-> unionexpr | pathexpr"); } - | pathexpr { $$=xp_new(XP_UNION,A_NAN,0.0,NULL,NULL,$1, NULL);clicon_debug(2,"unionexpr-> pathexpr"); } +unionexpr : unionexpr '|' pathexpr { $$=xp_new(XP_UNION,A_NAN,NULL,NULL,NULL,$1, $3);clicon_debug(2,"unionexpr-> unionexpr | pathexpr"); } + | pathexpr { $$=xp_new(XP_UNION,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(2,"unionexpr-> pathexpr"); } ; -pathexpr : locationpath { $$=xp_new(XP_PATHEXPR,A_NAN,0.0,NULL,NULL,$1, NULL);clicon_debug(2,"pathexpr-> locationpath"); } - | primaryexpr { $$=xp_new(XP_PATHEXPR,A_NAN,0.0,NULL,NULL,$1, NULL);clicon_debug(2,"pathexpr-> primaryexpr"); } +pathexpr : locationpath { $$=xp_new(XP_PATHEXPR,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(2,"pathexpr-> locationpath"); } + | primaryexpr { $$=xp_new(XP_PATHEXPR,A_NAN,NULL,NULL,NULL,$1, NULL);clicon_debug(2,"pathexpr-> primaryexpr"); } ; /* location path returns a node-set */ -locationpath : rellocpath { $$=xp_new(XP_LOCPATH,A_NAN,0.0,NULL,NULL,$1, NULL); clicon_debug(2,"locationpath-> rellocpath"); } - | abslocpath { $$=xp_new(XP_LOCPATH,A_NAN,0.0,NULL,NULL,$1, NULL); clicon_debug(2,"locationpath-> abslocpath"); } +locationpath : rellocpath { $$=xp_new(XP_LOCPATH,A_NAN,NULL,NULL,NULL,$1, NULL); clicon_debug(2,"locationpath-> rellocpath"); } + | abslocpath { $$=xp_new(XP_LOCPATH,A_NAN,NULL,NULL,NULL,$1, NULL); clicon_debug(2,"locationpath-> abslocpath"); } ; -abslocpath : '/' { $$=xp_new(XP_ABSPATH,A_ROOT,0.0,NULL,NULL,NULL, NULL);clicon_debug(2,"abslocpath-> /"); } - | '/' rellocpath { $$=xp_new(XP_ABSPATH,A_ROOT,0.0,NULL,NULL,$2, NULL);clicon_debug(2,"abslocpath->/ rellocpath");} +abslocpath : '/' { $$=xp_new(XP_ABSPATH,A_ROOT,NULL,NULL,NULL,NULL, NULL);clicon_debug(2,"abslocpath-> /"); } + | '/' rellocpath { $$=xp_new(XP_ABSPATH,A_ROOT,NULL,NULL,NULL,$2, NULL);clicon_debug(2,"abslocpath->/ rellocpath");} /* // is short for /descendant-or-self::node()/ */ - | DOUBLESLASH rellocpath {$$=xp_new(XP_ABSPATH,A_DESCENDANT_OR_SELF,0.0,NULL,NULL,$2, NULL); clicon_debug(2,"abslocpath-> // rellocpath"); } + | DOUBLESLASH rellocpath {$$=xp_new(XP_ABSPATH,A_DESCENDANT_OR_SELF,NULL,NULL,NULL,$2, NULL); clicon_debug(2,"abslocpath-> // rellocpath"); } ; -rellocpath : step { $$=xp_new(XP_RELLOCPATH,A_NAN,0.0,NULL,NULL,$1, NULL); clicon_debug(2,"rellocpath-> step"); } - | rellocpath '/' step { $$=xp_new(XP_RELLOCPATH,A_NAN,0.0,NULL,NULL,$1, $3);clicon_debug(2,"rellocpath-> rellocpath / step"); } - | rellocpath DOUBLESLASH step { $$=xp_new(XP_RELLOCPATH,A_DESCENDANT_OR_SELF,0.0,NULL,NULL,$1, $3); clicon_debug(2,"rellocpath-> rellocpath // step"); } +rellocpath : step { $$=xp_new(XP_RELLOCPATH,A_NAN,NULL,NULL,NULL,$1, NULL); clicon_debug(2,"rellocpath-> step"); } + | rellocpath '/' step { $$=xp_new(XP_RELLOCPATH,A_NAN,NULL,NULL,NULL,$1, $3);clicon_debug(2,"rellocpath-> rellocpath / step"); } + | rellocpath DOUBLESLASH step { $$=xp_new(XP_RELLOCPATH,A_DESCENDANT_OR_SELF,NULL,NULL,NULL,$1, $3); clicon_debug(2,"rellocpath-> rellocpath // step"); } ; -step : axisspec nodetest predicates {$$=xp_new(XP_STEP,$1,0.0, NULL, NULL, $2, $3);clicon_debug(2,"step->axisspec(%d) nodetest", $1); } - | '.' predicates { $$=xp_new(XP_STEP,A_SELF, 0.0,NULL, NULL, NULL, $2); clicon_debug(2,"step-> ."); } - | DOUBLEDOT predicates { $$=xp_new(XP_STEP, A_PARENT, 0.0,NULL, NULL, NULL, $2); clicon_debug(2,"step-> .."); } +step : axisspec nodetest predicates {$$=xp_new(XP_STEP,$1,NULL, NULL, NULL, $2, $3);clicon_debug(2,"step->axisspec(%d) nodetest", $1); } + | '.' predicates { $$=xp_new(XP_STEP,A_SELF, NULL,NULL, NULL, NULL, $2); clicon_debug(2,"step-> ."); } + | DOUBLEDOT predicates { $$=xp_new(XP_STEP, A_PARENT, NULL,NULL, NULL, NULL, $2); clicon_debug(2,"step-> .."); } ; axisspec : AXISNAME { clicon_debug(2,"axisspec-> AXISNAME(%d) ::", $1); $$=$1;} @@ -247,31 +253,31 @@ axisspec : AXISNAME { clicon_debug(2,"axisspec-> AXISNAME(%d) ::", $1); $$=$1 | { clicon_debug(2,"axisspec-> "); $$=A_CHILD;} ; -nodetest : '*' { $$=xp_new(XP_NODE,A_NAN,0.0, NULL, NULL, NULL, NULL); clicon_debug(2,"nodetest-> *"); } - | NAME { $$=xp_new(XP_NODE,A_NAN,0.0, NULL, $1, NULL, NULL); clicon_debug(2,"nodetest-> name(%s)",$1); } - | NAME ':' NAME { $$=xp_new(XP_NODE,A_NAN,0.0, $1, $3, NULL, NULL);clicon_debug(2,"nodetest-> name(%s) : name(%s)", $1, $3); } - | NAME ':' '*' { $$=xp_new(XP_NODE,A_NAN,0.0, $1, NULL, NULL, NULL);clicon_debug(2,"nodetest-> name(%s) : *", $1); } - | NODETYPE '(' ')' { $$=xp_new(XP_NODE_FN,A_NAN,0.0, $1, NULL, NULL, NULL); clicon_debug(1,"nodetest-> nodetype():%s", $1); } +nodetest : '*' { $$=xp_new(XP_NODE,A_NAN,NULL, NULL, NULL, NULL, NULL); clicon_debug(2,"nodetest-> *"); } + | NAME { $$=xp_new(XP_NODE,A_NAN,NULL, NULL, $1, NULL, NULL); clicon_debug(2,"nodetest-> name(%s)",$1); } + | NAME ':' NAME { $$=xp_new(XP_NODE,A_NAN,NULL, $1, $3, NULL, NULL);clicon_debug(2,"nodetest-> name(%s) : name(%s)", $1, $3); } + | NAME ':' '*' { $$=xp_new(XP_NODE,A_NAN,NULL, $1, NULL, NULL, NULL);clicon_debug(2,"nodetest-> name(%s) : *", $1); } + | NODETYPE '(' ')' { $$=xp_new(XP_NODE_FN,A_NAN,NULL, $1, NULL, NULL, NULL); clicon_debug(1,"nodetest-> nodetype():%s", $1); } ; /* evaluates to boolean */ -predicates : predicates '[' expr ']' { $$=xp_new(XP_PRED,A_NAN,0.0, NULL, NULL, $1, $3); clicon_debug(2,"predicates-> [ expr ]"); } - | { $$=xp_new(XP_PRED,A_NAN,0.0, NULL, NULL, NULL, NULL); clicon_debug(2,"predicates->"); } +predicates : predicates '[' expr ']' { $$=xp_new(XP_PRED,A_NAN,NULL, NULL, NULL, $1, $3); clicon_debug(2,"predicates-> [ expr ]"); } + | { $$=xp_new(XP_PRED,A_NAN,NULL, NULL, NULL, NULL, NULL); clicon_debug(2,"predicates->"); } ; -primaryexpr : '(' expr ')' { $$=xp_new(XP_PRI0,A_NAN,0.0, NULL, NULL, $2, NULL); clicon_debug(2,"primaryexpr-> ( expr )"); } - | NUMBER { $$=xp_new(XP_PRIME_NR,A_NAN, $1, NULL, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> NUMBER(%lf)", $1); } - | QUOTE string QUOTE { $$=xp_new(XP_PRIME_STR,A_NAN,0.0, $2, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> \" string \""); } - | QUOTE QUOTE { $$=xp_new(XP_PRIME_STR,A_NAN,0.0, NULL, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> \" \""); } - | APOST string APOST { $$=xp_new(XP_PRIME_STR,A_NAN,0.0, $2, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> ' string '"); } - | APOST APOST { $$=xp_new(XP_PRIME_STR,A_NAN,0.0, NULL, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> ' '"); } - | FUNCTIONNAME '(' ')' { $$=xp_new(XP_PRIME_FN,A_NAN,0.0, $1, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> functionname ( arguments )"); } - | FUNCTIONNAME '(' args ')' { $$=xp_new(XP_PRIME_FN,A_NAN,0.0, $1, NULL, $3, NULL);clicon_debug(2,"primaryexpr-> functionname ( arguments )"); } +primaryexpr : '(' expr ')' { $$=xp_new(XP_PRI0,A_NAN,NULL, NULL, NULL, $2, NULL); clicon_debug(2,"primaryexpr-> ( expr )"); } + | NUMBER { $$=xp_new(XP_PRIME_NR,A_NAN, $1, NULL, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> NUMBER(%s)", $1); /*XXX*/} + | QUOTE string QUOTE { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, $2, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> \" string \""); } + | QUOTE QUOTE { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, NULL, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> \" \""); } + | APOST string APOST { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, $2, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> ' string '"); } + | APOST APOST { $$=xp_new(XP_PRIME_STR,A_NAN,NULL, NULL, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> ' '"); } + | FUNCTIONNAME '(' ')' { $$=xp_new(XP_PRIME_FN,A_NAN,NULL, $1, NULL, NULL, NULL);clicon_debug(2,"primaryexpr-> functionname ( arguments )"); } + | FUNCTIONNAME '(' args ')' { $$=xp_new(XP_PRIME_FN,A_NAN,NULL, $1, NULL, $3, NULL);clicon_debug(2,"primaryexpr-> functionname ( arguments )"); } ; -args : args ',' expr { $$=xp_new(XP_EXP,A_NAN,0.0,NULL,NULL,$1, $3); +args : args ',' expr { $$=xp_new(XP_EXP,A_NAN,NULL,NULL,NULL,$1, $3); clicon_debug(2,"args -> args expr");} - | expr { $$=xp_new(XP_EXP,A_NAN,0.0,NULL,NULL,$1, NULL); + | expr { $$=xp_new(XP_EXP,A_NAN,NULL,NULL,NULL,$1, NULL); clicon_debug(2,"args -> expr "); } ;