SQ Files Reference

This chapter describes the syntax of SQ files, the "programs" run by SysQuake, and the contents of SQ Data files (files with a .sqd suffix), which store the state of a session with an SQ file.

SQ Files

SQ files define the set of interactive plots which can be displayed. Each SQ file corresponds to a specific kind of problem; for instance, one could have SQ files for the design of a digital filter or a PID controller for continuous-time systems, for the study of the effect of initial conditions on a simulation, and so on.

SQ files are text files. You can write them using any text editor or word processor. Make sure that you save them as plain ASCII files, without any style or formatting information; depending on the application, this option is called Text Document, Text Only, ASCII File, or an equivalent expression. Also, do not rely on automatic word wrapping; make sure that all lines end with an explicit end-of-line character. SysQuake accepts carriage returns, line feeds, or both, to accommodate for the text file formats found on different operating systems.

SQ files contain four kinds of elements:

Declaration of variables
Variables are used as parameters for the figures. Manipulating a figure changes some of the variables, and all the figures currently displayed are updated to reflect the changes.
Declaration of handlers
Handlers are functions executed to perform different tasks managed by SysQuake, such as initialization, figure manipulation, or menu selection. As input and output, they use variables as well as values managed directly by SysQuake, such as the position of the mouse. Values managed by SysQuake are identified with a name beginning with an underscore. In addition, handlers may also use integer numbers as input arguments (only scalar are permitted, not matrices).
Function definitions
Handlers are implemented by functions written in LME, an interpreted language well suited for numerical computation.
Help
A textual description can be provided in SQ files. SysQuake displays it upon user request.

In the description below, the elements marked optional can be omitted in most SQ files. They are required only for specific purposes. Note that technically, no element is required; an empty SQ file is valid, as well as one which defined an init handler without any variable, or only menu handlers. However, elements not marked optional are the meat of SQ files which define interactive figures.

Syntax

SQ files contain declarations, blocks of text, and comments. Declarations are always placed at the beginning of a line; they start with a keyword, and are usually followed by other elements. Here is the list of keywords:

data
draw
export
figure
function
functions
help
idle
import
init
input
make
menu
mousedown
mousedoubleclick
mousedrag
mousedragcont
mouseout
mouseover
mouseup
output
separator
terminate
variable
variables
 
 

Declarations must be either contained on a single line or split into several lines with the continuation characters ... at the end of the first line(s):

variable a, b, ...
         c, d, e

Many keywords are followed by handler declarations. These handlers are implemented in LME code in a functions block and may accept input arguments and output arguments. Arguments may be variables declared in the SQ file, special arguments beginning with an underscore, or (for the input arguments) integer numbers. In some case, handler declarations may be reduced to a simple assignment such as y=x or num=3. Expressions are not allowed.

Comments are either enclosed between /* and */ or span from // to the next end of line. They cannot be nested. In function blocks (see below), LME comments beginning with the character % are also permitted.

Declaration of Variables

Variables defined at the level of the SQ file play a very important role in SysQuake. They are global; all handlers can use them as input and/or output arguments. They are preserved between handler executions. They contain the whole state of SysQuake; together with the SQ file itself, they permit to restore what appears in the Figure window, and are used in the Save mechanism. Finally, they are the base of the Undo system, which enables the user to cancel the last operations (such as manipulating a figure with the mouse, changing a subplot or entering numerical values in a dialog box) and redo them.

Variables are declared with the variable (or variables) keyword, followed by one or several variable names separated by commas or spaces. They contain real or complex arrays of floating-point numbers, which include the empty array [], scalars, and logical values where 0 means false and anything else means true. Variables are always defined; variables whose value has not been set explicitly contain the empty array []. Variable names are made of letters, digits and underscores; they begin with a letter, and case is significant, like everywhere else in SysQuake. Names beginning with an underscore are reserved for special purposes and should not be used for variables.

Three variables are managed by SysQuake and cannot be used in handlers: _plots, which contains the name of the subplots (see the subplots command); _plotprops, which contains the properties and scaling of each subplot (see the subplotprops command); and _plotpos, which contains the position of subplots when Free Position is enabled. They are revealed when the state of SysQuake is saved in SQ Data files.

Variables are given initial values in the init handler (see below).

