Project Alice
Loading...
Searching...
No Matches
defines.cpp
Go to the documentation of this file.
1#include <string>
2#include <string_view>
3#include <stdlib.h>
4#include <ctype.h>
5#include "defines.hpp"
6#include "parsers.hpp"
7#include "system_state.hpp"
8
9void parsing::defines::assign_define(sys::state& state, int32_t line, std::string_view text, float v,
11 if(text.empty())
12 return;
13 if(parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "ai")
14 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "economy")
15 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "military")
16 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "diplomacy")
17 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "defines")
18 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "alice")
19 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "pops")
20 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "country")
21 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "graphics")
22 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "{")
23 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "}")
24 || parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), "},"))
25 return;
26
27#define LUA_DEFINES_LIST_ELEMENT(key, const_value) \
28 if(parsers::is_fixed_token_ci(text.data(), text.data() + text.length(), #key)) { key = v; return; }
30#undef LUA_DEFINES_LIST_ELEMENT
31 err.accumulated_errors += "Unknown define key " + std::string(text) + " (" + err.file_name + ", line " + std::to_string(line) + ")\n";
32}
33
34void parsing::defines::parse_line(sys::state& state, int32_t line, std::string_view data, parsers::error_handler& err) {
35 char const* start = data.data();
36 char const* end = data.data() + data.length();
37 char const* position = start;
38
39 for(; position < end && isspace(*position); ++position)
40 ;
41 auto first_non_ws = position;
42
43 for(; position < end && !isspace(*position) && *position != '='; ++position) // advances to end of identifier
44 ;
45
46 auto identifier_end = position;
47
48 for(; position < end && *position != '='; ++position) // advances to equal sign
49 ;
50 ++position; // advances past equality
51 for(; position < end && isspace(*position); ++position) // advances to next identifier
52 ;
53
54 auto value_start = position;
55 for(; position < end && !isspace(*position) && *position != ','; ++position) // advances to next identifier
56 ;
57
58 auto value_end = position;
59
60 if(parsers::is_fixed_token_ci(first_non_ws, identifier_end, "start_date")) {
61 position = value_start;
62
63 for(; position < value_end && !isdigit(*position); ++position) // advance to year
64 ;
65 auto year_start = position;
66 for(; position < value_end && isdigit(*position); ++position) // advance to year end
67 ;
68 auto year_end = position;
69
70 for(; position < value_end && !isdigit(*position); ++position) // advance to month
71 ;
72 auto month_start = position;
73 for(; position < value_end && isdigit(*position); ++position) // advance to month end
74 ;
75 auto month_end = position;
76
77 for(; position < value_end && !isdigit(*position); ++position) // advance to day
78 ;
79 auto day_start = position;
80 for(; position < value_end && isdigit(*position); ++position) // advance to day end
81 ;
82 auto day_end = position;
83
84 state.start_date = sys::absolute_time_point(
85 sys::year_month_day{parsers::parse_int(std::string_view(year_start, year_end - year_start), line, err),
86 uint16_t(parsers::parse_uint(std::string_view(month_start, month_end - month_start), line, err)),
87 uint16_t(parsers::parse_uint(std::string_view(day_start, day_end - day_start), line, err))});
88 } else if(parsers::is_fixed_token_ci(first_non_ws, identifier_end, "end_date")) {
89 position = value_start;
90
91 for(; position < value_end && !isdigit(*position); ++position) // advance to year
92 ;
93 auto year_start = position;
94 for(; position < value_end && isdigit(*position); ++position) // advance to year end
95 ;
96 auto year_end = position;
97
98 for(; position < value_end && !isdigit(*position); ++position) // advance to month
99 ;
100 auto month_start = position;
101 for(; position < value_end && isdigit(*position); ++position) // advance to month end
102 ;
103 auto month_end = position;
104
105 for(; position < value_end && !isdigit(*position); ++position) // advance to day
106 ;
107 auto day_start = position;
108 for(; position < value_end && isdigit(*position); ++position) // advance to day end
109 ;
110 auto day_end = position;
111
112 state.end_date = sys::absolute_time_point(
113 sys::year_month_day{parsers::parse_int(std::string_view(year_start, year_end - year_start), line, err),
114 uint16_t(parsers::parse_uint(std::string_view(month_start, month_end - month_start), line, err)),
115 uint16_t(parsers::parse_uint(std::string_view(day_start, day_end - day_start), line, err))});
116 } else {
117 auto const value = parsers::parse_float(std::string_view(value_start, value_end - value_start), line, err);
118 assign_define(state, line, std::string_view(first_non_ws, identifier_end - first_non_ws), value, err);
119 }
120}
121
122void parsing::defines::parse_file(sys::state& state, std::string_view data, parsers::error_handler& err) {
123 auto const remove_comments = [](std::string_view text) -> std::string_view {
124 auto end_it = text.end();
125 for(auto it = text.begin(); it != text.end(); it++) {
126 if(it != text.end() && (it + 1) != text.end() && it[0] == '-' && it[1] == '-') {
127 end_it = it;
128 break;
129 }
130 }
131 return text.substr(0, std::distance(text.begin(), end_it));
132 };
133
134 auto start_it = data.begin();
135 auto line_num = 1;
136 for(auto it = data.begin(); it != data.end(); it++) {
137 if(*it == '\n') {
138 auto const line_text = data.substr(std::distance(data.begin(), start_it), std::distance(start_it, it));
139 parse_line(state, line_num, remove_comments(line_text), err);
140 start_it = it + 1;
141 line_num++;
142 }
143 }
144
145 /* Fixups and nudges */
146 state.defines.investment_score_factor *= 0.05f;
147 state.defines.base_truce_months = std::max(0.f, state.defines.base_truce_months); //some mods try to be funny
148}
std::string accumulated_errors
Definition: parsers.hpp:62
std::string file_name
Definition: parsers.hpp:61
#define LUA_DEFINES_LIST
Definition: defines.hpp:6
bool is_fixed_token_ci(char const *start, char const *end, char const (&t)[N])
Definition: parsers.hpp:275
int32_t parse_int(std::string_view content, int32_t line, error_handler &err)
Definition: parsers.cpp:226
float parse_float(std::string_view content, int32_t line, error_handler &err)
Definition: parsers.cpp:208
uint32_t parse_uint(std::string_view content, int32_t line, error_handler &err)
Definition: parsers.cpp:235
Definition: bmfont.cpp:118
void parse_file(sys::state &state, std::string_view data, parsers::error_handler &err)
Definition: defines.cpp:122
void parse_line(sys::state &state, int32_t line, std::string_view data, parsers::error_handler &err)
Definition: defines.cpp:34
LUA_DEFINES_LIST void assign_define(sys::state &state, int32_t line, std::string_view key, float v, parsers::error_handler &err)
Definition: defines.cpp:9