M4(1) BSD Reference Manual M4(1) NNAAMMEE mm44 - macro language preprocessor for ratfor(1) and pascal(1) SSYYNNOOPPSSIISS mm44 [options] DDEESSCCRRIIPPTTIIOONN MM44 is a macro language preprocessor for Ratfor, Pascal, and similar lan- guages which do not have a built-in macro processing capability. MM44 reads standard input, and writes the results to the standard output. The options and their effects are as follows: --DD_n_a_m_e[_=_V_a_l] Defines _n_a_m_e to _v_a_l or to null in the absence of _v_a_l. --UU_n_a_m_e Undefines _n_a_m_e. The mm44 processor provides a kind of CC like syntax and some of the macro functions will be familiar: ddeeffiinnee _d_e_f_i_n_e_(_n_a_m_e _[_, _v_a_l_]_) the second argument is installed as the value of the macro whose name is the first argument. If there is no second argument, the value is null. Each occurrence of $$_n in the replacement text, where _n is a digit, is replaced by the _n'th argument. Argument 0 is the name of the macro; missing ar- guments are replaced by the null string. ddeeffnn _d_e_f_n_(_n_a_m_e _[_, _n_a_m_e _._._._]_) returns the quoted definition of its ar- gument(s). Useful in renaming macros. uunnddeeffiinnee _u_n_d_e_f_i_n_e_(_n_a_m_e _[_, _n_a_m_e _._._._]_) removes the definition of the macro(s) named. If there is more than one definition for the named macro, (due to previous use of ppuusshhddeeff) all definitions are removed. ppuusshhddeeff _p_u_s_h_d_e_f_(_n_a_m_e _[_, _v_a_l_]_) like ddeeffiinnee, but saves any previous defi- nition by stacking the current definition. ppooppddeeff _p_o_p_d_e_f_(_n_a_m_e _[_, _n_a_m_e _._._._]_) removes current definition of its ar- gument(s), exposing the previous one if any. iiffddeeff _i_f_d_e_f_(_n_a_m_e_, _i_f_-_d_e_f _[_, _i_f_n_o_t_-_d_e_f_]_) if the first argument is de- fined, the value is the second argument, otherwise the third. If there is no third argument, the value is null. A word indi- cating the current operating system is predefined (e.g. or sshhiifftt _s_h_i_f_t_(_a_r_g_, _a_r_g_, _a_r_g_, _._._._) returns all but its first argument. The other arguments are quoted and pushed back with commas in between. The quoting nullifies the effect of the extra scan that will subsequently be performed. cchhaannggeeqquuoottee _c_h_a_n_g_e_q_u_o_t_e_(_l_q_c_h_a_r_, _r_q_c_h_a_r_) change quote symbols to the first and second arguments. With no arguments, the quotes are reset back to the default characters (i.e., `` and )).. cchhaannggeeccoomm _c_h_a_n_g_e_c_o_m_(_l_c_c_h_a_r_, _r_c_c_h_a_r_) change left and right comment markers from the default ## and nneewwlliinnee. With no arguments, the comment mechanism is reset back to the default characters. With one ar- gument, the left marker becomes the argument and the right mark- er becomes newline. With two arguments, both markers are af- fected. ddiivveerrtt _d_i_v_e_r_t_(_d_i_v_n_u_m_) mm44 maintains 10 output streams, numbered 0-9. initially stream 0 is the current stream. The ddiivveerrtt macro changes the current output stream to its (digit-string) argu- ment. Output diverted to a stream other than 0 through 9 disap- pears into bitbucket. uunnddiivveerrtt _u_n_d_i_v_e_r_t_(_[_d_i_v_n_u_m _[_, _d_i_v_n_u_m _._._._]_) causes immediate output of text from diversions named as argument(s), or all diversions if no argument. Text may be undiverted into another diversion. Undi- verting discards the diverted text. At the end of input process- ing, MM44 forces an automatic uunnddiivveerrtt, unless mm44wwrraapp is defined. ddiivvnnuumm _d_i_v_n_u_m_(_) returns the value of the current output stream. ddnnll _d_n_l_(_) reads and discards characters up to and including the next newline. iiffeellssee _i_f_e_l_s_e_(_a_r_g_, _a_r_g_, _i_f_-_s_a_m_e _[_, _i_f_n_o_t_-_s_a_m_e _| _a_r_g_, _a_r_g _._._._]_) has three or more arguments. If the first argument is the same string as the second, then the value is the third argument. If not, and if there are more than four arguments, the process is repeated with arguments 4, 5, 6 and 7. Otherwise, the value is either the fourth string, or, if it is not present, null. iinnccrr _i_n_c_r_(_n_u_m_) returns the value of its argument incremented by 1. The value of the argument is calculated by interpreting an ini- tial digit-string as a decimal number. ddeeccrr _d_e_c_r_(_n_u_m_) returns the value of its argument decremented by 1. eevvaall _e_v_a_l_(_e_x_p_r_e_s_s_i_o_n_) evaluates its argument as a constant expres- sion, using integer arithmetic. The evaluation mechanism is very similar to that of cpp (#if expression). The expression can involve only integer constants and character constants, pos- sibly connected by the binary operators * / % + - >> << < > <= >= == != & ^ && or the unary operators ~~ !! or by the ternary operator ?? ::. Parentheses may be used for grouping. Octal numbers may be spec- ified as in C. lleenn _l_e_n_(_s_t_r_i_n_g_) returns the number of characters in its argument. iinnddeexx _i_n_d_e_x_(_s_e_a_r_c_h_-_s_t_r_i_n_g_, _s_t_r_i_n_g_) returns the position in its first argument where the second argument begins (zero origin), or -1 if the second argument does not occur. ssuubbssttrr _s_u_b_s_t_r_(_s_t_r_i_n_g_, _i_n_d_e_x _[_, _l_e_n_g_t_h_]_) returns a substring of its first argument. The second argument is a zero origin number se- lecting the first character (internally treated as an expres- sion); the third argument indicates the length of the substring. A missing third argument is taken to be large enough to extend to the end of the first string. ttrraannsslliitt _t_r_a_n_s_l_i_t_(_s_o_u_r_c_e_, _f_r_o_m _[_, _t_o_]_) transliterates the characters in its first argument from the set given by the second argument to the set given by the third. If the third argument is shorter than the second, all extra characters in the second argument are deleted from the first argument. If the third argument is miss- ing altogether, all characters in the second argument are delet- ed from the first argument. iinncclluuddee _i_n_c_l_u_d_e_(_f_i_l_e_n_a_m_e_) returns the contents of the file named in the argument. ssiinncclluuddee _s_i_n_c_l_u_d_e_(_f_i_l_e_n_a_m_e_) is identical to iinncclluuddee, except that it says nothing if the file is inaccessible. ppaassttee _p_a_s_t_e_(_f_i_l_e_n_a_m_e_) returns the contents of the file named in the argument without any processing, unlike iinncclluuddee. ssppaassttee _s_p_a_s_t_e_(_f_i_l_e_n_a_m_e_) is identical to ppaassttee, except that it says nothing if the file is inaccessible. ssyyssccmmdd _s_y_s_c_m_d_(_c_o_m_m_a_n_d_) executes the UNIX command given in the first ar- gument. No value is returned. ssyyssvvaall _s_y_s_v_a_l_(_) is the return code from the last call to ssyyssccmmdd. mmaakkeetteemmpp _m_a_k_e_t_e_m_p_(_s_t_r_i_n_g_) fills in a string of XXXXXX in its argument with the current process ID. mm44eexxiitt _m_4_e_x_i_t_(_[_e_x_i_t_c_o_d_e_]_) causes immediate exit from mm44. Argument 1, if given, is the exit code; the default is 0. mm44wwrraapp _m_4_w_r_a_p_(_m_4_-_m_a_c_r_o_-_o_r_-_b_u_i_l_t_-_i_n_) argument 1 will be pushed back at final EEOOFF; example: m4wrap(`dumptable()'). eerrrrpprriinntt _e_r_r_p_r_i_n_t_(_s_t_r _[_, _s_t_r_, _s_t_r_, _._._._]_) prints its argument(s) on stderr. If there is more than one argument, each argument is separated by a space during the output. dduummppddeeff _d_u_m_p_d_e_f_(_[_n_a_m_e_, _n_a_m_e_, _._._._]_) prints current names and definitions, for the named items, or for all if no arguments are given. AAUUTTHHOORR Ozan S. Yigit (oz) BBUUGGSS A sufficiently complex MM44 macro set is about as readable as APL. All complex uses of MM44 require the ability to program in deep recursion. Previous lisp experience is recommended. EEXXAAMMPPLLEESS The following macro program illustrates the type of things that can be done with MM44. changequote(<,>) define(HASHVAL,99) dnl define(hash,<expr(str(substr($1,1),0)%HASHVAL)>) dnl define(str, <ifelse($1,",$2, <str(substr(<$1>,1),<expr($2+'substr($1,0,1)')>)>) >) dnl define(KEYWORD,<$1,hash($1),>) dnl define(TSTART, <struct prehash { char *keyword; int hashval; } keytab[] = {>) dnl define(TEND,< "",0 };>) dnl Thus a keyword table containing the keyword string and its pre-calculated hash value may be generated thus: TSTART KEYWORD("foo") KEYWORD("bar") KEYWORD("baz") TEND which will expand into: struct prehash { char *keyword; int hashval; } keytab[] = { "foo",27, "bar",12, "baz",20, "",0 }; Presumably, such a table would speed up the installation of the keywords into a dynamic hash table. (Note that the above macro cannot be used with mm44, since eevvaall does not handle character constants.) SSEEEE AALLSSOO cpp(1) B. W. Kernighan, and D. M. Ritchie., _T_h_e _M_4 _M_a_c_r_o _P_r_o_c_e_s_s_o_r. HHIISSTTOORRYY An MM44 command appeared in Version 7 AT&T UNIX. The MM44 command this page describes is derived from code contributed by Ozan S. Yigit. AT&T 7th Edition June 6, 1993 4