Example

variable x
variables num den

Variables can be declared nondumpable to prevent SysQuake from saving and restoring them, be it with the Undo/Redo mechanism or with Save and Open. Nondumpable variables can be used and modified like any other variable; however, modifying them with any handler will prevent Undo from restoring their previous state, and Save (or Dump Data) will skip their value (the saving mechanism is detailed later in this chapter). Variable which should be declared as nondumpable include file descriptors for files and serial port connections: a file descriptor is only valid if the corresponding file or device has been opened with fopen or opendevice.

Nondumpable variables are declared with the keyword _nondumpable following immediately variable. No comma may precede or follow _nondumpable. Dumpable and nondumpable variables may not be mixed in the same declaration.

Example

variables _nondumpable fd, connection

Declaring variables explicitly incites to plan how they will be used as the glue between the different handlers. It makes easier the documentation; each variable can be commented, and their enumeration, if self-explanatory names are chosen, is itself an important help for future maintenance. But in case where small scripts are preferred (maybe as a simplified version for on-line distribution), implicit declarations are also possible. Implicit declarations are enabled as follows:

variable _implicit

When implicit declarations are enabled, all the variables appearing in the handler declarations are managed by SysQuake exactly as if they had been declared explicitly in variable statements. Implicit variables cannot have the _nondumpable attribute; however, you can declare only the nondumpable variables and have a variable _implicit declaration for all other variables.

Init and Terminate Handlers

(Terminate handler: optional)

The purpose of the init handler is to provide default values for the variables and the plot options. The variables are initialized with the values returned by the init handler; other variables (those not enumerated in the left-hand part of the handler declaration) are set to the empty array []. The initial plots are set up with the commands subplots, subplotprops, and subplotpos. By default, the first figure is displayed. The same functions can be used without any argument to retrieve the corresponding values; this is especially useful to store these settings in a data file.

Example

function [A,B,R,S] = init

  // default values for A, B, R and S

  A = [1,1];
  B = 1;
  R = 1;
  S = 5;

  // default plots

  subplots('roots\tstep');
    // kind of plots, separated with tabs and line feeds
    // (one row of two subplots)

  props = [0,-2,0,-1,1         // lin. scale, zoom on [-2,0,-1,1]
           0,nan,nan,nan,nan]; // default lin. scale
  subplotprops(props);

Should resources be allocated by the init handler, a terminate handler can be defined to release them. This is necessary only if commands with side effects are used, for instance if a file is opened by the init handler. The terminate handler is declared like other handlers. Output variables are useless, because the variables are discarded immediately after its execution.

terminate termFn(var)

Example

Here is an example of init and terminate handlers which open and close a file, respectively. Other handlers can read from or write to the file. In this example, a custom input handler should be written to avoid resetting the value of the file descriptor fd (see below).

variable fd

init fd = init
terminate terminate(fd)

functions
{@
function fd = init
    
    fd = fopen('data.txt', 'rt');

function terminate(fd)
    
    fclose(fd);
@}

Figure Declaration

Each figure is declared by a figure declaration, introduced by the figure keyword:

figure "Figure Name"

The string which follows the figure keyword is the figure name, which can contain any character and space. It is displayed as a title above the figure and in the Plots menu, and is used by the subplots command as an identifier. The figure declaration is followed by the draw, mousedown, mousedoubleclick, mousedrag, mousedragcont, mouseup, mouseover, and mouseout handlers corresponding to the figure. Only the draw handler is required.

The Plots menu follows the order of the figure declarations. Separators (horizontal lines in the menu) can be inserted to make the menu easier to read, with the separator keyword.

Example

figure "Input Signal"
  draw drawInputSignal(u);
  mousedrag u = dragInputSignal(u, _id, _y1);
  mouseover _cursor = overInputSignal(_id)

figure "Output Signal"
  draw drawOutputSignal(y);

separator

figure "Model"
  draw drawModel(u, y);

Draw Handler

Each figure has one draw handler, declared with the draw keyword:

draw drawFn(v1, v2, ...)

The handler draws the figure with graphic commands such as plot, circle, or step. The scale command may be used to set the default scale and the scale options.

The draw handler typically has input arguments; but it never has any output argument. It also accepts the special input argument _param (see below).

