diff options
author | An-Cheng Huang <ancheng@vyatta.com> | 2010-11-15 20:43:53 -0800 |
---|---|---|
committer | An-Cheng Huang <ancheng@vyatta.com> | 2010-11-15 20:43:53 -0800 |
commit | 239bed10328b12736e4f0fe55cc6df4ff46227a7 (patch) | |
tree | fa38a97d8d82a60ba66e7d4d6953e01213df7f58 | |
parent | 58ca1cd7f857b8cde91c063ccdda1b661c29e278 (diff) | |
download | vyatta-cfg-239bed10328b12736e4f0fe55cc6df4ff46227a7.tar.gz vyatta-cfg-239bed10328b12736e4f0fe55cc6df4ff46227a7.zip |
continue config file parser work
-rw-r--r-- | src/cnode/cnode-algorithm.cpp | 2 | ||||
-rw-r--r-- | src/cnode/cnode.cpp | 5 | ||||
-rw-r--r-- | src/cnode/cnode.hpp | 1 | ||||
-rw-r--r-- | src/cparse/cparse.hpp | 2 | ||||
-rw-r--r-- | src/cparse/cparse.ypp | 63 |
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; } |