Clean up argument handling in gen_sct for add_args and make_args

This commit is contained in:
Douglas Clowes
2014-11-03 16:30:33 +11:00
parent 79e4be4ca6
commit f59daef96b

View File

@ -637,6 +637,24 @@ def make_path(MyVar):
path += MyVar['name']
return path
def parse_args(arg_str):
'''
Parse the TCL argument string into a list of identifiers (in order) plus
a map of identifier to default value (or None) returned as a 2-tuple
'''
arg_list = re.findall(r'({[^}]+}|[A-Za-z0-9_]+)', arg_str)
arg_lst = []
arg_map = {}
for arg in arg_list:
if arg.startswith('{'):
bits = arg[1:-1].split(None, 1)
arg_lst.append(bits[0])
arg_map[bits[0]] = bits[1]
else:
arg_lst.append(arg)
arg_map[arg] = None
return (arg_lst, arg_map)
#
# This section handles building a driver tree from the Abstract Syntax Tree
# generated by the parser. The driver tree has all of the defaults and
@ -901,6 +919,24 @@ def build_driver(MyDriver, TheTree):
message = 'Error: duplicate permlink entries for "%s"' % item
message += " " + repr(MyDriver['Permlink'][item])
PrintPostError(message)
if 'add_args' in MyDriver:
MyDriver['add_args_lst'], MyDriver['add_args_map'] = parse_args(MyDriver['add_args'])
if Verbose:
print "ADD_ARGS:", MyDriver['add_args']
arg_map = MyDriver['add_args_map']
for arg in arg_map:
print ' %s:' % arg, arg_map[arg]
if 'make_args' in MyDriver:
MyDriver['make_args_lst'], MyDriver['make_args_map'] = parse_args(MyDriver['make_args'])
if Verbose:
print "MAKE_ARGS:", MyDriver['make_args']
arg_map = MyDriver['make_args_map']
for arg in arg_map:
print ' %s:' % arg, arg_map[arg]
if 'add_args_lst' in MyDriver and 'make_args_lst' in MyDriver:
if MyDriver['add_args_lst'] != MyDriver['make_args_lst']:
print "Add_Args:", MyDriver['add_args_lst']
print "Make_Args:", MyDriver['make_args_lst']
if Verbose:
print "MyDriver:", MyDriver
#
@ -959,6 +995,10 @@ def dump_driver_funcs(funcs):
def dump_driver(MyDriver):
print 'DRIVER ' + MyDriver['name'] + ' = {'
Comments = ['PathName', 'Permlink']
Comments += ['add_args_lst']
Comments += ['add_args_map']
Comments += ['make_args_lst']
Comments += ['make_args_map']
Deferred = ['Groups', 'Funcs', 'Deferred', 'name'] + Comments
for Comment in sorted(Comments):
if Comment in MyDriver:
@ -990,7 +1030,7 @@ def put_preamble(MyDriver):
txt += ['namespace eval %s {' % MyDriver['namespace']]
txt += [' set debug_threshold %s' % str( MyDriver['debug_threshold'])]
if len(MyDriver['Permlink']) > 0:
if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split():
if 'make_args_lst' in MyDriver and 'id' in MyDriver['make_args_lst']:
pass
else:
txt += [' if { ![info exists ::scobj::permlink_device_counter]} {']
@ -1401,13 +1441,13 @@ def put_var(MyDriver, MyGroup, MyVar):
if 'permlink' in MyVar:
device_type, node_type = MyVar['permlink'].split('.')
if device_type.startswith("#"):
if 'make_args' in MyDriver and 'permlink' in MyDriver['make_args'].split():
if 'make_args_lst' in MyDriver and 'permlink' in MyDriver['make_args_lst']:
idx = int(device_type[1:])
device_type = '[string index ${permlink} %d]' % idx
else:
message = 'Error: permlink required in make_ags'
PrintPostError(message)
if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split():
if 'make_args_lst' in MyDriver and 'id' in MyDriver['make_args_lst']:
permlink = device_type + '[format "%02d" ${id}]' + node_type
else:
permlink = device_type + '${permlink_device_number}' + node_type
@ -1519,8 +1559,8 @@ def put_mkDriver(MyDriver):
else:
line = 'proc %s::mkDriver { sct_controller name device_class simulation_flag ip_address tcp_port } {' % (MyDriver['namespace'])
txt += [line]
if 'make_args' in MyDriver:
make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()])
if 'make_args_lst' in MyDriver:
make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args_lst']])
txt += [' %s::sics_log 9 "%s::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} %s"' % (MyDriver['namespace'], MyDriver['namespace'], make_args)]
else:
txt += [' %s::sics_log 9 "%s::mkDriver ${sct_controller} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}"' % (MyDriver['namespace'], MyDriver['namespace'])]
@ -1534,7 +1574,7 @@ def put_mkDriver(MyDriver):
txt += ['# %s hook code ends' % func]
else:
if len(MyDriver['Permlink']) > 0:
if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split():
if 'make_args_lst' in MyDriver and 'id' in MyDriver['make_args_lst']:
pass
else:
txt += [' set permlink_device_number [format "%02d" [incr ::scobj::permlink_device_counter]]']
@ -1585,8 +1625,8 @@ def put_postamble(MyDriver):
line = 'proc %s::add_driver {name device_class simulation_flag ip_address tcp_port} {' % (MyDriver['namespace'])
txt += [line]
txt += [' set catch_status [ catch {']
if 'make_args' in MyDriver:
make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()])
if 'make_args_lst' in MyDriver:
make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args_lst']])
txt += [' %s::sics_log 9 "%s::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} %s"' % (MyDriver['namespace'], MyDriver['namespace'], make_args)]
else:
txt += [' %s::sics_log 9 "%s::add_driver ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port}"' % (MyDriver['namespace'], MyDriver['namespace'])]
@ -1611,8 +1651,8 @@ def put_postamble(MyDriver):
txt += [' %s::sics_log 9 "makesctcontroller sct_${name} aqadapter NULL"' % MyDriver['namespace']]
txt += [' makesctcontroller sct_${name} aqadapter NULL']
txt += [' }']
if 'make_args' in MyDriver:
make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()])
if 'make_args_lst' in MyDriver:
make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args_lst']])
txt += [' %s::sics_log 1 "%s::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} %s"' % (MyDriver['namespace'], MyDriver['namespace'], make_args)]
txt += [' %s::mkDriver sct_${name} ${name} ${device_class} ${simulation_flag} ${ip_address} ${tcp_port} %s' % (MyDriver['namespace'], make_args)]
else:
@ -1644,9 +1684,11 @@ def put_postamble(MyDriver):
line = 'proc add_%s {name ip_address tcp_port} {' % MyDriver['name']
txt += [line]
txt += [' set simulation_flag "[string tolower [SplitReply [%s]]]"' % MyDriver['simulation_group']]
line = ' %s::add_driver ${name} "%s" "${simulation_flag}" ${ip_address} ${tcp_port}' % (MyDriver['namespace'], MyDriver['class'])
if 'add_args' in MyDriver:
for arg in MyDriver['add_args'].split():
line = ' %s::add_driver ${name} "%s"' % (MyDriver['namespace'], MyDriver['class'])
for arg in ['simulation_flag', 'ip_address', 'tcp_port']:
line += ' "${%s}"' % arg
if 'add_args_lst' in MyDriver:
for arg in MyDriver['add_args_lst']:
line += ' "${%s}"' % arg
txt += [line]
txt += ['}']
@ -1715,10 +1757,10 @@ def put_read_config(MyDriver):
txt += [' ${asyncqueue} timeout "[dict get $v "timeout"]"']
txt += [' }']
txt += [' }']
if 'make_args' in MyDriver:
if 'add_args_lst' in MyDriver:
txt += [' set arg_list [list]']
txt += [' set missing_list [list]']
txt += [' foreach arg {' + MyDriver['make_args'] + '} {']
txt += [' foreach arg {' + ' '.join(MyDriver['add_args_lst']) + '} {']
txt += [' if {[dict exists $u $arg]} {']
txt += [' lappend arg_list "[dict get $u $arg]"']
txt += [' } elseif {[dict exists $v $arg]} {']