Mousedown, Mousedoubleclick, Mousedrag, Mousedragcont, Mouseup, Mouseover, and Mouseout Handlers

(Mousedown, mousedoubleclick, mousedragcont, mouseup, and mouseout handlers: optional)

The mousedown, mousedoubleclick, mousedrag, mouseup, mouseover, and mouseout handlers are called when the mouse is over the figure they are defined for and the mouse button is pressed, double-clicked, held down, released, left unpressed, or move outside respectively. The mousedragcont handler is an alternative to the mousedrag handler (see below). The table below summaries their differences. For example, the mousedrag handler accepts variables (declared with the variable keyword) as input and output arguments; it can set the special variable _msg with an output argument, and its role is to modify variables during a mouse drag.

HandlerVar._msg_cursorRole
mousedownin/out--Prepares a drag
mousedoubleclickin/out--2nd click of a dble-click
mousedragin/outout-Performs a drag
mousedragcontin/outout-Performs a drag
mouseupin/out--Cleans up after a drag
mouseoverin/outoutoutGives visual feedback
mouseoutin/out--Clean up visual fdback

The purpose of the mouseover handler is to give to the user visual feedback about what is below the cursor, with a message or the shape of the cursor. It is also possible to change the variable, and though them all the displayed graphics, when the mouse is moved over a figure. This should be used only to give some additional hint about what is below the cursor (such as highlighting a matching element in another graphic), not as a substitute of mousedrag, because the user has no way to select what he wants to manipulate. The mouseout handler should be used to restore the state of the variables.

The purpose of the mousedown, mousedoubleclick, mousedrag, mousedragcont, and mouseup handlers is to handle interactions. They receive as input arguments the position of the mouse and the value of variables, and return as output arguments new values for the variables. Unless an error occurs, the mousedown, mousedrag, mouseup, and draw handlers are called with the following arguments. The placeholder S0 represents the set of variables before the mouse down, and S1 the set after the mouse up.

S0 = mousedown(S0)
S0 = draw(S0)
S1 = S0
while the mouse button is down
  S1 = mousedrag(S0)
  S1 = draw(S1)
end
S1 = mouseup(S0)
S1 = draw(S1)

The Undo command discards S1 and reverts to S0. Hence the changes caused by mousedown should be limited to computing auxiliary values used for the drag operation, but invisible to the user. If an error occurs, the sequence is aborted, and S1 is discarded.

The sequence above can be reduced to much simpler forms. For dragging an element, it is often sufficient to define mousedrag and draw:

while the mouse button is down
  S1 = mousedrag(S0)
  S1 = draw(S1)
end

To change the controller on a simple mouse click, only the mouseup handler is used (as explained above, the mousedown function does not change S1).

S1 = mouseup(S0)
S1 = draw(S1)

The mousedrag handler is always executed immediately after the mousedown handler if there is one, even if the mouse is not moved. To display some information without changing anything when you drag the mouse and remove any trace afterwards, you can define a mousedrag handler which sets variables used by the draw handlers, then discard S1 with a mouseup handler which just contains the cancel command.

The mousedrag handler uses as input arguments the values the variables had before the drag. After the drag, the variables will be affected only by the position of the mouse at the beginning and at the end of the drag operation; the trajectory of the mouse is lost. This behavior is often desirable. In the infrequent cases where it is not, the mousedrag handler should be replaced with a mousedragcont handler. SysQuake calls the handlers in the following sequence:

S0 = mousedown(S0)
S0 = draw(S0)
S1 = S0
while the mouse button is down
  S1 = mousedragcont(S1)
  S1 = draw(S1)
end
S1 = mouseup(S0)
S1 = draw(S1)

The only difference with the mousedrag handler is that mousedragcont handlers use the new values of the variables as input arguments and modify them continuously. They can record the whole trajectory of the mouse (or any information derived from the trajectory). For example, a mousedragcont handler could be used to draw in a pixmap.

The mousedoubleclick handler is called when the mouse button is pressed down for the second time shortly after the first one. The mousedown, mousedrag, mouseup and draw handlers (if they exist) have been called for the first click.

In addition to the variables defined with the variable keyword, you can use the following predefined variables as input argument for the mousedown, mousedoubleclick, mousedrag, mouseup, and mouseover handlers.

