


M4(local)         Misc. Reference Manual Pages          M4(local)



NAME
     m4 - macro processor

ORIGIN
     MetaSystems

SYNOPSIS
     m4[ options ][ files ]

DESCRIPTION
     PD M4 is a un*x M4 look-alike macro processor intended as  a
     front  end  for  Ratfor, Pascal, and other languages that do
     not have a built-in  macro  processing  capability.   PD  M4
     reads  the  files  listed  on the command line, in the order
     they are listed, or standard input if no files  are  listed.
     The processed text is written on the standard output.

     The options and their effects are as follows:

     -Dname[=val]
          Defines name to val or to null in val's absence.

     -Uname
          undefines name.

     -c    Strip comments.

     -e    interactive; output is unbuffered and the INTR key  is
          ignored.

     -ofile
          output is directed to file instead of standard output.

     -B expr
          should change the size of the argument string stack and
          the push-back buffer, but is currently ignored.

     -H expr
          should change the size of the macro  name  hash  array,
          but  is  currently  ignored.  Note that PD M4 has is no
          fixed limit to the number of macro names.

     -S expr
          should change the size of the macro call stack (at  one
          slot  per  argument  and  four  slots per call), but is
          currently ignored.  This limit only applies  to  nested
          calls,  not  to  nested  running  macros;  the pushback
          buffer size limits that.

     -T expr
          should change the size of the macro name token  buffer,
          but  is  currently ignored.  The next public release of



SunOS 5.5.1         Last change: 11 Nov 1997                    1






M4(local)         Misc. Reference Manual Pages          M4(local)



          PD M4 won't have or need a token  buffer,  so  it  will
          always be ignored.

     -Mprefix
          Renames all the built in macros  by  adding  the  given
          prefix to their names.  The purpose of this is to avoid
          name clashes.

     -P    This is the same as -M``m4_''.  It is copied from  GNU
          M4, which does not have -M.

     -V    Writes  version  information  to  standard  error  and
          halts.

     Macro calls have the form:

          name(arg1,arg2, ..., argn)

     The left parenthesis must immediately follow the macro name,
     with  no  intervening  layout  characters.  If the name of a
     defined macro is not followed by a left parenthesis,  it  is
     taken  to  be  a  call of that macro with no arguments, i.e.
     name().  Any string may be  given  a  definition,  but  only
     identifiers  (a  letter or underscore followed by any number
     of letters, digits, and underscores) are recognised as macro
     names in macro calls.

     Leading unquoted blanks, tabs and newlines are ignored while
     collecting arguments.  Left and right single quotes are used
     to quote strings.  The value  of  a  quoted  string  is  the
     string stripped of the quotes.

     When a macro name is recognised, its arguments are collected
     by  searching for a matching ).  If fewer arguments are sup-
     plied than are in the macro definition, the  trailing  argu-
     ments  are taken to be null.  Macro evaluation proceeds nor-
     mally during the collection of the arguments, and any commas
     or  right  parentheses  which  happen  to turn up within the
     value of a nested call are as effective as those in the ori-
     ginal  input text. (This is typically referred as inside-out
     macro expansion.)  After argument collection, the  value  of
     the  macro  is  pushed  back  onto the input stream and res-
     canned.

     PD M4 makes available the following built-in  macros.   They
     may be redefined, but once this is done the original meaning
     is lost.  Their values are null unless otherwise stated.

     define        usage: define(name [, val])
                   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



SunOS 5.5.1         Last change: 11 Nov 1997                    2






