Conditional processing and related command-line options --define, --conditionals

Overview

Pascal allows for directives in the source code. These are comments that contain commands for the compiler introduced by the dollar sign.

To distinguish different compilers, libraries or development stages, conditional directives make it possible to make the compiler ignore part of the file.

An example:

unit SampleUnit;

{$ifdef MSWINDOWS}

uses Windows, WinProcs;
procedure WindowMove(H: TWindowHandle; DX, DY: Integer);

{$else}

procedure ClearConsole;
procedure PrintText(S: String);

{$endif}

As PasDoc parses Pascal files it must be able to correctly understand conditional directives. So it understands a number of directives dealing with conditional compilation: $ifdef, $if, $else, $endif, $ifend, $ifopt, $define and $undef.

In contrast from a real compiler, PasDoc starts with an empty list of conditional directives. For example, we don’t automatically define MSWINDOWS, even when you run PasDoc on Windows. The reason for this is that you probably want to generate one documentation that makes sense for all operating systems, all compiler versions and so on. It’s up to you to decide which symbols should be defined to achieve this.

You can tell PasDoc to have some symbol defined using the --define and --conditionals CommandLine options described below. It’s valid to specify multiple --define or --condtional options.

--define option

--define DIRECTIVES option (short form is -D DIRECTIVES) adds DIRECTIVES to the list of conditional directives that are present whenever parsing a unit is started. Each define should be separated from the others by a comma, as shown in the following example:

pasdoc --define DEBUG,FPC,MSWINDOWS myunit.pas

This defines three conditionals: DEBUG, FPC and MSWINDOWS.

You can use the assignment operator to define a symbol with a value, like this:

pasdoc --define FPC_FULLVERSION:=30202 --define LCL_FULLVERSION:=2020401 myunit.pas

This makes the given symbol behave like a macro, that expands to the given value, both during normal Pascal code parsing and during conditional expression evaluation in $if / $elseif.

This is useful to:

  • Define values for useful symbols used in conditional expressions, like:

    • Special FPC FPC_FULLVERSION symbol (available only in conditional expressions in FPC, though in PasDoc it will be also expanded during normal Pascal code parsing)

    • LCL_FULLVERSION defined in Lazarus LCLVersion unit,

    • CompilerVersion constant from Delphi.

  • Or to define FPC macros values at command-line.

--conditionals option

--conditionals CONDITIONALS-FILE option (short form is -d CONDITIONALS-FILE) adds the defines specified in a file CONDITIONALS-FILE to the list of conditional directives that are present whenever parsing a unit is started. The file must contain one conditional per line, without any comments.

Examples:

pasdoc --conditionals c:\sources\myconditionals.txt
pasdoc --conditionals /home/me/pascal/myconditionals.txt

where the myconditionals.txt file may contain, for example:

DEBUG
FPC
MSWINDOWS

Make sure the resulting code is valid

Consider this sample:

const NewLine = {$IFDEF MSWINDOWS} #13#10 {$ENDIF} {$IFDEF POSIX} #10 {$ENDIF};

By default PasDoc defines neither MSWINDOWS nor POSIX, so it will consider them both undefined and will try to parse (and fail) the following line:

const NewLine = ;

You have to make sure that the combination of symbols used by PasDoc "makes sense", i.e. results in code that can be parsed. Sometimes the right solution is to introduce a special variant, used only when parsing with PasDoc:

const NewLine =
  {$ifdef PASDOC}
    'The value of this constant depends on the operating system'
  {$else}
    {$ifdef MSWINDOWS} #13#10 {$endif} {$ifdef POSIX} #10 {$endif}
  {$endif};

Make sure to execute PasDoc with command-line option -d PASDOC to make it work.

Support for $if

The $if directive allows to evaluate an expression, like {$if defined(MSWINDOWS) and not defined(FPC)}.

Note
We had a number of improvements to $if parsing since last PasDoc 0.16.0 release. For now, use development snapshots to get the latest version with full support for $if expressions.

Most of $if features supported by compilers (like FPC or Delphi) are now supported.

We support:

  • Functions defined(SYMBOL), undefined(SYMBOL), option(R+)

  • Constants false, true

  • Composing the expression using and, or, not, xor operations

  • Comparing (Booleans and Integers) using =

  • Addition, multiplication operatoers.

In particular, some not supported features:

  • sizeof(xxx) function (not likely to be ever supported — requires a compiler to determine it)

  • declared(identifier) function