The Battle for Wesnoth  1.15.2+dev
parser.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by Iris Morelle <shadowm2006@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 #include "storyscreen/parser.hpp"
16 
17 #include "game_data.hpp"
19 #include "game_events/pump.hpp"
20 #include "log.hpp"
21 #include "resources.hpp"
22 #include "variable.hpp"
23 #include "deprecation.hpp"
24 #include "game_version.hpp"
25 
26 namespace storyscreen
27 {
28 
30 {
31  // Execution flow/branching/[image]
32  for(vconfig::all_children_iterator i = cfg.ordered_begin(); i != cfg.ordered_end(); ++i) {
33  // i->first and i->second are goddamn temporaries; do not make references
34  const std::string key = i->first;
35  const vconfig node = i->second;
36 
37  // Execute any special actions derived classes provide.
38  if(resolve_wml_helper(key, node)) {
39  continue;
40  }
41 
42  // [if]
43  if(key == "if") {
44  // check if the [if] tag has a [then] child;
45  // if we try to execute a non-existing [then], we get a segfault
47  if(node.has_child("then")) {
48  resolve_wml(node.child("then"));
49  }
50  }
51  // condition not passed, check [elseif] and [else]
52  else {
53  // get all [elseif] children and set a flag
54  vconfig::child_list elseif_children = node.get_children("elseif");
55  bool elseif_flag = false;
56  // for each [elseif]: test if it has a [then] child
57  // if the condition matches, execute [then] and raise flag
58  for(const auto& elseif : elseif_children) {
60  if(elseif.has_child("then")) {
61  resolve_wml(elseif.child("then"));
62  }
63 
64  elseif_flag = true;
65  break;
66  }
67  }
68 
69  // if we have an [else] tag and no [elseif] was successful (flag not raised), execute it
70  if(node.has_child("else") && !elseif_flag) {
71  resolve_wml(node.child("else"));
72  }
73  }
74  }
75  // [switch]
76  else if(key == "switch") {
77  const std::string var_name = node["variable"];
78  const std::string var_actual_value = resources::gamedata->get_variable_const(var_name);
79  bool case_not_found = true;
80 
81  for(vconfig::all_children_iterator j = node.ordered_begin(); j != node.ordered_end(); ++j) {
82  if(j->first != "case") {
83  continue;
84  }
85 
86  // Enter all matching cases.
87  const std::string var_expected_value = (j->second)["value"];
88  if(var_actual_value == var_expected_value) {
89  case_not_found = false;
90  resolve_wml(j->second);
91  }
92  }
93 
94  if(case_not_found) {
95  for(vconfig::all_children_iterator j = node.ordered_begin(); j != node.ordered_end(); ++j) {
96  if(j->first != "else") {
97  continue;
98  }
99 
100  // Enter all elses.
101  resolve_wml(j->second);
102  }
103  }
104  }
105  // [deprecated_message]
106  else if(key == "deprecated_message") {
107  // Won't appear until the scenario start event finishes.
108  DEP_LEVEL level = DEP_LEVEL(node["level"].to_int(2));
109  deprecated_message(node["what"], level, node["version"].str(), node["message"]);
110  }
111  // [wml_message]
112  else if(key == "wml_message") {
113  // As with [deprecated_message],
114  // it won't appear until the scenario start event is complete.
116  node["logger"], node["message"], node["in_chat"].to_bool(false));
117  }
118  }
119 }
120 
121 } // namespace storyscreen
vconfig child(const std::string &key) const
Returns a child of *this whose key is key.
Definition: variable.cpp:252
Interfaces for manipulating version numbers of engine, add-ons, etc.
all_children_iterator ordered_begin() const
In-order iteration over all children.
Definition: variable.cpp:445
virtual void resolve_wml(const vconfig &cfg)
Takes care of initializing and branching properties.
Definition: parser.cpp:29
game_data * gamedata
Definition: resources.cpp:22
child_list get_children(const std::string &key) const
Definition: variable.cpp:190
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
Definition: deprecation.cpp:29
all_children_iterator ordered_end() const
Definition: variable.cpp:450
virtual bool resolve_wml_helper(const std::string &key, const vconfig &node)=0
May be implemented by derived classes to perform additional actions When executing resolve_wml...
game_events::manager * game_events
Definition: resources.cpp:24
Define conditionals for the game&#39;s events mechanism, a.k.a.
std::size_t i
Definition: function.cpp:933
void put_wml_message(const std::string &logger, const std::string &message, bool in_chat)
Helper function which determines whether a wml_message text can really be pushed into the wml_message...
Definition: pump.cpp:473
bool has_child(const std::string &key) const
Returns whether or not *this has a child whose key is key.
Definition: variable.cpp:279
Define the game&#39;s event mechanism.
bool conditional_passed(const vconfig &cond)
virtual config::attribute_value get_variable_const(const std::string &varname) const
returns a blank attribute value if varname is no valid variable name.
Definition: game_data.cpp:67
DEP_LEVEL
See https://wiki.wesnoth.org/CompatibilityStandards for more info.
Definition: deprecation.hpp:19
A variable-expanding proxy for the config class.
Definition: variable.hpp:42
Standard logging facilities (interface).
game_events::wml_event_pump & pump()
Definition: manager.cpp:229
std::vector< vconfig > child_list
Definition: variable.hpp:78