The DCU32INT utility by Alexei Hmelnov.
Version 1.0

----------------------------------------------------------------------------
E-Mail: alex@monster.icc.ru
http://monster.icc.ru/~alex/DCU/
----------------------------------------------------------------------------

Purpose.
--------

Parse Delphi 2.0-5.0 units (DCU) and convert their information into the close 
to Pascal form.

DCU32INT stands for DCU32 INTerface, because this program can't extract 
the complete Pascal source, but the extracted unit interface is almost 
correct (see Compiler Information Loss Limitations section for exceptions).

This program is a by-product of the FlexT project (see 
http://monster.icc.ru/~alex/FlexT/ for details), but 
I have done my best to make it useful.

Usage.
------
DCU32INT <Source file name> <Switches> [<Destination file name>]

Destination file may contain * to be replaced by the unit name or name and 
extension. If * is the last char in the name, it will be replaced by 
<Unit name>.int, else - by <Unit name>.
Destination file = "-" => write to stdout.

Switches (start with "/" or "-"):
 -S<show flag>* - Show flags (-S - show all), default: (+) - on, (-) - off
    I(+) - show Imported names
    T(-) - show Type table
    A(-) - show Address table
    D(-) - show Data block
    F(-) - show fixups
    V(-) - show auxiliary Values
    M(-) - don't resolve class methods
    C(-) - don't resolve constant values
    d(-) - show dot types
    v(-) - show VMT for objects and classes
 -I - interface part only
 -U<paths> = Unit directories
 -N<Prefix> = No Name Prefix ("%" - Scope char)
 -D<Prefix> = Dot Name Prefix ("%" - Scope char)

The Scope char symbol will be replaced in the name by "T" for types "C" for
constants and so on (see source for details).

In general, there are two main ways to run the program:
- without the -S switch - to produce the most close to the original Pascal 
  source output without superfluous details;
- with the -S switch to see a lot of additional information, which reflects 
  the internal structure of the DCU file, e.g. the values of some fields of
  unknown purpose (You can try to guess what they mean), the data structures
  representing the VMT of classes, RTTI of data types or the table of 
  addresses.
Of course, You can always select only a subset of additional information using 
the -S<flags>.

Validity.
---------

The DCU32INT utility have passed successfully the "parse all .\LIB" test 
for all the supported by it Delphi versions, i.e. it have parsed all units 
in the <DELPHI LOCATION>\LIB directory with no errors reported. 
See alllib<N>.bat files for examples of running the DCU32INT to parse
all .\LIB (Drawback: it's a DOS BAT file, so the long unit names will be
replaced by the corresponding 8.3 ones).

This success doesn't mean, however, that the underlying DCU specification is 
absolutely correct. So, please, send me your bug reports (see the section 
"Home page" for details).

The Compiler Information Loss Limitations.
------------------------------------------

There are two kinds of limitations of the DCU32INT program:

1. The ones caused by some disadvantages in its implementation,
  which can be overcome later;
2. The ones caused by information loss in DCU after compiling Pascal
  source, which are inevitable.

Here we'll consider some of the latter limitations.

While converting Pascal source into DCU, Delphi compiler extracts from
source and stores into DCU only the information, which is necessary to
produce later an executable file and also, if required, a debug
information for this file. During this process the compiler performs
some simplifications, which cause information loss.

Examples:

1. Identifiers declared in implementation part and subroutines are discarded
  if the debug info checkbox doesn't checked.

2. Evaluation of expressions. Constant expressions are replaced by their
  values, so one can't determine, e.g. that CDM_FIRST = WM_USER+100,
  it will have the fixed value of $0464.
  
3. Resolution of rename types. The rename types (types, which are defined
  by declarations like THandle = integer), are replaced by their reference
  type, so all the references to the THandle type in the source code are
  replaced by the System.Integer type.
  
4. Merge of fields in the records with variants. The declaration like

  TVarRec = record
    case Byte of
      vtInteger:    (VInteger: Integer; VType: Byte);
      vtBoolean:    (VBoolean: Boolean);
    -----------------------------------------
  end;

  Is stored as

  TVarRec{88,7F9FF4C2}=record
    VInteger: Integer{F:2 Ofs:0};
    VType: Byte{F:2 Ofs:4};
    VBoolean: Boolean{F:2 Ofs:0};
    ----------------------------------
  end;

  where Ofs:_ is a field offset information. Of course, we can group
  the fields into cases according to their order and offsets (future work),
  but the information about case labels is lost here completely, and it can't
  be used, e.g. to display safely (Delphi version independent) the Variant
  type value using the TVarRec definition.

All the above mentioned limitations can be demonstrated by Delphi
browser and evaluator (those utilities are also limited by them).

So, the extracted Pascal code can cause some problems, if used in other
version of Delphi, than that, which produced the DCU.

Home page.
----------

The latest version of this program and all the related news will be available
at http://monster.icc.ru/~alex/DCU/

Please, send me (e-mail: alex@monster.icc.ru) bug reports (including the units 
which were not parsed correctly), but first check:
  1. that you have the latest version of DCU32INT,
  2. that this bug was not already reported at 
     http://monster.icc.ru/~alex/DCU/FAQ.htm (projected page name).