summaryrefslogtreecommitdiff
path: root/src/cparse
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2010-11-12 19:12:53 -0800
committerAn-Cheng Huang <ancheng@vyatta.com>2010-11-12 19:12:53 -0800
commit79a94470b0f3fd4f7924bb096c61b8e064b65750 (patch)
tree049225edbd21f873b9a4bcac6571603a35aa1e89 /src/cparse
parente08c1879028ddd3b594b01c82859f8431894f497 (diff)
downloadvyatta-cfg-79a94470b0f3fd4f7924bb096c61b8e064b65750.tar.gz
vyatta-cfg-79a94470b0f3fd4f7924bb096c61b8e064b65750.zip
initial work to parse config file into data structure.
Diffstat (limited to 'src/cparse')
-rw-r--r--src/cparse/cparse.hpp5
-rw-r--r--src/cparse/cparse.ypp117
-rw-r--r--src/cparse/cparse_lex.l24
3 files changed, 121 insertions, 25 deletions
diff --git a/src/cparse/cparse.hpp b/src/cparse/cparse.hpp
index 478af7b..0729416 100644
--- a/src/cparse/cparse.hpp
+++ b/src/cparse/cparse.hpp
@@ -17,9 +17,12 @@
#ifndef _CPARSE_HPP_
#define _CPARSE_HPP_
+#include <cstore/cstore.hpp>
+#include <cnode/cnode.hpp>
+
namespace cparse {
-int parse_file(FILE *fin);
+int parse_file(FILE *fin, Cstore& cs);
} // namespace cparse
diff --git a/src/cparse/cparse.ypp b/src/cparse/cparse.ypp
index eb2ab12..193077a 100644
--- a/src/cparse/cparse.ypp
+++ b/src/cparse/cparse.ypp
@@ -1,9 +1,16 @@
%{
#include <cstdio>
+#include <vector>
+#include <string>
+#include <cstore/cstore.hpp>
+#include <cnode/cnode.hpp>
#include "cparse.hpp"
#include "cparse_def.h"
+using namespace std;
+using namespace cnode;
+
// stuff from lex
extern "C" {
extern int cparse_lineno;
@@ -19,33 +26,86 @@ cparse_error(const char *s)
s, cparse_lineno, cparse_text);
}
-int level = 0;
-int ndeact = 0;
-char *ncomment = NULL;
-char *nname = NULL;
-char *nval = NULL;
+static int ndeact = 0;
+static char *ncomment = NULL;
+static char *nname = NULL;
+static char *nval = NULL;
+
+static Cstore *cstore = NULL;
+static CfgNode *cur_node = NULL;
+static CfgNode *cur_parent = NULL;
+static CfgNode *prev_sibling = NULL;
+static vector<CfgNode *> cur_path;
+static vector<string> pcomps;
+static vector<bool> pcomp_is_value;
static void
-print_node()
+print_path()
{
- int i = 0;
- if (ncomment) {
- for (i = 0; i <= level; i++) {
- printf(" ");
+ printf("[%p,%p] p[", cur_parent, cur_node);
+ for (size_t i = 0; i < pcomps.size(); i++) {
+ if (i > 0) {
+ printf(",");
}
- printf(" /*%s*/\n", ncomment);
- }
- printf("%s", ndeact ? "!" : " ");
- for (i = 0; i <= level; i++) {
- printf(" ");
+ printf("%s", pcomps[i].c_str());
}
- printf("%s", nname);
+ printf("] n[%s]", nname);
if (nval) {
- printf(" '%s'", nval);
+ printf(" v[%s]", nval);
+ }
+ if (ncomment) {
+ printf(" c[%s]", ncomment);
+ }
+ if (ndeact) {
+ printf(" D");
}
printf("\n");
}
+static void
+add_node()
+{
+ if (prev_sibling && nval
+ && prev_sibling->isValue() && prev_sibling->isMulti()
+ && prev_sibling->getName() == nname) {
+ prev_sibling->addMultiValue(nval);
+ } else {
+ cur_node = new CfgNode(pcomps, nname, nval, ncomment, ndeact, cstore);
+ cur_parent->addChildNode(cur_node);
+ prev_sibling = cur_node;
+ }
+}
+
+static void
+go_down()
+{
+ cur_path.push_back(cur_parent);
+ cur_parent = cur_node;
+ prev_sibling = NULL;
+
+ pcomps.push_back(nname);
+ pcomp_is_value.push_back(false);
+ if (nval) {
+ pcomps.push_back(nval);
+ pcomp_is_value.push_back(true);
+ }
+}
+
+static void
+go_up()
+{
+ cur_parent = cur_path.back();
+ cur_path.pop_back();
+ prev_sibling = NULL;
+
+ if (pcomp_is_value.back()) {
+ pcomps.pop_back();
+ pcomp_is_value.pop_back();
+ }
+ pcomps.pop_back();
+ pcomp_is_value.pop_back();
+}
+
%}
%token NODE
@@ -62,15 +122,27 @@ input: forest
;
forest: /* empty */
- | forest tree
+ | forest {
+ if (!cur_parent) {
+ // root node
+ cur_parent = new CfgNode(pcomps, nname, nval, ncomment,
+ ndeact, cstore);
+ }
+ } tree
;
tree: node {
- print_node();
+ add_node();
+ print_path();
}
| node {
- print_node();
- } LEFTB { ++level; } forest RIGHTB { --level; }
+ add_node();
+ print_path();
+ } LEFTB {
+ go_down();
+ } forest RIGHTB {
+ go_up();
+ }
;
node: nodec {
@@ -100,9 +172,10 @@ comment: COMMENT
%%
int
-cparse::parse_file(FILE *fin)
+cparse::parse_file(FILE *fin, Cstore& cs)
{
cparse_set_in(fin);
+ cstore = &cs;
return cparse_parse();
}
diff --git a/src/cparse/cparse_lex.l b/src/cparse/cparse_lex.l
index 167e2af..1afe886 100644
--- a/src/cparse/cparse_lex.l
+++ b/src/cparse/cparse_lex.l
@@ -9,6 +9,9 @@ ID ([-[:alnum:]_]+)
SPACE ([[:space:]]{-}[\n])
%{
+/* get rid of compiler warning */
+#define YY_NO_INPUT 1
+
#include <string.h>
#include "cparse_def.h"
#include "cparse.h"
@@ -80,8 +83,21 @@ set_ret_str()
}
<sComment>"*/" {
+ char *tmp;
+ size_t tlen;
set_ret_str();
- cparse_lval.str = strdup(out_buf);
+
+ /* need to strip out leading or trailing space */
+ tmp = out_buf;
+ tlen = strlen(tmp);
+ if (tlen > 0 && tmp[tlen - 1] == ' ') {
+ tmp[tlen - 1] = 0;
+ --tlen;
+ }
+ if (tlen > 0 && tmp[0] == ' ') {
+ ++tmp;
+ }
+ cparse_lval.str = strdup(tmp);
BEGIN(INITIAL);
return COMMENT;
}
@@ -90,7 +106,11 @@ set_ret_str()
node_deactivated = 1;
}
-<INITIAL>[[:space:]]+ {
+<INITIAL>{SPACE}+ {
+}
+
+<INITIAL>\n {
+ ++cparse_lineno;
}
<INITIAL>\} {