_z initial position of the mouse as a complex number
_x initial horizontal position of the mouse
_y initial vertical position of the mouse
_z0 initial position of the clicked element as a complex number
_x0 initial horizontal position of the clicked element
_y0 initial vertical position of the clicked element
_z1 current position of the mouse as a complex number
_x1 current horizontal position of the mouse
_y1 current vertical position of the mouse
_kx factor the horizontal position is multiplied by (_x1/_x)
_ky factor the horizontal position is multiplied by (_y1/_y)
_q additional data specific to the plot
_m true if the modifier key (Shift key) is held down
_id ID of the manipulated object
_nb number of the manipulated trace (1-based)
_ix index of the manipulated point (1-based)
_param subplot parameter

The value of _z0 is constrained to existing elements of the plot, contrary to _z which represents the actual position of the mouse click. The value of _z1 is not constrained. If you need the original position of the manipulated object, you should usually use _z0 (or _x0 or _y0) and replace it with _z1. The value of _z is used when the amplitude of the move is considered, not the initial and final positions, or when no object is selected.

The value of _id is the value you define in plot commands for elements you want to manipulate. You can use it to recognize different graphical objects in the same figure. The value of _nb defines which line is manipulated amongst those plotted by the same command (most graphical commands can draw multiple lines or multiple responses). The value of _ix, an integer starting from 1, is always defined when the user selected an element of the figure; it is useful mainly for traces where you define explicitly each point, e.g. plot and line. Note that you need not use IDs; all clicks generate calls to the mouse handler(s), and _z, _z1, _x, _x1, _y, and _y1 are always defined.

For each subplot, SysQuake maintains a piece of data which can be used freely for any purpose. This data is passed to and from all figure-related handlers with _param. It is initialized to the empty matrix []. It is useful in cases where the same figure is displayed in different subplots; _param may contain for instance initial data for a simulation. It may also be used as input or output argument of menu, import and export handlers and in their _enable and _checkmark expression; in these cases, the handlers are enabled when a single subplot is selected.

As output argument of the mousedrag and mouseover handlers, you can use the following special variables:

_msg string displayed in the status bar at the bottom of the window
_param new value of the subplot parameter

The variable _msg is typically set to describe what is below the cursor, with possibly some numerical values using sprintf.

As output argument of the mouseover handler, you can also use the following special variable:

_cursor true to display the cursor as a finger in manipulate mode

The shape of the cursor gives a hint to the user whether he can manipulate the object below the cursor. This can makes the use of SQ files much easier. By default in manipulate mode, the finger cursor is displayed in figures where mousedown, mousedrag and/or mouseup handlers are defined; otherwise, the cursor is the standard arrow. Sliders (see command slider) are a special case; the finger is displayed only when the cursor is over a slider. In case you define mouse handlers, though, you often want to specify explicitly whether any manipulation is possible.

Example

Here are handlers for displaying the roots of a polynomial A that you can manipulate.

figure "Roots"
  draw drawRoots(A)
  mousedrag A = dragRoots(A, _z0, _z1)
  mouseover _cursor = overRoots(_id)

functions
{@
function drawRoots(A)
  // plot the roots of polynomial A
  plotroots(A,'x',1);
  
function A = dragRoots(A, z0, z1)
  // if the click is too far away from a root of A, z0 is empty
  if isempty(z0)
    cancel;                 // discard the dragging operation
  end
  A = movezero(A, z0, z1);  // move the root
  
function cursor = overRoots(id)
  // displays a finger if the cursor is over a root,
  // and a plain cursor otherwise
  cursor = ~isempty(id);
@}

Last thing to note about cursors, if your mouseover handler declaration specifies _cursor as the (or one of the) output(s), and your mouseover handler is canceled by cancel, the cursor is set to the plain arrow. Hence you can have code like

if isempty(id)
  cancel;
end

early in your mouseover handler.

Menu Handler

(Optional)

The interactive manipulation of graphical elements is not suited for all the modifications of the variables. To change the structure of a controller or to specify numerical values, a command triggered by a menu entry, possibly with the help of a dialog box, is more convenient. That is the purpose of menu handlers, which are installed in the Settings menu. Menu handlers are declared as follows:

