summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2010-11-15 20:43:53 -0800
committerAn-Cheng Huang <ancheng@vyatta.com>2010-11-15 20:43:53 -0800
commit239bed10328b12736e4f0fe55cc6df4ff46227a7 (patch)
treefa38a97d8d82a60ba66e7d4d6953e01213df7f58 /src
parent58ca1cd7f857b8cde91c063ccdda1b661c29e278 (diff)
downloadvyatta-cfg-239bed10328b12736e4f0fe55cc6df4ff46227a7.tar.gz
vyatta-cfg-239bed10328b12736e4f0fe55cc6df4ff46227a7.zip
continue config file parser work
Diffstat (limited to 'src')
-rw-r--r--src/cnode/cnode-algorithm.cpp2
-rw-r--r--src/cnode/cnode.cpp5
-rw-r--r--src/cnode/cnode.hpp1
-rw-r--r--src/cparse/cparse.hpp2
-rw-r--r--src/cparse/cparse.ypp63
5 files changed, 58 insertions, 15 deletions
diff --git a/src/cnode/cnode-algorithm.cpp b/src/cnode/cnode-algorithm.cpp
index c830ce4..6926c74 100644
--- a/src/cnode/cnode-algorithm.cpp
+++ b/src/cnode/cnode-algorithm.cpp
@@ -164,9 +164,9 @@ _diff_check_and_show_leaf(CfgNode *cfg1, CfgNode *cfg2, int level,
}
}
+ _diff_print_comment(cfg1, cfg2, level);
if (cfg->isMulti()) {
// multi-value node
- _diff_print_comment(cfg1, cfg2, level);
if (force_pfx_diff) {
// simple case: just use the same diff prefix for all values
const vector<string>& vvec = cfg->getValues();
diff --git a/src/cnode/cnode.cpp b/src/cnode/cnode.cpp
index 0f6976d..05dc07a 100644
--- a/src/cnode/cnode.cpp
+++ b/src/cnode/cnode.cpp
@@ -27,7 +27,6 @@ using namespace std;
using namespace cnode;
/* XXX
- from cstore: extra level for tag node
delayed processing for _is_empty, _is_leaf_typeless
*/
@@ -56,9 +55,11 @@ CfgNode::CfgNode(vector<string>& path_comps, char *name, char *val,
vtw_def def;
if (cstore->validateTmplPath(path_comps, false, def)) {
// got the def
- _is_value = def.is_value;
_is_tag = def.tag;
_is_leaf = (!def.tag && def.def_type != ERROR_TYPE);
+
+ // match constructor from cstore (leaf node never _is_value)
+ _is_value = (def.is_value && !_is_leaf);
_is_multi = def.multi;
/* XXX given the current definition of "default", the concept of
diff --git a/src/cnode/cnode.hpp b/src/cnode/cnode.hpp
index aab2d4d..4d4990b 100644
--- a/src/cnode/cnode.hpp
+++ b/src/cnode/cnode.hpp
@@ -49,6 +49,7 @@ public:
void addMultiValue(char *val) { _values.push_back(val); }
void addChildNode(CfgNode *cnode) { _child_nodes.push_back(cnode); }
+ void setValue(char *val) { _value = val; }
private:
bool _is_tag;
diff --git a/src/cparse/cparse.hpp b/src/cparse/cparse.hpp
index 0729416..5751d64 100644
--- a/src/cparse/cparse.hpp
+++ b/src/cparse/cparse.hpp
@@ -22,7 +22,7 @@
namespace cparse {
-int parse_file(FILE *fin, Cstore& cs);
+cnode::CfgNode *parse_file(FILE *fin, Cstore& cs);
} // namespace cparse
diff --git a/src/cparse/cparse.ypp b/src/cparse/cparse.ypp
index 193077a..ed37932 100644
--- a/src/cparse/cparse.ypp
+++ b/src/cparse/cparse.ypp
@@ -1,6 +1,7 @@
%{
#include <cstdio>
#include <vector>
+#include <map>
#include <string>
#include <cstore/cstore.hpp>
@@ -31,10 +32,11 @@ static char *ncomment = NULL;
static char *nname = NULL;
static char *nval = NULL;
+// XXX optimize: use unordered_map with non-vector
+static map<vector<string>, CfgNode *> node_map;
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;
@@ -65,14 +67,47 @@ print_path()
static void
add_node()
{
- if (prev_sibling && nval
- && prev_sibling->isValue() && prev_sibling->isMulti()
- && prev_sibling->getName() == nname) {
- prev_sibling->addMultiValue(nval);
+ pcomps.push_back(nname);
+ CfgNode *onode = NULL;
+ if (node_map.find(pcomps) != node_map.end()) {
+ onode = node_map[pcomps];
+ }
+ pcomps.pop_back();
+ if (onode) {
+ if (nval) {
+ if (onode->isMulti()) {
+ // a new value for a "multi node"
+ onode->addMultiValue(nval);
+ cur_node = onode;
+ } else if (onode->isTag()) {
+ // a new value for a "tag node"
+ cur_node = new CfgNode(pcomps, nname, nval, ncomment, ndeact, cstore);
+ onode->addChildNode(cur_node);
+ } else {
+ /* a new value for a single-value node => invalid?
+ * for now, use the newer value.
+ */
+ cur_node = onode;
+ cur_node->setValue(nval);
+ }
+ } else {
+ // existing intermediate node => move current node pointer
+ cur_node = onode;
+ }
} else {
+ // new node
cur_node = new CfgNode(pcomps, nname, nval, ncomment, ndeact, cstore);
- cur_parent->addChildNode(cur_node);
- prev_sibling = cur_node;
+ CfgNode *mapped_node = cur_node;
+ if (cur_node->isTag() && cur_node->isValue()) {
+ // tag value => need to add the "tag node" on top
+ CfgNode *p = new CfgNode(pcomps, nname, NULL, NULL, ndeact, cstore);
+ p->addChildNode(cur_node);
+ mapped_node = p;
+ }
+ cur_parent->addChildNode(mapped_node);
+ pcomps.push_back(nname);
+ node_map[pcomps] = mapped_node;
+ pcomps.pop_back();
}
}
@@ -81,7 +116,6 @@ 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);
@@ -96,7 +130,6 @@ go_up()
{
cur_parent = cur_path.back();
cur_path.pop_back();
- prev_sibling = NULL;
if (pcomp_is_value.back()) {
pcomps.pop_back();
@@ -171,11 +204,19 @@ comment: COMMENT
%%
-int
+CfgNode *
cparse::parse_file(FILE *fin, Cstore& cs)
{
cparse_set_in(fin);
cstore = &cs;
- return cparse_parse();
+ if (cparse_parse() != 0) {
+ // parsing failed
+ return NULL;
+ }
+ if (cur_path.size() > 0) {
+ // didn't return to top-level => invalid
+ return NULL;
+ }
+ return cur_parent;
}