From f59daef96b441723f22a04d02d5e95d6b08893f7 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Mon, 3 Nov 2014 16:30:33 +1100 Subject: [PATCH] Clean up argument handling in gen_sct for add_args and make_args --- site_ansto/instrument/util/gen_sct.py | 72 +++++++++++++++++++++------ 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 0c2a89d6..c7b0e01a 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -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]} {']