menu "Title" (out1, out2, ...) = function(in1, in2, ...)

The string is the menu entry title. The function typically gives new values to one or more variables. If numerical values must be entered or modified by the user, or if a confirmation is required, the dialog command should be used. To cancel the action, the cancel command must be used to prevent a new set of variables from being created in the Undo buffer.

Like figures, menus are listed in the Settings menu in the same order as their declaration in the SQ file. Separators can be added with the separator keyword. The appearance of the menu entries can be modified in two ways: they can be disabled (they are written in gray and cannot be selected) with the _enable keyword, and they can be decorated with a check mark with the _checkmark keyword. Both keywords must appear between the menu handler title and the handler function declaration. They use a single LME boolean expression (typically based on the variables) as argument.

Example

In the following example, the variable color has the value 0 for black, 1 for blue and 2 for red.

variable color

menu "Black" _checkmark(color==0) color=0
menu "Blue" _checkmark(color==1) color=1
menu "Red" _checkmark(color==2) color=2
separator
menu "Polygon"
     _checkmark(polygon) polygon=toggle(polygon)
menu "Number of Sides..."
     _enable(polygon) sides=setNumberOfSides(sides)

functions
{@
function b = toggle(b)
  b = ~b;

function sides = setNumberOfSides(sides)
  (ok, sides) = dialog('Number of sides:', sides);
  if ~ok
    cancel;
  end
@}

Idle Handler

(Optional)

In addition to menu and mouse handlers, which modify SysQuake variables when the user performs some action, SQ files can define an idle handler, which is called periodically. Variables are modified without adding a new undo level. An idle handler is declared as follows:

idle (output_variables) = idleHandler(input_variables)

The rate at which the idle handler is executed depends on the operating system. It usually depends on the activity of the computer, such as the user interface or the network. You can give hints to SysQuake by adding a special output argument to the idle handler:

_idlerate time rate, in seconds, for calling the idle handler
_idleamount proportion of time for idle processing (between 0 and 1)

Only one of these arguments should be used. It should be stressed that the use of _idlerate does not guarantee real-time execution. SysQuake limits the time it gives to the idle handler to permit user interaction.

There may be only one idle handler per SQ file. It is useful when some external data can be acquired and displayed continuously, or for long optimization procedures to display their progress. Animations can also be made, though currently there is no mechanism to specify the execution rate.

Example

variable x
init x = init
idle (x, _idlerate) = idle(x)
functions
{@
function x = init
    x = 0;
function (x, idlerate) = idle(x)
    x = x + 1        // increment and display x
    idlerate = 1;    // the idle handler should be called
                     //  about every second
@}

Make Handler

(Optional)

It is often useful to have variables which hold the result of a computation based on other variables. If several figures depend on it, this avoids the need to calculate it in each draw handler and reduce the computation time. The computation may be performed in the handlers which change the independent variables. However, this forces to add arguments; handlers become more difficult to write, especially when dependencies are complicated. Make handlers describe the way to calculate variables not as the direct effect of some user action, but when their output arguments are required by another handler. The name make is borrowed from the programming utility which builds a complicated project based on a set of rules and dependencies. Make handlers do the same for variables. Their declaration is simply

make (output_variables) = makeHandler(input_variables)

Suppose that a variable x is changed, and that the draw handler of a figure uses variable y as input argument. If the following make handler is declared,

make y = f(x)

SysQuake calls the function f to compute y based on x. More complex dependencies may be defined using several make handlers. There must not be circular dependencies; no variable may depend on itself through one or more make handlers.

Examples

The examples below represent three different ways to implement the same behavior. A variable x may be modified either in a menu handler or by interactive manipulation of a figure. Two figures uses variable y, which is a function of x.

The first implementation does not store y in a variable declared to SysQuake. It is computed in each draw handler.

variable x
init x = init
menu "Change x" x = changeX(x)
figure "Figure 1"
  draw drawFig1(x)
  mousedrag x = dragFig1(_x1)
figure "Figure 2"
  draw drawFig2(x)
functions
{@
function x = init
  x = 3;
function x = changeX(x)
  // (dialog box to let the user edit x)
function drawFig1(x)
  y = f(x);
  // (plot based on x and y)
function x = dragFig1(x1)
  x = x1;
function drawFig2(x)
  y = f(x);
  // (other plot based on x and y)
function y = f(x)
  // computation of y
@}

