* makedsig has been integrated with makedstp, it should handle both LIB and TPL files * other tools have not been modified
218 lines
7.6 KiB
Plaintext
218 lines
7.6 KiB
Plaintext
PARSEHDR
|
|
|
|
1 What is ParseHdr?
|
|
|
|
2 What is dcclibs.dat?
|
|
|
|
3 How do I use ParseHdr?
|
|
|
|
4 What about languages other than C?
|
|
|
|
5 What is the structure of the dcclibs.dat file?
|
|
|
|
6 What are all these errors, and why do they happen?
|
|
|
|
|
|
1 What is ParseHdr?
|
|
-------------------
|
|
|
|
ParseHdr is a program that creates a special prototype file for DCC
|
|
from a set of include files (.h files). This allows DCC to be aware
|
|
of the type of library function arguments, and return types. The file
|
|
produced is called dcclibs.dat. ParseHdr is designed specifically for
|
|
C header files.
|
|
|
|
As an example, this is what allows DCC to recognise that printf has
|
|
(at least) a string argument, and so converts the first argument from
|
|
a numeric constant to a string. So you get
|
|
printf("Hello world")
|
|
instead of
|
|
printf(0x42).
|
|
|
|
|
|
2 What is dcclibs.dat?
|
|
----------------------
|
|
|
|
dcclibs.dat is the file created by the ParseHdr program. It contains
|
|
a list of function names and parameter and return types. See section
|
|
5 for details of the contents of the file.
|
|
|
|
|
|
3 How do I use ParseHdr?
|
|
------------------------
|
|
|
|
To use ParseHdr you need a file containing a list of header files,
|
|
like this:
|
|
\tc\include\alloc.h
|
|
\tc\include\assert.h
|
|
\tc\include\bios.h
|
|
...
|
|
\tc\include\time.h
|
|
|
|
There must be one file per line, no blank lines, and unless the
|
|
header files are in the current directory, a full path must be given.
|
|
The easiest way to create such a file is to redirect the output of a
|
|
dir command to a file, like this:
|
|
c>dir \tc\include\*.h > tcfiles.lst
|
|
and then edit the resultant file. Note that the path will not be
|
|
included in this, so you will have to add that manually. Remove
|
|
everything after the .h, such as file size, date, etc.
|
|
|
|
Once you have this file, you can run parsehdr:
|
|
|
|
parsehdr <listfile>
|
|
|
|
For example,
|
|
|
|
parsehdr tcfiles.lst
|
|
|
|
You will get some messages indicating which files are being
|
|
processed, but also some error messages. Just ignore the error
|
|
messages, see section 6 for why they occur.
|
|
|
|
|
|
|
|
4 What about languages other than C?
|
|
-----------------------------------------
|
|
|
|
ParseHdr will only work on C header files. It would be possible to
|
|
process files for other languages that contained type information, to
|
|
produce a dcclibs.dat file specific to that language. Ideally, DCC
|
|
should look for a different file for each language, but since only a
|
|
C version of dcclibs.dat has so far been created, this has not been
|
|
done.
|
|
|
|
Prototype information for Turbo Pascal exists in the file turbo.tpl,
|
|
at least for things like the graphics library, so it would be
|
|
possible for MakeDsTp to produce a dcclibs.dat file as well as the
|
|
signature file. However, the format of the turbo.tpl file is not
|
|
documented by Borland; for details see
|
|
|
|
W. L. Peavy, "Inside Turbo Pascal 6.0 Units", Public domain software
|
|
file tpu6doc.txt in tpu6.zip. Anonymous ftp from garbo.uwasa.fi and
|
|
mirrors, directory /pc/turbopas, 1991.
|
|
|
|
|
|
|
|
|
|
5 What is the structure of the dcclibs.dat file?
|
|
------------------------------------------------
|
|
|
|
The first 4 bytes are "dccp", identifying it as a DCC prototype file.
|
|
After this, there are two sections.
|
|
|
|
The first section begins with "FN", for Function Names. It is
|
|
followed by a two byte integer giving the number of function names
|
|
stored. The remainder of this section is an array of structures, one
|
|
per function name. Each has this structure:
|
|
char Name[SYMLEN]; /* Name of the function, NULL terminated */
|
|
int type; /* A 2 byte integer describing the return type */
|
|
int numArg; /* The number of arguments */
|
|
int firstArg; /* The index of the first arg, see below */
|
|
char bVarArg; /* 1 if variable arguments, 0 otherwise */
|
|
|
|
SYMLEN is 16, alowing 15 chars before the NULL. Therefore, the length
|
|
of this structure is 23 bytes.
|
|
|
|
The types are as defined in locident.h (actually a part of dcc), and
|
|
at present are as follows:
|
|
typedef enum {
|
|
TYPE_UNKNOWN = 0, /* unknown so far 00 */
|
|
TYPE_BYTE_SIGN, /* signed byte (8 bits) 01 */
|
|
TYPE_BYTE_UNSIGN, /* unsigned byte 02 */
|
|
TYPE_WORD_SIGN, /* signed word (16 bits) 03 */
|
|
TYPE_WORD_UNSIGN, /* unsigned word (16 bits) 04 */
|
|
TYPE_LONG_SIGN, /* signed long (32 bits) 05 */
|
|
TYPE_LONG_UNSIGN, /* unsigned long (32 bits) 06 */
|
|
TYPE_RECORD, /* record structure 07 */
|
|
TYPE_PTR, /* pointer (32 bit ptr) 08 */
|
|
TYPE_STR, /* string 09 */
|
|
TYPE_CONST, /* constant (any type) 0A */
|
|
TYPE_FLOAT, /* floating point 0B */
|
|
TYPE_DOUBLE, /* double precision float 0C */
|
|
} hlType;
|
|
|
|
firstArg is an index into the array in the second section.
|
|
|
|
The second section begins with "PM" (for Parameters). It is followed
|
|
by a 2 byte integer giving the number of parameter records. After
|
|
this is the array of parameter structures. Initially, the names of the
|
|
parameters were being stored, but this has been removed at present.
|
|
The parameter structure is therefore now just a single 2 byte
|
|
integer, representing the type of that argument.
|
|
|
|
The way it all fits together is perhaps best described by an example.
|
|
Lets consider this entry in dcclibs.dat:
|
|
|
|
73 74 72 63 6D 70 00 ; "strcmp"
|
|
00 00 00 00 00 00 00 00 00 ; Padding to 16 bytes
|
|
03 00 ; Return type 3, TYPE_WORD_UNSIGN
|
|
02 00 ; 2 arguments
|
|
15 02 ; First arg is 0215
|
|
00 ; Not var args
|
|
|
|
If we now skip to the "PM" part of the file, skip the number of
|
|
arguments word, then skip 215*2 = 42A bytes, we find this:
|
|
09 00 09 00 09 00 ...
|
|
|
|
The first 09 00 (TYPE_STR) refers to the type of the first parameter,
|
|
and the second to the second parameter. There are only 2 arguments,
|
|
so the third 09 00 refers to the first parameter of the next
|
|
function. So both parameters are strings, as is expected.
|
|
|
|
For functions with variable parameters, bVarArg is set to 01, and the
|
|
number of parameters reported is the number of fixed parameters. Here
|
|
is another example:
|
|
|
|
66 70 72 69 6E 74 66 00 ; "fprintf"
|
|
00 00 00 00 00 00 00 00 ; padding
|
|
03 00 ; return type 3, TYPE_WORD_UNSIGN
|
|
02 00 ; 2 fixed args
|
|
81 01 ; First arg at index 0181
|
|
01 ; Var args
|
|
|
|
and in the "PM" section at offset 181*2 = 0302, we find 08 00 09 00
|
|
03 00 meaning that the first parameter is a pointer (in fact, we know
|
|
it's a FILE *), and the second parameter is a string.
|
|
|
|
|
|
|
|
|
|
6 What are all these errors, and why do they happen?
|
|
----------------------------------------------------
|
|
|
|
When you run ParseHdr, as well as the progress statements like
|
|
Processing \tc\include\alloc.h ...
|
|
|
|
you can get error messages. Basically, ignore these errors. They occur
|
|
for a variety of reasons, most of which are detailed below.
|
|
|
|
1)
|
|
Expected type: got ) (29)
|
|
void __emit__()
|
|
^
|
|
This include file contained a non ansi prototype. This is rare, and
|
|
__emit__ is not a standard function anyway. If it really bothers you,
|
|
you could add the word "void" to the empty parentheses in your
|
|
include file.
|
|
|
|
2)
|
|
Expected ',' between parameter defs: got ( (28)
|
|
void _Cdecl ctrlbrk (int _Cdecl (*handler)(void))
|
|
|
|
Here "handler" is a pointer to a function. Being a basically simple
|
|
program, ParseHdr does not expand all typedef and #define statements,
|
|
so it cannot distinguish between types and user defined function
|
|
names. Therefore, it is not possible in general to parse any
|
|
prototypes containing pointers to functions, so at this stage, any
|
|
such prototypes will produce an error of some sort. DCC cannot
|
|
currently make use of this type information anyway, so this is no
|
|
real loss. There are typically half a dozen such errors.
|
|
|
|
3)
|
|
Unknown type time_t
|
|
|
|
Types (such as time_t) that are structures or pointers to structures
|
|
are not handled by ParseHdr, since typedef and #define statements are
|
|
ignored. Again, there are typically only about a dozen of these.
|