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:
@ -41,6 +41,10 @@ global DriveableFunctionTypes
|
||||
global NumberOfLinesIn
|
||||
global NumberOfLinesOut
|
||||
|
||||
states = (
|
||||
('tcl', 'exclusive'),
|
||||
)
|
||||
|
||||
FunctionTypes = [
|
||||
'read_function',
|
||||
'write_function',
|
||||
@ -147,6 +151,8 @@ tokens = [
|
||||
'TEXT_STRING2',
|
||||
'EQUALS',
|
||||
'ID',
|
||||
'TCL_BEG',
|
||||
'TCL_END',
|
||||
] + list(reserved.values())
|
||||
|
||||
#
|
||||
@ -158,6 +164,38 @@ t_LBRACE = r'{'
|
||||
t_RBRACE = 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):
|
||||
r'\'[^\']+\''
|
||||
t.value = t.value[1:-1]
|
||||
@ -462,6 +500,7 @@ def p_true_false(p):
|
||||
def p_code(p):
|
||||
'''
|
||||
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] }}
|
||||
|
||||
@ -817,15 +856,15 @@ def put_write_function(MyDriver, func):
|
||||
txt += [' set par [sct target]']
|
||||
txt += [' set cmd "${cmd_str}${par}"']
|
||||
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 += ['# hook code ends']
|
||||
txt += ['# %s hook code ends' % func]
|
||||
txt += [' if { [hpropexists [sct] geterror] } {']
|
||||
txt += [' debug_log 1 "[sct] error: [sct geterror]"']
|
||||
txt += [' error "[sct geterror]"']
|
||||
txt += [' }']
|
||||
else:
|
||||
txt += ['# hook code goes here']
|
||||
txt += ['# %s hook code goes here' % func]
|
||||
txt += [' if { [hpropexists [sct] driving] } {']
|
||||
txt += [' if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {']
|
||||
txt += [' sct driving 1']
|
||||
@ -848,11 +887,11 @@ def put_check_function(MyDriver, func):
|
||||
txt += [' set catch_status [ catch {']
|
||||
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:
|
||||
txt += ['# hook code starts']
|
||||
txt += ['# %s hook code starts' % func]
|
||||
txt += MyDriver['Funcs'][func]['text']
|
||||
txt += ['# hook code ends']
|
||||
txt += ['# %s hook code ends' % func]
|
||||
else:
|
||||
txt += ['# hook code goes here']
|
||||
txt += ['# %s hook code goes here' % func]
|
||||
txt += [' return "idle"']
|
||||
txt += [' } catch_message ]']
|
||||
txt += [' handle_exception ${catch_status} ${catch_message}']
|
||||
@ -870,15 +909,15 @@ def put_fetch_function(MyDriver, func):
|
||||
txt += [' }']
|
||||
txt += [' set cmd "${cmd_str}"']
|
||||
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 += ['# hook code ends']
|
||||
txt += ['# %s hook code ends' % func]
|
||||
txt += [' if { [hpropexists [sct] geterror] } {']
|
||||
txt += [' debug_log 1 "[sct] error: [sct geterror]"']
|
||||
txt += [' error "[sct geterror]"']
|
||||
txt += [' }']
|
||||
else:
|
||||
txt += ['# hook code goes here']
|
||||
txt += ['# %s hook code goes here' % func]
|
||||
txt += [' debug_log 1 "%s sct send ${cmd}"' % func]
|
||||
txt += [' if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {']
|
||||
txt += [' sct send "${cmd}"']
|
||||
@ -906,15 +945,15 @@ def put_read_function(MyDriver, func):
|
||||
txt += [' error "[sct geterror]"']
|
||||
txt += [' }']
|
||||
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 += ['# hook code ends']
|
||||
txt += ['# %s hook code ends' % func]
|
||||
txt += [' if { [hpropexists [sct] geterror] } {']
|
||||
txt += [' debug_log 1 "[sct] error: [sct geterror]"']
|
||||
txt += [' error "[sct geterror]"']
|
||||
txt += [' }']
|
||||
else:
|
||||
txt += ['# hook code goes here']
|
||||
txt += ['# %s hook code goes here' % func]
|
||||
txt += [' if { ${data} != [sct oldval] } {']
|
||||
txt += [' debug_log 1 "[sct] changed to new:${data}, from old:[sct oldval]"']
|
||||
txt += [' sct oldval ${data}']
|
||||
@ -947,11 +986,11 @@ def put_checkrange_function(MyDriver, func):
|
||||
txt += [' set hilimit [sct target]']
|
||||
txt += [' }']
|
||||
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 += ['# hook code ends']
|
||||
txt += ['# %s hook code ends' % func]
|
||||
else:
|
||||
txt += ['# hook code goes here']
|
||||
txt += ['# %s hook code goes here' % func]
|
||||
txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {']
|
||||
txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"']
|
||||
txt += [' }']
|
||||
@ -981,11 +1020,11 @@ def put_checklimits_function(MyDriver, func):
|
||||
txt += [' set hilimit [sct target]']
|
||||
txt += [' }']
|
||||
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 += ['# hook code ends']
|
||||
txt += ['# %s hook code ends' % func]
|
||||
else:
|
||||
txt += ['# hook code goes here']
|
||||
txt += ['# %s hook code goes here' % func]
|
||||
txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {']
|
||||
txt += [' sct driving 0']
|
||||
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 += [' set catch_status [ catch {']
|
||||
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 += ['# hook code ends']
|
||||
txt += ['# %s hook code ends' % func]
|
||||
else:
|
||||
txt += ['# hook code goes here']
|
||||
txt += ['# %s hook code goes here' % func]
|
||||
txt += [' if {[sct driving]} {']
|
||||
txt += [' set sp "[sct target]"']
|
||||
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 += [' ### TODO hset [sct] [hval [sct]]']
|
||||
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 += ['# hook code ends']
|
||||
txt += ['# %s hook code ends' % func]
|
||||
else:
|
||||
txt += ['# hook code goes here']
|
||||
txt += ['# %s hook code goes here' % func]
|
||||
txt += [' sct driving 0']
|
||||
txt += [' return "idle"']
|
||||
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 pid [expr ${p_value} + ${i_value} + ${d_value}]']
|
||||
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 += ['# hook code ends']
|
||||
txt += ['# %s hook code ends' % func]
|
||||
else:
|
||||
txt += ['# hook code goes here']
|
||||
txt += ['# %s hook code goes here' % func]
|
||||
txt += [' sct pid_output ${pid}']
|
||||
txt += [' } 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 += [' hsetprop ${scobj_hpath} klass %s' % MyDriver['class']]
|
||||
if 'mkDriver' in MyDriver['Funcs']:
|
||||
txt += ['# hook code starts']
|
||||
txt += MyDriver['Funcs']['mkDriver']['text']
|
||||
txt += ['# hook code ends']
|
||||
func = 'mkDriver'
|
||||
if func in MyDriver['Funcs']:
|
||||
txt += ['# %s hook code starts' % func]
|
||||
txt += MyDriver['Funcs'][func]['text']
|
||||
txt += ['# %s hook code ends' % func]
|
||||
else:
|
||||
txt += ['# hook code goes here']
|
||||
txt += ['# %s hook code goes here' % func]
|
||||
txt += [' } catch_message ]']
|
||||
txt += [' handle_exception ${catch_status} ${catch_message}']
|
||||
txt += ['}']
|
||||
@ -1351,14 +1391,24 @@ def put_config(MyDriver):
|
||||
txt += [' set IP [dict get $v ip]']
|
||||
txt += [' set PORT [dict get $v port]']
|
||||
txt += [' set name [dict get $v name]']
|
||||
txt += [' MakeAsyncProtocol ${name}_protocol']
|
||||
txt += [' if { [dict exists $v "terminator"] } {']
|
||||
txt += [' ${name}_protocol sendterminator "[dict get $v "terminator"]"']
|
||||
txt += [' ${name}_protocol replyterminator "[dict get $v "terminator"]"']
|
||||
txt += [' }']
|
||||
txt += [' MakeAsyncQueue ${name}_queue ${name}_protocol ${IP} ${PORT}']
|
||||
txt += [' if { [dict exists $v "timeout"] } {']
|
||||
txt += [' ${name}_queue timeout "[dict get $v "timeout"]"']
|
||||
txt += [' if { [dict exists $v "asyncqueue"] } {']
|
||||
txt += [' set asyncqueue [dict get $v "asyncqueue"]']
|
||||
txt += [' } else {']
|
||||
txt += [' if { [dict exists $v "asyncprotocol"] } {']
|
||||
txt += [' set asyncprotocol [dict get $v "asyncprotocol"]']
|
||||
txt += [' } else {']
|
||||
txt += [' set asyncprotocol ${name}_protocol']
|
||||
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 += [' }']
|
||||
if 'make_args' in MyDriver:
|
||||
txt += [' set arg_list [list]']
|
||||
@ -1371,10 +1421,10 @@ def put_config(MyDriver):
|
||||
txt += [' }']
|
||||
txt += [' }']
|
||||
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 += [' 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" ${asyncqueue} {*}$arg_list' % MyDriver['name']]
|
||||
else:
|
||||
txt += [' add_%s ${name} "aqadapter" ${name}_queue' % MyDriver['name']]
|
||||
txt += [' add_%s ${name} "aqadapter" ${asyncqueue}' % MyDriver['name']]
|
||||
txt += [' }']
|
||||
txt += [' }']
|
||||
txt += [' }']
|
||||
@ -1477,8 +1527,12 @@ def process_source(source_files):
|
||||
data = fd.read()
|
||||
fd.close()
|
||||
NumberOfLinesIn = data.count('\n')
|
||||
print 'Consumed file %s with %d lines' % (source_file, NumberOfLinesIn)
|
||||
start_line = lexer.lineno
|
||||
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)
|
||||
|
||||
|
Reference in New Issue
Block a user