The second implementation declares y, which is computed in all handlers which change the value of x. When both figures are displayed, y is computed only once when the menu or mousedrag handler is invoked.

variable x, y
init (x, y) = init
menu "Change x" (x, y) = changeX(x)
figure "Figure 1"
  draw drawFig1(x, y)
  mousedrag (x, y) = dragFig1(_x1)
figure "Figure 2"
  draw drawFig2(x, y)
functions
{@
function (x, y) = init
  x = 3;
  y = f(x);
function (x, y) = changeX(x)
  // (dialog box to let the user edit x)
  y = f(x);
function drawFig1(x, y)
  // (plot based on x and y)
function (x, y) = dragFig1(x1)
  x = x1;
  y = f(x);
function drawFig2(x, y)
  // (other plot based on x and y)
function y = f(x)
  // computation of y
@}

The third implementation also declares y, which is computed by a make handler when it is needed by another handler. Note how each handler is as simple as it can be. If none of the two figures is displayed, y is not computed at all.

variable x, y
init x = init
make y = f(x)
menu "Change x" x = changeX(x)
figure "Figure 1"
  draw drawFig1(x, y)
  mousedrag x = dragFig1(_x1)
figure "Figure 2"
  draw drawFig2(x, y)
functions
{@
function x = init
  x = 3;
function x = changeX(x)
  // (dialog box to let the user edit x)
function drawFig1(x, y)
  // (plot based on x and y)
function x = dragFig1(x1)
  x = x1;
function drawFig2(x, y)
  // (other plot based on x and y)
function y = f(x)
  // computation of y
@}

Function Definitions

All the functions declared by the different handlers must be defined in one or several function blocks. A function block has the following syntax:

function
{@
...
@}

The keyword functions is a synonym of function. The functions can be defined in any order and in any number of blocks. In addition to functions declared as handlers, other functions can be defined to extend the set of built-in commands.

Functions defined in other files (called libraries) can be used. To import functions defined in other files (called libraries), the function block can include use statements. Libraries are searched in the same folders or directories as SQ files.

Help

SQ files may include explanations about their purpose and how they can be used. The help is provided in a block of text:

help
{@
Text...
@}

In the block of text, paragraphs are separated by one or more empty lines. Initial and trailing empty lines and spaces are ignored. Upon user request, SysQuake displays the help text of the current SQ file. It discards the end of lines and performs soft word wrap automatically.

SQ Data Files and Input/Output Handlers

SQ Data files (or SQD files) are composed of a succession of LME statements which define variables. The contents of these variables are used by an input function which translates them to the variables used by SysQuake itself and which restores the subplots and their settings. This filtering step serves two purposes:

To avoid the hassle to write input and output handlers when these advanced features are not needed, SysQuake has a default behavior if the handlers are not declared in the SQ file. If the output function is missing, all the variables and the settings are written to the file. If the input function is missing, the variables declared in the SQ file are set to the values defined in the SQD file, or to the empty matrix [] if they are not found.

To permit the user to simply open the SQ data file without specifying the SQ file which can make use of it, the first line should form a valid LME comment with the name of the associated SQ file:

%SQ sqfile.sq
...

When the user opens a file, the first line is read. If it corresponds to a data file, the associated SQ file is read and its init function processed. Finally, the data file is executed and the content of its variables converted by the input function. If the file opened by the user is a SQ file, it is read and its init function executed.

A typical data file could be

%SQ greatDesign.sq

A = [1,2];
B = 2;
kp = 20;
_plots = 'greatView\tstep';
_plotprops = [0,-1,1,-1,1;
0,10,50,0,0];

Variables A, B, and kp correspond directly to variables defined in the SQ file. Variable _plots is the list of the subplots which were displayed when the file was saved; it corresponds to the input or output argument of the command subplots. Variable _plotprops is the properties of the subplots (options like logarithmic scaling and grids, and zoom); it corresponds to the input or output argument of the command subplotprops. The names _plots and _plotprops are those used by the default input and output handlers; it is better to use them also if you write your own handlers.

Input and Output Handlers

(Optional)

