asar coverage - build #248


src/asar/
File: src/asar/errors.h
Date: 2025-02-21 17:28:19
Lines:
2/2
100.0%
Functions:
1/1
100.0%
Branches:
1/12
8.3%

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