AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
anonymous_namespace{Config.cpp} Namespace Reference

Functions

bool IsAppConfig (std::string_view fileName)
 
bool IsLoggingSystemOptions (std::string_view optionName)
 
template<typename Format , typename... Args>
void PrintError (std::string_view filename, Format &&fmt, Args &&... args)
 
void AddKey (std::string const &optionName, std::string const &optionKey, std::string_view fileName, bool isOptional, bool isReload)
 
bool ParseFile (std::string const &file, bool isOptional, bool isReload)
 
bool LoadFile (std::string const &file, bool isOptional, bool isReload)
 
std::string IniKeyToEnvVarKey (std::string const &key)
 
Optional< std::string > EnvVarForIniKey (std::string const &key)
 

Variables

std::string _filename
 
std::vector< std::string > _additonalFiles
 
std::vector< std::string > _args
 
std::unordered_map< std::string, std::string > _configOptions
 
std::mutex _configLock
 

Function Documentation

◆ AddKey()

void anonymous_namespace{Config.cpp}::AddKey ( std::string const &  optionName,
std::string const &  optionKey,
std::string_view  fileName,
bool  isOptional,
bool  isReload 
)
71 {
72 auto const& itr = _configOptions.find(optionName);
73
74 // Check old option
75 if (isOptional && itr == _configOptions.end())
76 {
77 if (!IsLoggingSystemOptions(optionName) && !isReload)
78 {
79 PrintError(fileName, "> Config::LoadFile: Found incorrect option '{}' in config file '{}'. Skip", optionName, fileName);
80
81#ifdef CONFIG_ABORT_INCORRECT_OPTIONS
82 ABORT("> Core can't start if found incorrect options");
83#endif
84
85 return;
86 }
87 }
88
89 // Check exit option
90 if (itr != _configOptions.end())
91 {
92 _configOptions.erase(optionName);
93 }
94
95 _configOptions.emplace(optionName, optionKey);
96 }
#define ABORT
Definition: Errors.h:76
void PrintError(std::string_view filename, Format &&fmt, Args &&... args)
Definition: Config.cpp:56
std::unordered_map< std::string, std::string > _configOptions
Definition: Config.cpp:34
bool IsLoggingSystemOptions(std::string_view optionName)
Definition: Config.cpp:47

References _configOptions, ABORT, IsLoggingSystemOptions(), and PrintError().

Referenced by ParseFile().

◆ EnvVarForIniKey()

Optional< std::string > anonymous_namespace{Config.cpp}::EnvVarForIniKey ( std::string const &  key)
286 {
287 std::string envKey = "AC_" + IniKeyToEnvVarKey(key);
288 char* val = std::getenv(envKey.c_str());
289 if (!val)
290 return std::nullopt;
291
292 return std::string(val);
293 }
std::string IniKeyToEnvVarKey(std::string const &key)
Definition: Config.cpp:225

References IniKeyToEnvVarKey().

Referenced by ConfigMgr::GetValueDefault< std::string >().

◆ IniKeyToEnvVarKey()

std::string anonymous_namespace{Config.cpp}::IniKeyToEnvVarKey ( std::string const &  key)
226 {
227 std::string result;
228
229 const char* str = key.c_str();
230 size_t n = key.length();
231
232 char curr;
233 bool isEnd;
234 bool nextIsUpper;
235 bool currIsNumeric;
236 bool nextIsNumeric;
237
238 for (size_t i = 0; i < n; ++i)
239 {
240 curr = str[i];
241 if (curr == ' ' || curr == '.' || curr == '-')
242 {
243 result += '_';
244 continue;
245 }
246
247 isEnd = i == n - 1;
248 if (!isEnd)
249 {
250 nextIsUpper = isupper(str[i + 1]);
251
252 // handle "aB" to "A_B"
253 if (!isupper(curr) && nextIsUpper)
254 {
255 result += static_cast<char>(std::toupper(curr));
256 result += '_';
257 continue;
258 }
259
260 currIsNumeric = isNumeric(curr);
261 nextIsNumeric = isNumeric(str[i + 1]);
262
263 // handle "a1" to "a_1"
264 if (!currIsNumeric && nextIsNumeric)
265 {
266 result += static_cast<char>(std::toupper(curr));
267 result += '_';
268 continue;
269 }
270
271 // handle "1a" to "1_a"
272 if (currIsNumeric && !nextIsNumeric)
273 {
274 result += static_cast<char>(std::toupper(curr));
275 result += '_';
276 continue;
277 }
278 }
279
280 result += static_cast<char>(std::toupper(curr));
281 }
282 return result;
283 }
bool isNumeric(wchar_t wchar)
Definition: Util.h:204

References isNumeric().

Referenced by EnvVarForIniKey().

◆ IsAppConfig()

bool anonymous_namespace{Config.cpp}::IsAppConfig ( std::string_view  fileName)
39 {
40 size_t foundAuth = fileName.find("authserver.conf");
41 size_t foundWorld = fileName.find("worldserver.conf");
42
43 return foundAuth != std::string_view::npos || foundWorld != std::string_view::npos;
44 }

Referenced by PrintError().

◆ IsLoggingSystemOptions()

bool anonymous_namespace{Config.cpp}::IsLoggingSystemOptions ( std::string_view  optionName)
48 {
49 size_t foundAppender = optionName.find("Appender.");
50 size_t foundLogger = optionName.find("Logger.");
51
52 return foundAppender != std::string_view::npos || foundLogger != std::string_view::npos;
53 }

