The Battle for Wesnoth  1.17.21+dev
wml_exception.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2007 - 2023
3  by Mark de Wever <koraq@xs4all.nl>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * @file
18  * Add a special kind of assert to validate whether the input from WML
19  * doesn't contain any problems that might crash the game.
20  */
21 
22 #pragma once
23 
25 
26 #include <string>
27 
28 /**
29  * The macro to use for the validation of WML
30  *
31  * @param cond The condition to test, if false and exception is generated.
32  * @param message The translatable message to show at the user.
33  */
34 #ifndef __func__
35  #ifdef __FUNCTION__
36  #define __func__ __FUNCTION__
37  #endif
38 #endif
39 
40 #define VALIDATE(cond, message) \
41  do { \
42  if(!(cond)) { \
43  throw_wml_exception(#cond, __FILE__, __LINE__, __func__, message); \
44  } \
45  } while(false)
46 
47 #define VALIDATE_WML_CHILD(cfg, key, message) \
48  ([](auto c, auto k) { \
49  if(auto child = c.optional_child(k)) { return *child; } \
50  throw_wml_exception( "Missing [" key "]", __FILE__, __LINE__, __func__, message); \
51  })(cfg, key) \
52 
53 #define VALIDATE_WITH_DEV_MESSAGE(cond, message, dev_message) \
54  do { \
55  if(!(cond)) { \
56  throw_wml_exception(#cond \
57  , __FILE__ \
58  , __LINE__ \
59  , __func__ \
60  , message \
61  , dev_message); \
62  } \
63  } while(false)
64 
65 #define FAIL(message) \
66  do { \
67  throw_wml_exception(nullptr, __FILE__, __LINE__, __func__, message); \
68  } while(false)
69 
70 #define FAIL_WITH_DEV_MESSAGE(message, dev_message) \
71  do { \
72  throw_wml_exception(nullptr \
73  , __FILE__ \
74  , __LINE__ \
75  , __func__ \
76  , message \
77  , dev_message); \
78  } while(false)
79 
80 /**
81  * Helper function, don't call this directly.
82  *
83  * @param cond The textual presentation of the test that failed.
84  * @param file The file in which the test failed.
85  * @param line The line at which the test failed.
86  * @param function The function in which the test failed.
87  * @param message The translated message to show the user.
88  * @param dev_message Any additional information that might be useful to a developer.
89  */
90 [[noreturn]] void throw_wml_exception(
91  const char* cond
92  , const char* file
93  , int line
94  , const char *function
95  , const std::string& message
96  , const std::string& dev_message = "");
97 
98 /** Helper class, don't construct this directly. */
100  : public lua_jailbreak_exception
101 {
102  wml_exception(const std::string& user_msg, const std::string& dev_msg)
103  : user_message(user_msg)
104  , dev_message(dev_msg)
105  {
106  }
107 
108  ~wml_exception() noexcept {}
109 
110  /**
111  * The message for the user explaining what went wrong. This message can
112  * be translated so the user gets a explanation in his/her native tongue.
113  */
114  std::string user_message;
115 
116  /**
117  * The message for developers telling which problem was triggered, this
118  * shouldn't be translated. It's hard for a dev to parse errors in
119  * foreign tongues.
120  */
121  std::string dev_message;
122 
123  /**
124  * Shows the error in a dialog.
125  */
126  void show() const;
127 private:
129 };
130 
131 /**
132  * Returns a standard message for a missing wml key.
133  *
134  * @param section The section is which the key should appear
135  * (this should include the section brackets).
136  * It may contain parent sections to make it
137  * easier to find the wanted sections. They are
138  * listed like [parent][child][section].
139  * @param key The omitted key.
140  * @param primary_key The primary key of the section.
141  * @param primary_value The value of the primary key (mandatory if
142  * primary key isn't empty).
143  *
144  * @returns The error message.
145  */
146 std::string missing_mandatory_wml_key(
147  const std::string& section
148  , const std::string& key
149  , const std::string& primary_key = ""
150  , const std::string& primary_value = "");
Base class for exceptions that want to be thrown 'through' lua.
#define IMPLEMENT_LUA_JAILBREAK_EXCEPTION(type)
Helper macro for classes deriving from lua_jailbreak_exception.
void line(int from_x, int from_y, int to_x, int to_y)
Draw a line.
Definition: draw.cpp:171
Helper class, don't construct this directly.
wml_exception(const std::string &user_msg, const std::string &dev_msg)
void show() const
Shows the error in a dialog.
std::string dev_message
The message for developers telling which problem was triggered, this shouldn't be translated.
std::string user_message
The message for the user explaining what went wrong.
~wml_exception() noexcept
std::string missing_mandatory_wml_key(const std::string &section, const std::string &key, const std::string &primary_key="", const std::string &primary_value="")
Returns a standard message for a missing wml key.
void throw_wml_exception(const char *cond, const char *file, int line, const char *function, const std::string &message, const std::string &dev_message="")
Helper function, don't call this directly.