Skip to content

Commit ce4a60a

Browse files
committed
Much improved "Conditional expressions and related command-line options (--define, --conditionals)"
1 parent 294a9bc commit ce4a60a

2 files changed

Lines changed: 83 additions & 52 deletions

File tree

src/ConditionalDefines.asciidoc

Lines changed: 81 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,62 @@
1-
:doctitle: Conditional processing and related command-line options --define, --conditionals
1+
:doctitle: Conditional expressions and related command-line options (--define, --conditionals)
2+
:sectnums:
3+
:toc: left
4+
:toclevels: 4
25

3-
## [[overview]] Overview
6+
## Introduction
47

5-
Pascal allows for _directives_ in the source code. These are comments that contain commands for the compiler introduced by the dollar sign.
6-
7-
To distinguish different compilers, libraries or development stages,
8-
_conditional directives_ make it possible to make the compiler ignore
9-
part of the file.
8+
Pascal allows for _directives_ in the source code. These look similar to comments and they contain commands for the compiler to do something special, like conditionaly ignore (or not ignore) a piece of following Pascal code.
109

1110
An example:
1211

1312
[source,pascal]
1413
----
15-
unit SampleUnit;
14+
type
15+
TProcess = class
16+
public
17+
property CommandLine: TStrings read GetCommandLine;
18+
procedure Run;
19+
{$ifdef MSWINDOWS}
20+
property Handle: TWindowHandle read GetHandle;
21+
{$endif}
22+
{$ifdef UNIX}
23+
property StdIn: TUnixHandle read GetStdIn write SetStdIn;
24+
property StdOut: TUnixHandle read GetStdOut write SetStdOut;
25+
property StdErr: TUnixHandle read GetStdErr write SetStdErr;
26+
{$endif}
27+
end;
28+
----
1629

17-
{$ifdef MSWINDOWS}
30+
Just like a compiler, _PasDoc_ understands various directives when it parses Pascal code:
1831

19-
uses Windows, WinProcs;
20-
procedure WindowMove(H: TWindowHandle; DX, DY: Integer);
32+
- `$ifdef`, `$if`, `$ifopt` (and friends: `$else`, `$endif`, `$ifend`) - to conditionally use or ignore a piece of code.
33+
- `$define`, `$undef` - to define or undefine a symbol that can be used in `$if defined(SYMBOL)` / `$ifdef` expressions.
34+
- `$include` (short form `$I`) to include another file.
2135
22-
{$else}
36+
In contrast to a Pascal 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 usually 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.
2337

24-
procedure ClearConsole;
25-
procedure PrintText(S: String);
38+
You can tell PasDoc to have some symbol defined using the `--define` and `--conditionals`
39+
link:CommandLine[CommandLine] options described below.
2640

27-
{$endif}
28-
----
41+
## `--define` command-line option
2942

