TCL mode, async{queue,protocol}, and reset line number

The TCL mode allows a begin/end construct and TCL code without the
    leading '@' characters.

    Add the function name to the hook code comments that are generated.

    Reset the line counter to 1 between driver modules for error reporting.
This commit is contained in:
Douglas Clowes
2014-04-23 17:06:20 +10:00
parent be653c91fe
commit fd23ee2443

View File

@ -41,6 +41,10 @@ global DriveableFunctionTypes
global NumberOfLinesIn global NumberOfLinesIn
global NumberOfLinesOut global NumberOfLinesOut
states = (
('tcl', 'exclusive'),
)
FunctionTypes = [ FunctionTypes = [
'read_function', 'read_function',
'write_function', 'write_function',
@ -147,6 +151,8 @@ tokens = [
'TEXT_STRING2', 'TEXT_STRING2',
'EQUALS', 'EQUALS',
'ID', 'ID',
'TCL_BEG',
'TCL_END',
] + list(reserved.values()) ] + list(reserved.values())
# #
@ -158,6 +164,38 @@ t_LBRACE = r'{'
t_RBRACE = r'}' t_RBRACE = r'}'
t_SLASH = r'/' t_SLASH = r'/'
def t_TCL_BEG(t):
r'{%%'
if Verbose:
print 'TCL_BEG'
t.lexer.begin('tcl')
return t
def t_tcl_TCL_END(t):
r'.*%%}'
if Verbose:
print 'TCL_END'
t.lexer.begin('INITIAL')
return t
t_tcl_ignore = ""
def t_tcl_CODE_STRING(t):
r'.+'
if t.value[0] == '@':
t.value = t.value[1:]
if Verbose:
print 'TCL:', t.value
return t
def t_tcl_newline(t):
r'\n+'
t.lexer.lineno += t.value.count("\n")
def t_tcl_error(t):
print("Illegal tcl character '%s'" % t.value[0])
t.lexer.skip(1)
def t_TEXT_STRING1(t): def t_TEXT_STRING1(t):
r'\'[^\']+\'' r'\'[^\']+\''
t.value = t.value[1:-1] t.value = t.value[1:-1]
@ -462,6 +500,7 @@ def p_true_false(p):
def p_code(p): def p_code(p):
''' '''
code : CODE code_type id_or_str EQUALS LBRACE code_block RBRACE code : CODE code_type id_or_str EQUALS LBRACE code_block RBRACE
| CODE code_type id_or_str EQUALS TCL_BEG code_block TCL_END
''' '''
p[0] = { 'Code' : { 'name' : p[3], 'type' : p[2], 'text' : p[6] }} p[0] = { 'Code' : { 'name' : p[3], 'type' : p[2], 'text' : p[6] }}
@ -817,15 +856,15 @@ def put_write_function(MyDriver, func):
txt += [' set par [sct target]'] txt += [' set par [sct target]']
txt += [' set cmd "${cmd_str}${par}"'] txt += [' set cmd "${cmd_str}${par}"']
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
txt += ['# hook code starts'] txt += ['# %s hook code starts' % func]
txt += MyDriver['Funcs'][func]['text'] txt += MyDriver['Funcs'][func]['text']
txt += ['# hook code ends'] txt += ['# %s hook code ends' % func]
txt += [' if { [hpropexists [sct] geterror] } {'] txt += [' if { [hpropexists [sct] geterror] } {']
txt += [' debug_log 1 "[sct] error: [sct geterror]"'] txt += [' debug_log 1 "[sct] error: [sct geterror]"']
txt += [' error "[sct geterror]"'] txt += [' error "[sct geterror]"']
txt += [' }'] txt += [' }']
else: else:
txt += ['# hook code goes here'] txt += ['# %s hook code goes here' % func]
txt += [' if { [hpropexists [sct] driving] } {'] txt += [' if { [hpropexists [sct] driving] } {']
txt += [' if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {'] txt += [' if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {']
txt += [' sct driving 1'] txt += [' sct driving 1']
@ -848,11 +887,11 @@ def put_check_function(MyDriver, func):
txt += [' set catch_status [ catch {'] txt += [' set catch_status [ catch {']
txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] resp=[sct result]"' % func] txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] resp=[sct result]"' % func]
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
txt += ['# hook code starts'] txt += ['# %s hook code starts' % func]
txt += MyDriver['Funcs'][func]['text'] txt += MyDriver['Funcs'][func]['text']
txt += ['# hook code ends'] txt += ['# %s hook code ends' % func]
else: else:
txt += ['# hook code goes here'] txt += ['# %s hook code goes here' % func]
txt += [' return "idle"'] txt += [' return "idle"']
txt += [' } catch_message ]'] txt += [' } catch_message ]']
txt += [' handle_exception ${catch_status} ${catch_message}'] txt += [' handle_exception ${catch_status} ${catch_message}']
@ -870,15 +909,15 @@ def put_fetch_function(MyDriver, func):
txt += [' }'] txt += [' }']
txt += [' set cmd "${cmd_str}"'] txt += [' set cmd "${cmd_str}"']
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
txt += ['# hook code starts'] txt += ['# %s hook code starts' % func]
txt += MyDriver['Funcs'][func]['text'] txt += MyDriver['Funcs'][func]['text']
txt += ['# hook code ends'] txt += ['# %s hook code ends' % func]
txt += [' if { [hpropexists [sct] geterror] } {'] txt += [' if { [hpropexists [sct] geterror] } {']
txt += [' debug_log 1 "[sct] error: [sct geterror]"'] txt += [' debug_log 1 "[sct] error: [sct geterror]"']
txt += [' error "[sct geterror]"'] txt += [' error "[sct geterror]"']
txt += [' }'] txt += [' }']
else: else:
txt += ['# hook code goes here'] txt += ['# %s hook code goes here' % func]
txt += [' debug_log 1 "%s sct send ${cmd}"' % func] txt += [' debug_log 1 "%s sct send ${cmd}"' % func]
txt += [' if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {'] txt += [' if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {']
txt += [' sct send "${cmd}"'] txt += [' sct send "${cmd}"']
@ -906,15 +945,15 @@ def put_read_function(MyDriver, func):
txt += [' error "[sct geterror]"'] txt += [' error "[sct geterror]"']
txt += [' }'] txt += [' }']
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
txt += ['# hook code starts'] txt += ['# %s hook code starts' % func]
txt += MyDriver['Funcs'][func]['text'] txt += MyDriver['Funcs'][func]['text']
txt += ['# hook code ends'] txt += ['# %s hook code ends' % func]
txt += [' if { [hpropexists [sct] geterror] } {'] txt += [' if { [hpropexists [sct] geterror] } {']
txt += [' debug_log 1 "[sct] error: [sct geterror]"'] txt += [' debug_log 1 "[sct] error: [sct geterror]"']
txt += [' error "[sct geterror]"'] txt += [' error "[sct geterror]"']
txt += [' }'] txt += [' }']
else: else:
txt += ['# hook code goes here'] txt += ['# %s hook code goes here' % func]
txt += [' if { ${data} != [sct oldval] } {'] txt += [' if { ${data} != [sct oldval] } {']
txt += [' debug_log 1 "[sct] changed to new:${data}, from old:[sct oldval]"'] txt += [' debug_log 1 "[sct] changed to new:${data}, from old:[sct oldval]"']
txt += [' sct oldval ${data}'] txt += [' sct oldval ${data}']
@ -947,11 +986,11 @@ def put_checkrange_function(MyDriver, func):
txt += [' set hilimit [sct target]'] txt += [' set hilimit [sct target]']
txt += [' }'] txt += [' }']
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
txt += ['# hook code starts'] txt += ['# %s hook code starts' % func]
txt += MyDriver['Funcs'][func]['text'] txt += MyDriver['Funcs'][func]['text']
txt += ['# hook code ends'] txt += ['# %s hook code ends' % func]
else: else:
txt += ['# hook code goes here'] txt += ['# %s hook code goes here' % func]
txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {'] txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {']
txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"'] txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"']
txt += [' }'] txt += [' }']
@ -981,11 +1020,11 @@ def put_checklimits_function(MyDriver, func):
txt += [' set hilimit [sct target]'] txt += [' set hilimit [sct target]']
txt += [' }'] txt += [' }']
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
txt += ['# hook code starts'] txt += ['# %s hook code starts' % func]
txt += MyDriver['Funcs'][func]['text'] txt += MyDriver['Funcs'][func]['text']
txt += ['# hook code ends'] txt += ['# %s hook code ends' % func]
else: else:
txt += ['# hook code goes here'] txt += ['# %s hook code goes here' % func]
txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {'] txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {']
txt += [' sct driving 0'] txt += [' sct driving 0']
txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"'] txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"']
@ -1002,11 +1041,11 @@ def put_checkstatus_function(MyDriver, func):
txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)]
txt += [' set catch_status [ catch {'] txt += [' set catch_status [ catch {']
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
txt += ['# hook code starts'] txt += ['# %s hook code starts' % func]
txt += MyDriver['Funcs'][func]['text'] txt += MyDriver['Funcs'][func]['text']
txt += ['# hook code ends'] txt += ['# %s hook code ends' % func]
else: else:
txt += ['# hook code goes here'] txt += ['# %s hook code goes here' % func]
txt += [' if {[sct driving]} {'] txt += [' if {[sct driving]} {']
txt += [' set sp "[sct target]"'] txt += [' set sp "[sct target]"']
txt += [' set pv "[hval ${tc_root}/[sct driveable]]"'] txt += [' set pv "[hval ${tc_root}/[sct driveable]]"']
@ -1046,11 +1085,11 @@ def put_halt_function(MyDriver, func):
txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] driving=[sct driving]"' % func] txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] driving=[sct driving]"' % func]
txt += [' ### TODO hset [sct] [hval [sct]]'] txt += [' ### TODO hset [sct] [hval [sct]]']
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
txt += ['# hook code starts'] txt += ['# %s hook code starts' % func]
txt += MyDriver['Funcs'][func]['text'] txt += MyDriver['Funcs'][func]['text']
txt += ['# hook code ends'] txt += ['# %s hook code ends' % func]
else: else:
txt += ['# hook code goes here'] txt += ['# %s hook code goes here' % func]
txt += [' sct driving 0'] txt += [' sct driving 0']
txt += [' return "idle"'] txt += [' return "idle"']
txt += [' } catch_message ]'] txt += [' } catch_message ]']
@ -1078,11 +1117,11 @@ def put_pid_function(MyDriver, func):
txt += [' set i_value [expr [sct pid_ivalue] * [sct pid_integ]]'] txt += [' set i_value [expr [sct pid_ivalue] * [sct pid_integ]]']
txt += [' set pid [expr ${p_value} + ${i_value} + ${d_value}]'] txt += [' set pid [expr ${p_value} + ${i_value} + ${d_value}]']
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
txt += ['# hook code starts'] txt += ['# %s hook code starts' % func]
txt += MyDriver['Funcs'][func]['text'] txt += MyDriver['Funcs'][func]['text']
txt += ['# hook code ends'] txt += ['# %s hook code ends' % func]
else: else:
txt += ['# hook code goes here'] txt += ['# %s hook code goes here' % func]
txt += [' sct pid_output ${pid}'] txt += [' sct pid_output ${pid}']
txt += [' } catch_message ]'] txt += [' } catch_message ]']
txt += [' handle_exception ${catch_status} ${catch_message}'] txt += [' handle_exception ${catch_status} ${catch_message}']
@ -1273,12 +1312,13 @@ def put_mk_sct_driver(MyDriver):
txt += put_group(MyDriver, MyDriver['Groups'][group]) txt += put_group(MyDriver, MyDriver['Groups'][group])
txt += [' hsetprop ${scobj_hpath} klass %s' % MyDriver['class']] txt += [' hsetprop ${scobj_hpath} klass %s' % MyDriver['class']]
if 'mkDriver' in MyDriver['Funcs']: func = 'mkDriver'
txt += ['# hook code starts'] if func in MyDriver['Funcs']:
txt += MyDriver['Funcs']['mkDriver']['text'] txt += ['# %s hook code starts' % func]
txt += ['# hook code ends'] txt += MyDriver['Funcs'][func]['text']
txt += ['# %s hook code ends' % func]
else: else:
txt += ['# hook code goes here'] txt += ['# %s hook code goes here' % func]
txt += [' } catch_message ]'] txt += [' } catch_message ]']
txt += [' handle_exception ${catch_status} ${catch_message}'] txt += [' handle_exception ${catch_status} ${catch_message}']
txt += ['}'] txt += ['}']
@ -1351,14 +1391,24 @@ def put_config(MyDriver):
txt += [' set IP [dict get $v ip]'] txt += [' set IP [dict get $v ip]']
txt += [' set PORT [dict get $v port]'] txt += [' set PORT [dict get $v port]']
txt += [' set name [dict get $v name]'] txt += [' set name [dict get $v name]']
txt += [' MakeAsyncProtocol ${name}_protocol'] txt += [' if { [dict exists $v "asyncqueue"] } {']
txt += [' if { [dict exists $v "terminator"] } {'] txt += [' set asyncqueue [dict get $v "asyncqueue"]']
txt += [' ${name}_protocol sendterminator "[dict get $v "terminator"]"'] txt += [' } else {']
txt += [' ${name}_protocol replyterminator "[dict get $v "terminator"]"'] txt += [' if { [dict exists $v "asyncprotocol"] } {']
txt += [' }'] txt += [' set asyncprotocol [dict get $v "asyncprotocol"]']
txt += [' MakeAsyncQueue ${name}_queue ${name}_protocol ${IP} ${PORT}'] txt += [' } else {']
txt += [' if { [dict exists $v "timeout"] } {'] txt += [' set asyncprotocol ${name}_protocol']
txt += [' ${name}_queue timeout "[dict get $v "timeout"]"'] txt += [' MakeAsyncProtocol ${asyncprotocol}']
txt += [' if { [dict exists $v "terminator"] } {']
txt += [' ${asyncprotocol} sendterminator "[dict get $v "terminator"]"']
txt += [' ${asyncprotocol} replyterminator "[dict get $v "terminator"]"']
txt += [' }']
txt += [' }']
txt += [' set asyncqueue ${name}_queue']
txt += [' MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT}']
txt += [' if { [dict exists $v "timeout"] } {']
txt += [' ${asyncqueue} timeout "[dict get $v "timeout"]"']
txt += [' }']
txt += [' }'] txt += [' }']
if 'make_args' in MyDriver: if 'make_args' in MyDriver:
txt += [' set arg_list [list]'] txt += [' set arg_list [list]']
@ -1371,10 +1421,10 @@ def put_config(MyDriver):
txt += [' }'] txt += [' }']
txt += [' }'] txt += [' }']
txt += [' ${ns}::debug_log 1 "arg_list = $arg_list"'] txt += [' ${ns}::debug_log 1 "arg_list = $arg_list"']
txt += [' ${ns}::debug_log 1 "add_%s ${name} aqadapter ${name}_queue $arg_list"' % MyDriver['name']] txt += [' ${ns}::debug_log 1 "add_%s ${name} aqadapter ${asyncqueue} $arg_list"' % MyDriver['name']]
txt += [' add_%s ${name} "aqadapter" ${name}_queue {*}$arg_list' % MyDriver['name']] txt += [' add_%s ${name} "aqadapter" ${asyncqueue} {*}$arg_list' % MyDriver['name']]
else: else:
txt += [' add_%s ${name} "aqadapter" ${name}_queue' % MyDriver['name']] txt += [' add_%s ${name} "aqadapter" ${asyncqueue}' % MyDriver['name']]
txt += [' }'] txt += [' }']
txt += [' }'] txt += [' }']
txt += [' }'] txt += [' }']
@ -1477,8 +1527,12 @@ def process_source(source_files):
data = fd.read() data = fd.read()
fd.close() fd.close()
NumberOfLinesIn = data.count('\n') NumberOfLinesIn = data.count('\n')
print 'Consumed file %s with %d lines' % (source_file, NumberOfLinesIn) start_line = lexer.lineno
yaccer.parse(data) yaccer.parse(data)
stop_line = lexer.lineno
print 'Consumed file %s with %d lines (%d, %d)' % (source_file,
NumberOfLinesIn, start_line, stop_line - 1)
lexer.lineno = 1
process_drivers(TheDrivers) process_drivers(TheDrivers)