Using Miranda to build executable files FIRST METHOD (using a `magic string') Create a file (`prog' say) containing a normal miranda script, but with the first two lines in the following form #! /usr/bin/mira -exp <expression> The remainder of the file can be any legal miranda script, including that it can be empty. Remember to give the file execute permission (by saying `chmod +x prog'). When `prog' is executed the result will be that the miranda expression `<expression>' is evaluated in the environment defined by the rest of the script, and the results sent to the standard output. Note that only a single expression is permitted, and it must occur entirely on the second line of the file. The form of the first line is rigid - the two initial characters must be `#!' followed by the absolute pathname of the miranda interpreter. The flag "-exp" is necessary and no other flags can be added. A command of this form can take data from the terminal. The notation `$-' can be used anywhere in the second and later lines of the file to denote the list of characters taken from the standard input. (That is `$-' behaves like a Miranda identifier of type [char].) The command can be invoked with arguments, eg prog pig 23 and the notation `$*' can be used in the script as a Miranda identifier of type [[char]] denoting the argument list, with the convention that the initial (zero'th) argument is the name of the command. So in this case the value of `$*' would be ["prog","pig","23"] Of course, if there are no arguments, `$*' will be a singleton list containing just the command name. Explanation The line beginning `#!' is a standard UNIX incantation, called a `magic string', indicating that the following pathname is to be used as a command interpreter with the name of the file in which it occurs as its argument (see under `execve' in section 2 of the UNIX manual). The flag "-exp" advises the Miranda system to expect a special script, of the above form, containing an expression to be evaluated as its second line. [Notes (1) In some versions of UNIX `execve' places a limit (typically 32 chars) on the total length of the `magic string'. (2) Because the UNIX `execve' program permits at most one flag in a magic string, it is not possible to give a `-lib' flag to mira in conjunction with a `-exp' flag. This is a possible source of difficulty if you keep the miralib directory at a non-standard place. One way round this is to set the environment variable MIRALIB, instead of using a `-lib' flag. See manual section on flags etc.] Example The following script is a Miranda version of the UNIX `cat' command - if it is invoked without arguments it simply copies its standard input to its standard output, otherwise it concatenates the contents of its argument files to the standard output. #! /usr/local/mira -exp output output = [Stdout $-], if tl $* = [] = [Stdout (concat(map read(tl $*)))], if badargs=[] = [Stderr (concat(map errmess badargs))], otherwise badargs = [f|f<-tl $*;~member(filemode f)'r'] errmess f = f++": cannot access\n" See also the manual pages on input from UNIX files, output to UNIX files, for the explanation of `read', `filemode', and the constructors Stdout, Stderr etc. The rule that Miranda source files must have names ending in ".m" does not apply to scripts in this special form (in keeping with the UNIX convention that the names of executable programs require no special extension). Reducing start-up time A drawback of the way Miranda #! scripts are implemented is that such a script is recompiled each time it is used - if the script is large this can lead to an inconvenient delay each time the program is executed. This can be minimised by placing as many as possible of the definitions needed by the #! file in a separate script and %including them (see section on library directives). These definitions will then not be recompiled at each invocation, but retrieved from the corresponding object code file. Debugging stand-alone scripts As an aid to debugging a variant flag is available: #!/usr/bin/mira -log <expression> definitions... The -log flag has the same effect as -exp but stderr is redirected to file miralog/prog.err, where prog is the name of the script. The redirection takes place if a miralog directory exists in the current directory and the process running the Miranda script has write permission to it. This is useful for debugging cgi scripts written in Miranda, particularly in the not infrequent situation that they seem to work fine from the command line but fail when invoked by an http call. (You will need to create a directory miralog in cgi-bin and chown it to apache, or whatever personality cgi scripts run as). ALTERNATIVE METHOD (using a `here document') Create a file ("prog' say) containing the following mira [script] <> is in quotation marks, eg mira [script] <<"!" stuff ! then no substitutions will take place inside the here-document. The drawbacks of commands built in this way are two - (a) they have no way of taking information from the terminal during execution (because the here-document replaces the standard input) and (b) the method of access to command line arguments is clumsy.