30-
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`.
43+
`--define SYMBOL` (short form is `-D SYMBOL`) adds `SYMBOL` to the list of defined symbols. In effect, in Pascal code, `{$ifdef SYMBOL}` and (equivalent) `{$if defined(SYMBOL)}` will be considered true.
3144

32-
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.
45+
You can specify multiple symbols separated by a comma:
3346

34-
You can tell PasDoc to have some symbol defined using the `--define` and `--conditionals`
35-
link:CommandLine[CommandLine] options described below. It's valid to specify multiple --define or --condtional options.
47+
----
48+
pasdoc --define DEBUG,FPC,MSWINDOWS myunit.pas
49+
----
3650

37-
## [[define-option]] --define option
51+
This defines three conditionals: `DEBUG`, `FPC` and `MSWINDOWS`.
3852

39-
--define DIRECTIVES option (short form is -D DIRECTIVES) adds DIRECTIVES
40-
to the list of conditional directives that are present whenever parsing
41-
a unit is started. Each define should be separated from the others by a
42-
comma, as shown in the following example:
53+
You can also just use `--define SYMBOL` multiple times, like this:
4354

4455
----
45-
pasdoc --define DEBUG,FPC,MSWINDOWS myunit.pas
56+
pasdoc --define DEBUG --define FPC --define MSWINDOWS myunit.pas
4657
----
4758

48-
This defines three conditionals: DEBUG, FPC and MSWINDOWS.
59+
## `--define` command-line option with `:=` to define a symbol with a value
4960

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

@@ -61,19 +72,18 @@ This is useful to:
6172
+
6273
--
6374
- 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)
64-
- `LCL_FULLVERSION` defined in Lazarus `LCLVersion` unit,
75+
- `LCL_FULLVERSION` defined in Lazarus `LCLVersion` unit
6576
- https://delphi.fandom.com/wiki/CompilerVersion_Constant[CompilerVersion] constant from Delphi.
6677
--
6778
6879
- Or to define FPC macros values at command-line.
6980
70-
## [[conditionals-option]] --conditionals option
81+
## `--conditionals` command-line option
7182

72-
--conditionals CONDITIONALS-FILE option (short form is
73-
-d CONDITIONALS-FILE) adds the defines specified in a file
74-
CONDITIONALS-FILE to the list of conditional directives that are present
75-
whenever parsing a unit is started. The file must contain one
76-
conditional per line, without any comments.
83+
`--conditionals SYMBOLS-FILE` option (short form
84+
`-d SYMBOLS-FILE`) adds the symbols specified in a file
85+
`SYMBOLS-FILE` to the list of conditional symbols defined. The file must contain one
86+
symbol per line, without any comments.
7787

7888
Examples:
7989

@@ -90,50 +100,71 @@ FPC
90100
MSWINDOWS
91101
----
92102

93-
## Make sure the resulting code is valid
103+
## Define symbols to make the code valid for PasDoc
94104

95-
Consider this sample:
105+
When you use conditional directives in your code, make sure that the combination of symbols you define for PasDoc results in code that can be parsed by PasDoc. For example, if you have something like this:
96106

97107
```pascal
98-
const NewLine = {$IFDEF MSWINDOWS} #13#10 {$ENDIF} {$IFDEF POSIX} #10 {$ENDIF};
108+
const NewLine =
109+
{$ifdef MSWINDOWS} #13#10 {$endif}
110+
{$ifdef UNIX} #10 {$endif};
99111
```
100112

101-
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:
113+
By default PasDoc defines neither `MSWINDOWS` nor `UNIX`, so it will consider them both undefined. Thus PasDoc will "see" (and fail to parse) a code like this:
102114

103115
```pascal
104116
const NewLine = ;
105117
```
106118

107-
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:
119+
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:
108120

109121
```pascal
110122
const NewLine =
111123
{$ifdef PASDOC}
112124
'The value of this constant depends on the operating system'
113125
{$else}
114-
{$ifdef MSWINDOWS} #13#10 {$endif} {$ifdef POSIX} #10 {$endif}
126+
{$ifdef MSWINDOWS} #13#10 {$endif}
127+
{$ifdef UNIX} #10 {$endif}
115128
{$endif};
116129
```
117130

118-
Make sure to execute PasDoc with command-line option `-d PASDOC` to make it work.
119-
120-
## Support for `$if`
131+
Make sure to execute PasDoc with command-line option `-define PASDOC` to make it work.
121132

122-
The `$if` directive allows to evaluate an expression, like `{$if defined(MSWINDOWS) and not defined(FPC)}`.
133+
## Support for `$if` expressions
123134

124-
NOTE: We had a number of improvements to `$if` parsing since last PasDoc 0.16.0 release. For now, use link:DevelopmentShapshots[development snapshots] to get the latest version with full support for `$if` expressions.
135+
The `$if` directive allows to evaluate an expression, like
125136

126-
Most of `$if` features supported by compilers (like FPC or Delphi) are now supported.
137+
```pascal
138+
{$if defined(MSWINDOWS) and not defined(FPC)}
139+
const CompilerInfo = 'Delphi on Windows';
140+
{$endif}
141+
```
127142

128-
We support:
143+
Most of `$if` features supported by compilers (like FPC or Delphi) are supported. This includes:
129144

130145
- Functions `defined(SYMBOL)`, `undefined(SYMBOL)`, `option(R+)`
131146
- Constants `false`, `true`
132147
- Composing the expression using `and`, `or`, `not`, `xor` operations
133148
- Comparing (Booleans and Integers) using `=`
134149
- Addition, multiplication operatoers.
135150
136-
In particular, some not supported features:
151+
Some expressions remain not supported, ultimately because _PasDoc_ is not a compiler (so we don't have the knowledge about the units you used, like RTL; and we don't decide what are OS / CPU parameters). We don't support:
152+
153+
- `declared(...)`
154+
- `SizeOf(...)`
137155
138-
- `sizeof(xxx)` function (not likely to be ever supported -- requires a compiler to determine it)
139-
- `declared(identifier)` function
156+
The solution is to use a special symbol, like `PASDOC`, to make sure that the expression is valid for PasDoc. For example:
157+
158+
```pascal
159+
const
160+
{ Integer of the same size as Pointer.
161+
@deprecated Use NativeUInt (Delphi) or PtrUInt (FPC). }
162+
MyPointerInt =
163+
{$if defined(PASDOC)}
164+
UIntSystemDependent
165+
{$elseif SizeOf(Pointer) = 8}
166+
UInt64
167+
{$else}
168+
UInt32
169+
{$endif};
170+
```

src/_layouts/default.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ <h1>{{ page.title }}</h1>
8585
{% endif %}
8686
{% endcomment %}
8787

88-
<p><span class="site-footer-credits"><a href="https://www.patreon.com/castleengine">Support Michalis, developer of PasDoc and Castle Game Engine</a>.</span></p>
89-
9088
<p><span class="site-footer-credits">Improve this website by <a href="https://github.com/pasdoc/pasdoc.github.io">proposing a change to the sources</a>.</span></p>
9189

90+
<p><span class="site-footer-credits"><a href="https://castle-engine.io/donate">Support Michalis, developer of PasDoc and Castle Game Engine</a>.</span></p>
91+
9292
<p></p>
9393
</footer>
9494
</section>

0 commit comments

Comments
 (0)