diff --git a/lib/src/clixon_text_syntax.c b/lib/src/clixon_text_syntax.c index abc29e98..d4ed88b9 100644 --- a/lib/src/clixon_text_syntax.c +++ b/lib/src/clixon_text_syntax.c @@ -118,6 +118,7 @@ xml2txt(cxobj *xn, yang_stmt *ymod; yang_stmt *ypmod; char *prefix = NULL; + char *value; if (xn == NULL || fn == NULL){ clicon_err(OE_XML, EINVAL, "xn or fn is NULL"); @@ -148,7 +149,12 @@ xml2txt(cxobj *xn, if (!children){ /* If no children print line */ switch (xml_type(xn)){ case CX_BODY: - (*fn)(f, "%s;\n", xml_value(xn)); + value = xml_value(xn); + /* Add quotes if string contains spaces */ + if (index(value, ' ') != NULL) + (*fn)(f, "\"%s\";\n", xml_value(xn)); + else + (*fn)(f, "%s;\n", xml_value(xn)); break; case CX_ELMNT: (*fn)(f, "%*s%s;\n", 4*level, "", xml_name(xn)); diff --git a/lib/src/clixon_text_syntax_parse.l b/lib/src/clixon_text_syntax_parse.l index eb85cb60..66da05b1 100644 --- a/lib/src/clixon_text_syntax_parse.l +++ b/lib/src/clixon_text_syntax_parse.l @@ -75,7 +75,8 @@ int clixon_text_syntax_parsewrap(void) %} -%s COMMENT +%x COMMENT +%x STRING %% @@ -89,8 +90,8 @@ int clixon_text_syntax_parsewrap(void) \[ { return *yytext; } \] { return *yytext; } \; { return *yytext; } -\: { return *yytext; } -[^\n\r \t\[\]\{\}\;\:]+ { +\" { _TS->ts_lex_state =INITIAL; BEGIN(STRING); return *yytext; } +[^\n\r \t\[\]\{\}\;\"]+ { clixon_text_syntax_parselval.string = strdup(yytext); return TOKEN; } . { return -1; } @@ -99,6 +100,11 @@ int clixon_text_syntax_parsewrap(void) <> { return MY_EOF; } [^\n]+ +\" { BEGIN(_TS->ts_lex_state); return *yytext; } +[^\n\r\"]+ { clixon_text_syntax_parselval.string = strdup(yytext); + return TOKEN; } +. { return -1; } + %% /*! Initialize XML scanner. diff --git a/lib/src/clixon_text_syntax_parse.y b/lib/src/clixon_text_syntax_parse.y index bf2da9d9..14297885 100644 --- a/lib/src/clixon_text_syntax_parse.y +++ b/lib/src/clixon_text_syntax_parse.y @@ -119,18 +119,21 @@ text_add_value(cxobj *xn, static cxobj* text_create_node(clixon_text_syntax_yacc *ts, - char *module, char *name) { cxobj *xn; yang_stmt *ymod; char *ns; + char *prefix = NULL; + char *id = NULL; - if ((xn = xml_new(name, NULL, CX_ELMNT)) == NULL) + if (nodeid_split(name, &prefix, &id) < 0) goto done; - if (module && ts->ts_yspec){ + if ((xn = xml_new(id, NULL, CX_ELMNT)) == NULL) + goto done; + if (prefix && ts->ts_yspec){ /* Silently ignore if module name not found */ - if ((ymod = yang_find(ts->ts_yspec, Y_MODULE, NULL)) != NULL){ + if ((ymod = yang_find(ts->ts_yspec, Y_MODULE, prefix)) != NULL){ if ((ns = yang_find_mynamespace(ymod)) == NULL){ clicon_err(OE_YANG, 0, "No namespace"); goto done; @@ -141,6 +144,10 @@ text_create_node(clixon_text_syntax_yacc *ts, } } done: + if (prefix) + free(prefix); + if (id) + free(id); return xn; } @@ -166,6 +173,10 @@ stmt : id value ';' { _PARSE_DEBUG("stmt-> id value ;"); if (text_add_value($1, $2) < 0) YYERROR; $$ = $1; } + | id '"' value '"' ';' { _PARSE_DEBUG("stmt-> id \" value \" ;"); + if (text_add_value($1, $3) < 0) YYERROR; + $$ = $1; + } | id '{' stmts '}' { _PARSE_DEBUG("stmt-> id { stmts }"); if (clixon_child_xvec_append($1, $3) < 0) YYERROR; clixon_xvec_free($3); @@ -176,11 +187,8 @@ stmt : id value ';' { _PARSE_DEBUG("stmt-> id value ;"); ; id : TOKEN { _PARSE_DEBUG("id->TOKEN"); - if (($$ = text_create_node(_TS, NULL, $1)) == NULL) YYERROR;; + if (($$ = text_create_node(_TS, $1)) == NULL) YYERROR;; } - | TOKEN ':' TOKEN { _PARSE_DEBUG("id->TOKEN : TOKEN"); - if (($$ = text_create_node(_TS, $1, $3)) == NULL) YYERROR;; - } ; values : values TOKEN { _PARSE_DEBUG("values->values TOKEN"); } diff --git a/test/test_openconfig_interfaces.sh b/test/test_openconfig_interfaces.sh index 771af6f6..00cbde53 100755 --- a/test/test_openconfig_interfaces.sh +++ b/test/test_openconfig_interfaces.sh @@ -20,7 +20,7 @@ fi OCDIR=$OPENCONFIG/release/models # Generate autocli for these modules -AUTOCLI=$(autocli_config clixon-example kw-nokey false) +AUTOCLI=$(autocli_config openconfig* kw-nokey false) cat < $cfg @@ -197,7 +197,6 @@ if [ $BE -ne 0 ]; then stop_backend -f $cfg fi - rm -rf $dir new "endtest" diff --git a/test/test_text_syntax.sh b/test/test_text_syntax.sh new file mode 100755 index 00000000..9dae9db8 --- /dev/null +++ b/test/test_text_syntax.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# Test: TEX syntax parser tests. + +# 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_text_syntax:=clixon_util_text_syntax} +: ${clixon_util_xml:=clixon_util_xml} + +fyang=$dir/example.yang + +cat < $fyang +module example{ + prefix ex; + namespace "urn:example:clixon"; + /* Generic config data */ + container table{ + list parameter{ + key name; + leaf name{ + type string; + } + leaf value{ + type string; + } + } + } +} +EOF + +cat < $dir/x1.xml + + + a + foo bar + + + b + bar:fie + +
+EOF + +cat < $dir/x1.txt +example:table { + parameter { + name a; + value "foo bar"; + } + parameter { + name b; + value bar:fie; + } +} +EOF + +new "test params: -y $fyang" + +# No yang +new "xml to txt" +expectpart "$($clixon_util_xml -f $dir/x1.xml -y $fyang -oX -D $DBG > $dir/x2.txt)" 0 "" + +ret=$(diff $dir/x1.txt $dir/x2.txt) +if [ $? -ne 0 ]; then + err1 "$ret" +fi + +new "txt to xml" +expectpart "$($clixon_util_text_syntax -f $dir/x1.txt -y $fyang -D $DBG > $dir/x2.xml)" 0 "" + +ret=$(diff $dir/x1.xml $dir/x2.xml) +if [ $? -ne 0 ]; then + err1 "XML" "$ret" +fi + +rm -rf $dir + +# unset conditional parameters +unset clixon_util_text_syntax +unset clixon_util_xml + +new "endtest" +endtest