Skip to content

Commit

Permalink
Add: Options to disable optimisation and/or deprecation warnings (#230)
Browse files Browse the repository at this point in the history
  • Loading branch information
glx22 authored Aug 15, 2021
1 parent 04355be commit b8ca217
Show file tree
Hide file tree
Showing 22 changed files with 130 additions and 39 deletions.
10 changes: 7 additions & 3 deletions nml/actions/action0.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,10 +476,12 @@ def get_property_info_list(feature, name):
for prop_info in prop_info_list:
if "replaced_by" in prop_info:
generic.print_warning(
"'{}' is deprecated, consider using '{}' instead".format(prop_name, prop_info["replaced_by"]), name.pos
generic.Warning.DEPRECATION,
"'{}' is deprecated, consider using '{}' instead".format(prop_name, prop_info["replaced_by"]),
name.pos,
)
if "warning" in prop_info:
generic.print_warning(prop_info["warning"], name.pos)
generic.print_warning(generic.Warning.GENERIC, prop_info["warning"], name.pos)
return prop_info_list


Expand Down Expand Up @@ -667,7 +669,9 @@ def validate_prop_info_list(prop_info_list, pos_list, feature):
for prop_name, prop_info in properties[feature].items():
if info == prop_info or (isinstance(prop_info, list) and info in prop_info):
generic.print_warning(
"Property '{}' should be set before all other properties and graphics.".format(prop_name), pos
generic.Warning.GENERIC,
"Property '{}' should be set before all other properties and graphics.".format(prop_name),
pos,
)
break

Expand Down
5 changes: 4 additions & 1 deletion nml/actions/action14.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,10 @@ def param_desc_actions(root, params):
max_val = setting.max_val.uvalue if setting.max_val is not None else 0xFFFFFFFF
def_val = setting.def_val.uvalue if setting.def_val is not None else 0
if min_val > max_val or def_val < min_val or def_val > max_val:
generic.print_warning("Limits for GRF parameter {} are incoherent, ignoring.".format(param_num))
generic.print_warning(
generic.Warning.GENERIC,
"Limits for GRF parameter {} are incoherent, ignoring.".format(param_num),
)
min_val = 0
max_val = 0xFFFFFFFF
setting_node.subnodes.append(LimitNode(min_val, max_val))
Expand Down
6 changes: 5 additions & 1 deletion nml/actions/action2.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,11 @@ def prepare_act2_output(self):
if len(self._referencing_nodes) == 0 and (not self.optimised or self.optimised is self):
# if we can be 'not used', there ought to be a way to refer to this block
assert self.name is not None
generic.print_warning("Block '{}' is not referenced, ignoring.".format(self.name.value), self.pos)
generic.print_warning(
generic.Warning.OPTIMISATION,
"Block '{}' is not referenced, ignoring.".format(self.name.value),
self.pos,
)

return len(self._referencing_nodes) != 0

Expand Down
2 changes: 1 addition & 1 deletion nml/actions/action2real.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def get_real_action2s(spritegroup, feature):
"Sprite groups for feature {:02X} will not be supported in the future, as they are no longer needed."
" Directly refer to sprite sets instead."
).format(feature)
generic.print_warning(msg, spritegroup.pos)
generic.print_warning(generic.Warning.GENERIC, msg, spritegroup.pos)
if view_names != ["default"]:
raise generic.ScriptError("Expected only a 'default' (list of) sprite set(s).", spritegroup.pos)

Expand Down
12 changes: 10 additions & 2 deletions nml/actions/action2var.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,11 @@ def parse(self, expr):

