- Added code to read SANS TOF frames from a) files and b) from HM
- Fixed an bug causing core dumps on bad Tcl scripts - Started on a syntax checker for SICS
This commit is contained in:
86
utils/check/sicssyntax.tex
Normal file
86
utils/check/sicssyntax.tex
Normal file
@@ -0,0 +1,86 @@
|
||||
\documentclass[12pt,a4paper]{article}
|
||||
%%\usepackage[dvips]{graphics}
|
||||
%%\usepackage{epsf}
|
||||
\setlength{\textheight}{24cm}
|
||||
\setlength{\textwidth}{16cm}
|
||||
\setlength{\headheight}{0cm}
|
||||
\setlength{\headsep}{0cm}
|
||||
\setlength{\topmargin}{0cm}
|
||||
\setlength{\oddsidemargin}{0cm}
|
||||
\setlength{\evensidemargin}{0cm}
|
||||
\setlength{\hoffset}{0cm}
|
||||
\setlength{\marginparwidth}{0cm}
|
||||
|
||||
\begin{document}
|
||||
\begin{center}
|
||||
\begin{Large}
|
||||
SICS Syntax Checker\\
|
||||
Implementation Notes\\
|
||||
\end{Large}
|
||||
Mark K\"onnecke\\
|
||||
Mark.Koennecke@psi.ch\\
|
||||
March/April 2003\\
|
||||
Laboratory for Neutron Scattering\\
|
||||
Paul Scherrer Institute\\
|
||||
CH--5232 Villigen--PSI
|
||||
Switzerland
|
||||
\end{center}
|
||||
|
||||
Users wish to check their batch files for syntax errors before
|
||||
submitting them to SICS for the weekend or the night. Unfortunately
|
||||
checking SICS syntax is not so easy as it consists of Tcl syntax plus
|
||||
SICS commands. In order to implement a syntax checker various
|
||||
possibilities exist:\begin{itemize}
|
||||
\item Implement the syntax checker as a calculation mode within
|
||||
SICS. This has the disadvantage that the syntax check can only be run
|
||||
by one person and only when the SICS server is not performing an
|
||||
experiment. This is due to the fact, that SICS has only one set of
|
||||
variables which may be changed dureing the syntax check. In order to
|
||||
prevent corruption the security measures stated above are necessary.
|
||||
\item Use a SICServer with simulated hardware. This would
|
||||
work. Problems are that this is very time consuming to set up and the
|
||||
synchronisation of parameter values with the main SICServer. This has
|
||||
been solved through the sync command and thus this option is available
|
||||
for complex scripts.
|
||||
\item Use a Tcl interpreter with dummy SICS commands as a syntax
|
||||
checker. In many cases batch files are fairly simple and a complete
|
||||
simulation is not needed. The such a option would be sufficient.
|
||||
\end{itemize}
|
||||
\end{document}
|
||||
|
||||
\section{The Tcl Syntax Checker}
|
||||
This section describes the syntax checker built from a Tcl interpreter
|
||||
with dummy routines testing SICS syntax. The dummy procedures only
|
||||
have to test the syntax and else do nothing. Not many such proecdures
|
||||
have to be implemented but a means is needed for mapping names, for
|
||||
instance motor names, to a suitable procedure for checking the syntax.
|
||||
|
||||
This syntax checker can be used in a variety of situations:
|
||||
\begin{itemize}
|
||||
\item Standalone: the preferred mode of operation
|
||||
\item Within SICS: SICS would need to have a second Tcl interpreter
|
||||
for this purpose in order to prevent corruption of the main
|
||||
interpreter. Even then a rogue script could go into an endless loop
|
||||
and thus hang the SICS server. Thus this second interpreter would have
|
||||
to run as a separate process or thread.
|
||||
\item This syntax checker could also help debugging SICS scripts.
|
||||
\end{itemize}
|
||||
|
||||
For each instrument two files are needed for this syntax checker. The
|
||||
first is a common library file which implements the syntax checking
|
||||
procedures and the sics_alias procedure which maps names to
|
||||
procedures. The second is a mapping file which defines the instrument
|
||||
and enables those names the instrument provides. This is much like the
|
||||
instrument initialization file for the main SICS program.
|
||||
|
||||
In order to help in script debugging, a global array with parameter
|
||||
values defined through the user script will be maintained.
|
||||
|
||||
In a latter stage a connection to the main SICS could be added to the
|
||||
system. Through this connection the actual configuration of the
|
||||
instrument could be queried. Also parameter values can be updated in
|
||||
order to help in debugging sophisticated scripts. Moreover this
|
||||
connection could be used to check limit violations.
|
||||
|
||||
|
||||
|
||||
168
utils/check/sicssyntaxlib.tcl
Normal file
168
utils/check/sicssyntaxlib.tcl
Normal file
@@ -0,0 +1,168 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
# This is the library file for the Tcl syntax checker for SICS commands.
|
||||
# The basic idea is this:
|
||||
# - SICS commands are replaced by Tcl procedures with the same name which
|
||||
# implement the actual syntax check for this command.
|
||||
# - As many SICS commands are object commands a facility is needed to map
|
||||
# syntax checking procedures to names.
|
||||
#
|
||||
# copyright: see file COPYRIGHT
|
||||
#
|
||||
# Mark Koennecke, March 2003
|
||||
#---------------------------------------------------------------------------
|
||||
# sicsSyntaxMap maps the procedure syntaxProc to the name name. The name
|
||||
# is prepended to the argument list in order to make the name available
|
||||
# in the syntax checking procedure as the first argument
|
||||
# This means syntax check procedures have two arguments:
|
||||
# - the name
|
||||
# - the list of remaining parameters as a string. Use syntaxListify
|
||||
# to convert the list to a proper list for further processing
|
||||
#---------------------------------------------------------------------------
|
||||
proc sicsSyntaxMap {name syntaxProc} {
|
||||
append newProc "proc " $name " args " \{ $syntaxProc " "
|
||||
append newProc $name " " "\$args" \}
|
||||
eval $newProc
|
||||
}
|
||||
#--------------------------------------------------------------------------
|
||||
# a helper procedure which tests a value if it is numeric
|
||||
#--------------------------------------------------------------------------
|
||||
proc syntaxNumeric {val} {
|
||||
set ret [catch {expr $val *1.} msg]
|
||||
if { $ret == 0} {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
#--------------------------------------------------------------------------
|
||||
# a helper procedure which converts a stringified list back into a proper
|
||||
# list
|
||||
#--------------------------------------------------------------------------
|
||||
proc syntaxListify {uff} {
|
||||
set l [string trim $uff "{}"]
|
||||
return [split $l]
|
||||
}
|
||||
#--------------------------------------------------------------------------
|
||||
# a helper procedure which gets a parameter from the global parameter
|
||||
# array or replaces it by the default 77 if it does not exist
|
||||
#-------------------------------------------------------------------------
|
||||
proc syntaxGet {name} {
|
||||
global sicsPar
|
||||
if { [info exists sicsPar($name)] == 1} {
|
||||
return [format "%s = %s" $name \
|
||||
$sicsPar($name)]
|
||||
} else {
|
||||
return [format " %s = 77" $name]
|
||||
}
|
||||
}
|
||||
#------------------------------------------------------------------------
|
||||
# syntaxCounterMode tests if par is a valid counter mode
|
||||
#-----------------------------------------------------------------------
|
||||
proc syntaxCounterMode {par} {
|
||||
set p [string trim [string tolower $par]]
|
||||
switch $p{
|
||||
monitor { return 1}
|
||||
timer {return 1}
|
||||
default { return 0}
|
||||
}
|
||||
}
|
||||
#---------------------------------------------------------------------------
|
||||
# syntaxDummy is a syntax checking procedure which does nothing. This is a
|
||||
# quick fix for SICS commands for which no syntax checking procedure has yet
|
||||
# been defined.
|
||||
#-------------------------------------------------------------------------
|
||||
proc syntaxDummy {name args} {
|
||||
set args [syntaxListify $args]
|
||||
return
|
||||
}
|
||||
#-----------------------------------------------------------------------
|
||||
# syntaxTextPar is a syntax handling procedure for simple text variables
|
||||
#----------------------------------------------------------------------
|
||||
proc syntaxTextPar {name args} {
|
||||
global sicsPar
|
||||
|
||||
set args [syntaxListify $args]
|
||||
if { [llength $args] > 0} {
|
||||
set sicsPar($name) [join $args]
|
||||
} else {
|
||||
if { [info exists sicsPar($name)] == 1} {
|
||||
return [format "%s = %s" $name \
|
||||
$sicsPar($name)]
|
||||
} else {
|
||||
return [format " %s = UNKNOWN" $name]
|
||||
}
|
||||
}
|
||||
}
|
||||
#------------------------------------------------------------------------
|
||||
# syntaxNumPar is a syntax handling procedure for a numeric variable
|
||||
#-----------------------------------------------------------------------
|
||||
proc syntaxNumPar {name args} {
|
||||
global sicsPar
|
||||
|
||||
set args [syntaxListify $args]
|
||||
if { [llength $args] > 0} {
|
||||
if { [syntaxNumeric [lindex $args 0]] == 1} {
|
||||
set sicsPar($name) [lindex $args 0]
|
||||
} else {
|
||||
error [format \
|
||||
"ERROR: expected numeric argument for %s, received: %s" \
|
||||
$name [lindex $args 0]]
|
||||
}
|
||||
} else {
|
||||
return [syntaxGet $name]
|
||||
}
|
||||
}
|
||||
#--------------------------------------------------------------------------
|
||||
# syntaxMotor handles the syntax for a SICS motor
|
||||
#-------------------------------------------------------------------------
|
||||
lappend motSubKey list reset interest uninterest position hardposition
|
||||
lappend motSub hardlowerlim hardupperlim softlowerlim
|
||||
lappend motSub softupperlim softzero fixed interruptmode precision
|
||||
lappend motSub accessmode sign failafter
|
||||
|
||||
proc syntaxMotor {name args} {
|
||||
global sicsPar motSub motSubKey
|
||||
|
||||
set args [syntaxListify $args]
|
||||
#----- value request
|
||||
if { [llength $args] == 0} {
|
||||
return [syntaxGet $name]
|
||||
}
|
||||
#---------- keywords
|
||||
set subcommand [string tolower [lindex $args 0]]
|
||||
if { [lsearch $motSubKey $subcommand] >= 0} {
|
||||
return
|
||||
}
|
||||
#---------- parameters
|
||||
if { [lsearch $motSub $subcommand] < 0} {
|
||||
error [format "ERROR: motor %s does not know subcommand %s" \
|
||||
$name $subcommand]
|
||||
} else {
|
||||
if { [llength $args] > 1 } {
|
||||
set val [lindex $args 1]
|
||||
if { [syntaxNumeric $val] == 0 } {
|
||||
error [format "ERROR: %s.%s expected number, received %s" \
|
||||
$name $subcommand $val]
|
||||
} else {
|
||||
set sicsPar($name.$subcommand) $val
|
||||
}
|
||||
} else {
|
||||
return [syntaxGet $name.$subcommand]
|
||||
}
|
||||
}
|
||||
}
|
||||
#---------------------------------------------------------------------------
|
||||
# syntaxCounter deals with the syntax for a single counter
|
||||
#---------------------------------------------------------------------------
|
||||
proc syntaxCounter {name args} {
|
||||
global sicsPar motSub motSubKey
|
||||
|
||||
set args [syntaxListify $args]
|
||||
if { [llength $args == 0} {
|
||||
error [format "ERROR: subcommand expected to %s" $name]
|
||||
}
|
||||
#--------- get command
|
||||
set subcommand [string trim [string tolower [lindex $args 0]]]
|
||||
switch $subcommand {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user