PreDefinedIdents.txt contains a list of in Delphi
defined identifiers. It is by far not complete. All unknown identifiers
found when parsing that are not in this list will be listed as unknown
identifiers. This has no real consequence, it is just for informational
SystemIdents.txt contains a list of internal
identifiers defined inside the Delphi compiler. They will be added only
when the unit System is parsed, because they are treated by the compiler
as if they were defined there. The file
contains correspondingly the list of internal types.
The parsed data can be saved to a file, for instance to allow the comparison of different versions of a project with faster access to the different versions and without the necessity to unpack the whole directory just to parse it again.
The format of the file is binary to decrease its size. As the file is
binary and contains lots of different information a
description would be quite lengthy, so here follows only some key
information, the algorithm to save and load such files can be seen in
USaveParsed and the other files within the sub-directory
At the beginning of files of this format are always eight magic bytes, the eight characters "JADD&%$#", thus allowing the identification of correct files. After that the version number of the file follows as four bytes. This program can read files of each version, although some generators may fail when they need information that wasn't saved by very old versions of this program. But the original source files can be extracted and parsed again to gather the complete information needed by any generator.
The file format was designed to be dynamic and modular, meaning for instance additional to the version of the file itself, each class writing data to the file also has its own version number that will be written to the file. Even the list of classes that write the information, and so are needed again to read it, is written.
The log files of components, that can be used to generate a help on the GUI are simple text files, each line containing some information. They consist of three parts, in the first line the help context of the whole form is written, then the components are logged, each on a separate line, and optionally after an empty line as a separator the automatic component aliases follow.
Each component is logged with four values on a line on its own, the
values are separated by a simple space. First comes the name of the
component, then the rectangle its occupying on the screen shot as four
comma-separated values (left, top, right, bottom) in pixels. The third
value is the help context set for the component, if it does not support
a help context
-1 is written. The final value is either
1 representing a boolean, whether the
component should be used, i.e. was not outside a set constraint.
The automatic aliases are written for all Labels and StaticTexts that have a FocusControl assigned. Each entry consists of a line with the name of the label and the name of the component it will focus separated by a space.
Most files of DelphiDoc are in the format of Windows
initialization files. Initialization files have a simple and easy to
understand syntax, can be viewed and edited with a simple text editor,
and can be copied and back-uped by the users. They can even easily
created manually when their format is known.
Delphi has almost native support for initialization files by several classes within its standard units (unit
Just to rant a bit again, the registry is no real good place to save settings of programs. There was only one reason to do it anyway and that was because Windows was not a decent multi-user operating system. But that was long ago, now, by default, ini files are created in the directory for local settings inside the user's home directory. So there is no reason, unless compatibilty for multi-user Windows 95/98/ME systems is needed, but I doubt anyone with a multi-user system is still running such an old version of windows. And there are several reasons to use (initialization) files for the settings, as outlined in the first paragraph.
Well, anyway, as Delphi programs generally do not need to be installed I always keep it even simpler and save the ini file in the same directory as the executable file. That way the settings are always as easy accessible as the program itself. Of course it means every user needs a separate copy of it, but a few MBs are negligible for today's hard drives.
There is another feature of initialization files that is important for DelphiDoc: Initialization files can be merged. As long as they don't have sections with the same name, it is no problem so save several settings in just one file or even copy files together.
This file saves the general settings of the program, this means mainly
the GUI version. Generally each form and some pages have a sections on
their own to save their settings. The name of the section is generally
the same name as their class. The framework for this is implemented in
USettingsKeeper, but most forms also implement a
specialized class to save, set and load their settings.
Additional to the visual settings the ini file also contains the section "JADDState" containing the general state of the program, which is also read by the command line version. It includes the version of Delphi to emulate when parsing source code and the generator and helper objects to use when generating documentation.
Even more interestingly and as mentioned above other data can be merged into the initialization file. So localized texts and options of the generator objects can also be saved within this main file, which will then be read at program start-up and each change of the selected generator. For the format of these settings see below.
A DelphiDoc Project File consists of several sections which
contain the files to be parsed and the compiler options to use when
As can be seen in the GUI version there are actually three lists of files, each is saved in an own section with the same format. The list of files to be parsed is saved in the section "ToParse", the list not to be parsed in the section "NotToParse" and the list of library files in "Libs".
Each list has a field "Count" with the number of entries in the list and then for each entry two values with the prefixes "Item" and "Recurse" followed by the number between 0 and Count - 1. The item specifies the file in the list and the other boolean flag specifies whether the item is checked, i.e. whether for Delphi project files all files within the project should also be parsed or for directories whether files in sub-directory should be parsed.
For the additional compiler options some general settings are saved in
the section "PreDefines". These include the list of defined symbols, the
settings of the compiler switches and unit aliases. It specifies also
whether the .cfg file of Delphi projects should be read and options
which may be set after parsing it. Then there are two lists, they are
saved in the same format as the lists of files to parse, but without
the additional flag. One is the list of "SearchPaths", which should
contain directories. The other is a list of constants for expressions
for conditional compiling in "CondCompilingConstants", each entry is a
declaration of an untyped constant (without the
These files contain the list of log files of GUIs to read and generate documentation about and the alternative content for the main index of the documentation, each in its own section. The list of log files are written in the section "GUILogFiles" in the same format as used for the source project files for list of files.
The content of the main index is written in a recursive format. Each
entry consists of three comma-separated values within a field. The first
one defines the link (commas are replaced with %44, as they could only
appear in external links, and commas can be quoted that way in HTTP) and
the third one defines the text for the entry. And the value in the
middle is either empty or defines the prefix for the child entries of
the entry. The prefix for the top-level entries is the empty string.
Each list of entries consists of the "Count" field with the number of entries and each entry is saved in a field whose name is just the number of the entry, between 1 and Count. The field name is always appended to the prefix of the name. While the prefix itself does not contain a real meaning, it just has to be unique, it is by default generated by taking the whole field name of the parent entry and appending a dot ".".
These files are a bit different, and maybe they shouldn't be initialization files. There are no special sections, each section is interpreted as a separate diagram lay-out. The only constraint about the section name is of course, that it has to be unique, this is achieved by adding a random number to the prefix "Diagram_". Each section consists of two kinds of values, settings about the diagram and its content.
All settings have a dot "." as prefix. They define the options of the diagram in a similar format as in the inline command to create diagrams, but the names are more verbose. The rest of the entries define the files or classes that are in the diagram. The name of the field is always the name of the unit, or for class diagrams the name of the class prefixed with the name of the unit it is declared in separated by a dot ".". Its value is the position of the box inside the diagram as a comma-separated pair of numbers, first the x- then the y-coordinate.
There are no special files for the options of the objects to generate the documentation. Any ini file can be used to save the options. This means they can be saved in extra files, in the default ini file "DelphiDoc.ini" or in one of the project files (source or GUI help).
The options are saved as simple "Name=Value" pairs, with the name being the name of the option and the value being the string representation of the value to be set. More interesting are the sections the options are saved in. As the generators (and most helper objects) are declared in a class hierarchy, the options can be saved either in a section with the name of the class of the generator, or all options can be saved in the corresponding section of the class they are defined in.
When loading the options from a file, first all options are read from the base class, then of all other ancestor classes and finally from the section with the name of the class itself. This allows to define option values for all generators in their common base class, but also to override values for some generators in their own section.
When a new generator object is selected, it will automatically be initialized from the options in the default ini file "DelphiDoc.ini".
The localized texts are written and loaded just like the options of the generator objects. The values also consist of "Name=Value" pairs with the name being the name of the text to be localized and the value being the text to be used for it, it will generally be quoted with single quotes "'", just like in Pascal. This is necessary to keep trailing spaces within the values, normally they would be stripped. The texts will be read from the section with the name "TEditDocumentationTexts".
When the program starts, it will automatically read the localized texts from the default ini file "DelphiDoc.ini".