/*
* Copyright (C) 2011 Vyatta, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef _CTEMPLATE_H_
#define _CTEMPLATE_H_
#include
#include
namespace cstore { // begin namespace cstore
class Ctemplate {
public:
Ctemplate(std::tr1::shared_ptr def)
: _def(def), _is_value(false) {};
~Ctemplate() {};
bool isValue() const { return _is_value; };
bool isMulti() const { return _def->multi; };
bool isTag() const { return _def->tag; };
bool isTagNode() const { return (isTag() && !isValue()); };
bool isTagValue() const { return (isTag() && isValue()); };
bool isLeafValue() const { return (!isTag() && isValue()); };
bool isTypeless(size_t tnum = 1) const {
/* note: the current "multi-type" implementation only supports two types.
* the interface here is generalized so it can support more in the
* future.
*
* isTypeless(i) implies isTypeless(j) for all (j > i).
* therefore, isTypeless() means the node has no types at all
* and is equivalent to isTypeless(1).
*
* originally, some "users" of vtw_def checks both is_value and
* def_type for typeless nodes. this should not be necessary so
* here we only check def_type.
*/
return ((tnum == 1) ? (_def->def_type == ERROR_TYPE)
: (_def->def_type2 == ERROR_TYPE));
};
bool isSingleLeafNode() const {
return (!isValue() && !isMulti() && !isTag() && !isTypeless());
};
bool isSingleLeafValue() const {
// assume isValue implies !isTypeless
return (isValue() && !isMulti() && !isTag());
};
bool isMultiLeafNode() const {
// assume isMulti implies !isTag && !isTypeless
return (!isValue() && isMulti());
};
bool isMultiLeafValue() const {
// assume isMulti implies !isTag && !isTypeless
return (isValue() && isMulti());
};
size_t getNumTypes() const {
return (isTypeless(1) ? 0 : (isTypeless(2) ? 1 : 2));
};
vtw_type_e getType(size_t tnum = 1) const {
return ((tnum == 1) ? _def->def_type : _def->def_type2);
};
const char *getTypeName(size_t tnum = 1) const {
return type_to_name(getType(tnum));
};
const char *getDefault() const { return _def->def_default; };
const char *getNodeHelp() const { return _def->def_node_help; };
const char *getEnumeration() const { return _def->def_enumeration; };
const char *getAllowed() const { return _def->def_allowed; };
const vtw_node *getActions(vtw_act_type act) const {
return _def->actions[act].vtw_list_head;
};
const char *getCompHelp() const { return _def->def_comp_help; };
const char *getValHelp() const { return _def->def_val_help; };
unsigned int getTagLimit() const { return _def->def_tag; };
unsigned int getMultiLimit() const { return _def->def_multi; };
unsigned int getPriority() const { return _def->def_priority; };
void setIsValue(bool is_val) { _is_value = is_val; };
void setPriority(unsigned int p) const {
/* this changes the parsed template and is only used during commit IF the
* priority specified in the template violates the "hierarchical
* constraint" and therefore needs to be changed.
*/
_def->def_priority = p;
}
const vtw_def *getDef() const {
/* XXX this is a hack for code that has not been converted and is still
* using vtw_def directly. this should go away once the transition
* is completed.
*/
return _def.get();
};
private:
/* XXX ideally, template should be parsed directly into this class instead
* of wrapping the vtw_def struct in here. however, the legacy code
* (e.g., commit and code used by commit) still requires vtw_def, so
* need to keep it around for now until the transition is completed.
*
* note that the use of shared_ptr deals with the memory of the vtw_def
* struct *itself*. however, various members of vtw_def are allocated
* dynamically by the parser and were never freed before, i.e., they
* have always been leaked since the beginning. such leaks are not going
* to be fixed by the shared_ptr use here.
*
* once the transition is completed, vtw_def can be eliminated, and
* template data should be stored directly in this class using more
* suitable containers so that memory allocation/deallocation can be
* handled properly.
*/
std::tr1::shared_ptr _def;
bool _is_value; /* whether the last path component is a "value". set by
* the cstore in get_parsed_tmpl().
*/
};
} // end namespace cstore
#endif /* _CTEMPLATE_H_ */