Referenced by AddKey().

◆ LoadFile()

bool anonymous_namespace{Config.cpp}::LoadFile ( std::string const &  file,
bool  isOptional,
bool  isReload 
)
207 {
208 try
209 {
210 return ParseFile(file, isOptional, isReload);
211 }
212 catch (const std::exception& e)
213 {
214 PrintError(file, "> {}", e.what());
215 }
216
217 return false;
218 }
bool ParseFile(std::string const &file, bool isOptional, bool isReload)
Definition: Config.cpp:98

References ParseFile(), and PrintError().

◆ ParseFile()

bool anonymous_namespace{Config.cpp}::ParseFile ( std::string const &  file,
bool  isOptional,
bool  isReload 
)
99 {
100 std::ifstream in(file);
101
102 if (in.fail())
103 {
104 if (isOptional)
105 {
106 // No display erorr if file optional
107 return false;
108 }
109
110 throw ConfigException(Acore::StringFormatFmt("Config::LoadFile: Failed open {}file '{}'", isOptional ? "optional " : "", file));
111 }
112
113 uint32 count = 0;
114 uint32 lineNumber = 0;
115 std::unordered_map<std::string /*name*/, std::string /*value*/> fileConfigs;
116
117 auto IsDuplicateOption = [&](std::string const& confOption)
118 {
119 auto const& itr = fileConfigs.find(confOption);
120 if (itr != fileConfigs.end())
121 {
122 PrintError(file, "> Config::LoadFile: Dublicate key name '{}' in config file '{}'", confOption, file);
123 return true;
124 }
125
126 return false;
127 };
128
129 while (in.good())
130 {
131 lineNumber++;
132 std::string line;
133 std::getline(in, line);
134
135 // read line error
136 if (!in.good() && !in.eof())
137 {
138 throw ConfigException(Acore::StringFormatFmt("> Config::LoadFile: Failure to read line number {} in file '{}'", lineNumber, file));
139 }
140
141 // remove whitespace in line
142 line = Acore::String::Trim(line, in.getloc());
143
144 if (line.empty())
145 {
146 continue;
147 }
148
149 // comments
150 if (line[0] == '#' || line[0] == '[')
151 {
152 continue;
153 }
154
155 size_t found = line.find_first_of('#');
156 if (found != std::string::npos)
157 {
158 line = line.substr(0, found);
159 }
160
161 auto const equal_pos = line.find('=');
162
163 if (equal_pos == std::string::npos || equal_pos == line.length())
164 {
165 PrintError(file, "> Config::LoadFile: Failure to read line number {} in file '{}'. Skip this line", lineNumber, file);
166 continue;
167 }
168
169 auto entry = Acore::String::Trim(line.substr(0, equal_pos), in.getloc());
170 auto value = Acore::String::Trim(line.substr(equal_pos + 1, std::string::npos), in.getloc());
171
172 value.erase(std::remove(value.begin(), value.end(), '"'), value.end());
173
174 // Skip if 2+ same options in one config file
175 if (IsDuplicateOption(entry))
176 {
177 continue;
178 }
179
180 // Add to temp container
181 fileConfigs.emplace(entry, value);
182 count++;
183 }
184
185 // No lines read
186 if (!count)
187 {
188 if (isOptional)
189 {
190 // No display erorr if file optional
191 return false;
192 }
193
194 throw ConfigException(Acore::StringFormatFmt("Config::LoadFile: Empty file '{}'", file));
195 }
196
197 // Add correct keys if file load without errors
198 for (auto const& [entry, key] : fileConfigs)
199 {
200 AddKey(entry, key, file, isOptional, isReload);
201 }
202
203 return true;
204 }
std::uint32_t uint32
Definition: Define.h:108
std::string StringFormatFmt(std::string_view fmt, Args &&... args)
Definition: StringFormat.h:44
void AddKey(std::string const &optionName, std::string const &optionKey, std::string_view fileName, bool isOptional, bool isReload)
Definition: Config.cpp:70
AC_COMMON_API Str Trim(const Str &s, const std::locale &loc=std::locale())
Definition: StringFormat.cpp:23
Definition: Config.h:90

References AddKey(), PrintError(), Acore::StringFormatFmt(), and Acore::String::Trim().

Referenced by LoadFile().

◆ PrintError()

template<typename Format , typename... Args>
void anonymous_namespace{Config.cpp}::PrintError ( std::string_view  filename,
Format &&  fmt,
Args &&...  args 
)
inline
57 {
58 std::string message = Acore::StringFormatFmt(std::forward<Format>(fmt), std::forward<Args>(args)...);
59
60 if (IsAppConfig(filename))
61 {
62 fmt::print("{}\n", message);
63 }
64 else
65 {
66 LOG_ERROR("server.loading", message);
67 }
68 }
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
bool IsAppConfig(std::string_view fileName)
Definition: Config.cpp:38

References IsAppConfig(), LOG_ERROR, and Acore::StringFormatFmt().

Referenced by AddKey(), LoadFile(), and ParseFile().

Variable Documentation

◆ _additonalFiles

std::vector<std::string> anonymous_namespace{Config.cpp}::_additonalFiles

◆ _args

std::vector<std::string> anonymous_namespace{Config.cpp}::_args

◆ _configLock

std::mutex anonymous_namespace{Config.cpp}::_configLock

◆ _configOptions

std::unordered_map<std::string , std::string > anonymous_namespace{Config.cpp}::_configOptions

◆ _filename

std::string anonymous_namespace{Config.cpp}::_filename