From 53d6274e7de782c675092bc9d175c30811d652ff Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Mon, 14 Apr 2014 14:09:30 +1000 Subject: [PATCH] Add 'permlink' code to generated drivers --- site_ansto/instrument/util/gen_sct.py | 79 +++++++++++++++++++-------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 387b5d13..9350f208 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -95,6 +95,7 @@ reserved = { 'READABLE' : 'READABLE', 'WRITEABLE' : 'WRITEABLE', 'DRIVEABLE' : 'DRIVEABLE', + 'PERMLINK' : 'PERMLINK', 'TRUE' : 'TRUE', 'FALSE' : 'FALSE', # Data Types @@ -391,6 +392,7 @@ def p_var_val_ass(p): | LOWERLIMIT EQUALS value | UPPERLIMIT EQUALS value | TOLERANCE EQUALS value + | PERMLINK EQUALS text_string | DRIVEABLE EQUALS var_path ''' p[0] = { p[1] : p[3] } @@ -510,6 +512,16 @@ def p_empty(p): def p_error(t): print("Syntax error at '%s'" % t.value), t +# +# Utility functions +# +def make_path(MyVar): + path = MyVar['path'] + if len(path) > 0: + path = path.replace('/', '_') + path += '_' + MyVar['name'] + return path + # # 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 @@ -623,6 +635,11 @@ def build_variable(MyDriver, p): # TODO FIXME error message print 'Error: Function type mismatch: var = ' + str(MyVar) + ', code = ' + str(MyDriver['Funcs'][MyVar[func]]) + ', func = ' + str(func) MyDriver['Funcs'][MyVar[func]]['reference_count'] += 1 + if 'permlink' in MyVar: + device_type, node_type = MyVar['permlink'].split('.') + if node_type not in MyDriver['Permlink']: + MyDriver['Permlink'][node_type] = []; + MyDriver['Permlink'][node_type] += [make_path(MyVar)]; if Verbose: print '==>>MyVar:', MyVar return MyVar @@ -695,6 +712,9 @@ def build_driver(MyDriver, TheTree): continue for key in item: MyDriver[key] = item[key] + for item in MyDriver['Permlink']: + if len(MyDriver['Permlink'][item]) > 1: + print 'Error: duplicate permlink entries for "%s"' % item, MyDriver['Permlink'][item] if Verbose: print "MyDriver:", MyDriver # @@ -763,6 +783,13 @@ def put_preamble(MyDriver): txt += [''] txt += ['namespace eval %s {' % MyDriver['namespace']] txt += [' set debug_threshold 0'] + if len(MyDriver['Permlink']) > 0: + if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split(): + pass + else: + txt += [' if { ![info exists ::scobj::permlink_device_counter]} {'] + txt += [' set ::scobj::permlink_device_counter 0'] + txt += [' }'] txt += ['}'] txt += [''] txt += ['proc %s::debug_log {debug_level debug_string} {' % MyDriver['namespace']] @@ -1148,6 +1175,20 @@ def put_group(MyDriver, MyGroup): txt += [' hsetprop ${scobj_hpath}/%s units %s' % (nodename, MyVar['units'])] if 'allowed' in MyVar: txt += [' hsetprop ${scobj_hpath}/%s values %s' % (nodename, MyVar['allowed'])] + 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(): + idx = int(device_type[1:]) + device_type = '[string index ${permlink} %d]' % idx + else: + print 'Error: permlink required in make_ags' + if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split(): + permlink = device_type + '[format "%02d" ${id}]' + node_type + else: + permlink = device_type + '${permlink_device_number}' + node_type + txt += [' hsetprop ${scobj_hpath}/%s permlink data_set "%s"' % (nodename, permlink)] + txt += [' hsetprop ${scobj_hpath}/%s @description "%s"' % (nodename, permlink)] if 'value' in MyVar: txt += [' hsetprop ${scobj_hpath}/%s oldval %s' % (nodename, MyVar['value'])] txt += [' hset ${scobj_hpath}/%s %s' % (nodename, MyVar['value'])] @@ -1162,14 +1203,9 @@ def put_group(MyDriver, MyGroup): txt += [' hsetprop ${scobj_hpath}/%s oldval UNKNOWN' % nodename] for key in sorted(MyVar['Property']): txt += [' hsetprop ${scobj_hpath}/%s %s "%s"' % (nodename, key, MyVar['Property'][key])] - # Generated at runtime __ for nxalias and driveable - path = MyVar['path'] - if len(path) > 0: - path = path.replace('/', '_') + '_' - path += MyVar['name'] - #print "Path: %s" % MyVar['path'] - nxalias = '${name}_' + path + # Generate __ at runtime for nxalias if 'nxalias' not in MyVar['Property']: + nxalias = '${name}_' + make_path(MyVar) txt += [' hsetprop ${scobj_hpath}/%s nxalias "%s"' % (nodename, nxalias)] if not MyGroup['name']: if 'GroupProperty' in MyGroup: @@ -1193,7 +1229,9 @@ def put_group(MyDriver, MyGroup): if MyVar['writeable'] > 0 or MyVar['driveable']: txt += [' ${sct_controller} write ${scobj_hpath}/%s' % nodename] if MyVar['driveable']: - txt += [' ansto_makesctdrive %s ${scobj_hpath}/%s ${scobj_hpath}/%s ${sct_controller}' % (nxalias, nodename, MyVar['driveable'])] + # Generate __ at runtime for driveable + driveable = '${name}_' + make_path(MyVar) + txt += [' ansto_makesctdrive %s ${scobj_hpath}/%s ${scobj_hpath}/%s ${sct_controller}' % (driveable, nodename, MyVar['driveable'])] txt += [' }'] for grp in sorted(MyGroup['Groups']): txt += put_group(MyDriver, MyGroup['Groups'][grp]) @@ -1207,17 +1245,19 @@ def put_mk_sct_driver(MyDriver): line = 'proc %s::mk_sct_%s { sct_controller name } {' % (MyDriver['namespace'], MyDriver['name']) txt += [line] if 'make_args' in MyDriver: - make_args = '' - for arg in MyDriver['make_args'].split(): - if len(make_args) > 0: - make_args += ' ' - make_args += '${' + arg + '}' + make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()]) txt += [' debug_log 1 "mk_sct_%s ${sct_controller} ${name} %s"' % (MyDriver['name'], make_args)] else: txt += [' debug_log 1 "mk_sct_%s for ${name}"' % MyDriver['name']] txt += [' set ns "[namespace current]"'] txt += [' set catch_status [ catch {'] txt += [''] + if len(MyDriver['Permlink']) > 0: + if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split(): + pass + else: + txt += [' set permlink_device_number [format "%02d" [incr ::scobj::permlink_device_counter]]'] + txt += [''] txt += [' MakeSICSObj ${name} SCT_OBJECT'] txt += [''] txt += [' sicslist setatt ${name} klass %s' % MyDriver['class']] @@ -1258,11 +1298,7 @@ def put_postamble(MyDriver): txt += [' set catch_status [ catch {'] txt += [' set ns "%s"' % MyDriver['namespace']] if 'make_args' in MyDriver: - make_args = '' - for arg in MyDriver['make_args'].split(): - if len(make_args) > 0: - make_args += ' ' - make_args += '${' + arg + '}' + make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()]) txt += [' ${ns}::debug_log 1 "add_%s ${name} ${IP} ${port} %s"' % (MyDriver['name'], make_args)] else: txt += [' ${ns}::debug_log 1 "add_%s ${name} ${IP} ${port}"' % MyDriver['name']] @@ -1281,11 +1317,7 @@ def put_postamble(MyDriver): txt += [' }'] txt += [' }'] if 'make_args' in MyDriver: - make_args = '' - for arg in MyDriver['make_args'].split(): - if len(make_args) > 0: - make_args += ' ' - make_args += '${' + arg + '}' + make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()]) txt += [' ${ns}::debug_log 1 "mk_sct_%s sct_${name} ${name} %s"' % (MyDriver['name'], make_args)] txt += [' ${ns}::mk_sct_%s sct_${name} ${name} %s' % (MyDriver['name'], make_args)] else: @@ -1405,6 +1437,7 @@ def process_drivers(TheDrivers): MyDriver['namespace'] = '::scobj::%s' % driver MyDriver['Groups'] = {} MyDriver['Funcs'] = {} + MyDriver['Permlink'] = {} build_driver(MyDriver, TheDrivers[driver]) if Verbose: print "MyDriver:", MyDriver['name'], '=', MyDriver