Line |
Branch |
Exec |
Source |
1 |
|
|
#pragma once |
2 |
|
|
|
3 |
|
|
#define ALL_ERRORS(ERR) \ |
4 |
|
|
ERR(limit_reached, "Over %d errors detected. Aborting.") \ |
5 |
|
|
ERR(werror, "One or more warnings was detected with werror on.") \ |
6 |
|
|
ERR(buffer_too_small, "The given buffer is too small to contain the resulting ROM.") \ |
7 |
|
|
ERR(params_null, "params passed to asar_patch_ex() is null.") \ |
8 |
|
|
ERR(params_invalid_size, "Size of params passed to asar_patch_ex() is invalid.") \ |
9 |
|
|
ERR(cmdl_define_invalid, "Invalid define name in %s: '%s'.") \ |
10 |
|
|
ERR(cmdl_define_override, "%s '%s' overrides a previous define. Did you specify the same define twice?") \ |
11 |
|
|
ERR(create_rom_failed, "Couldn't create ROM.") \ |
12 |
|
|
ERR(open_rom_failed, "Couldn't open ROM.") \ |
13 |
|
|
ERR(open_rom_not_smw_extension, "Doesn't look like an SMW ROM. (Maybe its extension is wrong?)") \ |
14 |
|
|
ERR(open_rom_not_smw_header, "Doesn't look like an SMW ROM. (Maybe it's headered?)") \ |
15 |
|
|
ERR(stddefines_no_identifier, "stddefines.txt contains a line with a value, but no identifier.") \ |
16 |
|
|
ERR(stddefine_after_closing_quote, "Broken std defines. (Something after closing quote)") \ |
17 |
|
|
ERR(failed_to_open_file, "Failed to open file '%s'.") \ |
18 |
|
|
ERR(file_not_found, "File '%s' wasn't found.") \ |
19 |
|
|
ERR(file_offset_out_of_bounds, "File offset %s out of bounds for file '%s'.") \ |
20 |
|
|
ERR(mismatched_parentheses, "Mismatched parentheses.") \ |
21 |
|
|
ERR(invalid_hex_value, "Invalid hex value.") \ |
22 |
|
|
ERR(invalid_binary_value, "Invalid binary value.") \ |
23 |
|
|
ERR(invalid_character, "Invalid character.") \ |
24 |
|
|
ERR(string_literal_not_terminated, "String literal not terminated.") \ |
25 |
|
|
ERR(malformed_function_call, "Malformed function call.") \ |
26 |
|
|
ERR(invalid_number, "Invalid number.") \ |
27 |
|
|
ERR(garbage_near_quoted_string, "Garbage near quoted string.") \ |
28 |
|
|
ERR(mismatched_quotes, "Mismatched quotes.") \ |
29 |
|
|
ERR(rom_too_short, "ROM is too short to have a title. (Expected '%s')") \ |
30 |
|
|
ERR(rom_title_incorrect, "ROM title is incorrect. Expected '%s', got '%s'.") \ |
31 |
|
|
ERR(bank_border_crossed, "A bank border was crossed, SNES address $%06X.") \ |
32 |
|
|
ERR(start_of_file, "This command may only be used at the start of a file.") \ |
33 |
|
|
ERR(invalid_version_number, "Invalid version number.") \ |
34 |
|
|
ERR(asar_too_old, "This version of Asar is too old for this patch.") \ |
35 |
|
|
ERR(relative_branch_out_of_bounds, "Relative branch out of bounds. (Distance is %s).") \ |
36 |
|
|
ERR(snes_address_doesnt_map_to_rom, "SNES address %s doesn't map to ROM.") \ |
37 |
|
|
ERR(snes_address_out_of_bounds, "SNES address %s out of bounds.") \ |
38 |
|
|
ERR(invalid_tcall, "Invalid tcall.") \ |
39 |
|
|
ERR(use_xplus, "Use (x+) instead.") \ |
40 |
|
|
ERR(opcode_length_too_long, "Opcode length is too long.") \ |
41 |
|
|
ERR(superfx_invalid_short_address, "Invalid short address parameter: $%s. (Must be even number and $0000-$01FE)") \ |
42 |
|
|
ERR(superfx_invalid_register, "Invalid register for opcode; valid range is %d-%d.") \ |
43 |
|
|
ERR(invalid_opcode_length, "Invalid opcode length specification.") \ |
44 |
|
|
ERR(invalid_mapper, "Invalid mapper.") \ |
45 |
|
|
ERR(nan, "NaN encountered.") \ |
46 |
|
|
ERR(division_by_zero, "Division by zero.") \ |
47 |
|
|
ERR(modulo_by_zero, "Modulo by zero.") \ |
48 |
|
|
ERR(unknown_operator, "Unknown operator.") \ |
49 |
|
|
ERR(invalid_input, "Invalid input.") \ |
50 |
|
|
ERR(invalid_function_name, "Invalid function name.") \ |
51 |
|
|
ERR(function_not_found, "Function '%s' wasn't found.") \ |
52 |
|
|
ERR(function_redefined, "Function '%s' redefined.") \ |
53 |
|
|
ERR(broken_function_declaration, "Broken function declaration.") \ |
54 |
|
|
ERR(wrong_num_parameters, "Wrong number of parameters to function.") \ |
55 |
|
|
ERR(invalid_param_name, "Invalid parameter name.") \ |
56 |
|
|
ERR(invalid_label_name, "Invalid label name.") \ |
57 |
|
|
ERR(label_not_found, "Label '%s' wasn't found.") \ |
58 |
|
|
ERR(label_redefined, "Label '%s' redefined.") \ |
59 |
|
|
ERR(broken_label_definition, "Broken label definition.") \ |
60 |
|
|
ERR(macro_label_outside_of_macro, "Macro label outside of a macro.") \ |
61 |
|
|
ERR(invalid_namespace_name, "Invalid namespace name.") \ |
62 |
|
|
ERR(invalid_namespace_use, "Invalid use of namespace command.") \ |
63 |
|
|
ERR(invalid_struct_name, "Invalid struct name.") \ |
64 |
|
|
ERR(struct_not_found, "Struct '%s' wasn't found.") \ |
65 |
|
|
ERR(struct_redefined, "Struct '%s' redefined.") \ |
66 |
|
|
ERR(struct_invalid_parent_name, "Invalid parent name.") \ |
67 |
|
|
ERR(invalid_label_missing_closer, "Invalid label name, missing array closer.") \ |
68 |
|
|
ERR(invalid_subscript, "Invalid array subscript after first scope resolution.") \ |
69 |
|
|
ERR(label_missing_parent, "This label has no parent.") \ |
70 |
|
|
ERR(struct_without_endstruct, "struct without matching endstruct.") \ |
71 |
|
|
ERR(nested_struct, "Can not nest structs.") \ |
72 |
|
|
ERR(missing_struct_params, "Missing struct parameters.") \ |
73 |
|
|
ERR(too_many_struct_params, "Too many struct parameters.") \ |
74 |
|
|
ERR(missing_extends, "Missing extends keyword.") \ |
75 |
|
|
ERR(invalid_endstruct_count, "Invalid endstruct parameter count.") \ |
76 |
|
|
ERR(expected_align, "Expected align parameter.") \ |
77 |
|
|
ERR(endstruct_without_struct, "endstruct can only be used in combination with struct.") \ |
78 |
|
|
ERR(alignment_too_small, "Alignment must be >= 1.") \ |
79 |
|
|
ERR(invalid_define_name, "Invalid define name.") \ |
80 |
|
|
ERR(define_not_found, "Define '%s' wasn't found.") \ |
81 |
|
|
ERR(broken_define_declaration, "Broken define declaration.") \ |
82 |
|
|
ERR(overriding_builtin_define, "Trying to set define '%s', which is the name of a built-in define and thus can't be modified.") \ |
83 |
|
|
ERR(define_label_math, "!Define #= Label is not allowed with non-static labels.") \ |
84 |
|
|
ERR(mismatched_braces, "Mismatched braces.") \ |
85 |
|
|
ERR(invalid_macro_name, "Invalid macro name.") \ |
86 |
|
|
ERR(macro_not_found, "Macro '%s' wasn't found.") \ |
87 |
|
|
ERR(macro_redefined, "Macro '%s' redefined. First defined at: %s:%d") \ |
88 |
|
|
ERR(broken_macro_declaration, "Broken macro declaration.") \ |
89 |
|
|
ERR(invalid_macro_param_name, "Invalid macro parameter name.") \ |
90 |
|
|
ERR(macro_param_not_found, "Macro parameter '%s' wasn't found.%s") \ |
91 |
|
|
ERR(macro_param_redefined, "Macro parameter '%s' redefined") \ |
92 |
|
|
ERR(broken_macro_usage, "Broken macro usage.") \ |
93 |
|
|
ERR(macro_wrong_num_params, "Wrong number of parameters to macro.") \ |
94 |
|
|
ERR(misplaced_endmacro, "Misplaced endmacro.") \ |
95 |
|
|
ERR(unclosed_macro, "Unclosed macro: '%s'.") \ |
96 |
|
|
ERR(label_in_conditional, "Non-static label in %s command.") \ |
97 |
|
|
ERR(misplaced_elseif, "Misplaced elseif.") \ |
98 |
|
|
ERR(elseif_in_while, "Can't use elseif in a while loop.") \ |
99 |
|
|
ERR(misplaced_endif, "Misplaced endif.") \ |
100 |
|
|
ERR(misplaced_else, "Misplaced else.") \ |
101 |
|
|
ERR(else_in_while_loop, "Can't use else in a while loop.") \ |
102 |
|
|
ERR(unclosed_if, "Unclosed if statement.") \ |
103 |
|
|
ERR(unknown_command, "Unknown command.") \ |
104 |
|
|
ERR(broken_incbin, "Broken incbin command.") \ |
105 |
|
|
ERR(recursion_limit, "Recursion limit reached.") \ |
106 |
|
|
ERR(cant_be_main_file, "This file may not be used as the main file.%s") \ |
107 |
|
|
ERR(no_labels_here, "Can't use non-static labels here.") \ |
108 |
|
|
ERR(invalid_freespace_request, "Invalid freespace request.") \ |
109 |
|
|
ERR(static_freespace_autoclean, "A static freespace must be targeted by at least one autoclean.") \ |
110 |
|
|
ERR(static_freespace_growing, "A static freespace may not grow.") \ |
111 |
|
|
ERR(no_freespace_in_mapped_banks, "No freespace found in the mapped banks. (Requested size: %s)") \ |
112 |
|
|
ERR(no_freespace, "No freespace found. (Requested size: %s)") \ |
113 |
|
|
ERR(prot_not_at_freespace_start, "PROT must be used at the start of a freespace block.") \ |
114 |
|
|
ERR(prot_too_many_entries, "Too many entries to PROT.") \ |
115 |
|
|
ERR(autoclean_in_freespace, "autoclean used in freespace.") \ |
116 |
|
|
ERR(autoclean_label_at_freespace_end, "Don't autoclean a label at the end of a freespace block, you'll remove some stuff you're not supposed to remove.") \ |
117 |
|
|
ERR(broken_autoclean, "Broken autoclean command.") \ |
118 |
|
|
ERR(pulltable_without_table, "Using pulltable when there is no table on the stack yet.") \ |
119 |
|
|
ERR(pad_in_freespace, "pad does not make sense in a freespaced code.") \ |
120 |
|
|
ERR(base_label_invalid, "base Label is not valid.") \ |
121 |
|
|
ERR(pushpc_without_pullpc, "pushpc without matching pullpc.") \ |
122 |
|
|
ERR(pullpc_without_pushpc, "pullpc without matching pushpc.") \ |
123 |
|
|
ERR(pullpc_different_arch, "pullpc in another architecture than the pushpc.") \ |
124 |
|
|
ERR(pullbase_without_pushbase, "pullbase without matching pushbase.") \ |
125 |
|
|
ERR(invalid_check, "Invalid check command.") \ |
126 |
|
|
ERR(assertion_failed, "Assertion failed%s") \ |
127 |
|
|
ERR(error_command, "error command%s") \ |
128 |
|
|
ERR(invalid_print_function_syntax, "Invalid printable string syntax.") \ |
129 |
|
|
ERR(unknown_variable, "Unknown variable.") \ |
130 |
|
|
ERR(pushwarnings_without_pullwarnings, "warnings push without matching warnings pull.") \ |
131 |
|
|
ERR(pullwarnings_without_pushwarnings, "warnings pull without matching warnings push.") \ |
132 |
|
|
ERR(failed_to_open_file_access_denied, "Failed to open file '%s'. Access denied.") \ |
133 |
|
|
ERR(failed_to_open_not_regular_file, "Failed to open file '%s'. Not a regular file (did you try to use a directory?)") \ |
134 |
|
|
ERR(bad_dp_base, "The dp base should be page aligned (i.e. a multiple of 256), got %s") \ |
135 |
|
|
ERR(bad_dp_optimize, "Bad dp optimize value %s, expected: [none, ram, always]") \ |
136 |
|
|
ERR(bad_address_optimize, "Bad dp optimize value %s, expected: [default, ram, mirrors]") \ |
137 |
|
|
ERR(bad_optimize, "Bad optimize value %s, expected: [dp, address]") \ |
138 |
|
|
ERR(require_parameter, "Missing required function parameter") \ |
139 |
|
|
ERR(expected_parameter, "Not enough parameters in calling of function %s") \ |
140 |
|
|
ERR(unexpected_parameter, "Too many parameters in calling of function %s") \ |
141 |
|
|
ERR(duplicate_param_name, "Duplicated parameter name: %s in creation of function %s") \ |
142 |
|
|
ERR(invalid_alignment, "Invalid alignment. Expected a power of 2.") \ |
143 |
|
|
ERR(alignment_too_big, "Requested alignment too large.") \ |
144 |
|
|
ERR(negative_shift, "Bitshift amount is negative.") \ |
145 |
|
|
ERR(macro_not_varadic, "Invalid use of %s, active macro is not variadic.") \ |
146 |
|
|
ERR(vararg_sizeof_nomacro, "Invalid use of sizeof(...), no active macro.") \ |
147 |
|
|
ERR(macro_wrong_min_params, "Variadic macro call with too few parameters") \ |
148 |
|
|
ERR(vararg_out_of_bounds, "Variadic macro parameter %s is out of bounds.%s") \ |
149 |
|
|
ERR(vararg_must_be_last, "Variadic macro parameter must be the last parameter.") \ |
150 |
|
|
ERR(invalid_global_label, "Global label definition contains an invalid label [%s].") \ |
151 |
|
|
ERR(spc700_addr_out_of_range, "Address %s out of range for instruction, valid range is 0000-1FFF") \ |
152 |
|
|
ERR(label_ambiguous, "Label (%s) location is ambiguous due to straddling optimization border.") \ |
153 |
|
|
ERR(feature_unavaliable_in_spcblock, "This feature may not be used while an spcblock is active") \ |
154 |
|
|
ERR(endspcblock_without_spcblock, "Use of endspcblock without matching spcblock") \ |
155 |
|
|
ERR(missing_endspcblock, "Use of endspcblock without matching spcblock") \ |
156 |
|
|
ERR(spcblock_inside_struct, "Can not start an spcblock while a struct is still open") \ |
157 |
|
|
ERR(spcblock_too_few_args, "Too few args passed to spcblock") \ |
158 |
|
|
ERR(spcblock_too_many_args, "Too many args passed to spcblock") \ |
159 |
|
|
ERR(unknown_spcblock_type, "Unknown spcblock format") \ |
160 |
|
|
ERR(custom_spcblock_missing_macro, "Custom spcblock types must refer to a valid macro") \ |
161 |
|
|
ERR(spcblock_macro_doesnt_exist, "Macro specified to custom spcblock was not found") \ |
162 |
|
|
ERR(extra_spcblock_arg_for_type, "Only custom spcblock type takes a fourth argument") \ |
163 |
|
|
ERR(spcblock_macro_must_be_varadic, "Custom spcblock macros must be variadic") \ |
164 |
|
|
ERR(spcblock_macro_invalid_static_args, "Custom spcblock macros must have three static arguments") \ |
165 |
|
|
ERR(spcblock_custom_types_incomplete, "Custom spcblock types are not yet supported. One day.") \ |
166 |
|
|
ERR(invalid_endspcblock_arg, "Invalid argument to endspcblock: \"%s\"") \ |
167 |
|
|
ERR(unknown_endspcblock_format, "Unsupported endspcblock format. Currently supported formats are \"endspcblock\" and \"endspcblock execute [label]\"") \ |
168 |
|
|
ERR(internal_error, "An internal error occured (%s). This is a bug in Asar, please report it at https://github.com/RPGHacker/asar/issues, along with a patch that reproduces it if possible.") \ |
169 |
|
|
ERR(pushns_without_pullns, "pushns without matching pullns.") \ |
170 |
|
|
ERR(pullns_without_pushns, "pullns without matching pushns.") \ |
171 |
|
|
ERR(label_forward, "The use of forward labels is not allowed in this context.") \ |
172 |
|
|
ERR(undefined_char, "'%s' is not defined in the character table") \ |
173 |
|
|
ERR(invalid_utf8, "Invalid text encoding detected. Asar expects UTF-8-encoded text. Please re-save this file in a text editor of choice using UTF-8 encoding.") \ |
174 |
|
|
ERR(cmdl_utf16_to_utf8_failed, "UTF-16 to UTF-8 string conversion failed: %s.") \ |
175 |
|
|
ERR(broken_command, "Broken %s command. %s") \ |
176 |
|
|
ERR(oob, "Operation out of bounds: Requested index %d for object of size %d") \ |
177 |
|
|
ERR(unclosed_vararg, "Variadic macro parameter wasn't closed properly.") \ |
178 |
|
|
ERR(invalid_vararg, "Trying to use variadic macro parameter syntax to resolve a non variadic argument <%s>.") \ |
179 |
|
|
ERR(invalid_depth_resolve, "Invalid %s resolution depth: Trying to backwards-resolve a %s using %i '^', but current scope only supports up to %i '^'.") \ |
180 |
|
|
ERR(platform_paths, "Platform-specific paths aren'supported. Please use platform-independent paths (use / instead of \\).") \ |
181 |
|
|
ERR(bad_single_line_for, "Single-line for loop not allowed here.") \ |
182 |
|
|
ERR(broken_for_loop, "Broken for loop command: %s") \ |
183 |
|
|
ERR(missing_org, "Missing org or freespace command.") \ |
184 |
|
|
ERR(unclosed_block_comment, "Unclosed block comment.") \ |
185 |
|
|
ERR(bad_addr_mode, "This addressing mode is not valid for this instruction.") \ |
186 |
|
|
ERR(bad_access_width, "This addressing mode can accept %s arguments, but the provided argument is %d-bit.") \ |
187 |
|
|
ERR(label_before_if, "Labels are not allowed before \"%s\" commands. Suggestion: move the label to a separate line.") \ |
188 |
|
|
// this line intentionally left blank |
189 |
|
|
|
190 |
|
|
enum asar_error_id : int { |
191 |
|
|
#define DO(id, fmt) error_id_ ## id, |
192 |
|
|
ALL_ERRORS(DO) |
193 |
|
|
#undef DO |
194 |
|
|
error_id_end, |
195 |
|
|
}; |
196 |
|
|
|
197 |
|
|
struct asar_error_mapping { |
198 |
|
|
const char* name; |
199 |
|
|
const char* fmt_string; |
200 |
|
|
}; |
201 |
|
|
|
202 |
|
|
inline constexpr asar_error_mapping asar_all_errors[] = { |
203 |
|
|
#define DO(id, fmt) { "E" #id, fmt }, |
204 |
|
|
ALL_ERRORS(DO) |
205 |
|
|
#undef DO |
206 |
|
|
}; |
207 |
|
|
|
208 |
|
683 |
constexpr const char* get_error_fmt(asar_error_id errid) { |
209 |
1/12
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
710 |
return asar_all_errors[errid].fmt_string; |
210 |
|
|
} |
211 |
|
|
|
212 |
|
|
enum asar_error_type |
213 |
|
|
{ |
214 |
|
|
error_type_fatal, |
215 |
|
|
error_type_line, |
216 |
|
|
error_type_block, |
217 |
|
|
error_type_null |
218 |
|
|
}; |
219 |
|
|
|
220 |
|
|
struct errfatal {}; |
221 |
|
|
struct errline : public errfatal {}; |
222 |
|
|
struct errblock : public errline {}; |
223 |
|
|
struct errnull : public errblock {}; |
224 |
|
|
|
225 |
|
|
#ifdef __clang__ |
226 |
|
|
// okay so this ## thing isn't very nice of me, but it works on all compilers |
227 |
|
|
// for now. i'll refactor all use sites of asar_throw_error at some point so i |
228 |
|
|
// can do a different hack to always pass at least 1 variadic argument |
229 |
|
|
//edit: lol nevermind, different hack didn't work either, guess we're stuck |
230 |
|
|
// with this shit until we upgrade to c++20 |
231 |
|
|
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" |
232 |
|
|
#endif |
233 |
|
|
#if defined(__clang__) || defined(__GNUC__) |
234 |
|
|
#define FORMAT [[gnu::format(printf, 3, 4)]] |
235 |
|
|
#else |
236 |
|
|
// msvc only has format string checking in enterprise edition lmao |
237 |
|
|
// ehh who tf even develops on windows anyways |
238 |
|
|
#define FORMAT |
239 |
|
|
#endif |
240 |
|
|
|
241 |
|
|
// "Magic Trick" to get noreturn on all but the null throw functions: use |
242 |
|
|
// preprocessor macros as makeshift template specializations |
243 |
|
|
|
244 |
|
|
// i would do this with explicit template specializations, but there's a 6 year |
245 |
|
|
// old open Clang bug report about [[noreturn]] not working with function |
246 |
|
|
// specializations. |
247 |
|
|
|
248 |
|
|
FORMAT void asar_throw_error_impl_error_type_null(int whichpass, asar_error_id errid, const char* fmt, ...); |
249 |
|
|
FORMAT [[noreturn]] void asar_throw_error_impl_error_type_block(int whichpass, asar_error_id errid, const char* fmt, ...); |
250 |
|
|
FORMAT [[noreturn]] void asar_throw_error_impl_error_type_line(int whichpass, asar_error_id errid, const char* fmt, ...); |
251 |
|
|
FORMAT [[noreturn]] void asar_throw_error_impl_error_type_fatal(int whichpass, asar_error_id errid, const char* fmt, ...); |
252 |
|
|
#undef FORMAT |
253 |
|
|
#define asar_throw_error(whichpass, type, errid, ...) asar_throw_error_impl_ ## type(whichpass, errid, get_error_fmt(errid), ## __VA_ARGS__) |
254 |
|
|
const char* get_error_name(asar_error_id errid); |
255 |
|
|
|