wmlunits: Handle code paths for missing attributes (#7580)
This commit is contained in:
parent
01f28b12ae
commit
fa76e775ac
4 changed files with 73 additions and 66 deletions
|
@ -187,6 +187,7 @@ class WesnothList:
|
||||||
n = 0
|
n = 0
|
||||||
for terrain in self.parser.get_all(tag="terrain_type"):
|
for terrain in self.parser.get_all(tag="terrain_type"):
|
||||||
tstring = terrain.get_text_val("string")
|
tstring = terrain.get_text_val("string")
|
||||||
|
if tstring is None: continue
|
||||||
self.terrain_lookup[tstring] = terrain
|
self.terrain_lookup[tstring] = terrain
|
||||||
n += 1
|
n += 1
|
||||||
return n
|
return n
|
||||||
|
@ -205,6 +206,8 @@ class WesnothList:
|
||||||
for locale in parser.get_all(tag="locale"):
|
for locale in parser.get_all(tag="locale"):
|
||||||
isocode = locale.get_text_val("locale")
|
isocode = locale.get_text_val("locale")
|
||||||
name = locale.get_text_val("name")
|
name = locale.get_text_val("name")
|
||||||
|
if isocode is None or name is None:
|
||||||
|
continue
|
||||||
if isocode == "ang_GB":
|
if isocode == "ang_GB":
|
||||||
continue
|
continue
|
||||||
self.languages_found[isocode] = name
|
self.languages_found[isocode] = name
|
||||||
|
@ -220,7 +223,7 @@ class WesnothList:
|
||||||
era.faction_lookup = {}
|
era.faction_lookup = {}
|
||||||
for multiplayer_side in era.get_all(tag="multiplayer_side"):
|
for multiplayer_side in era.get_all(tag="multiplayer_side"):
|
||||||
fid = multiplayer_side.get_text_val("id")
|
fid = multiplayer_side.get_text_val("id")
|
||||||
if fid == "Random":
|
if fid == "Random" or fid in era.faction_lookup:
|
||||||
continue
|
continue
|
||||||
era.faction_lookup[fid] = multiplayer_side
|
era.faction_lookup[fid] = multiplayer_side
|
||||||
recruit = multiplayer_side.get_text_val("recruit", "").strip()
|
recruit = multiplayer_side.get_text_val("recruit", "").strip()
|
||||||
|
@ -284,7 +287,7 @@ class WesnothList:
|
||||||
# Find all unit types.
|
# Find all unit types.
|
||||||
newunits = getall("unit_type") + getall("unit")
|
newunits = getall("unit_type") + getall("unit")
|
||||||
for unit in newunits:
|
for unit in newunits:
|
||||||
uid = unit.get_text_val("id")
|
uid = unit.get_text_val("id", "none")
|
||||||
unit.id = uid
|
unit.id = uid
|
||||||
|
|
||||||
if unit.get_text_val("do_not_list", "no") not in ["no", "false"] or \
|
if unit.get_text_val("do_not_list", "no") not in ["no", "false"] or \
|
||||||
|
@ -309,18 +312,18 @@ class WesnothList:
|
||||||
for race in newraces:
|
for race in newraces:
|
||||||
rid = race.get_text_val("id")
|
rid = race.get_text_val("id")
|
||||||
if rid is None:
|
if rid is None:
|
||||||
rid = race.get_text_val("name")
|
rid = race.get_text_val("name", "none")
|
||||||
self.race_lookup[rid] = race
|
self.race_lookup[rid] = race
|
||||||
|
|
||||||
# Find all movetypes.
|
# Find all movetypes.
|
||||||
newmovetypes = getall("movetype")
|
newmovetypes = getall("movetype")
|
||||||
for movetype in newmovetypes:
|
for movetype in newmovetypes:
|
||||||
mtname = movetype.get_text_val("name")
|
mtname = movetype.get_text_val("name")
|
||||||
|
if mtname is None: continue
|
||||||
self.movetype_lookup[mtname] = movetype
|
self.movetype_lookup[mtname] = movetype
|
||||||
|
|
||||||
# Store race/movetype/faction of each unit for easier access later.
|
# Store race/movetype/faction of each unit for easier access later.
|
||||||
for unit in newunits:
|
for unit in newunits:
|
||||||
uid = unit.get_text_val("id")
|
|
||||||
race = self.get_unit_value(unit, "race")
|
race = self.get_unit_value(unit, "race")
|
||||||
try:
|
try:
|
||||||
unit.race = self.race_lookup[race]
|
unit.race = self.race_lookup[race]
|
||||||
|
@ -360,21 +363,9 @@ class WesnothList:
|
||||||
def check_units(self):
|
def check_units(self):
|
||||||
"""
|
"""
|
||||||
Once all units have been added, do some checking.
|
Once all units have been added, do some checking.
|
||||||
|
This function used to handle now-removed advancefrom tags
|
||||||
"""
|
"""
|
||||||
# handle advancefrom tags
|
return
|
||||||
for uid, unit in list(self.unit_lookup.items()):
|
|
||||||
for advancefrom in unit.get_all(tag="advancefrom"):
|
|
||||||
fromid = advancefrom.get_text_val("unit")
|
|
||||||
if fromid:
|
|
||||||
try:
|
|
||||||
fromunit = self.unit_lookup[fromid]
|
|
||||||
except KeyError:
|
|
||||||
error_message(
|
|
||||||
"Error: Unit '%s' references non-existant [advancefrom] unit '%s'" % (
|
|
||||||
uid, fromid))
|
|
||||||
continue
|
|
||||||
if uid not in fromunit.advance:
|
|
||||||
fromunit.advance.append(uid)
|
|
||||||
|
|
||||||
def find_unit_factions(self):
|
def find_unit_factions(self):
|
||||||
for unit in list(self.unit_lookup.values()):
|
for unit in list(self.unit_lookup.values()):
|
||||||
|
@ -503,7 +494,7 @@ class UnitNode:
|
||||||
def __init__(self, unit):
|
def __init__(self, unit):
|
||||||
self.unit = unit
|
self.unit = unit
|
||||||
self.children = []
|
self.children = []
|
||||||
self.id = unit.get_text_val("id")
|
self.id = unit.get_text_val("id", "none")
|
||||||
self.child_ids = []
|
self.child_ids = []
|
||||||
self.parent_ids = []
|
self.parent_ids = []
|
||||||
self.child_ids.extend(unit.advance)
|
self.child_ids.extend(unit.advance)
|
||||||
|
|
|
@ -665,7 +665,7 @@ class HTMLOutput:
|
||||||
name = self.wesnoth.get_unit_value(un, "name",
|
name = self.wesnoth.get_unit_value(un, "name",
|
||||||
translation=self.translation.translate)
|
translation=self.translation.translate)
|
||||||
if not name:
|
if not name:
|
||||||
error_message("Warning: Unit uid=" + uid + " has no name.\n")
|
error_message("Warning: Unit uid=%s has no name.\n" % uid)
|
||||||
name = uid
|
name = uid
|
||||||
add_menuitem(link, name)
|
add_menuitem(link, name)
|
||||||
end_menu()
|
end_menu()
|
||||||
|
@ -758,7 +758,7 @@ class HTMLOutput:
|
||||||
try:
|
try:
|
||||||
id = ability.get_text_val("id")
|
id = ability.get_text_val("id")
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
error_message("Error: Ignoring ability " + ability.debug())
|
error_message("Error: Ignoring ability %s" % ability.debug())
|
||||||
continue
|
continue
|
||||||
if id in already:
|
if id in already:
|
||||||
continue
|
continue
|
||||||
|
@ -1299,7 +1299,7 @@ class HTMLOutput:
|
||||||
if ticon:
|
if ticon:
|
||||||
terrainlist.append((name, tid, ticon))
|
terrainlist.append((name, tid, ticon))
|
||||||
else:
|
else:
|
||||||
error_message("Terrain " + tid + " has no symbol_image\n")
|
error_message("Terrain %s has no symbol_image\n" % tid)
|
||||||
terrainlist.sort()
|
terrainlist.sort()
|
||||||
|
|
||||||
for tname, tid, ticon in terrainlist:
|
for tname, tid, ticon in terrainlist:
|
||||||
|
@ -1340,7 +1340,7 @@ class HTMLOutput:
|
||||||
|
|
||||||
write('<tr>\n')
|
write('<tr>\n')
|
||||||
picname = image_collector.add_image(self.addon,
|
picname = image_collector.add_image(self.addon,
|
||||||
"terrain/" + ticon + ".png",
|
"terrain/%s.png" % ticon,
|
||||||
no_tc=True)
|
no_tc=True)
|
||||||
icon = os.path.join(PICS_LOCATION, picname)
|
icon = os.path.join(PICS_LOCATION, picname)
|
||||||
write('<td><img src="%s" alt="(icon)" /></td>\n' % cleanurl(icon))
|
write('<td><img src="%s" alt="(icon)" /></td>\n' % cleanurl(icon))
|
||||||
|
@ -1368,9 +1368,9 @@ def generate_campaign_report(addon, isocode, campaign, wesnoth):
|
||||||
else:
|
else:
|
||||||
cid = "mainline"
|
cid = "mainline"
|
||||||
if not cid:
|
if not cid:
|
||||||
cid = addon + "_" + campaign.get_text_val("define")
|
cid = "%s_%s" % (addon, campaign.get_text_val("define"))
|
||||||
|
|
||||||
print(("campaign " + addon + " " + cid + " " + isocode))
|
print("campaign %s %s %s" % (addon, cid, isocode))
|
||||||
|
|
||||||
path = os.path.join(options.output, addon, isocode)
|
path = os.path.join(options.output, addon, isocode)
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
|
@ -1396,7 +1396,7 @@ def generate_campaign_report(addon, isocode, campaign, wesnoth):
|
||||||
def generate_era_report(addon, isocode, era, wesnoth):
|
def generate_era_report(addon, isocode, era, wesnoth):
|
||||||
eid = era.get_text_val("id")
|
eid = era.get_text_val("id")
|
||||||
|
|
||||||
print("era " + addon + " " + eid + " " + isocode)
|
print("era %s %s %s" % (addon, eid, isocode))
|
||||||
|
|
||||||
path = os.path.join(options.output, addon, isocode)
|
path = os.path.join(options.output, addon, isocode)
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
|
|
|
@ -16,29 +16,28 @@ def main():
|
||||||
|
|
||||||
punits = {}
|
punits = {}
|
||||||
|
|
||||||
defines = "NORMAL,ENABLE_ARMAGEDDON_DRAKE,ENABLE_DWARVISH_ARCANISTER," +\
|
base_defines = ["NORMAL"]
|
||||||
"ENABLE_DWARVISH_RUNESMITH,ENABLE_ANCIENT_LICH,ENABLE_DEATH_KNIGHT," +\
|
|
||||||
"ENABLE_TROLL_SHAMAN,ENABLE_WOLF_ADVANCEMENT,ENABLE_WOSE_SHAMAN," +\
|
|
||||||
"ENABLE_PARAGON,ENABLE_SAURIAN_SPEARTHROWER,DISABLE_GRAND_MARSHAL"
|
|
||||||
|
|
||||||
sys.stderr.write("Parsing core units...\n")
|
sys.stderr.write("Parsing core units...\n")
|
||||||
wesnoth.parser.parse_text("{core/units.cfg}", defines)
|
wesnoth.parser.parse_text("{core/units.cfg}", ",".join(base_defines))
|
||||||
punits["mainline"] = wesnoth.parser.get_all(tag = "units")
|
punits["mainline"] = wesnoth.parser.get_all(tag = "units")
|
||||||
punits["mainline"] += wesnoth.parser.get_all(tag = "+units")
|
punits["mainline"] += wesnoth.parser.get_all(tag = "+units")
|
||||||
|
|
||||||
all_campaigns = {}
|
all_campaigns = {}
|
||||||
sys.stderr.write("Parsing campaigns...\n")
|
sys.stderr.write("Parsing campaigns...\n")
|
||||||
wesnoth.parser.parse_text("{campaigns}", defines)
|
wesnoth.parser.parse_text("{campaigns}", ",".join(base_defines))
|
||||||
campaigns = wesnoth.parser.get_all(tag = "campaign")
|
campaigns = wesnoth.parser.get_all(tag = "campaign")
|
||||||
for campaign in campaigns:
|
for campaign in campaigns:
|
||||||
|
campaign_defines = base_defines[:]
|
||||||
define = campaign.get_text_val("define")
|
define = campaign.get_text_val("define")
|
||||||
ed = campaign.get_text_val("extra_defines")
|
ed = campaign.get_text_val("extra_defines")
|
||||||
if ed: define += "," + ed
|
if define is not None: campaign_defines.append(define)
|
||||||
|
if ed is not None: campaign_defines.extend(ed.split(","))
|
||||||
name = campaign.get_text_val("name", translation = translated.translate)
|
name = campaign.get_text_val("name", translation = translated.translate)
|
||||||
sys.stderr.write("Parsing " + name + "...\n")
|
sys.stderr.write("Parsing " + name + "...\n")
|
||||||
campaign.name = name
|
campaign.name = name
|
||||||
all_campaigns[campaign.get_text_val("id")] = campaign
|
all_campaigns[campaign.get_text_val("id")] = campaign
|
||||||
wesnoth.parser.parse_text("{campaigns}", defines + "," + define)
|
wesnoth.parser.parse_text("{campaigns}", ",".join(campaign_defines))
|
||||||
punits[name] = wesnoth.parser.get_all(tag = "units")
|
punits[name] = wesnoth.parser.get_all(tag = "units")
|
||||||
punits[name] += wesnoth.parser.get_all(tag = "+units")
|
punits[name] += wesnoth.parser.get_all(tag = "+units")
|
||||||
|
|
||||||
|
@ -47,7 +46,12 @@ def main():
|
||||||
for campaign, unitslists in list(punits.items()):
|
for campaign, unitslists in list(punits.items()):
|
||||||
for unitlist in unitslists:
|
for unitlist in unitslists:
|
||||||
for race in unitlist.get_all(tag = "race"):
|
for race in unitlist.get_all(tag = "race"):
|
||||||
races[race.get_text_val("id")] = race
|
race_id = race.get_text_val("id")
|
||||||
|
if race_id is None: race_id = race.get_text_val("name")
|
||||||
|
if race_id is None:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
races[race_id] = race
|
||||||
|
|
||||||
# Go through all units and put them into a dictionary.
|
# Go through all units and put them into a dictionary.
|
||||||
all_units = {}
|
all_units = {}
|
||||||
|
@ -57,6 +61,8 @@ def main():
|
||||||
if unit.get_text_val("do_not_list") in ["yes", "true"]: continue
|
if unit.get_text_val("do_not_list") in ["yes", "true"]: continue
|
||||||
if unit.get_text_val("hide_help") in ["yes", "true"]: continue
|
if unit.get_text_val("hide_help") in ["yes", "true"]: continue
|
||||||
unit.id = unit.get_text_val("id")
|
unit.id = unit.get_text_val("id")
|
||||||
|
if unit.id is None:
|
||||||
|
continue
|
||||||
unit.campaign = campaign
|
unit.campaign = campaign
|
||||||
all_units[unit.id] = unit
|
all_units[unit.id] = unit
|
||||||
unit.children = []
|
unit.children = []
|
||||||
|
@ -66,7 +72,10 @@ def main():
|
||||||
x = unit.get_text_val(val, translation = translation)
|
x = unit.get_text_val(val, translation = translation)
|
||||||
if x: return x
|
if x: return x
|
||||||
for base_unit in unit.get_all(tag = "base_unit"):
|
for base_unit in unit.get_all(tag = "base_unit"):
|
||||||
base = all_units[base_unit.get_text_val("id")]
|
base_uid = base_unit.get_text_val("id")
|
||||||
|
if base_uid is None or not base_uid in all_units:
|
||||||
|
continue
|
||||||
|
base = all_units[base_uid]
|
||||||
x = base_val(base, val, translation = translation)
|
x = base_val(base, val, translation = translation)
|
||||||
if x: return x
|
if x: return x
|
||||||
return None
|
return None
|
||||||
|
@ -91,6 +100,8 @@ def main():
|
||||||
# Find children and parents of all units.
|
# Find children and parents of all units.
|
||||||
for unit in list(all_units.values()):
|
for unit in list(all_units.values()):
|
||||||
for aid in unit.advances_to:
|
for aid in unit.advances_to:
|
||||||
|
if not aid in all_units:
|
||||||
|
continue
|
||||||
unit.children.append(all_units[aid])
|
unit.children.append(all_units[aid])
|
||||||
all_units[aid].parents.append(unit)
|
all_units[aid].parents.append(unit)
|
||||||
# [advancefrom] was removed
|
# [advancefrom] was removed
|
||||||
|
|
|
@ -314,28 +314,25 @@ def list_contents():
|
||||||
info["eras"] = list_eras(batchlist, addon)
|
info["eras"] = list_eras(batchlist, addon)
|
||||||
info["campaigns"] = list_campaigns(batchlist, addon)
|
info["campaigns"] = list_campaigns(batchlist, addon)
|
||||||
info["version"] = version
|
info["version"] = version
|
||||||
sys.stdout.write("ok\n")
|
print("ok")
|
||||||
except wmlparser3.WMLError as e:
|
except wmlparser3.WMLError as e:
|
||||||
ef = open(logname, "w")
|
with open(logname, "w") as ef
|
||||||
ef.write("<PARSE ERROR>\n")
|
ef.write("<PARSE ERROR>\n")
|
||||||
ef.write(str(e))
|
ef.write(str(e))
|
||||||
ef.write("</PARSE ERROR>\n")
|
ef.write("\n</PARSE ERROR>\n")
|
||||||
ef.close()
|
print("failed")
|
||||||
sys.stdout.write("failed\n")
|
|
||||||
except queue.Empty as e:
|
except queue.Empty as e:
|
||||||
ef = open(logname, "w")
|
with open(logname, "w") as ef
|
||||||
ef.write("<TIMEOUT ERROR>\n")
|
ef.write("<TIMEOUT ERROR>\n")
|
||||||
ef.write("Failed to parse the WML within " + str(TIMEOUT) + " seconds.")
|
ef.write("Failed to parse the WML within " + str(TIMEOUT) + " seconds.")
|
||||||
ef.write("</TIMEOUT ERROR>\n")
|
ef.write("\n</TIMEOUT ERROR>\n")
|
||||||
ef.close()
|
print("failed")
|
||||||
sys.stdout.write("failed\n")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
ef = open(logname, "w")
|
with open(logname, "w") as ef
|
||||||
ef.write("<INTERNAL ERROR>\n")
|
ef.write("<INTERNAL ERROR>\n")
|
||||||
ef.write(repr(e))
|
ef.write(repr(e))
|
||||||
ef.write("</INTERNAL ERROR>\n")
|
ef.write("\n</INTERNAL ERROR>\n")
|
||||||
ef.close()
|
print("failed")
|
||||||
sys.stdout.write("failed\n")
|
|
||||||
finally:
|
finally:
|
||||||
move(os.path.join(options.config_dir, "data", "add-ons"), options.addons, addon)
|
move(os.path.join(options.config_dir, "data", "add-ons"), options.addons, addon)
|
||||||
for d in get_dependencies(addon):
|
for d in get_dependencies(addon):
|
||||||
|
@ -471,21 +468,29 @@ def batch_process():
|
||||||
campaign["units"] = n
|
campaign["units"] = n
|
||||||
|
|
||||||
except wmlparser3.WMLError as e:
|
except wmlparser3.WMLError as e:
|
||||||
ef = open(logname, "a")
|
print(" " + name + " failed")
|
||||||
|
with open(logname, "a") as ef
|
||||||
ef.write("<WML ERROR>\n")
|
ef.write("<WML ERROR>\n")
|
||||||
ef.write(str(e))
|
ef.write(str(e))
|
||||||
ef.write("</WML ERROR>\n")
|
ef.write("\n</WML ERROR>\n")
|
||||||
ef.close()
|
except (AttributeError, KeyError, TypeError) as e:
|
||||||
|
# Common logic errors.
|
||||||
|
traceback.print_exc()
|
||||||
print(" " + name + " failed")
|
print(" " + name + " failed")
|
||||||
|
with open(logname, "a") as ef
|
||||||
|
ef.write("<INTERNAL ERROR>\n")
|
||||||
|
ef.write("please report as bug\n")
|
||||||
|
# Show last few stack frames of traceback to make bug reports more useful.
|
||||||
|
ef.write(traceback.format_exc(limit=-2))
|
||||||
|
ef.write("\n</INTERNAL ERROR>\n")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
print(" " + name + " failed")
|
print(" " + name + " failed")
|
||||||
ef = open(logname, "a")
|
with open(logname, "a") as ef
|
||||||
ef.write("<INTERNAL ERROR>\n")
|
ef.write("<INTERNAL ERROR>\n")
|
||||||
ef.write("please report as bug\n")
|
ef.write("please report as bug\n")
|
||||||
ef.write(str(e))
|
ef.write(str(e))
|
||||||
ef.write("</INTERNAL ERROR>\n")
|
ef.write("\n</INTERNAL ERROR>\n")
|
||||||
ef.close()
|
|
||||||
finally:
|
finally:
|
||||||
if name != "mainline":
|
if name != "mainline":
|
||||||
move(os.path.join(options.config_dir, "data", "add-ons"), options.addons, name)
|
move(os.path.join(options.config_dir, "data", "add-ons"), options.addons, name)
|
||||||
|
|
Loading…
Add table
Reference in a new issue