summaryrefslogtreecommitdiff
path: root/src/cstore/ctemplate.hpp
blob: 96c47b58f7e8aa1063a57baef06a6cc7c8576b4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * 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 <http://www.gnu.org/licenses/>.
 */

#ifndef _CTEMPLATE_H_
#define _CTEMPLATE_H_

#include <tr1/memory>

#include <cli_cstore.h>

namespace cstore { // begin namespace cstore

class Ctemplate {
public:
  Ctemplate(std::tr1::shared_ptr<vtw_def> 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<vtw_def> _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_ */