To generate and read back the data file above, the following handlers can be declared:

output outputHandler(_fd, v1, v2, ...)
input (v1, v2, ...) = inputHandler(in1, in2, ...)

The output handler must write to _fd the contents of the variables. You need not save all the variables; for example, if pol is a polynomial and you have defined a variable r to store its roots, saving pol is enough; you can restore r in the input handler with r=roots(pol). The variable _fd represents the file descriptor of the output file:

_fd file descriptor of the output file

You can use it with fprintf and dumpvar. You can write the data using any format. However, it is better to follow the format of standard SQD files, as described above, with perhaps calls to the built-in functions of LME. The first line, which contains the name of the SQ file, is required to permit SysQuake to find the appropriate SQ file.

The input handler takes as input arguments the variables stored in the SQD file, and produces values stored in SysQuake variables. The name of the input arguments need not be declared as variables; they must match the names used typically with dumpvar in the input handler. The input handler is always called after the init handler; variables which are not output arguments of the input handler keep the value set by the init handler.

The following example shows how to write input and output handlers which save and restore three variables, check the validity of the variables in the SQD file, and save and restore the subplots.

output myOutputHandler(_fd,A,B,kp)
input (A,B,kp) = myInputHandler(A,B,gain,...
                         _plots,_plotprops,_plotpos)

function
{@
function myOutputHandler(fd,A,B,kp)
    
    // write header line
    fprintf(fd, '%SQ greatDesign.sq\n\n');
    
    // write variables
    dumpvar(fd, 'A', A);
    dumpvar(fd, 'B', B);
    dumpvar(fd, 'gain', kp);  // different name
    
    // write current subplot settings
    dumpvar(fd, '_plots', subplots);
    dumpvar(fd, '_plotprops', subplotprops);
    if ~isempty(subplotpos)
        dumpvar(fd, '_plotpos', subplotpos);
    end

function (A,B,kp) = myInputHandler(A,B,gain,...
                            _plots,_plotprops,_plotpos)
    
    // map the names in the SQD file to the variable names
    kp = gain;
    
    // check the validity of the transfer function
    if length(A) >= length(B)
    dialog(['The transfer function of the system B/A ',...
            'must be strictly causal.');
        cancel;
    end
    
    // restore subplot settings
    subplots(_plots);
    subplotprops(_plotprops);
    subplotpos(_plotpos);
@}

The content of what might be a data file can also be written in the data block of a SQ file. The user may find more convenient to save the data in the SQ file itself, either to have an SQ file with new default values or to distribute it to other people. The data block should be at the end of the SQ file, so that all the variables and the functions used by the input handler are defined. You can write it manually, but its purpose is to be written by SysQuake when the user chooses to save the data as an SQ file. Its syntax is

data
{@
content of a data file
@}

Error Messages

Here is the list of error messages; some of them may appear in a message box when you read a bad file, but many are internal errors. LME errors are listed in the LME Reference chapter and are caused by a bad function either at compile time or at execution time.

Exhausted resources
Not enough memory for the current operation.
Too small name buffer
Not enough memory for the table of variable names.
No more name slot
Too many variable names.
Too small SysQuake buffer
Not enough memory to launch SysQuake.
Not enough memory for decoding SQ file
Class file too complex.
Too small Undo buffer
Not enough memory to create the Undo structures.
Too many variables for the Undo buffer
Undo structures too small for the large number of variables.
Variable too large for the Undo buffer
The new value given to a variable is too large.
Variable not found
Attempt to retrieve a variable which has not been defined (should never occur).
Variable already exists
Attempt to redefine a variable.
Syntax error in class file
Unbalanced quotes or parenthesis, missing element, or other syntax error in the class file.
Bad block of text
Block of text (such as a block of function definitions) without end mark.
Bad variable definition
The variable keyword is not followed by a valid variable name.
Bad function definition
The function keyword is not followed by a valid function call.
Undefined element
The keyword is unknown.
Nonexistent set of variables in the Undo buffer
Attempt to revert to an undo state which is not available.
Not a data file
The file does not begin with the expected "% SQ" characters.
Cannot undo
Too many attempts to undo.
Cannot redo
Too many attempts to redo.

Copyright 1998-2001, Calerga.

All rights reserved.