Text syntax parser/loader

Added string quites around text containing spaces
Added support for colon in text
This commit is contained in:
Olof hagsand 2022-05-19 14:35:18 +02:00
parent 2ece0b8f51
commit 820ed5686b
5 changed files with 116 additions and 14 deletions

View file

@ -118,6 +118,7 @@ xml2txt(cxobj *xn,
yang_stmt *ymod; yang_stmt *ymod;
yang_stmt *ypmod; yang_stmt *ypmod;
char *prefix = NULL; char *prefix = NULL;
char *value;
if (xn == NULL || fn == NULL){ if (xn == NULL || fn == NULL){
clicon_err(OE_XML, EINVAL, "xn or fn is 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 */ if (!children){ /* If no children print line */
switch (xml_type(xn)){ switch (xml_type(xn)){
case CX_BODY: 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; break;
case CX_ELMNT: case CX_ELMNT:
(*fn)(f, "%*s%s;\n", 4*level, "", xml_name(xn)); (*fn)(f, "%*s%s;\n", 4*level, "", xml_name(xn));

View file

@ -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)
<INITIAL>\[ { return *yytext; } <INITIAL>\[ { return *yytext; }
<INITIAL>\] { return *yytext; } <INITIAL>\] { return *yytext; }
<INITIAL>\; { return *yytext; } <INITIAL>\; { return *yytext; }
<INITIAL>\: { return *yytext; } <INITIAL>\" { _TS->ts_lex_state =INITIAL; BEGIN(STRING); return *yytext; }
<INITIAL>[^\n\r \t\[\]\{\}\;\:]+ { <INITIAL>[^\n\r \t\[\]\{\}\;\"]+ {
clixon_text_syntax_parselval.string = strdup(yytext); clixon_text_syntax_parselval.string = strdup(yytext);
return TOKEN; } return TOKEN; }
<INITIAL>. { return -1; } <INITIAL>. { return -1; }
@ -99,6 +100,11 @@ int clixon_text_syntax_parsewrap(void)
<COMMENT><<EOF>> { return MY_EOF; } <COMMENT><<EOF>> { return MY_EOF; }
<COMMENT>[^\n]+ <COMMENT>[^\n]+
<STRING>\" { BEGIN(_TS->ts_lex_state); return *yytext; }
<STRING>[^\n\r\"]+ { clixon_text_syntax_parselval.string = strdup(yytext);
return TOKEN; }
<STRING>. { return -1; }
%% %%
/*! Initialize XML scanner. /*! Initialize XML scanner.

View file

@ -119,18 +119,21 @@ text_add_value(cxobj *xn,
static cxobj* static cxobj*
text_create_node(clixon_text_syntax_yacc *ts, text_create_node(clixon_text_syntax_yacc *ts,
char *module,
char *name) char *name)
{ {
cxobj *xn; cxobj *xn;
yang_stmt *ymod; yang_stmt *ymod;
char *ns; 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; 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 */ /* 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){ if ((ns = yang_find_mynamespace(ymod)) == NULL){
clicon_err(OE_YANG, 0, "No namespace"); clicon_err(OE_YANG, 0, "No namespace");
goto done; goto done;
@ -141,6 +144,10 @@ text_create_node(clixon_text_syntax_yacc *ts,
} }
} }
done: done:
if (prefix)
free(prefix);
if (id)
free(id);
return xn; return xn;
} }
@ -166,6 +173,10 @@ stmt : id value ';' { _PARSE_DEBUG("stmt-> id value ;");
if (text_add_value($1, $2) < 0) YYERROR; if (text_add_value($1, $2) < 0) YYERROR;
$$ = $1; $$ = $1;
} }
| id '"' value '"' ';' { _PARSE_DEBUG("stmt-> id \" value \" ;");
if (text_add_value($1, $3) < 0) YYERROR;
$$ = $1;
}
| id '{' stmts '}' { _PARSE_DEBUG("stmt-> id { stmts }"); | id '{' stmts '}' { _PARSE_DEBUG("stmt-> id { stmts }");
if (clixon_child_xvec_append($1, $3) < 0) YYERROR; if (clixon_child_xvec_append($1, $3) < 0) YYERROR;
clixon_xvec_free($3); clixon_xvec_free($3);
@ -176,11 +187,8 @@ stmt : id value ';' { _PARSE_DEBUG("stmt-> id value ;");
; ;
id : TOKEN { _PARSE_DEBUG("id->TOKEN"); 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"); } values : values TOKEN { _PARSE_DEBUG("values->values TOKEN"); }

View file

@ -20,7 +20,7 @@ fi
OCDIR=$OPENCONFIG/release/models OCDIR=$OPENCONFIG/release/models
# Generate autocli for these modules # Generate autocli for these modules
AUTOCLI=$(autocli_config clixon-example kw-nokey false) AUTOCLI=$(autocli_config openconfig* kw-nokey false)
cat <<EOF > $cfg cat <<EOF > $cfg
<clixon-config xmlns="http://clicon.org/config"> <clixon-config xmlns="http://clicon.org/config">
@ -197,7 +197,6 @@ if [ $BE -ne 0 ]; then
stop_backend -f $cfg stop_backend -f $cfg
fi fi
rm -rf $dir rm -rf $dir
new "endtest" new "endtest"

83
test/test_text_syntax.sh Executable file
View file

@ -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 <<EOF > $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 <<EOF > $dir/x1.xml
<table xmlns="urn:example:clixon">
<parameter>
<name>a</name>
<value>foo bar</value>
</parameter>
<parameter>
<name>b</name>
<value>bar:fie</value>
</parameter>
</table>
EOF
cat <<EOF > $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