home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
dosdisas.zip
/
parsehdr.zip
/
PARSEHDR.TXT
< prev
next >
Wrap
Text File
|
1994-03-31
|
8KB
|
218 lines
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.