def parse_var(name, info, pos):
if "replaced_by" in info:
generic.print_warning("'{}' is deprecated, consider using '{}' instead".format(name, info["replaced_by"]), pos)
generic.print_warning(
generic.Warning.DEPRECATION,
"'{}' is deprecated, consider using '{}' instead".format(name, info["replaced_by"]),
pos,
)
param = expression.ConstantNumeric(info["param"]) if "param" in info else None
res = expression.Variable(
expression.ConstantNumeric(info["var"]),
Expand Down Expand Up @@ -1141,7 +1145,11 @@ def parse_varaction2(switch_block):
if check_min and check_max:
for existing_range in used_ranges:
if existing_range[0] <= range_min.value and range_max.value <= existing_range[1]:
generic.print_warning("Range overlaps with existing ranges so it'll never be reached", r.min.pos)
generic.print_warning(
generic.Warning.GENERIC,
"Range overlaps with existing ranges so it'll never be reached",
r.min.pos,
)
range_overlap = True
break
if not range_overlap:
Expand Down
2 changes: 1 addition & 1 deletion nml/actions/action3.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def parse_graphics_block_single_id(

for info in info_list:
if "deprecate_message" in info:
generic.print_warning(info["deprecate_message"], cargo_id.pos)
generic.print_warning(generic.Warning.DEPRECATION, info["deprecate_message"], cargo_id.pos)
if house_tile is not None and "tiles" in info and house_tile not in info["tiles"]:
continue

Expand Down
4 changes: 2 additions & 2 deletions nml/actions/action5.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def parse_action5(replaces):
"Too many sprites specified for sprite replacement type '{}',"
" expected {:d}, got {:d}, extra sprites may be ignored"
).format(replaces.type, num_required, num_sprites)
generic.print_warning(msg, replaces.pos)
generic.print_warning(generic.Warning.GENERIC, msg, replaces.pos)

if replaces.offset != 0:
msg = "replacenew parameter 'offset' must be zero for sprite replacement type '{}'".format(replaces.type)
Expand All @@ -120,7 +120,7 @@ def parse_action5(replaces):
if num_sprites + replaces.offset > num_required:
msg = "Exceeding the limit of {:d} sprites for sprite replacement type '{}', extra sprites may be ignored"
msg = msg.format(num_required, replaces.type)
generic.print_warning(msg, replaces.pos)
generic.print_warning(generic.Warning.GENERIC, msg, replaces.pos)

if replaces.offset != 0 or num_sprites != num_required:
offset = replaces.offset
Expand Down
4 changes: 3 additions & 1 deletion nml/actions/actionD.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ def pre_process(self):
elif isinstance(self.param, expression.Identifier):
if global_constants.identifier_refcount[self.param.value] == 0:
generic.print_warning(
"Named parameter '{}' is not referenced, ignoring.".format(self.param.value), self.param.pos
generic.Warning.OPTIMISATION,
"Named parameter '{}' is not referenced, ignoring.".format(self.param.value),
self.param.pos,
)
return
num = action6.free_parameters.pop_unique(self.pos)
Expand Down
4 changes: 3 additions & 1 deletion nml/actions/real_sprite.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,9 @@ def parse_sprite_data(sprite_container):
if action_list[i].sprite_list[0].is_empty and not sprite.is_empty:
# if the first sprite is empty, all others are ignored
generic.print_warning(
"Alternative sprites for an empty real sprite are ignored.", sprite_container.pos
generic.Warning.OPTIMISATION,
"Alternative sprites for an empty real sprite are ignored.",
sprite_container.pos,
)
if isinstance(sprite, RealSprite):
action_list[i].add_sprite(sprite)
Expand Down
6 changes: 5 additions & 1 deletion nml/ast/cargotable.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ def register_names(self):
self.cargo_list[i]
) # we don't care about the result, only validate the input
if self.cargo_list[i].value in global_constants.cargo_numbers:
generic.print_warning("Duplicate entry in cargo table: {}".format(self.cargo_list[i].value), cargo.pos)
generic.print_warning(
generic.Warning.GENERIC,
"Duplicate entry in cargo table: {}".format(self.cargo_list[i].value),
cargo.pos,
)
else:
global_constants.cargo_numbers[self.cargo_list[i].value] = i

Expand Down
6 changes: 5 additions & 1 deletion nml/ast/produce.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ def __init__(self, param_list, pos):
self.param_list.append(expression.ConstantNumeric(0))

def pre_process(self):
generic.print_warning("Consider using the new produce() syntax for '{}'".format(self.name), self.name.pos)
generic.print_warning(
generic.Warning.DEPRECATION,
"Consider using the new produce() syntax for '{}'".format(self.name),
self.name.pos,
)
var_scope = action2var.get_scope(0x0A)
for i, param in enumerate(self.param_list):
self.param_list[i] = action2var.reduce_varaction2_expr(param, var_scope)
Expand Down
2 changes: 1 addition & 1 deletion nml/ast/sprite_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def add_sprite_data(self, sprite_list, default_file, pos, zoom_level=0, bit_dept
+ "level / bit depth combination. This data will be overridden."
)
msg = msg.format(self.block_type, self.block_name.value)
generic.print_warning(msg, pos)
generic.print_warning(generic.Warning.GENERIC, msg, pos)
self.sprite_data[key] = (sprite_list, default_file, default_mask_file, pos)

