Next: , Previous: , Up: MFL   [Contents][Index]

4.26 MFL Preprocessor

Before compiling the script file, mailfromd preprocesses it. The built-in preprocessor handles only file inclusion (see include), while the rest of traditional facilities, such as macro expansion, are supported via m4, which is used as an external preprocessor.

The detailed description of m4 facilities lies far beyond the scope of this document. You will find a complete user manual in GNU M4 in GNU M4 macro processor. For the rest of this section we assume the reader is sufficiently acquainted with m4 macro processor.

The external preprocessor is invoked with -s flag, instructing it to include line synchronization information in its output, which is subsequently used by MFL compiler for purposes of error reporting. The initial set of macro definitions is supplied in preprocessor setup file pp-setup, located in the library search path20, which is fed to the preprocessor input before the script file itself. The default pp-setup file renames all m4 built-in macro names so they all start with the prefix ‘m4_21. It changes comment characters to ‘/*’, ‘*/’ pair, and leaves the default quoting characters, grave (‘`’) and acute (‘'’) accents without change. Finally, pp-setup defines several useful macros (see m4 macros).


Next: , Up: Preprocessor   [Contents][Index]

4.26.1 Preprocessor Configuration

The preprocessor is configured in the mailfromd configuration file, using the preprocessor statement (see conf-preprocessor). The default settings correspond to the following configuration:

preprocessor {
  # Enable preprocessor
  enable yes;
  # Preprocessor command line stub.
  command "m4 -s";
  # Pass current include path to the preprocessor via -I options.
  pass-includes false;
  # Pass to the preprocessor the feature definitions via -D options
  # as well as any -D/-U options from the command line
  pass-defines true;
  # Name of the preprocessor setup file.  Unless absolute, it is
  # looked up in the include path.
  setup-file "pp-setup";
}

If pass-includes is true, the command value is augmented by zero or more -I options supplying it the mailfromd include search path (see include search path).

Furthermore, if pass-defines is set, zero or more -D options defining optional features are passed to it (e.g. -DWITH_DKIM) as well as any -D and -U options from the mailfromd command line.

Unless the value of setup-file begins with a slash, the file with this name is looked up in the current include search path. If found, its absolute name is passed to the preprocessor as first argument.

If it begins with a slash, it is passed to the preprocessor as is.


Next: , Previous: , Up: Preprocessor   [Contents][Index]

4.26.2 Preprocessor Usage

You can obtain the preprocessed output, without starting actual compilation, using -E command line option:

$ mailfromd -E file.mfl

The output is in the form of preprocessed source code, which is sent to the standard output. This can be useful, among others, to debug your own macro definitions.

Macro definitions and deletions can be made on the command line, by using the -D and -U options, provided that their use is allowed by the pass-defines preprocessor configuration setting (see Configuring Preprocessor. They have the following format:

-D name[=value]
--define=name[=value]

Define a symbol name to have a value value. If value is not supplied, the value is taken to be the empty string. The value can be any string, and the macro can be defined to take arguments, just as if it was defined from within the input using the m4_define statement.

For example, the following invocation defines symbol COMPAT to have a value 43:

$ mailfromd -DCOMPAT=43
-U name
--undefine=name

A counterpart of the -D option is the option -U (--undefine). It undefines a preprocessor symbol whose name is given as its argument. The following example undefines the symbol COMPAT:

$ mailfromd -UCOMPAT

The following two options are supplied mainly for debugging purposes:

--no-preprocessor

Disables the external preprocessor.

--preprocessor[=command]

Use command as external preprocessor. If command is not supplied, use the default preprocessor, overriding the enable preprocessor configuration setting.

Be especially careful with this option, because mailfromd cannot verify whether command is actually some kind of a preprocessor or not.


Previous: , Up: Preprocessor   [Contents][Index]

4.26.3 Preprocessor Macros

M4 Macro: boolean defined (identifier)

The identifier must be the name of an optional abstract argument to the function. This macro must be used only within a function definition. It expands to the MFL expression that yields true if the actual parameter is supplied for identifier. For example:

func rcut(string text; number num)
  returns string
do
  if (defined(num))
    return substr(text, length(text) - num)
  else
    return text
  fi
done

This function will return last num characters of text if num is supplied, and entire text otherwise, e.g.:

rcut("text string") ⇒ "text string"
rcut("text string", 3) ⇒ "ing"

Invoking the defined macro with the name of a mandatory argument yields true

M4 Macro: printf (format, …)

Provides a printf statement, that formats its optional parameters in accordance with format and sends the resulting string to the current log output (see Logging and Debugging). See String formatting, for a description of format.

Example usage:

printf('Function %s returned %d', funcname, retcode)
M4 Macro: string _ (msgid)

A convenience macro. Expands to a call to gettext (see NLS Functions).

M4 Macro: string_list_iterate (list, delim, var, code)

This macro intends to compensate for the lack of array data type in MFL. It splits the string list into segments delimited by string delim. For each segment, the MFL code code is executed. The code can use the variable var to refer to the segment string.

For example, the following fragment prints names of all existing directories listed in the PATH environment variable:

string path getenv("PATH")
string seg

string_list_iterate(path, ":", seg, `
     if access(seg, F_OK)
       echo "%seg exists"
     fi')

Care should be taken to properly quote its arguments. In the code below the string str is treated as a comma-separated list of values. To avoid interpreting the comma as argument delimiter the second argument must be quoted:

string_list_iterate(str, `","', seg, `
     echo "next segment: " . seg')
M4 Macro: N_ (msgid)

A convenience macro, that expands to msgid verbatim. It is intended to mark the literal strings that should appear in the .po file, where actual call to gettext (see NLS Functions) cannot be used. For example:

/* Mark the variable for translation: cannot use gettext here */
string message N_("Mail accepted")

prog envfrom
do
  …
  /* Translate and log the message */
  echo gettext(message)

Footnotes

(20)

It is usually located in /usr/local/share/mailfromd/9.0/include/pp-setup.

(21)

This is similar to GNU m4 --prefix-builtin options. This approach was chosen to allow for using non-GNU m4 implementations as well.


Previous: , Up: Preprocessor   [Contents][Index]