added instance_id parse files
This commit is contained in:
parent
5fc9fa0b8d
commit
7bcd6aed08
3 changed files with 606 additions and 0 deletions
69
lib/src/clixon_instance_id_parse.h
Normal file
69
lib/src/clixon_instance_id_parse.h
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2020 Olof Hagsand
|
||||||
|
|
||||||
|
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 *****
|
||||||
|
|
||||||
|
* "instance-id" is a subset of XPath and defined in RF7950 Sections 9.13 and 14.
|
||||||
|
*/
|
||||||
|
#ifndef _CLIXON_INSTANCE_ID_PARSE_H_
|
||||||
|
#define _CLIXON_INSTANCE_ID_PARSE_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types
|
||||||
|
*/
|
||||||
|
struct clicon_instance_id_yacc_arg{
|
||||||
|
const char *iy_name; /* Name of syntax (for error string) */
|
||||||
|
int iy_linenum; /* Number of \n in parsed buffer */
|
||||||
|
char *iy_parse_string; /* original (copy of) parse string */
|
||||||
|
void *iy_lexbuf; /* internal parse buffer from lex */
|
||||||
|
clixon_path *iy_top;
|
||||||
|
int iy_lex_state; /* lex return state */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variables
|
||||||
|
*/
|
||||||
|
extern char *clixon_instance_id_parsetext;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototypes
|
||||||
|
*/
|
||||||
|
int instance_id_scan_init(struct clicon_instance_id_yacc_arg *);
|
||||||
|
int instance_id_scan_exit(struct clicon_instance_id_yacc_arg *);
|
||||||
|
|
||||||
|
int instance_id_parse_init(struct clicon_instance_id_yacc_arg *);
|
||||||
|
int instance_id_parse_exit(struct clicon_instance_id_yacc_arg *);
|
||||||
|
|
||||||
|
int clixon_instance_id_parselex(void *);
|
||||||
|
int clixon_instance_id_parseparse(void *);
|
||||||
|
void clixon_instance_id_parseerror(void *, char*);
|
||||||
|
|
||||||
|
#endif /* _CLIXON_INSTANCE_ID_PARSE_H_ */
|
||||||
157
lib/src/clixon_instance_id_parse.l
Normal file
157
lib/src/clixon_instance_id_parse.l
Normal file
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2020 Olof Hagsand
|
||||||
|
|
||||||
|
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 *****
|
||||||
|
*
|
||||||
|
* "instance-id" is a subset of XPath and defined in RF7950 Sections 9.13 and 14.
|
||||||
|
* BNF:
|
||||||
|
* instance-identifier = ("/" (node-identifier [key-predicate+ | leaf-list-predicate | pos]))+
|
||||||
|
* key-predicate = "[" key-predicate-expr "]"
|
||||||
|
* key-predicate-expr = node-identifier "=" quoted-string
|
||||||
|
* leaf-list-predicate = "[" leaf-list-predicate-expr "]"
|
||||||
|
* leaf-list-predicate-expr = "." "=" quoted-string
|
||||||
|
* pos = "[" positive-integer-value "]"
|
||||||
|
* node-identifier = [prefix ":"] identifier
|
||||||
|
* quoted-string = (DQUOTE string DQUOTE) / (SQUOTE string SQUOTE)
|
||||||
|
* positive-integer-value = (non-zero-digit DIGIT*)
|
||||||
|
* prefix = identifier
|
||||||
|
* identifier = (ALPHA | "_")(ALPHA | DIGIT | "_" | "-" | ".")*
|
||||||
|
*/
|
||||||
|
|
||||||
|
%{
|
||||||
|
|
||||||
|
#include "clixon_config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "clixon_instance_id_parse.tab.h" /* generated */
|
||||||
|
|
||||||
|
#include <cligen/cligen.h>
|
||||||
|
|
||||||
|
#include "clixon_queue.h"
|
||||||
|
#include "clixon_hash.h"
|
||||||
|
#include "clixon_handle.h"
|
||||||
|
#include "clixon_yang.h"
|
||||||
|
#include "clixon_log.h"
|
||||||
|
#include "clixon_string.h"
|
||||||
|
#include "clixon_xml.h"
|
||||||
|
#include "clixon_path.h"
|
||||||
|
#include "clixon_instance_id_parse.h"
|
||||||
|
|
||||||
|
/* Redefine main lex function so that you can send arguments to it: _yy is added to arg list */
|
||||||
|
#define YY_DECL int clixon_instance_id_parselex(void *_iy)
|
||||||
|
|
||||||
|
/* Dont use input function (use user-buffer) */
|
||||||
|
#define YY_NO_INPUT
|
||||||
|
|
||||||
|
/* typecast macro */
|
||||||
|
#define _IY ((struct clicon_instance_id_yacc_arg *)_iy)
|
||||||
|
|
||||||
|
#define MAXBUF 4*4*64*1024
|
||||||
|
|
||||||
|
#undef clixon_instance_id_parsewrap
|
||||||
|
int
|
||||||
|
clixon_instance_id_parsewrap(void)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
namestart [A-Z_a-z]
|
||||||
|
namechar [A-Z_a-z\-\.0-9]
|
||||||
|
identifier {namestart}{namechar}*
|
||||||
|
uint [1-9][0-9]*
|
||||||
|
|
||||||
|
%x INIT
|
||||||
|
%s STRDQ
|
||||||
|
%s STRSQ
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
<INIT,STRDQ,STRSQ>[ \t]
|
||||||
|
<INIT,STRDQ,STRSQ>\n { _IY->iy_linenum++; }
|
||||||
|
<INIT,STRDQ,STRSQ>\r
|
||||||
|
<INIT,STRDQ,STRSQ><<EOF>> { return X_EOF; }
|
||||||
|
|
||||||
|
<INIT>\/ { return SLASH;}
|
||||||
|
<INIT>\[ { return LSQBR;}
|
||||||
|
<INIT>\] { return RSQBR;}
|
||||||
|
<INIT>\= { return EQUAL; }
|
||||||
|
<INIT>\: { return COLON; }
|
||||||
|
<INIT>\. { return DOT; }
|
||||||
|
<INIT>\" { _IY->iy_lex_state=INIT;BEGIN(STRDQ); return DQUOTE; }
|
||||||
|
<INIT>\' { _IY->iy_lex_state=INIT;BEGIN(STRSQ); return SQUOTE; }
|
||||||
|
<INIT>{identifier} { clixon_instance_id_parselval.string = strdup(yytext);
|
||||||
|
return IDENTIFIER; }
|
||||||
|
<INIT>{uint} { clixon_instance_id_parselval.string = strdup(yytext);
|
||||||
|
return UINT; }
|
||||||
|
<INIT>. { clixon_instance_id_parseerror(_IY, "LEXICAL ERROR\n"); return -1; }
|
||||||
|
|
||||||
|
<STRDQ>[^\"]+ { clixon_instance_id_parselval.string = strdup(yytext); return STRING; }
|
||||||
|
<STRDQ>\" { BEGIN(_IY->iy_lex_state); return DQUOTE; }
|
||||||
|
|
||||||
|
<STRSQ>[^\']+ { clixon_instance_id_parselval.string = strdup(yytext); return STRING; }
|
||||||
|
<STRSQ>\' { BEGIN(_IY->iy_lex_state); return SQUOTE; }
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
/*! Initialize scanner.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
instance_id_scan_init(struct clicon_instance_id_yacc_arg *iy)
|
||||||
|
{
|
||||||
|
BEGIN(INIT);
|
||||||
|
iy->iy_lexbuf = yy_scan_string(iy->iy_parse_string);
|
||||||
|
#if 1 /* XXX: just to use unput to avoid warning */
|
||||||
|
if (0)
|
||||||
|
yyunput(0, "");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* free buffers
|
||||||
|
* Even within Flex version 2.5 (this is assumed), freeing buffers is different.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
instance_id_scan_exit(struct clicon_instance_id_yacc_arg *iy)
|
||||||
|
{
|
||||||
|
yy_delete_buffer(iy->iy_lexbuf);
|
||||||
|
clixon_instance_id_parselex_destroy(); /* modern */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
380
lib/src/clixon_instance_id_parse.y
Normal file
380
lib/src/clixon_instance_id_parse.y
Normal file
|
|
@ -0,0 +1,380 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2020 Olof Hagsand
|
||||||
|
|
||||||
|
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 *****
|
||||||
|
|
||||||
|
* "instance-id" is a subset of XPath and defined in RF7950 Sections 9.13 and 14.
|
||||||
|
* BNF:
|
||||||
|
* instance-identifier = ("/" (node-identifier [key-predicate+ | leaf-list-predicate | pos]))+
|
||||||
|
* node-identifier = [prefix ":"] identifier
|
||||||
|
* prefix = identifier
|
||||||
|
* key-predicate = "[" key-predicate-expr "]"
|
||||||
|
* key-predicate-expr = node-identifier "=" quoted-string
|
||||||
|
* leaf-list-predicate = "[" leaf-list-predicate-expr "]"
|
||||||
|
* leaf-list-predicate-expr = "." "=" quoted-string
|
||||||
|
* pos = "[" positive-integer-value "]"
|
||||||
|
* quoted-string = (DQUOTE string DQUOTE) / (SQUOTE string SQUOTE)
|
||||||
|
* positive-integer-value = (non-zero-digit DIGIT*)
|
||||||
|
* identifier = (ALPHA | "_")(ALPHA | DIGIT | "_" | "-" | ".")*
|
||||||
|
*/
|
||||||
|
|
||||||
|
%start start
|
||||||
|
|
||||||
|
/* Must be here to define YYSTYPE */
|
||||||
|
%union {
|
||||||
|
char *string;
|
||||||
|
void *stack; /* cv / cvec */
|
||||||
|
}
|
||||||
|
|
||||||
|
%token <string> UINT
|
||||||
|
%token <string> IDENTIFIER
|
||||||
|
%token <string> STRING
|
||||||
|
%token <string> SLASH
|
||||||
|
%token <string> COLON
|
||||||
|
%token <string> EQUAL
|
||||||
|
%token <string> LSQBR
|
||||||
|
%token <string> RSQBR
|
||||||
|
%token <string> DOT
|
||||||
|
%token <string> DQUOTE
|
||||||
|
%token <string> SQUOTE
|
||||||
|
%token <string> X_EOF
|
||||||
|
|
||||||
|
%type <stack> list
|
||||||
|
%type <stack> element
|
||||||
|
%type <stack> node_id
|
||||||
|
%type <string> prefix
|
||||||
|
%type <stack> element2
|
||||||
|
%type <stack> leaf_list_pred
|
||||||
|
%type <stack> leaf_list_pred_expr
|
||||||
|
%type <stack> pos
|
||||||
|
%type <stack> key_preds
|
||||||
|
%type <stack> key_pred
|
||||||
|
%type <stack> key_pred_expr
|
||||||
|
%type <string> node_id_k
|
||||||
|
%type <string> qstring
|
||||||
|
|
||||||
|
%lex-param {void *_iy} /* Add this argument to parse() and lex() function */
|
||||||
|
%parse-param {void *_iy}
|
||||||
|
|
||||||
|
%{
|
||||||
|
/* Here starts user C-code */
|
||||||
|
|
||||||
|
/* typecast macro */
|
||||||
|
#define _IY ((struct clicon_instance_id_yacc_arg *)_iy)
|
||||||
|
|
||||||
|
#define _YYERROR(msg) {clicon_err(OE_XML, 0, "YYERROR %s '%s' %d", (msg), clixon_instance_id_parsetext, _IY->iy_linenum); YYERROR;}
|
||||||
|
|
||||||
|
/* add _yy to error parameters */
|
||||||
|
#define YY_(msgid) msgid
|
||||||
|
|
||||||
|
#include "clixon_config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include <cligen/cligen.h>
|
||||||
|
|
||||||
|
#include "clixon_err.h"
|
||||||
|
#include "clixon_log.h"
|
||||||
|
#include "clixon_queue.h"
|
||||||
|
#include "clixon_string.h"
|
||||||
|
#include "clixon_hash.h"
|
||||||
|
#include "clixon_handle.h"
|
||||||
|
#include "clixon_yang.h"
|
||||||
|
#include "clixon_xml.h"
|
||||||
|
#include "clixon_path.h"
|
||||||
|
#include "clixon_instance_id_parse.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
also called from yacc generated code *
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
clixon_instance_id_parseerror(void *_iy,
|
||||||
|
char *s)
|
||||||
|
{
|
||||||
|
clicon_err(OE_XML, 0, "%s on line %d: %s at or before: '%s'",
|
||||||
|
_IY->iy_name,
|
||||||
|
_IY->iy_linenum ,
|
||||||
|
s,
|
||||||
|
clixon_instance_id_parsetext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
instance_id_parse_init(struct clicon_instance_id_yacc_arg *iy)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
instance_id_parse_exit(struct clicon_instance_id_yacc_arg *iy)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Append new path structure to clixon path list
|
||||||
|
*/
|
||||||
|
static clixon_path *
|
||||||
|
path_append(clixon_path *list,
|
||||||
|
clixon_path *new)
|
||||||
|
{
|
||||||
|
clicon_debug(1, "%s()", __FUNCTION__);
|
||||||
|
if (new == NULL)
|
||||||
|
return NULL;
|
||||||
|
ADDQ(new, list);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Add keyvalue to existing clixon path
|
||||||
|
* If cvk has one integer argument, interpret as position, eg x/y[42]
|
||||||
|
* else as keyvalue strings, eg x/y[k1="foo"][k2="bar"]
|
||||||
|
*/
|
||||||
|
static clixon_path *
|
||||||
|
path_add_keyvalue(clixon_path *cp,
|
||||||
|
cvec *cvk)
|
||||||
|
{
|
||||||
|
clicon_debug(1, "%s()", __FUNCTION__);
|
||||||
|
if (cp == NULL)
|
||||||
|
goto done;
|
||||||
|
cp->cp_cvk = cvk;
|
||||||
|
done:
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static clixon_path *
|
||||||
|
path_new(char *prefix,
|
||||||
|
char *id)
|
||||||
|
{
|
||||||
|
clixon_path *cp = NULL;
|
||||||
|
|
||||||
|
clicon_debug(1, "%s(%s,%s)", __FUNCTION__, prefix, id);
|
||||||
|
if ((cp = malloc(sizeof(*cp))) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "malloc");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
memset(cp, 0, sizeof(*cp));
|
||||||
|
if (prefix)
|
||||||
|
if ((cp->cp_prefix = strdup(prefix)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((cp->cp_id = strdup(id)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
return cp;
|
||||||
|
done:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Create a single key-value positions (int) cv + cvv and return it
|
||||||
|
*/
|
||||||
|
static cvec *
|
||||||
|
keyval_pos(char *uint)
|
||||||
|
{
|
||||||
|
cg_var *cv = NULL;
|
||||||
|
cvec *cvv = NULL;
|
||||||
|
char *reason=NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
clicon_debug(1, "%s(%s)", __FUNCTION__, uint);
|
||||||
|
if ((cvv = cvec_new(1)) == NULL) {
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cv = cvec_i(cvv, 0);
|
||||||
|
if (cv_type_set(cv, CGV_UINT32) < 0){
|
||||||
|
clicon_err(OE_UNIX, errno, "cv_type_set");
|
||||||
|
cvv = NULL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((ret = cv_parse1(uint, cv, &reason)) < 0){
|
||||||
|
clicon_err(OE_UNIX, errno, "cv_parse1");
|
||||||
|
cvv = NULL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (ret == 0){
|
||||||
|
clicon_err(OE_UNIX, errno, "cv_parse1: %s", reason);
|
||||||
|
cvv = NULL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
if (reason)
|
||||||
|
free(reason);
|
||||||
|
return cvv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Append a key-value cv to a cvec, create the cvec if not exist
|
||||||
|
* @param[in] cvv Either created cvv or NULL, in whihc case it is created
|
||||||
|
* @param[in] cv Is consumed by thius function (if appended)
|
||||||
|
* @retval NULL Error
|
||||||
|
* @retval cvv Cvec
|
||||||
|
*/
|
||||||
|
static cvec *
|
||||||
|
keyval_add(cvec *cvv,
|
||||||
|
cg_var *cv)
|
||||||
|
{
|
||||||
|
clicon_debug(1, "%s()", __FUNCTION__);
|
||||||
|
if (cv == NULL)
|
||||||
|
goto done;
|
||||||
|
if (cvv == NULL &&
|
||||||
|
(cvv = cvec_new(0)) == NULL) {
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (cvec_append_var(cvv, cv) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cvec_append_var");
|
||||||
|
cvv = NULL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cv_free(cv);
|
||||||
|
done:
|
||||||
|
return cvv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Create a single key-value as cv and return it
|
||||||
|
*/
|
||||||
|
static cg_var *
|
||||||
|
keyval_set(char *name,
|
||||||
|
char *val)
|
||||||
|
{
|
||||||
|
cg_var *cv = NULL;
|
||||||
|
|
||||||
|
clicon_debug(1, "%s(%s=%s)", __FUNCTION__, name, val);
|
||||||
|
if ((cv = cv_new(CGV_STRING)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cv_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (name && cv_name_set(cv, name) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cv_string_set");
|
||||||
|
cv = NULL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (cv_string_set(cv, val) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cv_string_set");
|
||||||
|
cv = NULL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
return cv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
|
start : list X_EOF { clicon_debug(2,"top"); _IY->iy_top=$1; YYACCEPT; }
|
||||||
|
;
|
||||||
|
|
||||||
|
list : list SLASH element { if (($$ = path_append($1, $3)) == NULL) YYABORT;
|
||||||
|
clicon_debug(2,"list = list / element");}
|
||||||
|
| SLASH element { if (($$ = path_append(NULL, $2)) == NULL) YYABORT;
|
||||||
|
clicon_debug(2,"list = / element");}
|
||||||
|
;
|
||||||
|
|
||||||
|
element : node_id element2 { $$ = path_add_keyvalue($1, $2);
|
||||||
|
clicon_debug(2,"element = node_id element2");}
|
||||||
|
;
|
||||||
|
|
||||||
|
node_id : IDENTIFIER { $$ = path_new(NULL, $1); free($1);
|
||||||
|
clicon_debug(2,"node_id = IDENTIFIER");}
|
||||||
|
| prefix COLON IDENTIFIER { $$ = path_new($1, $3); free($1); free($3);
|
||||||
|
clicon_debug(2,"node_id = prefix : IDENTIFIER");}
|
||||||
|
;
|
||||||
|
|
||||||
|
prefix : IDENTIFIER { $$=$1; clicon_debug(2,"prefix = IDENTIFIER");}
|
||||||
|
|
||||||
|
element2 : key_preds { $$=$1; clicon_debug(2,"element2 = key_preds"); }
|
||||||
|
| leaf_list_pred { $$=$1; clicon_debug(2,"element2 = leaf_list_pred"); }
|
||||||
|
| pos { $$=$1; clicon_debug(2,"element2 = key_preds"); }
|
||||||
|
| { $$=NULL; clicon_debug(2,"element2 = "); }
|
||||||
|
;
|
||||||
|
|
||||||
|
leaf_list_pred : LSQBR leaf_list_pred_expr RSQBR
|
||||||
|
{ if (($$ = keyval_add(NULL, $2)) == NULL) YYABORT;
|
||||||
|
clicon_debug(2,"leaf_list_pred = [ leaf_list_pred_expr ]"); }
|
||||||
|
;
|
||||||
|
|
||||||
|
leaf_list_pred_expr : DOT EQUAL qstring { $$ = keyval_set(".", $3); free($3);
|
||||||
|
clicon_debug(2,"leaf_list_pred_expr = '.=' qstring"); }
|
||||||
|
;
|
||||||
|
|
||||||
|
pos : LSQBR UINT RSQBR { $$ = keyval_pos($2); free($2);
|
||||||
|
clicon_debug(2,"pos = [ UINT ]"); }
|
||||||
|
;
|
||||||
|
|
||||||
|
key_preds : key_preds key_pred { if (($$ = keyval_add($1, $2)) == NULL) YYABORT;
|
||||||
|
clicon_debug(2,"key_preds = key_pred key_preds"); }
|
||||||
|
| key_pred { if (($$ = keyval_add(NULL, $1)) == NULL) YYABORT;
|
||||||
|
clicon_debug(2,"key_preds = key_pred");}
|
||||||
|
;
|
||||||
|
|
||||||
|
key_pred : LSQBR key_pred_expr RSQBR { $$ = $2;
|
||||||
|
clicon_debug(2,"key_pred = [ key_pred_expr ]"); }
|
||||||
|
;
|
||||||
|
|
||||||
|
key_pred_expr : node_id_k EQUAL qstring { $$ = keyval_set($1, $3); free($1);
|
||||||
|
clicon_debug(2,"key_pred_expr = node_id_k = qstring"); }
|
||||||
|
;
|
||||||
|
|
||||||
|
node_id_k : IDENTIFIER { $$ = $1;
|
||||||
|
clicon_debug(2,"node_id_k = IDENTIFIER %s", $1); }
|
||||||
|
| prefix COLON IDENTIFIER { $$ = $3; /* ignore prefix in key? */
|
||||||
|
clicon_debug(2,"node_id_k = prefix %s : IDENTIFIER %s", $1, $3); free($1);}
|
||||||
|
;
|
||||||
|
|
||||||
|
qstring : DQUOTE STRING DQUOTE { $$=$2;
|
||||||
|
clicon_debug(2,"qstring = \" string \""); }
|
||||||
|
| DQUOTE DQUOTE { $$=strdup("");
|
||||||
|
clicon_debug(2,"qstring = \" \""); }
|
||||||
|
| SQUOTE STRING SQUOTE { $$=$2;
|
||||||
|
clicon_debug(2,"qstring = ' string '"); }
|
||||||
|
| SQUOTE SQUOTE { $$=strdup("");
|
||||||
|
clicon_debug(2,"qstring = ''"); }
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue