@?, @#, @0, @1, @2, @3, ... @p - Macro arguments
@? - Boolean flagging if a numeric argument was supplied
@# - The value of the numeric argument
@0 - The name of the macro
@1 - The first argument of macro
@2 - The second argument of macro
@3 ... @n
@p - The name of the calling (or parent) macro.
Macros may be passed arguments, allowing a macro to be used by other macros. The @? and @# are used to determine the numeric argument given to the command. The @n variable (where n is an integer) used in the context of a macro allows the macro body to determine it's arguments.
From a macro all commands are called in the following form
[num] <macro-name> "arg1" "arg2" ....
When executed macros do not have to be given an argument, in this case @? will be 0 and @# will be 1 (the default argument). If an argument is given then @? will be 1 and @# will be set to the numeric argument given.
The current macro command name <macro-name> can be obtain by using the @0 variable, e.g.
define-macro Test-it ml-write @0 !emacro
When executed, writes the message "Test-it" which is the name of the macro.
Arguments may be passed into macro commands in the same way as standard commands are given arguments. The macro being called can access these by the @1 to @n variables, where n is a positive integer. Any variables given as arguments are evaluated so if the variable name is required then enclose it in quotes, e.g.
set-variable %test-var "Hello World" define-macro Test-it ml-write &cat &cat &cat &cat @0 " " @1 " = " &ind @1 set-variable @1 @2 !emacro Test-it "%test-var" "Goodbye World"
On execution the macro writes the message
"Test-it %test-var = Hello World"
and will set variable %test-var to "Goodbye World". Note that the @1 has been used by reference on the set-variable rather than by value as it is used in an assignment.
The @p variable can be used to obtain the name of the macro which is executing the current macro, i.e. the value of the parent's @0 variable. If the macro was executed directly by the user then there is no parent macro and the value of @p is an empty string ("").
The variables @# and @? are automatically set on entry to a macro, the values may be over-written by the calling macro if required, but their assignment values are restricted to being integer values, assignment of a character string causes an error.
If an attempt is made to access an argument which has not been given then a error occurs. This error can be trapped using the !force(4) directive, enabling the macro to take appropriate action, see example.
Consider the implementation of replace-all-string(3) macro defined in search.emf:
define-macro replace-all-string !force set-variable #l0 @3 !if ¬ $status set-variable #l1 @ml05 "Replace all" set-variable #l2 @ml05 &spr "Replace [%s] with" #l1 set-variable #l0 @ml00 "In files" !else set-variable #l1 @1 set-variable #l2 @2 !endif . . . !emacro
In this example if the 3rd argument is not given then the macro gets all arguments from the user.
The @p variable having a value of "" when a macro is called directly by the user can be useful when determining the amount of information to feed-back to the user. For example, executing the clean macro is an easy way to remove surplus white characters, so it is often used by other macros as well as by the user. When called directly clean refreshes the display and prints a message of completion, but when called by other macros this would cause an unwanted screen-update and message, so clean only does this when executed by the user. This is done as follows:
define-macro clean ; ; Prepare to clean up file. . . . !if &seq @p "" screen-update ml-write "[Cleaned up buffer]" !endif !emacro
The parsing of arguments can be inefficient because of the way the arguments have to be parsed; to get the 4th argument the 1st, 2nd and 3rd arguments must be evaluated. This is because each argument is not guaranteed to be only one element, it could be an expression which needs to be evaluated. Consider the following invocation of our Test-it macro
Test-it &cat "%test" "-var" "Goodbye World"
The 2nd argument is not "%test" as this is part of the first argument, the 2nd argument is in fact the 4th element and the invocation will have the same effect except slower.
(c) Copyright JASSPA 2009
Last Modified: 2009/08/29
Generated On: 2009/10/12