Add support for lists on the command line.
svn: r17690
This commit is contained in:
parent
7f33b7778a
commit
a896ef5457
@ -52,6 +52,89 @@ from gen.plug import BasePluginManager
|
||||
from gen.plug.report import CATEGORY_BOOK, CATEGORY_CODE
|
||||
from cli.plug import cl_report
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# private functions
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def _split_options(options_str):
|
||||
"""
|
||||
Split the options for the action.
|
||||
|
||||
Rules:
|
||||
* Entries in the list of options are separated by commas without spaces
|
||||
between entries
|
||||
* List values must be inclosed in brackets ("[" and "]")
|
||||
* Entries within a list value are separated by commas
|
||||
* Text values (as a value or as entries in a list) do not have to be
|
||||
enclosed in quotes unless they include commas or quotation marks.
|
||||
* Text containing double quotes must be contained in single quotes
|
||||
* Text containing single quotes must be contained in double quotes
|
||||
* Text cannot include both single and double quotes
|
||||
|
||||
Examples:
|
||||
* Multiple options specified:
|
||||
report -p 'name=ancestor_chart,father_disp=["$n born $b"]'
|
||||
* Using text with commas and quotes:
|
||||
title="This is some text with ,s and 's"
|
||||
title='This is some text with ,s and "s'
|
||||
* Using a list of text
|
||||
textlist=[row1,row2,"row3 with ' and ,"]
|
||||
"""
|
||||
name = ""
|
||||
value = ""
|
||||
parsing_value = False
|
||||
in_quotes = False
|
||||
in_list = False
|
||||
quote_type = ""
|
||||
options_str_dict = {}
|
||||
|
||||
for char in options_str:
|
||||
if not parsing_value:
|
||||
# Parsing the name of the option
|
||||
if char == "=":
|
||||
#print char, "This value ends the name"
|
||||
parsing_value = True
|
||||
else:
|
||||
#print char, "This value is part of the name"
|
||||
name += char
|
||||
else:
|
||||
# Parsing the value of the option
|
||||
if value == "" and char == '[':
|
||||
#print char, "This character begins a list"
|
||||
in_list = True
|
||||
value += char
|
||||
elif in_list == True and char == ']':
|
||||
#print char, "This character ends the list"
|
||||
in_list = False
|
||||
value += char
|
||||
elif not in_quotes and ( char == '"' or char == "'"):
|
||||
#print char, "This character starts a quoted string"
|
||||
in_quotes = True
|
||||
quote_type = char
|
||||
value += char
|
||||
elif in_quotes and char == quote_type:
|
||||
#print char, "This character ends a quoted string"
|
||||
in_quotes = False
|
||||
value += char
|
||||
elif not in_quotes and not in_list and char == ",":
|
||||
#print char, "This character ends the value of the option"
|
||||
options_str_dict[name] = value
|
||||
name = ""
|
||||
value = ""
|
||||
parsing_value = False
|
||||
in_quotes = False
|
||||
in_list = False
|
||||
else:
|
||||
#print char, "This character is part of the value"
|
||||
value += char
|
||||
|
||||
if parsing_value and not in_quotes and not in_list:
|
||||
# Add the last option
|
||||
options_str_dict[name] = value
|
||||
|
||||
return options_str_dict
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# ArgHandler
|
||||
#-------------------------------------------------------------------------
|
||||
@ -465,8 +548,7 @@ class ArgHandler(object):
|
||||
pmgr = BasePluginManager.get_instance()
|
||||
if action == "report":
|
||||
try:
|
||||
options_str_dict = dict( [ tuple(chunk.split('='))
|
||||
for chunk in options_str.split(',') ] )
|
||||
options_str_dict = _split_options(options_str)
|
||||
except:
|
||||
options_str_dict = {}
|
||||
print >> sys.stderr, "Ignoring invalid options string."
|
||||
|
@ -67,6 +67,71 @@ from cli.grampscli import CLIManager
|
||||
# Private Functions
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def _convert_str_to_match_type(str_val, type_val):
|
||||
"""
|
||||
Returns a value representing str_val that is the same type as type_val.
|
||||
"""
|
||||
str_val = str_val.strip()
|
||||
ret_type = type(type_val)
|
||||
|
||||
if ret_type in (str, unicode):
|
||||
if ( str_val.startswith("'") and str_val.endswith("'") ) or \
|
||||
( str_val.startswith('"') and str_val.endswith('"') ):
|
||||
# Remove enclosing quotes
|
||||
return unicode(str_val[1:-1])
|
||||
else:
|
||||
return unicode(str_val)
|
||||
|
||||
elif ret_type == int:
|
||||
if str_val.isdigit():
|
||||
return int(str_val)
|
||||
else:
|
||||
print "%s is not an integer number" % str_val
|
||||
return 0
|
||||
|
||||
elif ret_type == float:
|
||||
if str_val.isdecimal():
|
||||
return float(ret_type)
|
||||
else:
|
||||
print "%s is not a decimal number" % str_val
|
||||
return 0.0
|
||||
|
||||
elif ret_type == bool:
|
||||
if str_val == str(True):
|
||||
return True
|
||||
return False
|
||||
|
||||
elif ret_type == list:
|
||||
ret_val = []
|
||||
if not ( str_val.startswith("[") and str_val.endswith("]") ):
|
||||
print "%s is not a list" % str_val
|
||||
return ret_val
|
||||
|
||||
entry = ""
|
||||
quote_type = None
|
||||
|
||||
# Search through characters between the brackets
|
||||
for char in str_val[1:-1]:
|
||||
if (char == "'" or char == '"') and quote_type == None:
|
||||
# This character starts a string
|
||||
quote_type = char
|
||||
elif char == quote_type:
|
||||
# This character ends a string
|
||||
quote_type = None
|
||||
elif quote_type == None and char == ",":
|
||||
# This character ends an entry
|
||||
ret_val.append(entry.strip())
|
||||
entry = ""
|
||||
quote_type = None
|
||||
else:
|
||||
entry += char
|
||||
|
||||
if entry != "":
|
||||
# Add the last entry
|
||||
ret_val.append(entry.strip())
|
||||
|
||||
return ret_val
|
||||
|
||||
def _validate_options(options, dbase):
|
||||
"""
|
||||
Validate all options by making sure that their values are consistent with
|
||||
@ -291,13 +356,15 @@ class CommandLineReport(object):
|
||||
elif isinstance(option, NumberOption):
|
||||
self.options_help[name].append("A number")
|
||||
elif isinstance(option, BooleanOption):
|
||||
self.options_help[name].append(["False\tno", "True\tyes"])
|
||||
self.options_help[name].append(["False", "True"])
|
||||
elif isinstance(option, DestinationOption):
|
||||
self.options_help[name].append("A file system path")
|
||||
elif isinstance(option, StringOption):
|
||||
self.options_help[name].append("Any text")
|
||||
elif isinstance(option, TextOption):
|
||||
self.options_help[name].append("Any text")
|
||||
self.options_help[name].append(
|
||||
"A list of text values. Each entry in the list "
|
||||
"represents one line of text." )
|
||||
elif isinstance(option, EnumeratedListOption):
|
||||
ilist = []
|
||||
for (value, description) in option.get_items():
|
||||
@ -320,8 +387,10 @@ class CommandLineReport(object):
|
||||
menu_opt_names = menu.get_all_option_names()
|
||||
for opt in self.options_str_dict:
|
||||
if opt in self.options_dict:
|
||||
converter = Utils.get_type_converter(self.options_dict[opt])
|
||||
self.options_dict[opt] = converter(self.options_str_dict[opt])
|
||||
self.options_dict[opt] = \
|
||||
_convert_str_to_match_type(self.options_str_dict[opt],
|
||||
self.options_dict[opt])
|
||||
|
||||
self.option_class.handler.options_dict[opt] = \
|
||||
self.options_dict[opt]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user