Go to the previous, next section.
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\nwill 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 $3which 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 $2which 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 2or@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 {aa2is 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 2is 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 MACROor
LIST MACRO x yThe 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 histogramwould 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 filenameAny 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 filenameIf 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 filenamewrites 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 filenameundefines 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 jdefines 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: nwhere
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.