The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tag.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2016 by Sytyi Nick <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Implementation of tag.hpp.
18  */
19 
20 #include "tools/schema/tag.hpp"
21 
22 #include "config.hpp"
23 
24 namespace schema_validation{
25 
26 /*WIKI
27  * @begin{parent}{name="wml_schema/tag/"}
28  * @begin{tag}{name="key"}{min=0}{max=-1}
29  * @begin{table}{config}
30  * name & string & & The name of key. $
31  * type & string & & The type of key value. $
32  * default & string & & The default value of the key. $
33  * mandatory & string & & Shows if key is mandatory $
34  * @end{table}
35  * @end{tag}{name="key"}
36  * @end{parent}{name="wml_schema/tag/"}
37  */
38 
40  : name_(cfg["name"].str())
41  , type_(cfg["type"].str())
42  , default_()
43  , mandatory_(false)
44  {
45  if (cfg.has_attribute("mandatory")){
46  mandatory_ = cfg["mandatory"].to_bool();
47  }else{
48  if (cfg.has_attribute("default")){
49  default_= cfg["default"].str();
50  }
51  }
52  }
53 void class_key::print(std::ostream& os,int level) const {
54  std::string s;
55  for (int j=0;j<level;j++){
56  s.append(" ");
57  }
58  os << s << "[key]\n"
59  << s << " name=\""<< name_ <<"\"\n"
60  << s << " type=\""<< type_ <<"\"\n";
61  if (is_mandatory()){
62  os << s << " mandatory=\"true\"\n";
63  }else{
64  os << s <<" default="<< default_ <<"\n";
65  }
66  os << s << "[/key]\n";
67 }
69  : name_(cfg["name"].str())
70  , min_(cfg["min"].to_int())
71  , max_(cfg["max"].to_int())
72  , super_("")
73  , tags_()
74  , keys_()
75  , links_()
76 {
77  if (max_ < 0){
78  max_ = INT_MAX;
79  }
80  if (cfg.has_attribute("super")){
81  super_ = cfg["super"].str();
82  }
83  for (const config &child : cfg.child_range("tag")) {
84  class_tag child_tag (child);
85  add_tag(child_tag);
86  }
87  for (const config &child : cfg.child_range("key")) {
88  class_key child_key (child);
89  add_key(child_key);
90  }
91  for (const config &link : cfg.child_range("link")) {
92  std::string link_name = link["name"].str();
93  add_link(link_name);
94  }
95 }
96 
97 void class_tag::print(std::ostream& os){
98  printl(os,4,4);
99 }
100 
102  std::string::size_type pos_last = link.rfind('/');
103  //if (pos_last == std::string::npos) return;
104  std::string name_link = link.substr(pos_last+1,link.length());
105  links_.insert(std::pair<std::string,std::string>(name_link,link));
106 }
107 
109  key_map::const_iterator it_keys = keys_.find(name);
110  if ( it_keys!= keys_.end() ){
111  return &(it_keys->second);
112  }
113  return nullptr;
114 }
115 
117  link_map::const_iterator it_links = links_.find(name);
118  if ( it_links!= links_.end() ){
119  return &(it_links->second);
120  }
121  return nullptr;
122 }
123 
124 const class_tag * class_tag::find_tag(const std::string &fullpath,
125  const class_tag &root) const{
126  if (fullpath.empty()) return nullptr;
127  std::string::size_type pos = fullpath.find('/');
129  std::string next_path;
130  if (pos != std::string::npos) {
131  name = fullpath.substr(0,pos);
132  next_path = fullpath.substr(pos+1,fullpath.length());
133  }else{
134  name = fullpath;
135  }
136  tag_map::const_iterator it_tags = tags_.find(name);
137  if (it_tags != tags_.end()){
138  if (next_path.empty()){
139  return &(it_tags->second);
140  }else{
141  return it_tags->second.find_tag(next_path,root);
142  }
143  }
144  link_map::const_iterator it_links = links_.find(name);
145  if (it_links != links_.end()){
146  return root.find_tag(it_links->second + "/" +next_path,root);
147  }
148  return nullptr;
149 
150  }
151 
153  for (tag_map::iterator i = tags_.begin(); i!= tags_.end(); ++i){
154  i->second.expand(root);
155  i->second.expand_all(root);
156  }
157 }
159  key_iterator i= keys_.begin ();
160  while(i != keys_.end()) {
161  if(i->second.get_type() == type) {
162  keys_.erase(i++);
163  } else {
164  ++i;
165  }
166  }
167  for (tag_iterator t = tags_.begin(); t!=tags_.end();++t){
168  t->second.remove_keys_by_type(type);
169  }
170 }
171 
172 /*WIKI
173  * @begin{parent}{name="wml_schema/"}
174  * @begin{tag}{name="tag"}{min=0}{max=1}
175  * @begin{table}{config}
176  * name & string & & The name of tag. $
177  * min & int & & The min number of occurences. $
178  * max & int & & The max number of occurences. $
179  * super & string & "" & The super-tag of this tag $
180  * @end{table}
181  * @begin{tag}{name="link"}{min=0}{max=-1}
182  * @begin{table}{config}
183  * name & string & & The name of link. $
184  * @end{table}
185  * @end{tag}{name="link"}
186  * @begin{tag}{name="tag"}{min=0}{max=-1}{super="wml_schema/tag"}
187  * @end{tag}{name="tag"}
188  * @end{tag}{name="tag"}
189  * @begin{tag}{name="type"}{min=0}{max=-1}
190  * @begin{table}{config}
191  * name & string & & The name of type. $
192  * value & string & & The value of the type, regex. $
193  * @end{table}
194  * @end{tag}{name="type"}
195  * @end{parent}{name="wml_schema/"}
196  */
197 void class_tag::printl(std::ostream &os,int level, int step){
198 
199  std::string s;
200  for (int j=0;j<level;j++){
201  s.append(" ");
202  }
203  os << s << "[tag]\n"
204  << s <<" name=\""<< name_ <<"\"\n"
205  << s <<" min=\""<< min_ <<"\"\n"
206  << s <<" max=\""<< max_ <<"\"\n";
207  if (! super_.empty() ){
208  os<< s <<" super=\""<< super_ <<"\"\n";
209  }
210  for (tag_map::iterator i = tags_.begin();
211  i != tags_.end(); ++i ){
212  i->second.printl(os,level+step,step);
213  }
214  for (link_map::iterator i = links_.begin();
215  i != links_.end(); ++i ){
216  os << s << "" << "[link]\n"
217  << s << "" << " name=\"" <<i->second << "\"\n"
218  << s << "" << "[/link]\n";
219  }
220  for (key_map::iterator i = keys_.begin();
221  i != keys_.end(); ++i ){
222  i->second.print(os,level+step);
223  }
224  os<< s << "[/tag]\n";
225 }
226 
228  class_tag &root) {
229  if (fullpath.empty()) return nullptr;
230  std::string::size_type pos = fullpath.find('/');
232  std::string next_path;
233  if (pos != std::string::npos) {
234  name = fullpath.substr(0,pos);
235  next_path = fullpath.substr(pos+1,fullpath.length());
236  }else{
237  name = fullpath;
238  }
239 
240  tag_map::iterator it_tags = tags_.find(name);
241  if (it_tags != tags_.end()){
242  if (next_path.empty()){
243  return &(it_tags->second);
244  }else{
245  return it_tags->second.find_tag(next_path,root);
246  }
247  }
248  link_map::iterator it_links = links_.find(name);
249  if (it_links != links_.end()){
250  return root.find_tag(it_links->second +"/" +next_path,root);
251  }
252  return nullptr;
253 
254  }
255 // class_tag & class_tag::operator= (class_tag const& t){
256 // if (&t != this){
257 // name_ = t.name_;
258 // min_ = t.min_;
259 // max_ = t.max_;
260 // super_ = t.super_;
261 // tags_ = t.tags_;
262 // keys_ = t.keys_;
263 // links_ = t.links_;
264 // }
265 // return *this;
266 // }
267 
269  class_tag &root){
270  if ( path.empty() || path == "/" ){
271  tag_map::iterator it = tags_.find(tag.name_);
272  if (it == tags_.end()){
273  tags_.insert(tag_map_value(tag.name_,tag));
274  }else{
275  it->second.set_min(tag.min_);
276  it->second.set_max(tag.max_);
277  it->second.add_tags(tag.tags_);
278  it->second.add_keys(tag.keys_);
279  it->second.add_links(tag.links_);
280  }
281  links_.erase (tag.get_name ());
282  return ;
283  }
284  std::string::size_type pos = path.find('/');
285  std::string name = path.substr(0,pos);
286  std::string next_path = path.substr(pos+1,path.length());
287 
288  link_map::const_iterator it_links= links_.find(name);
289  if (it_links != links_.end()){
290  root.add_tag(it_links->second + "/" + next_path,tag,root);
291  }
292  tag_map::iterator it_tags = tags_.find(name);
293  if (it_tags == tags_.end()){
294  class_tag subtag;
295  subtag.set_name(name);
296  subtag.add_tag(next_path,tag,root);
297  tags_.insert(tag_map_value(name,subtag));
298  return;
299  }
300  it_tags->second.add_tag(next_path,tag,root);
301 }
302 
304  add_keys(tag.keys_);
305  add_links(tag.links_);
306  for (tag_map::const_iterator i = tag.tags_.begin();i!=tag.tags_.end();++i){
307  links_.erase(i->first);
308  add_link(path + "/" + i->first);
309 
310  }
311 }
312 
314  if (! super_.empty()){
315  class_tag * super_tag = root.find_tag(super_,root);
316  if (super_tag){
317  if (super_tag != this){
318  super_tag->expand(root);
319  append_super(*super_tag,super_);
320  super_.clear();
321  }else{
322  std::cerr << "the same" << super_tag->name_ <<"\n";
323  }
324  }
325  }
326 }
327 }//namespace schema_generator
void remove_keys_by_type(const std::string &type)
Removes all keys with this type.
Definition: tag.cpp:158
child_itors child_range(const std::string &key)
Definition: config.cpp:613
bool is_mandatory() const
Definition: tag.hpp:61
std::string name_
Name of key.
Definition: tag.hpp:99
void expand(class_tag &root)
Expands all "super" copying their data to this.
Definition: tag.cpp:313
const class_tag * find_tag(const std::string &fullpath, const class_tag &root) const
Returns pointer to tag using full path to it.
Definition: tag.cpp:124
const class_key * find_key(const std::string &name) const
Returns pointer to child key.
Definition: tag.cpp:108
std::pair< std::string, class_tag > tag_map_value
Definition: tag.hpp:119
GLint level
Definition: glew.h:1220
int pos
Definition: formula.cpp:800
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
const std::string * find_link(const std::string &name) const
Returns pointer to child link.
Definition: tag.cpp:116
int max_
number of maximum occasions
Definition: tag.hpp:309
tag_map::iterator tag_iterator
Definition: tag.hpp:134
void add_key(const class_key &new_key)
Definition: tag.hpp:229
const std::string & get_name() const
Definition: tag.hpp:189
void append_super(const class_tag &tag, const std::string &super)
Copies tags, keys and links of tag to this.
Definition: tag.cpp:303
int min_
number of minimum occasions
Definition: tag.hpp:307
std::string default_
Default value.
Definition: tag.hpp:103
void set_name(const std::string &name)
Definition: tag.hpp:205
std::string type_
Type of key.
Definition: tag.hpp:101
GLdouble GLdouble t
Definition: glew.h:1366
Definitions for the interface to Wesnoth Markup Language (WML).
class_key is used to save the information about one key.
Definition: tag.hpp:37
void print(std::ostream &os, int level) const
is used to print key info the format is next [key] name="name" type="type" default="default" mandator...
Definition: tag.cpp:53
This file contains objects "tag" and "key", which are used to store information about tags and keys w...
void expand_all(class_tag &root)
Calls the expansion on each child.
Definition: tag.cpp:152
std::string super_
name of tag to extend "super-tag" Extension is smth like inheritance and is used in case when you nee...
Definition: tag.hpp:317
GLsizei const char ** path
Definition: glew.h:4654
void add_keys(const key_map &list)
Definition: tag.hpp:342
void printl(std::ostream &os, int level, int step=4)
the same as class_tag::print(std::ostream&) but indents different levels with step space...
Definition: tag.cpp:197
void add_links(const link_map &list)
Definition: tag.hpp:345
void add_link(const std::string &link)
Definition: tag.cpp:101
size_t i
Definition: function.cpp:1057
link_map links_
links to possible children.
Definition: tag.hpp:323
tag_map tags_
children tags
Definition: tag.hpp:319
GLuint const GLchar * name
Definition: glew.h:1782
void add_tag(const class_tag &new_tag)
Definition: tag.hpp:232
bool has_attribute(const std::string &key) const
Definition: config.cpp:514
std::string name_
name of tag
Definition: tag.hpp:305
bool mandatory_
Shows, if key is a mandatory key.
Definition: tag.hpp:105
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
key_map::iterator key_iterator
Definition: tag.hpp:127
GLdouble s
Definition: glew.h:1358
GLsizei const GLcharARB ** string
Definition: glew.h:4503
Stores information about tag.
Definition: tag.hpp:116
void print(std::ostream &os)
Prints information about tag to outputstream, recursively is used to print tag info the format is nex...
Definition: tag.cpp:97