M4(local)         Misc. Reference Manual Pages          M4(local)



                   null.   Each  occurrence of $n in the replace-
                   ment 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.   There are several special
                   forms:  $# is replaced by the number of  argu-
                   ments  passed  to the macro; $* is replaced by
                   all of the arguments, separated by commas, and
                   not quoted; $@ is replaced by all of the argu-
                   ments, separated by commas, and quoted so they
                   won't be expanded again; and there are several
                   new forms peculiar to PD M4.

     defn          usage: defn(name [, name ...])
                   returns   the   quoted   definition   of   its
                   argument(s).  This is useful for renaming mac-
                   ros, including built-in ones.

     undefine      usage: undefine(name [, name ...])
                   removes the definition of the macro(s)  named.
                   If  there  is more than one definition for the
                   named macro, (due to previous use of  pushdef)
                   all definitions are removed.

     pushdef       usage: pushdef(name [, val])
                   like define, but saves any previous definition
                   on a stack.

     popdef        usage: popdef(name [, name ...])
                   removes  the   current   definition   of   its
                   argument(s),  exposing  the previous one(s) if
                   any.

     ifdef         usage: ifdef(name, if-def [, ifnot-def])
                   if the first argument is defined, the value is
                   the  second argument, otherwise the third.  If
                   there is no third argument, the value is null.
                   A word indicating the current operating system
                   is predefined.  (e.g.  unixor msdosor  macosor
                   vmsor cmsor mvs)

     shift         usage: shift(arg, arg, arg, ...)
                   returns all but its first argument.  The other
                   arguments are quoted and pushed back with com-
                   mas in between.   The  quoting  nullifies  the
                   effect  of  the  extra  scan  that will subse-
                   quently be performed.

     changequote   usage: changequote(left, right, escape)
                   change quote delimiters to those given in  the
                   arguments.   With no arguments, the quotes are
                   reset back to the default  characters.  (i.e.,



SunOS 5.5.1         Last change: 11 Nov 1997                    3






M4(local)         Misc. Reference Manual Pages          M4(local)



                   back quote, single quote, and Control-V).  The
                   quote delimiters may be any length.

     changecom     usage: changecom(left, right, escape)
                   change left and right comment markers from the
                   default  #  and  newline.  The escape argument
                   has been added to PD M4 so that C preprocessor
                   directives  can be treated as comments even if
                   they span several lines, but it is not enabled
                   by  default.   With no arguments, there are no
                   comment markers, which means there will be  no
                   comments.   With one argument, the left marker
                   becomes the  argument  and  the  right  marker
                   becomes  newline.   With  two  arguments, both
                   markers are affected.  The comment markers may
                   be any length.

     divert        usage: divert(divnum)
                   m4 maintains 10 output streams, numbered  0-9.
                   Initially  stream 0 is the current stream. The
                   divert macro changes the current output stream
                   to its (expression) argument.  Output diverted
                   to a stream other than 0 through 9  disappears
                   into  a  bit-bucket.   If  you  want output to
                   disappear, you are advised to divert to stream
                   -1.

     undivert      usage: undivert([divnum [, divnum ...]])
                   causes immediate output of  text  from  diver-
                   sions  named as argument(s), or all diversions
                   if no argument.  Text may be  undiverted  into
                   another  diversion.   Undiverting discards the
                   diverted text. At the end of input processing,
                   M4 forces an automatic undivert, unless m4wrap
                   has been used  to  set  some  other  shut-down
                   action.

     divnum        usage: divnum()
                   returns  the  value  of  the  current   output
                   stream.

     dnl           usage: dnl()
                   reads  and  discards  characters  up  to   and
                   including the next newline.

     ifelse        usage: ifelse(arg, arg, if-same [,  ifnot-same
                   | arg, arg ...])
                   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



SunOS 5.5.1         Last change: 11 Nov 1997                    4






