summaryrefslogtreecommitdiff
path: root/src/cnode
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2011-04-15 13:58:20 -0700
committerAn-Cheng Huang <ancheng@vyatta.com>2011-04-15 13:58:20 -0700
commit74b730a5a95abadba47bd05e816ed8c93abe9ca2 (patch)
tree4e7b3d790121d2637d807080988cc9cd080f7d2f /src/cnode
parent53f4203e924f9f98347f962408fec532e0a1849f (diff)
downloadvyatta-cfg-74b730a5a95abadba47bd05e816ed8c93abe9ca2.tar.gz
vyatta-cfg-74b730a5a95abadba47bd05e816ed8c93abe9ca2.zip
initial implementation of "config file" shell API
* this API allows shell scripts to "query" the "config" represented by a config file in a way similar to how they query the active/working config.
Diffstat (limited to 'src/cnode')
-rw-r--r--src/cnode/cnode-algorithm.cpp115
-rw-r--r--src/cnode/cnode-algorithm.hpp6
2 files changed, 121 insertions, 0 deletions
diff --git a/src/cnode/cnode-algorithm.cpp b/src/cnode/cnode-algorithm.cpp
index 602d9fb..607d5d2 100644
--- a/src/cnode/cnode-algorithm.cpp
+++ b/src/cnode/cnode-algorithm.cpp
@@ -946,3 +946,118 @@ cnode::showConfig(const string& cfg1, const string& cfg2,
}
}
+/* find and return pointer to the CfgNode corresponding to specified path in
+ * the tree rooted at root. return NULL if not found.
+ *
+ * if path ends in value, the actual "node" (i.e., at path minus value)
+ * is returned *if* the value actually exists (in which case is_value is
+ * set to true). otherwise return NULL.
+ */
+CfgNode *
+cnode::findCfgNode(CfgNode *root, const Cpath& path, bool& is_value)
+{
+ is_value = false;
+ if (path.size() < 1) {
+ return NULL;
+ }
+
+ CfgNode *node = root;
+ for (size_t i = 0; i < path.size(); i++) {
+ if (node->isLeaf()) {
+ // reached a leaf node
+ if (i != (path.size() - 1)) {
+ // there's more after the current comp => can't exist
+ return NULL;
+ }
+
+ // look for value
+ if (node->isMulti()) {
+ // multi-value
+ const vector<string>& vals = node->getValues();
+ for (size_t j = 0; j < vals.size(); j++) {
+ if (vals[j] == path[i]) {
+ is_value = true;
+ return node;
+ }
+ }
+ return NULL;
+ } else {
+ // single-value
+ if (node->getValue() == path[i]) {
+ is_value = true;
+ return node;
+ }
+ return NULL;
+ }
+ }
+
+ const vector<CfgNode *>& cnodes = node->getChildNodes();
+ bool found = false;
+ for (size_t j = 0; j < cnodes.size(); j++) {
+ if (cnodes[j]->isValue()) {
+ // tag value
+ found = (cnodes[j]->getValue() == path[i]);
+ } else {
+ // others
+ found = (cnodes[j]->getName() == path[i]);
+ }
+ if (found) {
+ node = cnodes[j];
+ break;
+ }
+ }
+ if (!found) {
+ return NULL;
+ }
+ }
+
+ return node;
+}
+
+// wrapper for above
+CfgNode *
+cnode::findCfgNode(CfgNode *root, const Cpath& path)
+{
+ bool dummy;
+ return findCfgNode(root, path, dummy);
+}
+
+bool
+cnode::getCfgNodeValue(CfgNode *root, const Cpath& path, string& value)
+{
+ bool is_val;
+ CfgNode *node = findCfgNode(root, path, is_val);
+ if (!node) {
+ // doesn't exist
+ return false;
+ }
+ if (is_val || !node->isLeaf() || node->isMulti()) {
+ // invalid path (already value, non-leaf, or multi-value)
+ fprintf(stderr, "Invalid path used with cnode::getCfgNodeValue()\n");
+ return false;
+ }
+
+ value = node->getValue();
+ return true;
+}
+
+bool
+cnode::getCfgNodeValues(CfgNode *root, const Cpath& path,
+ vector<string>& values)
+{
+ bool is_val;
+ CfgNode *node = findCfgNode(root, path, is_val);
+ if (!node) {
+ // doesn't exist
+ return false;
+ }
+ if (is_val || !node->isLeaf() || !node->isMulti()) {
+ // invalid path (already value, non-leaf, or single-value)
+ fprintf(stderr, "Invalid path used with cnode::getCfgNodeValues()\n");
+ return false;
+ }
+
+ values = node->getValues();
+ return true;
+}
+
diff --git a/src/cnode/cnode-algorithm.hpp b/src/cnode/cnode-algorithm.hpp
index 3985b9f..547b55c 100644
--- a/src/cnode/cnode-algorithm.hpp
+++ b/src/cnode/cnode-algorithm.hpp
@@ -44,6 +44,12 @@ void showConfig(const string& cfg1, const string& cfg2,
bool hide_secret = false, bool context_diff = false,
bool show_cmds = false, bool ignore_edit = false);
+CfgNode *findCfgNode(CfgNode *root, const Cpath& path, bool& is_value);
+CfgNode *findCfgNode(CfgNode *root, const Cpath& path);
+bool getCfgNodeValue(CfgNode *root, const Cpath& path, string& value);
+bool getCfgNodeValues(CfgNode *root, const Cpath& path,
+ vector<string>& values);
+
} // namespace cnode
#endif /* _CNODE_ALGORITHM_HPP_ */