From 6c21b63190de70898ee4eacd66687d9759242331 Mon Sep 17 00:00:00 2001
From: An-Cheng Huang <ancheng@vyatta.com>
Date: Wed, 17 Nov 2010 19:19:51 -0800
Subject: continue work on parser/output framework

* handle empty and leaf typeless nodes from parsed nodes.
* fix bug 6436 show level issue.
---
 src/cnode/cnode-algorithm.cpp | 17 ++++++++++++++---
 src/cnode/cnode.cpp           | 22 ++++++++++++++++------
 src/cnode/cnode.hpp           |  7 ++++++-
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/src/cnode/cnode-algorithm.cpp b/src/cnode/cnode-algorithm.cpp
index 6926c74..c5a2d54 100644
--- a/src/cnode/cnode-algorithm.cpp
+++ b/src/cnode/cnode-algorithm.cpp
@@ -315,8 +315,10 @@ _diff_show_other(CfgNode *cfg1, CfgNode *cfg2, int level, bool show_def,
     CfgNode *c1 = (in1 ? nmap1[cnodes[i]] : NULL);
     CfgNode *c2 = (in2 ? nmap2[cnodes[i]] : NULL);
 
-    int next_level = ((cfg->isTag() && !cfg->isValue())
-                      ? ((level >= 0) ? level : 0) : (level + 1));
+    int next_level = level + 1;
+    if (!print_this) {
+      next_level = (level >= 0 ? level : 0);
+    }
     _show_diff(c1, c2, next_level, show_def, hide_secret);
   }
 
@@ -331,6 +333,14 @@ static void
 _show_diff(CfgNode *cfg1, CfgNode *cfg2, int level, bool show_def,
            bool hide_secret)
 {
+  // if doesn't exist, treat as NULL
+  if (cfg1 && !cfg1->exists()) {
+    cfg1 = NULL;
+  }
+  if (cfg2 && !cfg2->exists()) {
+    cfg2 = NULL;
+  }
+
   /* cfg1 and cfg2 point to the same config node in two configs. a "diff"
    * output is shown comparing the two configs recursively with this node
    * as the root of the config tree.
@@ -349,7 +359,8 @@ _show_diff(CfgNode *cfg1, CfgNode *cfg2, int level, bool show_def,
     exit(1);
   }
 
-  if (_diff_check_and_show_leaf(cfg1, cfg2, level, show_def, hide_secret)) {
+  if (_diff_check_and_show_leaf(cfg1, cfg2, (level >= 0 ? level : 0),
+                                show_def, hide_secret)) {
     // leaf node has been shown. done.
     return;
   } else {
diff --git a/src/cnode/cnode.cpp b/src/cnode/cnode.cpp
index 05dc07a..697c89b 100644
--- a/src/cnode/cnode.cpp
+++ b/src/cnode/cnode.cpp
@@ -26,16 +26,12 @@
 using namespace std;
 using namespace cnode;
 
-/* XXX
-   delayed processing for _is_empty, _is_leaf_typeless
- */
-
 ////// constructors/destructors
 CfgNode::CfgNode(vector<string>& path_comps, char *name, char *val,
                  char *comment, int deact, Cstore *cstore)
   : _is_tag(false), _is_leaf(false), _is_multi(false), _is_value(false),
     _is_default(false), _is_deactivated(false), _is_leaf_typeless(false),
-    _is_invalid(false), _is_empty(false)
+    _is_invalid(false), _is_empty(true), _exists(true)
 {
   if (name && name[0]) {
     // name must be non-empty
@@ -77,6 +73,14 @@ CfgNode::CfgNode(vector<string>& path_comps, char *name, char *val,
           _value = val;
         }
       }
+
+      vector<string> tcnodes;
+      cstore->tmplGetChildNodes(path_comps, tcnodes);
+      if (tcnodes.size() == 0) {
+        // typeless leaf node
+        _is_leaf_typeless = true;
+      }
+
       if (comment) {
         _comment = comment;
       }
@@ -103,12 +107,18 @@ CfgNode::CfgNode(Cstore& cstore, vector<string>& path_comps,
                  bool active, bool recursive)
   : _is_tag(false), _is_leaf(false), _is_multi(false), _is_value(false),
     _is_default(false), _is_deactivated(false), _is_leaf_typeless(false),
-    _is_invalid(false), _is_empty(false)
+    _is_invalid(false), _is_empty(false), _exists(true)
 {
   /* first get the def (only if path is not empty). if path is empty, i.e.,
    * "root", treat it as an intermediate node.
    */
   if (path_comps.size() > 0) {
+    if (!cstore.cfgPathExists(path_comps, active)) {
+      // path doesn't exist
+      _exists = false;
+      return;
+    }
+
     vtw_def def;
     if (cstore.validateTmplPath(path_comps, false, def)) {
       // got the def
diff --git a/src/cnode/cnode.hpp b/src/cnode/cnode.hpp
index 4d4990b..40fb5b6 100644
--- a/src/cnode/cnode.hpp
+++ b/src/cnode/cnode.hpp
@@ -40,6 +40,7 @@ public:
   bool isLeafTypeless() const { return _is_leaf_typeless; }
   bool isInvalid() const { return _is_invalid; }
   bool isEmpty() const { return _is_empty; }
+  bool exists() const { return _exists; }
 
   const std::string& getName() const { return _name; }
   const std::string& getValue() const { return _value; }
@@ -48,7 +49,10 @@ public:
   const std::vector<CfgNode *>& getChildNodes() const { return _child_nodes; }
 
   void addMultiValue(char *val) { _values.push_back(val); }
-  void addChildNode(CfgNode *cnode) { _child_nodes.push_back(cnode); }
+  void addChildNode(CfgNode *cnode) {
+    _child_nodes.push_back(cnode);
+    _is_empty = false;
+  }
   void setValue(char *val) { _value = val; }
 
 private:
@@ -61,6 +65,7 @@ private:
   bool _is_leaf_typeless;
   bool _is_invalid;
   bool _is_empty;
+  bool _exists;
   std::string _name;
   std::string _value;
   std::vector<std::string> _values;
-- 
cgit v1.2.3