Preprocessor directives - Maple Help

Home : Support : Online Help : Programming : Compiling : Preprocessor directives

The Maple Preprocessor

 Calling Sequence $include "fileName"$include $define macroName macroDefinition$define macroName( macroParameters ) macroDefinition $undef macroName$ifdef macroName $ifndef macroName$elifdef macroName $elifndef macroName$else macroName $endif$file "newFileName" $file "newFileName" lineNumber Parameters  fileName - name of file to include macroName - macro name macroDefinition - text to be substituted for a macro macroParameters - comma-separated macro formal parameter sequence newFileName - new name to use for current file lineNumber - new line number to use for next line of current file Description  • The Maple preprocessor is modeled after the C preprocessor, but implements only a subset of the C preprocessor's capabilities. However, many of the design decisions were driven by those of the C preprocessor.  • The preprocessor directives are not part of the Maple language and therefore cannot be entered at the Maple command prompt. However, they can be embedded within Maple files and are preprocessed during the loading or reading of the file.  • To avoid potential collisions with Maple comments, the Maple preprocessor uses the dollar sign ("$") instead of the number sign ("#", as used by C) as the preprocessor directive introducer. Furthermore, no white space can appear between the "$" and the directive's keyword.  • The introducer ("$") must appear as the first character of a line to be recognized as a preprocessor directive.
 • Preprocessor directives appearing within multi-line comments (those delimited by (* and *) characters) are ignored.
 • Since preprocessing is performed during Maple's parsing phase, any error that occurs during preprocessing is reported as a syntax error.

