The Battle for Wesnoth  1.15.1+dev
schema_validator.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2018 by Sytyi Nick <nsytyi@gmail.com>
3  Part of the Battle for Wesnoth Project https://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 #pragma once
16 
17 #include "config_cache.hpp"
18 #include "serialization/parser.hpp"
23 
24 #include <iostream>
25 #include <queue>
26 #include <stack>
27 #include <string>
28 
29 class config;
30 
31 /** @file
32  * One of the realizations of serialization/validator.hpp abstract validator.
33  */
34 namespace schema_validation
35 {
36 /**
37  * Realization of serialization/validator.hpp abstract validator.
38  * Based on stack. Uses some stacks to store different info.
39  */
41 {
42 public:
43  virtual ~schema_validator();
44 
45  /**
46  * Initializes validator from file.
47  * Throws abstract_validator::error if any error.
48  */
49  schema_validator(const std::string& filename, bool validate_schema = false);
50 
51  void set_create_exceptions(bool value)
52  {
53  create_exceptions_ = value;
54  }
55 
56  virtual void open_tag(const std::string& name, const config& parent, int start_line = 0, const std::string& file = "", bool addition = false) override;
57  virtual void close_tag() override;
58  virtual void validate(const config& cfg, const std::string& name, int start_line, const std::string& file) override;
59  virtual void validate_key(const config& cfg, const std::string& name, const std::string& value, int start_line, const std::string& file) override;
60 
61 private:
62  // types section
63  // Just some magic to ensure zero initialization.
64  struct counter
65  {
66  int cnt;
68  : cnt(0)
69  {
70  }
71  };
72 
73  /** Counters are mapped by tag name. */
74  typedef std::map<std::string, counter> cnt_map;
75 
76  /** And counter maps are organize in stack. */
77  typedef std::stack<cnt_map> cnt_stack;
78 
79 protected:
81 private:
82  // error_cache
83 
84  /**
85  * Messages are cached.
86  * The reason is next: in file where [tag]...[/tag][+tag]...[/tag]
87  * config object will be validated each [/tag]. So message can be as wrong
88  * (when [+tag] section contains missed elements) as duplicated.
89  *
90  * Messages are mapped by config*. That ensures uniqueness.
91  * Also message-maps are organized in stack to avoid memory leaks.
92  */
93  struct message_info
94  {
96  std::string file;
97  int line;
98  int n;
99  std::string tag;
100  std::string key;
101  std::string value;
102 
103  message_info(message_type t, const std::string& file, int line = 0, int n = 0, const std::string& tag = "", const std::string& key = "", const std::string& value = "")
104  : type(t)
105  , file(file)
106  , line(line)
107  , n(n)
108  , tag(tag)
109  , key(key)
110  , value(value)
111  {
112  }
113  };
114 
115  typedef std::deque<message_info> message_list;
116  typedef std::map<const config*, message_list> message_map;
117 
118  void print(message_info&);
119 
120  /** Reads config from input. */
121  bool read_config_file(const std::string& filename);
122 
123  /** Shows, if validator is initialized with schema file. */
125 
126  /** Controls the way to print errors. */
128 
129  /** Root of schema information. */
131 
132  std::stack<const wml_tag*> stack_;
133 
134  /** Contains number of children. */
135  cnt_stack counter_;
136 
137  /** Caches error messages. */
138  std::stack<message_map> cache_;
139 
140  /** Type validators. */
142 
144 protected:
145  void queue_message(const config& cfg, message_type t, const std::string& file, int line = 0, int n = 0, const std::string& tag = "", const std::string& key = "", const std::string& value = "");
146  const wml_tag& active_tag() const;
147  std::string active_tag_path() const;
148  bool have_active_tag() const;
149  bool is_valid() const {return config_read_;}
150  wml_type::ptr find_type(const std::string& type) const;
151 };
152 
153 // A validator specifically designed for validating a schema
154 // In addition to the usual, it verifies that references within the schema are valid, for example via the [link] tag
156 {
157 public:
159  virtual void open_tag(const std::string& name, const config& parent, int start_line = 0, const std::string& file = "", bool addition = false) override;
160  virtual void close_tag() override;
161  virtual void validate(const config& cfg, const std::string& name, int start_line, const std::string& file) override;
162  virtual void validate_key(const config& cfg, const std::string& name, const std::string& value, int start_line, const std::string& file) override;
163 private:
164  struct reference {
165  reference(const std::string& value, const std::string& file, int line, const std::string& tag)
166  : value_(value)
167  , file_(file)
168  , tag_(tag)
169  , line_(line)
170  {}
171  std::string value_, file_, tag_;
172  int line_;
173  bool match(const std::set<std::string>& with);
174  bool can_find(const wml_tag& root, const config& cfg);
175  bool operator<(const reference& other) const;
176  };
177  std::string current_path() const;
178  std::set<std::string> defined_types_, defined_tag_paths_;
179  std::vector<reference> referenced_types_, referenced_tag_paths_;
180  std::stack<std::string> tag_stack_;
181  std::map<std::string, std::string> links_;
182  std::multimap<std::string, std::string> derivations_;
183  int type_nesting_, condition_nesting_;
184  bool tag_path_exists(const config& cfg, const reference& ref);
185 };
186 
187 } // namespace schema_validation{
std::stack< cnt_map > cnt_stack
And counter maps are organize in stack.
std::stack< const wml_tag * > stack_
bool create_exceptions_
Controls the way to print errors.
message_info(message_type t, const std::string &file, int line=0, int n=0, const std::string &tag="", const std::string &key="", const std::string &value="")
cnt_stack counter_
Contains number of children.
This file contains object "type", which is used to store information about types while annotation par...
std::multimap< std::string, std::string > derivations_
Stores information about tag.
Definition: tag.hpp:46
std::deque< message_info > message_list
This file contains information about validation abstract level interface.
std::map< const config *, message_list > message_map
wml_tag root_
Root of schema information.
std::map< std::string, ptr > map
Definition: type.hpp:41
bool config_read_
Shows, if validator is initialized with schema file.
This file contains object "tag", which is used to store information about tags while annotation parsi...
static const char * name(const std::vector< SDL_Joystick *> &joysticks, const std::size_t index)
Definition: joystick.cpp:48
Used in parsing config file.
Definition: validator.hpp:35
std::stack< message_map > cache_
Caches error messages.
wml_type::map types_
Type validators.
void queue_message(const config &cfg, message_type t, const std::string &file, int line=0, int n=0, const std::string &tag="", const std::string &key="", const std::string &value="")
schema_validator(const std::string &filename, bool validate_schema=false)
Initializes validator from file.
bool read_config_file(const std::string &filename)
Reads config from input.
static bool operator<(const placing_info &a, const placing_info &b)
Definition: game_state.cpp:138
virtual void close_tag() override
As far as parser is built on stack, some realizations can store stack too.
std::shared_ptr< wml_type > ptr
Definition: type.hpp:40
This file contains object "key", which is used to store information about keys while annotation parsi...
double t
Definition: astarsearch.cpp:64
virtual void open_tag(const std::string &name, const config &parent, int start_line=0, const std::string &file="", bool addition=false) override
Is called when parser opens tag.
static const char * match(MatchState *ms, const char *s, const char *p)
Definition: lstrlib.cpp:425
Realization of serialization/validator.hpp abstract validator.
wml_type::ptr find_type(const std::string &type) const
std::map< std::string, counter > cnt_map
Counters are mapped by tag name.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:92
reference(const std::string &value, const std::string &file, int line, const std::string &tag)
virtual void validate_key(const config &cfg, const std::string &name, const std::string &value, int start_line, const std::string &file) override
Checks if key is allowed and if its value is valid What exactly is validated depends on validator rea...
static map_location::DIRECTION n
virtual void validate(const config &cfg, const std::string &name, int start_line, const std::string &file) override
Validates config.
std::map< std::string, std::string > links_