def get_all_sprite_data(self):
Expand Down
18 changes: 15 additions & 3 deletions nml/ast/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ def optimise(self):
self.optimised = self

if self.optimised:
generic.print_warning("Block '{}' returns a constant, optimising.".format(self.name.value), self.pos)
generic.print_warning(
generic.Warning.OPTIMISATION,
"Block '{}' returns a constant, optimising.".format(self.name.value),
self.pos,
)
return self.optimised is not self

self.optimised = self # Prevent multiple run on the same non optimisable Switch
Expand Down Expand Up @@ -190,7 +194,11 @@ def reduce_expressions(self, var_scope, extra_dicts=None):
if len(self.ranges) != 0:
if any(self.default.value != r.result.value for r in self.ranges):
return
generic.print_warning("Switch-Block ranges are the same as default, optimising.", self.default.pos)
generic.print_warning(
generic.Warning.OPTIMISATION,
"Switch-Block ranges are the same as default, optimising.",
self.default.pos,
)
self.ranges = []

def debug_print(self, indentation):
Expand Down Expand Up @@ -385,7 +393,11 @@ def optimise(self):
or (isinstance(optimised, expression.SpriteGroupRef) and not optimised.is_procedure)
or isinstance(optimised, expression.String)
):
generic.print_warning("Block '{}' returns a constant, optimising.".format(self.name.value), self.pos)
generic.print_warning(
generic.Warning.OPTIMISATION,
"Block '{}' returns a constant, optimising.".format(self.name.value),
self.pos,
)
self.optimised = optimised
return True

Expand Down
4 changes: 3 additions & 1 deletion nml/ast/townnames.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ def make_actions(self):
for piece in self.pieces:
piece.pre_process()
if piece.probability.value == 0:
generic.print_warning("Dropping town name piece with 0 probability.", piece.pos)
generic.print_warning(
generic.Warning.OPTIMISATION, "Dropping town name piece with 0 probability.", piece.pos
)
else:
new_pieces.append(piece)

Expand Down
1 change: 1 addition & 0 deletions nml/expression/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def __init__(self, num, pos=None, by_user=False):
self.num = num
if by_user and isinstance(num, ConstantNumeric) and not (0 <= num.value <= 63):
generic.print_warning(
generic.Warning.GENERIC,
"Accessing parameters out of the range 0..63 is not supported and may lead to unexpected behaviour.",
pos,
)
Expand Down
16 changes: 13 additions & 3 deletions nml/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,13 @@ def clear(cls):
cls.seen = {}


class Warning:
GENERIC = 0
DEPRECATION = 1
OPTIMISATION = 2
disabled = None


VERBOSITY_WARNING = 1 # Verbosity level for warnings
VERBOSITY_INFO = 2 # Verbosity level for info messages
VERBOSITY_PROGRESS = 3 # Verbosity level for progress feedback
Expand Down Expand Up @@ -409,12 +416,14 @@ def print_info(msg):
show_progress()


def print_warning(msg, pos=None):
def print_warning(type, msg, pos=None):
"""
Output a warning message to the user.
"""
if verbosity_level < VERBOSITY_WARNING:
return
if Warning.disabled and type in Warning.disabled:
return
if pos:
msg = str(pos) + ": " + msg

Expand Down Expand Up @@ -524,7 +533,7 @@ def find_file(filepath):
'Path "{}" at the file system does not match path "{}" given in the input'
" (case mismatch in the last component)"
).format(real_path, given_path)
print_warning(msg)
print_warning(Warning.GENERIC, msg)
elif os.access(path, os.X_OK):
# Path is only accessible, cannot inspect the file system.
matches = [comp]
Expand Down Expand Up @@ -593,6 +602,7 @@ def open_cache_file(sources, extension, mode):
except OSError:
if "w" in mode:
print_warning(
"Can't create cache file {}. Check permissions, or use --cache-dir or --no-cache.".format(path)
Warning.GENERIC,
"Can't create cache file {}. Check permissions, or use --cache-dir or --no-cache.".format(path),
)
raise
4 changes: 3 additions & 1 deletion nml/global_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

def constant_number(name, info, pos):
if isinstance(info, str):
generic.print_warning("'{}' is deprecated, consider using '{}' instead".format(name, info), pos)
generic.print_warning(
generic.Warning.DEPRECATION, "'{}' is deprecated, consider using '{}' instead".format(name, info), pos
)
info = constant_numbers[info]
return expression.ConstantNumeric(info, pos)

