Go to the previous, next section.

Macros

In SM, it is possible to define sets of plot commands as "subprogrammes", which can be used just like a plot command, to generate a standard plot. These plot macros allow variables (e.g. name of the data file, plot label or limits, etc) to be supplied at execution time.

You can also bind commands to keys to save typing; for example I usually bind `cursor' to the PF1 key of my terminal. Such keyboard macros are discussed under KEY and at the bottom of this section.

The macro facility consists of commands to define macros, delete them, write them to disk files, read them from disk files, delete all those macros defined in a specified disk file and list all currently defined macros. In addition, the help command applied to a macro prints out its definition. It is possible to pass up to 9 arguments to a macro, referred to as $1, ... , $9, and in addition $0 gives the name of the macro. While macro arguments are being read they are treated as if they are in sets of {2, except that variables are expanded. If you want to include a space in an argument, enclose it in quotes. If the number of declared arguments is 10 or more, the macro is treated as having a variable number of arguments. If it is 100 or more the last argument extends to the end of the line. For further discussion see the discussion of how macros are used.

A macro is defined by the statement @example MACRO name nargs { body-of-macro 2 or@example MACRO name nargs < body-of-macro > where name may be up to 80 characters, and must not be a keyword @footnote #{unless you have been playing with OVERLOAD}, and body-of-macro is the statements within the macro, and may be up to 2000 characters long. Macros defined using an editor on a file may be up to 10000 characters. If nargs, the number of arguments, is 0 it may be omitted. Macros may also be created using the MACRO EDIT command, which is discussed below, and which is probably easier. To define the macro in a disk file, the file format must be: the name of the macro starts in the first column, followed by a tab or spaces, followed by the number of arguments, if greater than 0, followed by commands, followed by comments if any. The next line and any necessary subsequent lines contain the macro definition (starting in a column other than the first one). Any number of macros may appear in the same file, as long as the macro name is given in the first column and the definition starts in some other column. The first two blanks or tabs are deleted in continuation lines, but any further indentation will survive into the macro definition. Tabs will be replaced by spaces as the macro is read. By default a tab is taken to be 8 characters wide, but this may be changed by specifying tabsize in your `.sm' file.

When a macro is invoked, by typing its name wherever a command is valid, for example at a prompt, it first reads its arguments from the terminal (if they are not in the lookahead buffer, it will prompt you for them), and defines them as the variables $1, ..., $9, before executing the commands contained within the macro. The number of arguments must be declared correctly. As an alternative it is possible to declare that a macro has a variable number of arguments by declaring 10 or more. The macro will then expect between 0 and the number declared modulo 10 arguments, all on the same line as the macro itself. (i.e. the argument list is terminated by a newline, which may either be a `real' one, or an \n). If the number of arguments is 100 or more it is still reduced modulo 10, but the last argument is taken to be the rest of the line (which may consist of many words). The macro may find out if a particular argument is provided by using $? to see if the variable is defined. For example the macro check, in the format in which it would appear in a file,

check  11   if($?1 == 1) { echo Arg 1 is $1 2\n
will echo its argument, if it has one, and@example split 102 if($?2 == 0) { DEFINE 2 "(none)" 2
echo $1:$2:
if invoked as split word many arguments will print word:many arguments:. If you add an explicit newline, split word many\n arguments, you'll get word:many: and then a complaint that arguments is not a macro.

If you try to execute a non-existent macro, if it is defined SM will call a special macro called macro_error_handler. It has two arguments; the first is the string NOT_FOUND, and the second is the name of your non-existent macro. When you start SM, the error handler is:

macro_error_handler 2 ## handle errors associated with macros
		if($?missing_macro_continue) {
		   echo $2 is not a macro
		   RETURN
		}
		if('$1' == 'NOT_FOUND') {
		   del1
		   define 3 "$2 is not a macro; aborting"
		2 else {
		   define 3 "Unknown macro error for $2: $1"
		}
		USER ABORT $3
which causes an immediate syntax error (the USER ABORT), and remove the errant command from the history list (the del1). You can turn this off by defining the variable $missing_macro_continue, which you can do in your `.sm' file; this was the default in SM versions 2.1.0 and earlier, and is what you get if the macro macro_error_handler isn't defined.

Unfortunately we can get into trouble with IF's at the end of macros, for much the same reason that RETURN can get into trouble (see section The Command Interpreter). The symptoms are that a macro either gets the arguments that were passed to the macro that called it, or complains that it can't handle numbered variables at all because it isn't in a macro at all. To avoid this, there is an explicit \n at the end of the macro check. It is possible to redefine the values of arguments (it won't affect the values you originally specified, arguments are passed by value), or to DEFINE values for arguments that you didn't declare. The latter case allows you to have temporary variables, local in scope to the macro. An example is the rel macro, which is defined as

