_U_s_i_n_g_ _M_i_r_a_n_d_a_ _t_o_ _b_u_i_l_d_ _e_x_e_c_u_t_a_b_l_e_ _f_i_l_e_s FIRST METHOD (using a `magic string') Create a file, prog.m say, containing a normal miranda script, but with first line #! /usr/bin/mira -exec The first two characters must be "#!" followed by an optional space and the absolute pathname of the miranda interpreter. This may be somewhere other than /usr/bin/mira, the UNIX shell command "which mira" should tell you where it is. The flag "-exec" is necessary and no other flags should be added. (Note "-exec2" can be substituted for "-exec", see below.) The remainder of the file can be any legal miranda script, which may %include other scripts. Somewhere in the file, or in an included file, there must be a definition of `main'. When `prog.m' is executed as a UNIX command, the result will be that `main' is evaluated, using the same rules as if you had entered it in an interactive session, and the results sent to standard output. Remember to give the file execute permission (e.g. by saying `chmod +x prog.m'). 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.m fig 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.m","fig","23"] If there are no arguments, `$*' will be a singleton list containing just the command name. _E_x_p_l_a_n_a_t_i_o_n The line beginning `#!' is a standard UNIX incantation, called a `magic string', indicating that the following pathname is an interpreter to be invoked with the name of the file in which it occurs as argument (see under `execve' in section 2 of the UNIX manual). The flag "-exec" instructs the Miranda system to evaluate `main', which can be of any type. If main is a string this is sent to stdout, if it is of another printable type `show main' is sent to stdout, or if main is of type [sys-message] the sequence of I/O commands is executed. Examples Here is the Miranda "hello world" program #! /usr/bin/mira -exec main = "hello world\n" 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/bin/mira -exec main = [Stdout $-], _i_f tl $* = [] = [Stdout (concat(map read(tl $*)))], _i_f badargs=[] = [Stderr (concat(map errmess badargs))], _o_t_h_e_r_w_i_s_e badargs = [f|f<-tl $*;~member(filemode f)'r'] errmess f = f++": cannot access\n" See the manual pages on input from UNIX files and 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" is not enforced for "magic" scripts, in keeping with the UNIX convention that executables require no special suffix. However a magic script whose name ends in ".m" can also be made the subject of a miranda session. This is advantageous during development, as individual definitions can be tested. A first line beginning #! is ignored by the Miranda compiler which treats it as a comment. In this situation $* has the value [], since the script was not executed as a command. Note also that if your Miranda executable file has the ".m" suffix, a corresponding ".x" file will be created at its first call, avoiding the need for mira to recompile it on subsequent calls (unless there has been an update of the source file). Notes (1) In some UNIX-like systems `execve' places a limit on the total length of the `magic string'. (2) Because in many systems (including Linux) `execve' permits at most one flag in a magic string, mira does not understand a `-lib' flag given in conjunction with a `-exec' 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 environment variable MIRALIB, instead of using a `-lib' flag. See manual section on flags etc. [To do: more general mechanism to add other flags to -exec in a magic string - DT] (3) If called from the UNIX command line, mira -exec script.m will find and evaluate `main' in script.m and in this situation you can combine -exec with other flags, -lib miralib, -heap N, etc preceding the name of the script. Any additional arguments following script.m will be found in $*. _D_e_b_u_g_g_i_n_g_ _s_t_a_n_d_-_a_l_o_n_e_ _s_c_r_i_p_t_s As an aid to debugging a variant flag is available: #!/usr/bin/mira -exec2 definitions... The -exec2 flag has the same effect as -exec but runtime errors (only, not compile time errors) are redirected to file miralog/prog, where prog is the name of the script. The redirection takes place if a miralog directory exists in the current working directory and the process running the script has write permission to it. This is useful for debugging cgi scripts written in Miranda, particularly in the not infrequent situation that they compile without errors and 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). SECOND 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.