Expand Down
37 changes: 26 additions & 11 deletions nml/grfstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,9 @@ def read_extra_commands(custom_tags_file):
value = line[i + 1 :]
if name in commands:
generic.print_warning(
'Overwriting existing tag "' + name + '".', generic.LinePosition(custom_tags_file, line_no)
generic.Warning.GENERIC,
'Overwriting existing tag "' + name + '".',
generic.LinePosition(custom_tags_file, line_no),
)
commands[name] = {"unicode": value}
if is_ascii_string(value):
Expand Down Expand Up @@ -653,7 +655,9 @@ def __init__(self, string, lang, pos):
raise generic.ScriptError('Undefined command "{}"'.format(command_name), pos)
if command_name in commands and "deprecated" in commands[command_name]:
generic.print_warning(
"String code '{}' has been deprecated and will be removed soon".format(command_name), pos
generic.Warning.DEPRECATION,
"String code '{}' has been deprecated and will be removed soon".format(command_name),
pos,
)
del commands[command_name]["deprecated"]
#
Expand Down Expand Up @@ -1121,29 +1125,35 @@ def handle_text(self, string, case, value, pos):
self.strings[string].remove_non_default_commands()
else:
if string not in default_lang.strings:
generic.print_warning('String name "{}" does not exist in master file'.format(string), pos)
generic.print_warning(
generic.Warning.GENERIC, 'String name "{}" does not exist in master file'.format(string), pos
)
return

newgrf_string = NewGRFString(value, self, pos)
if not default_lang.strings[string].match_commands(newgrf_string):
generic.print_warning(
'String commands don\'t match with master file "{}"'.format(DEFAULT_LANGNAME), pos
generic.Warning.GENERIC,
'String commands don\'t match with master file "{}"'.format(DEFAULT_LANGNAME),
pos,
)
return

if case is None:
self.strings[string] = newgrf_string
else:
if string not in self.strings:
generic.print_warning("String with case used before the base string", pos)
generic.print_warning(generic.Warning.GENERIC, "String with case used before the base string", pos)
return
if self.cases is None or case not in self.cases:
generic.print_warning('Invalid case name "{}"'.format(case), pos)
generic.print_warning(generic.Warning.GENERIC, 'Invalid case name "{}"'.format(case), pos)
return
if case in self.strings[string].cases:
raise generic.ScriptError('String name "{}.{}" is used multiple times'.format(string, case), pos)
if newgrf_string.gender:
generic.print_warning("Case-strings can't set the gender, only the base string can", pos)
generic.print_warning(
generic.Warning.GENERIC, "Case-strings can't set the gender, only the base string can", pos
)
return
self.strings[string].cases[case] = newgrf_string

Expand Down Expand Up @@ -1228,15 +1238,19 @@ def parse_file(filename, default):
pos = generic.LanguageFilePosition(filename)
if default:
raise generic.ScriptError("The default language file contains non-utf8 characters.", pos)
generic.print_warning("Language file contains non-utf8 characters. Ignoring (part of) the contents.", pos)
generic.print_warning(
generic.Warning.GENERIC, "Language file contains non-utf8 characters. Ignoring (part of) the contents.", pos
)
except generic.ScriptError as err:
if default:
raise
generic.print_warning(err.value, err.pos)
generic.print_warning(generic.Warning.GENERIC, err.value, err.pos)
else:
if lang.langid is None:
generic.print_warning(
"Language file does not contain a ##grflangid pragma", generic.LanguageFilePosition(filename)
generic.Warning.GENERIC,
"Language file does not contain a ##grflangid pragma",
generic.LanguageFilePosition(filename),
)
else:
for lng in langs:
Expand Down Expand Up @@ -1266,7 +1280,8 @@ def read_lang_files(lang_dir, default_lang_file):
DEFAULT_LANGNAME = default_lang_file
if not os.path.exists(lang_dir + os.sep + default_lang_file):
generic.print_warning(
'Default language file "{}" doesn\'t exist'.format(os.path.join(lang_dir, default_lang_file))
generic.Warning.GENERIC,
'Default language file "{}" doesn\'t exist'.format(os.path.join(lang_dir, default_lang_file)),
)
return
parse_file(lang_dir + os.sep + default_lang_file, True)
Expand Down
Loading

0 comments on commit b8ca217

Please sign in to comment.