M4(local)         Misc. Reference Manual Pages          M4(local)



                   7.   Otherwise, the value is either the fourth
                   string, or, if it is not present, null.

     incr          usage: incr(num)
                   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.

     decr          usage: decr(num)
                   returns the value of its argument  decremented
                   by 1.

     eval          usage: eval(expression [, radix [, mindigs ]])
                   evaluates its argument as a  constant  expres-
                   sion,  using  integer arithmetic.  The evalua-
                   tion mechanism is very similar to that of  cpp
                   (#if  expression).  The expression can involve
                   only  integer  constants  and  character  con-
                   stants,   possibly  connected  by  the  binary
                   operators

                   *    /    %    +    -    >>   <<   <    >
                   <=   >=   ==   !=   &    ^    |    &&   ||

                   or the unary operators - ~ !  or by  the  ter-
                   nary  operator  ? : .  Parentheses may be used
                   for grouping.  Octal and  hexadecimal  numbers
                   may be specified as in C.  The second argument
                   specifies the radix (2 to 36) for the  result;
                   if omitted it defaults to 10.  The third argu-
                   ment specifies the minimum number of digits to
                   be produced; if omitted it defaults to 1.  For
                   the benefit of CS 241 students, RAO'K has made
                   eval()  accept  the  Pascal  operators  'not',
                   'div', 'mod', 'and', and 'or'.  The precedence
                   of  these operators is as in C, not as in Pas-
                   cal, but this should not be a  problem.   Just
                   as in C, the conditional operators
                   e1 && e2    e1 || e2  e1 ? e2 : e3
                   will skip a sub-expression entirely if e1 says
                   so.   Thus  eval(N>0 ? 128/N : 1) is perfectly
                   safe, even if N is 0.  Other  versions  of  M4
                   evaluate  all  sub-expressions,  which is less
                   useful.

     len           usage: len(string)
                   returns the number of characters in its  argu-
                   ment.

     index         usage: index(search-string, string)
                   returns the position  in  its  first  argument



SunOS 5.5.1         Last change: 11 Nov 1997                    5






M4(local)         Misc. Reference Manual Pages          M4(local)



                   where  the  second  argument begins (zero ori-
                   gin), or -1 if the second  argument  does  not
                   occur.

     substr        usage: substr(string, offset [, length])
                   returns a substring  of  its  first  argument.
                   The  second  argument  is a zero origin number
                   selecting  the  first  character   (internally
                   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.

     translit      usage: translit(source, from [, to])
                   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.

     include       usage: include(filename)
                   returns the contents of the file named in  the
                   argument.   Whenever  PD M4 reads from a file,
                   you may supply  an  operating  system  command
                   preceded  by a pipe symbol (|) instead, and PD
                   M4 will use the output of that command  as  if
                   it  were the contents of a file.  For example,
                   on a UNIX system, you can find out how  big  a
                   file  is  by  doing m4trim(include(`wc -c The-
                   File')).  The call to m4trim is needed to  get
                   rid of trailing newlines.  Filenames like this
                   are accepted on the command line as well.

     sinclude      usage: sinclude(filename)
                   is identical to include, except that  it  says
                   nothing if the file is inaccessible.

     paste         usage: paste(filename)
                   returns the contents of the file named in  the
                   argument   without   any   processing,  unlike
                   include.

     spaste        usage: spaste(filename)
                   is identical to paste,  except  that  it  says
                   nothing if the file is inaccessible.

     syscmd        usage: syscmd(command)



SunOS 5.5.1         Last change: 11 Nov 1997                    6






M4(local)         Misc. Reference Manual Pages          M4(local)



                   executes the operating system command given in
                   the  first  argument.  On a UNIX (MS-DOS, VMS)
                   system, commands are interpreted by the Bourne
                   shell  (COMMAND.COM,  DCL), just like the sys-
                   tem() function  in  C.   No  string  value  is
                   returned.

     sysval        usage: sysval()
                   is the decimal return code from the last  call
                   to syscmd.

     maketemp      usage: maketemp(string)
                   fills in a string of XXXXXX  in  its  argument
                   with the current process ID.

     m4exit        usage: m4exit([exitcode])
                   causes immediate exit from m4.  Argument 1, if
                   given, is the exit code; the default is 0.

     m4getenv      usage: m4getenv(var[,default])
                   looks up the environment variable  `var'.   If
                   it  is  defined,  returns its value.  If it is
                   not  defined,  and  a  default  is   provided,
                   returns  the  default.   In  either  case, the
                   result is not rescanned (it is quoted).  It is
                   a  run-time  error  if `var' is not defined in
                   the environment and a default is not provided.
                   If  you  want  to load a `.m4rc' file from the
                   user's   home   directory,    you    can    do
                   include(m4getenv(HOME)/.m4rc)

     m4trim        usage: m4trim(str[,lead[,trail[,mid[,rep]]]])
                   The result is a  trimmed  copy  of  the  first
                   argument.   Any  prefix consisting entirely of
                   characters in the `lead' set is  removed.   If
                   there  is  no  `lead' argument, the default is
                   space, tab, and newline.  Any suffix  consist-
                   ing  entirely of characters in the `trail' set
                   is removed.  If there is no `trail'  argument,
                   the  default  is  to  use the `lead' set.  Any
                   block of consecutive characters in  the  `mid'
                   set is replaced by the `rep' string.  If there
                   is no `mid' argument, the default  is  to  use
                   the  `trail'  set.  If there is no `rep' argu-
                   ment, the default is to use first character of
                   the  `mid'  set.   For  the  purposes  of this
                   macro, an empty argument not  the  same  as  a
                   missing argument.

     m4wrap        usage: m4wrap(final-text)
                   the argument is  saved;  when  all  the  input
                   files  have  been read, the final-text will be



SunOS 5.5.1         Last change: 11 Nov 1997                    7






M4(local)         Misc. Reference Manual Pages          M4(local)



                   read and acted on.  This wrapup action will be
                   done  instead  of  the  normal  wrapup  action
                   (which is to undivert  all  live  diversions).
                   For  example,  m4wrap(``''))  will  cancel the
                   usual undiversions.  If you create any scratch
                   files, use m4wrap to delete them.

     errprint      usage: errprint(str [, str, str, ...])
                   prints its argument(s) on stderr. If there  is
                   more  than  one  argument,  each  argument  is
                   separated by a space during the output.

     dumpdef       usage: dumpdef([name, name, ...])
                   writes to the standard error stream the  names
                   and  current  definitions  of the named macros
                   (if names are supplied) or for all macros  (if
                   not  arguments are supplied).  The definitions
                   are well-formed  calls  to  define  which  you
                   could save in a file and reload.

AUTHOR
     Ozan S. Yigit <oz@sis.yorku.ca> wrote the original code.

     Richard  A.  O'Keefe  <ok@cs.rmit.edu.au>  has   made   many
     changes.

     Jack J. Woehr <jwoehr@ibm.net> did the IBM VM port.

BUGS
     PD M4 is distributed at  the  source  level,  and  does  not
     require an expensive licence agreement.

     Languages with unusual quoting conventions, such as Perl and
     AWK,  leave m4 completely baffled.  (E.g. in AWK, / is some-
     times a division sign and sometimes a quotation mark.)

     A sufficiently complex M4 macro set is about as readable  as
     APL.

     All complex uses of M4 require the  ability  to  program  in
     deep recursion.  Previous lisp experience is recommended.

EXAMPLES
     The following macro program illustrates the type  of  things
     that can be done with M4.

          changequote(<,>) define(HASHVAL,99) dnl
          define(hash,<eval(str(substr($1,1),0)%HASHVAL)>) dnl
          define(str,
               <ifelse($1,",$2,
                    <str(substr(<$1>,1),<eval($2+'substr($1,0,1)')>)>)
               >) dnl



SunOS 5.5.1         Last change: 11 Nov 1997                    8






M4(local)         Misc. Reference Manual Pages          M4(local)



          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 System V M4, since its  eval  does
     not handle character constants.)

     The following example is adapted from the  System  V  manual
     page  for  m4,  but  corrects a rather glaring error in that
     manual page.  A single m4 source  file  could  conditionally
     generate  one  of  two  output  files.  The file oneoftwo.m4
     could contain lines like
          ifelse(VER, 1, `do one thing',
                 VER, 2, `do other thing',
                         `errprint(`VER must 1 or 2')')
     A makefile using this script might look like
          first.pas: oneoftwo.m4
               m4 -o first.pas -DVER=1 oneoftwo.m4

          second.pas: oneoftwo.m4
               m4 -o second.pas -DVER=2 oneoftwo.m4

     SH "EXIT STATUS" The following exit values are returned:

     =0      All went well.



SunOS 5.5.1         Last change: 11 Nov 1997                    9






M4(local)         Misc. Reference Manual Pages          M4(local)



     >0      An error occurred.

     A script can specify the exit status using the m4exit macro;
     PD M4 itself only uses 0 and 1.

SEE ALSO
     cc(1), m4(1), cpp(1), fpp(1), getenv(3c),  system(3s).   The
     M4 Macro Processor by B. W. Kernighan and D. M. Ritchie.















































SunOS 5.5.1         Last change: 11 Nov 1997                   10



