Commit 2db8ba02 authored by Stefan Behnel's avatar Stefan Behnel

support non-bool options and multiple options as compiler comment directives

parent 99eac7ae
...@@ -121,7 +121,7 @@ def parse_command_line(args): ...@@ -121,7 +121,7 @@ def parse_command_line(args):
options.emit_linenums = True options.emit_linenums = True
elif option in ("-X", "--directive"): elif option in ("-X", "--directive"):
try: try:
options.compiler_directives = Options.parse_directive_list(pop_arg()) options.compiler_directives = Options.parse_directive_list(pop_arg(), relaxed_bool=True)
except ValueError, e: except ValueError, e:
sys.stderr.write("Error in compiler directive: %s\n" % e.message) sys.stderr.write("Error in compiler directive: %s\n" % e.message)
sys.exit(1) sys.exit(1)
......
...@@ -84,7 +84,7 @@ directive_scopes = { # defaults to available everywhere ...@@ -84,7 +84,7 @@ directive_scopes = { # defaults to available everywhere
'test_fail_if_path_exists' : ('function',), 'test_fail_if_path_exists' : ('function',),
} }
def parse_directive_value(name, value): def parse_directive_value(name, value, relaxed_bool=False):
""" """
Parses value as an option value for the given name and returns Parses value as an option value for the given name and returns
the interpreted value. None is returned if the option does not exist. the interpreted value. None is returned if the option does not exist.
...@@ -102,9 +102,14 @@ def parse_directive_value(name, value): ...@@ -102,9 +102,14 @@ def parse_directive_value(name, value):
type = directive_types.get(name) type = directive_types.get(name)
if not type: return None if not type: return None
if type is bool: if type is bool:
if value == "True": return True value = str(value)
elif value == "False": return False if value == 'True': return True
else: raise ValueError("%s directive must be set to True or False" % name) if value == 'False': return False
if relaxed_bool:
value = value.lower()
if value in ("true", "yes"): return True
elif value in ("false", "no"): return False
raise ValueError("%s directive must be set to True or False" % name)
elif type is int: elif type is int:
try: try:
return int(value) return int(value)
...@@ -115,7 +120,7 @@ def parse_directive_value(name, value): ...@@ -115,7 +120,7 @@ def parse_directive_value(name, value):
else: else:
assert False assert False
def parse_directive_list(s): def parse_directive_list(s, relaxed_bool=False):
""" """
Parses a comma-seperated list of pragma options. Whitespace Parses a comma-seperated list of pragma options. Whitespace
is not considered. is not considered.
...@@ -132,7 +137,7 @@ def parse_directive_list(s): ...@@ -132,7 +137,7 @@ def parse_directive_list(s):
>>> parse_directive_list('boundscheck=hey') >>> parse_directive_list('boundscheck=hey')
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: Must pass a boolean value for option "boundscheck" ValueError: boundscheck directive must be set to True or False
>>> parse_directive_list('unknown=True') >>> parse_directive_list('unknown=True')
Traceback (most recent call last): Traceback (most recent call last):
... ...
...@@ -143,19 +148,9 @@ def parse_directive_list(s): ...@@ -143,19 +148,9 @@ def parse_directive_list(s):
item = item.strip() item = item.strip()
if not item: continue if not item: continue
if not '=' in item: raise ValueError('Expected "=" in option "%s"' % item) if not '=' in item: raise ValueError('Expected "=" in option "%s"' % item)
name, value = item.strip().split('=') name, value = [ s.strip() for s in item.strip().split('=', 1) ]
try: parsed_value = parse_directive_value(name, value, relaxed_bool=relaxed_bool)
type = directive_types[name] if parsed_value is None:
except KeyError:
raise ValueError('Unknown option: "%s"' % name) raise ValueError('Unknown option: "%s"' % name)
if type is bool: result[name] = parsed_value
value = value.lower()
if value in ('true', 'yes'):
value = True
elif value in ('false', 'no'):
value = False
else: raise ValueError('Must pass a boolean value for option "%s"' % name)
result[name] = value
else:
assert False
return result return result
...@@ -2579,18 +2579,16 @@ def p_code(s, level=None): ...@@ -2579,18 +2579,16 @@ def p_code(s, level=None):
repr(s.sy), repr(s.systring))) repr(s.sy), repr(s.systring)))
return body return body
COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*(\w+)\s*=(.*)$") COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*(\w+\s*=.*)$")
def p_compiler_directive_comments(s): def p_compiler_directive_comments(s):
result = {} result = {}
while s.sy == 'commentline': while s.sy == 'commentline':
m = COMPILER_DIRECTIVE_COMMENT_RE.match(s.systring) m = COMPILER_DIRECTIVE_COMMENT_RE.match(s.systring)
if m: if m:
name = m.group(1) directives = m.group(1).strip()
try: try:
value = Options.parse_directive_value(str(name), str(m.group(2).strip())) result.update( Options.parse_directive_list(directives) )
if value is not None: # can be False!
result[name] = value
except ValueError, e: except ValueError, e:
s.error(e.args[0], fatal=False) s.error(e.args[0], fatal=False)
s.next() s.next()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment