M4(1) UNIX Reference Manual M4(1) NNAAMMEE mm44 - macro language preprocessor for Ratfor and Pascal SSYYNNOOPPSSIISS mm44 [options] DDEESSCCRRIIPPTTIIOONN MM44 is a macro language preprocessor for Ratfor, Pascal, and similar languages which do not have a built-in macro processing capability. M4 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 argu- ment, 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 arguments 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 argument(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 definition 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 argument(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 defined, the value is the second argu- ment, otherwise the third. If there is no third argument, the value is null. 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 charac- ters. (i.e., \*'). 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 argument, the left marker becomes the argument and the right marker becomes new- line. With two arguments, both markers are affected. 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) argument. Output diverted to a stream other than 0 through 9 disappears 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 un- diverted into another diversion. Undiverting discards the diverted text. At the end of input processing, MM44 forces an au- tomatic 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 new- line. 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 initial 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 expression, using integer arithmetic. The evaluation mechanism is very similar to that of cpp (#if expression). The expression can involve only in- teger constants and character constants, possibly connected by the binary operators * / % + - >> << < > <= >= == != & ^ && or the unary operators ~~ !! or by the ternary operator ?? ::. Parentheses may be used for grouping. Octal numbers may be specified 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 ar- gument 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 selecting the first character (inter- nally treated as an expression); 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 missing altogether, all characters in the second argument are deleted 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 argument. 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 ar- gument, each argument is separated by a space during the out- put. 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 M4 macro set is about as readable as _A_P_L. All complex uses of M4 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 M4. changequote(<,>) define(HASHVAL,99) dnl define(hash,) dnl define(str, ,1),)>) >) dnl define(KEYWORD,<$1,hash($1),>) dnl define(TSTART, ) 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 cc(1), cpp(1). m4(1) _T_h_e _M_4 _M_a_c_r_o _P_r_o_c_e_s_s_o_r by B. W. Kernighan and D. M. Ritchie. HHIISSTTOORRYY MM44 command appeared in Version 7 AT&T UNIX. The mm44 command this page describes is derived from code contributed by Ozan S. Yigit.