rel  2  DEFINE 1 ($1) DEFINE 2 ($2) RELOCATE $1 $2
which allows you to specify expressions to the relocate command. For more examples see the `useful macros' section.

Newlines are allowed within macros, and as usual any text from a # to the next newline is taken to be a comment. If a # is needed within a macro, escape the # with a \ or enclose it in double quotes. If a macro starts with a comment the comment will not affect the macro's speed of execution. Macros starting with ## are treated specially by SAVE (they are not saved) and MACRO LIST (they are not listed if VERBOSE is 0).

If the macro command is given as

MACRO name { DELETE 2
or@example MACRO name DELETE the macro will be deleted (you can also delete a macro from the macro editor by specifying a negative number of arguments). If the name is already defined, it will be silently redefined. Macros may be nested freely, and even called recursively. For example, the definition
MACRO aa {aa2
is perfectly legal, but SM will go away and think about it for ever if you ever type aa (or at least until you type ^C.) The definition
MACRO zz { zz zz    # comment: not recommended 2
is also legal, but in this case if you execute it SM will fill its call and macro stacks and complain when it grabs more space. As before, it will think about it forever. More useful examples of recursive macros are compatible (see section Tips for Mongo Users), which starts
IF($?1 == 0) { compatible 1 RETURN 2 ...
providing a default value for its argument, and repeat which is discussed under DO.

To find how a particular macro is defined, type HELP macroname. For a listing of the first line of all currently defined macros, type

LIST MACRO
or
LIST MACRO x y
The optional x and y are the alphabetical (actually asciial ) range of macro names to list. As mentioned above, if VERBOSE is 0, macros starting with ## are not listed by this command. There is a macro ls defined as DELETE HISTORY LIST MACRO which will list macros without appearing on the history list. (Or you could overload list; see under overload in the index).

A related command is APROPOS pattern which lists all macros and help files@footnote %{usually; this may not be available on Unix System V and VMS systems.} whose names or initial comments contain the pattern, for example

APROPOS histogram
would list bar_hist and get_hist as well as the abbreviations hi and hist. If you wanted to find all macros starting with a single comment character which mentioned histogram you could say @example APROPOS "^#[^#] .*histogram" where the double quotes prevent the #'s being interpreted as comment characters. @example APROPOS ^[a-z] will list all macros beginning with lowercase letters -- this is similar to MACRO LIST a z, but pays no attention to the value of VERBOSE.

It is also possible to read macros in from disk, and in fact when SM is started, it tries to read the file `default' in the directory specified by macro in the environment file `.sm'. The command to read a file of macros is

MACRO READ filename
Any line with a # in the first column is treated as a comment, and is echoed to the terminal if VERBOSE is greater than zero. All the currently defined macros may be written to a file with the command
MACRO WRITE filename
If the file exists, it will be overwritten (under VMS, a new version of the file will be written). Macros are written out in alphabetical order.

The command

MACRO WRITE macroname filename
writes the macro macroname to the file filename. This command remembers which file it last wrote a macro to, and if the current filename is the same then it appends the macro to the end of the file, otherwise it overwrites it (or creates a new version under VMS) unless the filename is preceded by a +, in which case the macros will always be appended. This allows a set of related macros to be written to a file.
MACRO DELETE filename
undefines all macros which are defined in filename. This allows a file of macros to be read in, used and forgotten again. The difference between this command and MACRO macroname DELETE should be noted. The SAVE command is probably a better way of saving all current macros. The format of macros on disk is name nargs text, where nargs may be omitted if it is 0. Continuation lines start with a space or tab. See the files in the directory specified by macro in your `.sm' file for examples.

It is possible to define macros from the history list. The command

MACRO name i j
defines a macro name to be lines i to j inclusive of the history list, as seen using HISTORY. The opposite of this command, which places a macro upon the history list, is WRITE HISTORY name. Examples of these commands are the macros playback and edit_hist given in the section `A Simple Plot'. This way of defining macros can be convenient if you have created a useful set of commands on the history buffer, and now want to save it in a macro and go on to other things. Editing the playback buffer, and then changing its name to something else (see next paragraph) is a convenient way of saving it that implicitly uses this command.

Macros may be edited, using essentially the same keys as described above for the history editor. The command MACRO EDIT name starts up the editor, which works on one line at a time. @footnote ^{you might prefer to use the macro ed which is equivalent to MACRO EDIT, but doesn't appear on the history list and, if invoked without a macro name, will edit the same macro as last time. In addition, you can list the current macro with hm.} The zeroth line has the format

0> Macro name : Number of arguments: n
where name is the name of the macro, and n is the number of arguments to the macro. If this line is changed, except to change name or n, any changes made to the macro will be ignored (note that the space after name is required). This can be useful if you decide that you didn't want to make those changes after all. Changing name or n has the obvious effect, except that if n is negative the macro is deleted when you exit the editor. An empty macro is also deleted when you leave the editor (i.e. one with no characters in it, not even a space). The first line that you are presented with is the first line in the macro rather than this special one. Use ^N (or ) to get the next line, ^P (or ) to get the previous line. Carriage return (^M) inserts a new line before the cursor, breaking the line in the process, while ^O inserts a new line before the current line. To save the changes and return to the command interpreter use ^X. All other keys have the same meaning as for the history editor (e.g. ^A to go to the beginning of a line). Note that ^K and ^Y can be used to copy lines, and that the bindings can be changed with EDIT or READ EDIT.

It is sometimes convenient to define a key to be equivalent to typing some string, such as playback or cursor. This can be done with the KEY command, whose syntax is KEY key string. If you just type KEY <CR> you'll be prompted for the key and string. In this case you are not using the history editor to read the key, and you can simply hit the desired key followed by a space and the desired string, terminated by a carriage return. If you put KEY, key and string on one line you'll probably have to quote the key with ^Q or ESC-q, or write the escape sequences out in the way used by EDIT. If this sounds confusing, here is an example. Type KEY<CR>, then hit the PF1 key on your terminal, type a space, and type "echo Hello World\N". Now just hit the PF1 key and see what happens. (The closing \N meant `and put a newline at the end'). These keyboard macros are not generally terminal independent, but they can be convenient. Definitions for the `PF' keys on your keyboard can be made in a terminal-independent way by specifying the key as pfn or PFn where n is 1, 2, 3, or 4. If you always use the same terminal you might want to put some KEY definitions in your private startup file (see the discussion of startup2 in the section on useful macros). The current KEY definitions are listed with the LIST EDIT command, along with the other key bindings.

Go to the previous, next section.