mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-30 23:35:41 +00:00
Fix some issues with wmlvalidator
This commit is contained in:
parent
5950a82a68
commit
30c33ab654
@ -2,10 +2,10 @@
|
|||||||
identifier="re ^[a-zA-Z0-9_ ]+$"
|
identifier="re ^[a-zA-Z0-9_ ]+$"
|
||||||
identifierlist="re ^([a-zA-Z0-9_ ]+,)*[a-zA-Z0-9_ ]+$"
|
identifierlist="re ^([a-zA-Z0-9_ ]+,)*[a-zA-Z0-9_ ]+$"
|
||||||
# slash-separated filenames
|
# slash-separated filenames
|
||||||
path="re ^([a-zA-Z0-9_\-.+]+/)*[a-zA-Z0-9_\-.+]+(~(TC|RC|PAL|FL|GS|CS|CROP|SCALE|BL|O|R|G|B|NOP)\(.*\))*$"
|
path="re ^([a-zA-Z0-9_\-.+]+/)*[a-zA-Z0-9_\-.+]+(~(TC|RC|PAL|FL|GS|CS|CROP|SCALE|BL|O|R|G|B|NOP|RIGHT)\(.*\))*$"
|
||||||
#TODO: imagepath, remove imagepathfunctions from path
|
#TODO: imagepath, remove imagepathfunctions from path
|
||||||
# comma-separated paths
|
# comma-separated paths
|
||||||
pathlist="re ^(([a-zA-Z0-9_\-.+]+/)*[a-zA-Z0-9_\-.+]+(~(TC|RC|PAL|FL|GS|CS|CROP|SCALE|BL|O|R|G|B|NOP)\(.*\))*,)*([a-zA-Z0-9_\-.+]+/)*[a-zA-Z0-9_\-.+]+(~(TC|RC|PAL|FL|GS|CS|CROP|SCALE|BL|O|R|G|B|NOP)\(.*\))*$"
|
pathlist="re ^(([a-zA-Z0-9_\-.+]+/)*[a-zA-Z0-9_\-.+]+(~(TC|RC|PAL|FL|GS|CS|CROP|SCALE|BL|O|R|G|B|NOP|RIGHT)\(.*\))*,)*([a-zA-Z0-9_\-.+]+/)*[a-zA-Z0-9_\-.+]+(~(TC|RC|PAL|FL|GS|CS|CROP|SCALE|BL|O|R|G|B|NOP|RIGHT)\(.*\))*$"
|
||||||
#TODO: imagepathlist, same as above
|
#TODO: imagepathlist, same as above
|
||||||
[root]
|
[root]
|
||||||
# All possible root elements
|
# All possible root elements
|
||||||
@ -95,6 +95,7 @@
|
|||||||
wikiuser="optional string"
|
wikiuser="optional string"
|
||||||
[/entry]
|
[/entry]
|
||||||
[female:unit_type]
|
[female:unit_type]
|
||||||
|
id="forbidden identifier"
|
||||||
inherit="optional boolean"
|
inherit="optional boolean"
|
||||||
[/female:unit_type]
|
[/female:unit_type]
|
||||||
[font]
|
[font]
|
||||||
@ -181,6 +182,7 @@
|
|||||||
code="required string"
|
code="required string"
|
||||||
[/lua]
|
[/lua]
|
||||||
[male:unit_type]
|
[male:unit_type]
|
||||||
|
id="forbidden identifier"
|
||||||
inherit="optional boolean"
|
inherit="optional boolean"
|
||||||
[/male:unit_type]
|
[/male:unit_type]
|
||||||
[movetype]
|
[movetype]
|
||||||
@ -316,7 +318,7 @@
|
|||||||
experience="optional integer" # required
|
experience="optional integer" # required
|
||||||
flag_rgb="optional string" # list of integers
|
flag_rgb="optional string" # list of integers
|
||||||
gender="optional string" # enum male,female
|
gender="optional string" # enum male,female
|
||||||
halo="optional path"
|
halo="optional string" # should be animlist: list of imagepaths with animation length
|
||||||
hide_help="optional boolean"
|
hide_help="optional boolean"
|
||||||
hitpoints="optional integer" # required
|
hitpoints="optional integer" # required
|
||||||
id="required identifier"
|
id="required identifier"
|
||||||
@ -333,6 +335,7 @@
|
|||||||
zoc="optional boolean"
|
zoc="optional boolean"
|
||||||
[/unit_type]
|
[/unit_type]
|
||||||
[variation:unit_type]
|
[variation:unit_type]
|
||||||
|
id="forbidden identifier"
|
||||||
inherit="optional boolean"
|
inherit="optional boolean"
|
||||||
variation_name="required identifier"
|
variation_name="required identifier"
|
||||||
[/variation:unit_type]
|
[/variation:unit_type]
|
||||||
|
@ -6,8 +6,9 @@ import re
|
|||||||
REQUIRED = 1
|
REQUIRED = 1
|
||||||
OPTIONAL = 2
|
OPTIONAL = 2
|
||||||
REPEATED = 3
|
REPEATED = 3
|
||||||
|
FORBIDDEN = 4
|
||||||
|
|
||||||
class Grammar:
|
class Grammar(object):
|
||||||
def __init__(self, schema):
|
def __init__(self, schema):
|
||||||
schema = schema.get_first("schema")
|
schema = schema.get_first("schema")
|
||||||
self.datatypes = {
|
self.datatypes = {
|
||||||
@ -34,21 +35,21 @@ class Grammar:
|
|||||||
def get_datatype(self, name):
|
def get_datatype(self, name):
|
||||||
return self.datatypes[name]
|
return self.datatypes[name]
|
||||||
|
|
||||||
class Node:
|
class Node(object):
|
||||||
def __init__(self, schema, datatypes):
|
def __init__(self, schema, datatypes):
|
||||||
self.name = schema.name
|
self.name = schema.name
|
||||||
self.elements = []
|
self.elements = set([])
|
||||||
self.ext_elements = [] #Ugh, do we really want to do this?
|
self.ext_elements = [] #Ugh, do we really want to do this?
|
||||||
self.attributes = []
|
self.attributes = set([])
|
||||||
self.parent = None
|
self.parent = None
|
||||||
for item in schema.get_all_text():
|
for item in schema.get_all_text():
|
||||||
if item.name[0] == '_':
|
if item.name[0] == '_':
|
||||||
self.elements.append( Element(item) )
|
self.elements.add( Element(item) )
|
||||||
else:
|
else:
|
||||||
self.attributes.append( Attribute(item, datatypes) )
|
self.attributes.add( Attribute(item, datatypes) )
|
||||||
for item in schema.get_all_subs():
|
for item in schema.get_all_subs():
|
||||||
if item.name == "element":
|
if item.name == "element":
|
||||||
print "[element] found, not parsing yet"
|
print "[element] found in schema, not parsing yet"
|
||||||
#self.ext_elements...
|
#self.ext_elements...
|
||||||
else:
|
else:
|
||||||
raise Exception( "Unknown element [%s] encountered in grammar for [%s]" % (item.name, self.name) )
|
raise Exception( "Unknown element [%s] encountered in grammar for [%s]" % (item.name, self.name) )
|
||||||
@ -56,8 +57,8 @@ class Node:
|
|||||||
self.name, self.parent = self.name.split(':',1)
|
self.name, self.parent = self.name.split(':',1)
|
||||||
def inherit(self, other):
|
def inherit(self, other):
|
||||||
assert self.parent == other.name
|
assert self.parent == other.name
|
||||||
self.elements += other.elements
|
self.elements.update( other.elements )
|
||||||
self.attributes += other.attributes
|
self.attributes.update( other.attributes )
|
||||||
self.parent = None
|
self.parent = None
|
||||||
def get_attributes(self):
|
def get_attributes(self):
|
||||||
return self.attributes
|
return self.attributes
|
||||||
@ -65,7 +66,7 @@ class Node:
|
|||||||
return self.elements
|
return self.elements
|
||||||
|
|
||||||
|
|
||||||
class Element:
|
class Element(object):
|
||||||
def __init__(self, schema):
|
def __init__(self, schema):
|
||||||
first, second = schema.data.split(" ",1)
|
first, second = schema.data.split(" ",1)
|
||||||
self.name = schema.name[1:]
|
self.name = schema.name[1:]
|
||||||
@ -73,6 +74,10 @@ class Element:
|
|||||||
self.subname = second
|
self.subname = second
|
||||||
def match(self, name):
|
def match(self, name):
|
||||||
return self.name == name
|
return self.name == name
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self.name)
|
||||||
|
def __cmp__(self, other):
|
||||||
|
return (isinstance(other, type(self)) or isinstance(self, type(other))) and cmp(self.name, other.name)
|
||||||
|
|
||||||
class ExtElement(Element):
|
class ExtElement(Element):
|
||||||
def __init__(self, schema):
|
def __init__(self, schema):
|
||||||
@ -82,7 +87,7 @@ class ExtElement(Element):
|
|||||||
def match(self, name):
|
def match(self, name):
|
||||||
return bool(self.re.match(name))
|
return bool(self.re.match(name))
|
||||||
|
|
||||||
class Attribute:
|
class Attribute(object):
|
||||||
def __init__(self, schema, datatypes):
|
def __init__(self, schema, datatypes):
|
||||||
first, second = schema.data.split(" ",1)
|
first, second = schema.data.split(" ",1)
|
||||||
if not second in datatypes:
|
if not second in datatypes:
|
||||||
@ -95,6 +100,10 @@ class Attribute:
|
|||||||
return self.name == name
|
return self.name == name
|
||||||
def validate(self, value):
|
def validate(self, value):
|
||||||
return bool(self.re.match(value))
|
return bool(self.re.match(value))
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self.name)
|
||||||
|
def __cmp__(self, other):
|
||||||
|
return (isinstance(other, type(self)) or isinstance(self, type(other))) and cmp(self.name, other.name)
|
||||||
|
|
||||||
def parse_frequency(string):
|
def parse_frequency(string):
|
||||||
if string == "required":
|
if string == "required":
|
||||||
@ -103,6 +112,8 @@ def parse_frequency(string):
|
|||||||
return OPTIONAL
|
return OPTIONAL
|
||||||
elif string == "repeated":
|
elif string == "repeated":
|
||||||
return REPEATED
|
return REPEATED
|
||||||
|
elif string == "forbidden":
|
||||||
|
return FORBIDDEN
|
||||||
else:
|
else:
|
||||||
raise Exception( "Unknown frequency '%s'" % (string,) )
|
raise Exception( "Unknown frequency '%s'" % (string,) )
|
||||||
|
|
||||||
|
@ -55,6 +55,8 @@ class Validator:
|
|||||||
print "Attribute '[%s] %s' should appear exactly once, not %d times" % (verbosename, attribute.name, nummatches)
|
print "Attribute '[%s] %s' should appear exactly once, not %d times" % (verbosename, attribute.name, nummatches)
|
||||||
elif attribute.freq == wmlgrammar.OPTIONAL and nummatches > 1:
|
elif attribute.freq == wmlgrammar.OPTIONAL and nummatches > 1:
|
||||||
print "Attribute '[%s] %s' should appear at most once, not %d times" % (verbosename, attribute.name, nummatches)
|
print "Attribute '[%s] %s' should appear at most once, not %d times" % (verbosename, attribute.name, nummatches)
|
||||||
|
elif attribute.freq == wmlgrammar.FORBIDDEN and nummatches > 0:
|
||||||
|
print "Attribute '[%s] %s' should not appear. It appears %d times" % (verbosename, attribute.name, nummatches)
|
||||||
for match in matches:
|
for match in matches:
|
||||||
if not attribute.validate(match.data):
|
if not attribute.validate(match.data):
|
||||||
print "Attribute '[%s] %s's value should be %s, found: %s" % (verbosename, attribute.name, attribute.type, match.data)
|
print "Attribute '[%s] %s's value should be %s, found: %s" % (verbosename, attribute.name, attribute.type, match.data)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user