$include  • The$include directive causes a specified file to be processed as part of the input, just as though the contents of the file had appeared in place of the directive.
 • An $include directive of the form$include "filename" searches for exactly the file specified, and then will search for the file relative to the include path. The filename can be an absolute or a relative path name. Any valid pathname is allowed. To enhance portability on non-UNIX platforms, any slash (/) characters appearing in the filename are automatically translated to the directory separator used by the underlying operating system ("\" under Windows).
 • An $include directive of the form$include  searches for the specified file in the directories specified by the include path first. If it fails to find it, it searches for exactly the file specified.
 • The maximum number of nested $include files is limited by the maximum number of files that can be opened by the given version of Maple. This varies from system to system, but is at least 63.  • The include path can be specified on the command line that invokes Maple by using the -I option or it can be modified by calling kernelopts(includepath). Multiple paths can be specified within a single string separated by commas or semicolons or alternatively a list of paths can be entered. When using kernelopts(includepath), do not prefix the include path with -I. The maximum number of include path entries is 25.  • The following problems can occur when using an$include directive:
 • Not enclosing the file name in "" or <> delimiters.
 • Using a file name that is longer than supported by the operating system.
 • Inability to find the specified file.
 • Reaching the end of an included file while a multi-line comment has not been closed.
 • Reaching the end of an included file when the terminating $endif of an$ifdef or $ifndef has not yet been encountered.  • Nesting too many levels of included files.  • Any error reported by the operating system when attempting to access the file (for example, "permission denied").$define

 • The $define directive creates a macro definition.  • The macroName can be any valid C language identifier, namely a letter or underscore followed by zero or more letters, digits, or underscores.  • The macroDefinition can be any sequence of characters. If a "#" character is encountered outside of a quoted Maple name () or string (""), it is assumed to start a comment, and it terminates the macro definition (the comment and any preceding whitespace do not become part of the definition). If no macroDefinition is provided, the macro is defined to have the value NULL.  • The macroParameters are a comma-separated sequence of single-letter formal parameter names. When the macro is invoked and replaced by the macroDefinition, occurrences of these parameter names in the definition are replaced by the actual parameters in the macro invocation. There can be at most 52 formal parameters to a macro, and the same parameter cannot appear more than once in the macroParameters.  • Alternatively, the last entry in macroParameters can be a sequence of three periods (...). Such a macro can take any number of actual parameters, greater than or equal to the number of single-letter formal parameters. Any occurrence of ... in the macroDefinition is replaced by all of the actual parameters not corresponding to named formal parameters, preceded by commas. If a comma would be syntactically invalid before the first such parameter, it is omitted.  • Simple macro definitions can also be made on the command line that invokes Maple, by using -D macroName or -D macroName=macroDefinition.  • There are two predefined macros:  • __FILE__ expands to a string giving the name of the file being processed (as the result of read statement or an$include directive), or to the empty string if redirected input is being read directly.
 • __LINE__ expands to an integer that gives the current line number of the file being processed.
 • The macro invocation mechanism is aware of Maple syntax, and will correctly treat strings, quoted names, and expressions delimited by (), [], or {} as single arguments, even if they contain commas. It will not correctly deal with a single quoted (that is, unevaluation quote) expression containing a comma that is not otherwise enclosed.
 • The maximum number of active macro definitions, including the two predefined macros, is 511. Attempting to define more results in an error.
 • Macros are expanded from the outside in. For example, if macros A and B are defined, each having a parameter, then A(B(x)) is expanded by first expanding A, with B(x) as a parameter. Then, the input is rescanned and each occurrence of B(x) is expanded.
 • The following problems can occur when defining or using macros:
 • Defining more than 511 active macros.
 • Redefining a macro without first undefining it.
 • Declaring a formal parameter that is not a single letter, or declaring the same formal parameter more than once in the same macro.
 • Declaring a named formal parameter after ... in the parameter sequence.
 • Invoking a macro with fewer arguments than formal parameters.
 • Invoking a macro with more arguments than formal parameters, unless the formal parameter sequences ends with ....
 • Invoking a macro with an argument list, even if empty, when the macro's definition has no formal parameters.
 • Invoking a macro that expands to another invocation of itself, resulting in a potentially infinite expansion.
 • The last issue above can be avoided by quoting the name in the macro's expansion, for example, $define MyFunc(x) MyModule:-MyFunc(x)$undef

 • The $undef directive removes the definition of a macro, if it exists.  • Macro undefinitions can also be made on the command line that invokes Maple, by using the -U macroName option. Command line undefinitions only undefine macros that were defined by earlier -D options.  • Undefining a macro that does not already exist is allowed, and quietly does nothing.$ifdef, $ifndef,$elifdef, $elifndef,$else, $endif  • The$ifdef and $ifndef directives, both of which must be followed by a legal macro name, tests whether a macro is defined or not defined respectively.  • If the test is positive, the text lines after the directive are processed, up to a corresponding$else, $elifdef,$elifndef, or $endif. If the test is negative, those lines are skipped. If a corresponding$else, $elifdef, or$elifndef directive exists, the lines between it and the corresponding $endif are skipped if the test was positive, but are processed if the test was negative.  • These directives can be nested, but a given level of nesting cannot extend outside of the file in which it was started. In other words, corresponding$ifdef/$ifndef,$else, $elifdef,$elifndef, and $endif directives must all be within the same file. The maximum nesting depth is 100 levels.  • At a given nesting level, any number of$elifdef or $elifndef directives can appear between the$ifdef or $ifndef directive and the corresponding$endif directive. Only one $else can appear, and if present, it must be the last directive before the$endif.
 • The $elifdef directive can be abbreviated to$elif.
 • The following problems can occur when using $ifdef, etc.:  • Using more than 100 levels of nesting.  • Encountering an$elifdef, $elifndef,$else, or $endif directive when no$ifdef or $ifndef is active.  • Reaching the end of a file when the terminating$endif of an $ifdef or$ifndef has not yet been encountered.

$file  • The$file directive can be used to alter the filename and reset the line number, returned by subsequent __FILE__ and __LINE__ macro invocations. The altered filename and line number also affect debugging information as shown by the debugger and the showsource command.
 • The filename is specified as a double-quoted string following the directive.
 • The line number, if present, is specified as a literal integer following the filename. If not present, the line number is reset to 1.
 • The $file directive is useful if Maple source text is to be modified by some other program before being passed to Maple. By inserting$file directives appropriately, any error messages reported by Maple can still refer to the original unmodified source file.

Compatibility

 • The Maple preprocessor was updated in Maple 2020:
 • The $file and$elifndef directives were introduced.
 • The $elifdef directive was introduced as a synonym for the existing$elif directive (for consistency with \$elifndef).