parsehdr.txt 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. PARSEHDR
  2. 1 What is ParseHdr?
  3. 2 What is dcclibs.dat?
  4. 3 How do I use ParseHdr?
  5. 4 What about languages other than C?
  6. 5 What is the structure of the dcclibs.dat file?
  7. 6 What are all these errors, and why do they happen?
  8. 1 What is ParseHdr?
  9. -------------------
  10. ParseHdr is a program that creates a special prototype file for DCC
  11. from a set of include files (.h files). This allows DCC to be aware
  12. of the type of library function arguments, and return types. The file
  13. produced is called dcclibs.dat. ParseHdr is designed specifically for
  14. C header files.
  15. As an example, this is what allows DCC to recognise that printf has
  16. (at least) a string argument, and so converts the first argument from
  17. a numeric constant to a string. So you get
  18. printf("Hello world")
  19. instead of
  20. printf(0x42).
  21. 2 What is dcclibs.dat?
  22. ----------------------
  23. dcclibs.dat is the file created by the ParseHdr program. It contains
  24. a list of function names and parameter and return types. See section
  25. 5 for details of the contents of the file.
  26. 3 How do I use ParseHdr?
  27. ------------------------
  28. To use ParseHdr you need a file containing a list of header files,
  29. like this:
  30. \tc\include\alloc.h
  31. \tc\include\assert.h
  32. \tc\include\bios.h
  33. ...
  34. \tc\include\time.h
  35. There must be one file per line, no blank lines, and unless the
  36. header files are in the current directory, a full path must be given.
  37. The easiest way to create such a file is to redirect the output of a
  38. dir command to a file, like this:
  39. c>dir \tc\include\*.h > tcfiles.lst
  40. and then edit the resultant file. Note that the path will not be
  41. included in this, so you will have to add that manually. Remove
  42. everything after the .h, such as file size, date, etc.
  43. Once you have this file, you can run parsehdr:
  44. parsehdr <listfile>
  45. For example,
  46. parsehdr tcfiles.lst
  47. You will get some messages indicating which files are being
  48. processed, but also some error messages. Just ignore the error
  49. messages, see section 6 for why they occur.
  50. 4 What about languages other than C?
  51. -----------------------------------------
  52. ParseHdr will only work on C header files. It would be possible to
  53. process files for other languages that contained type information, to
  54. produce a dcclibs.dat file specific to that language. Ideally, DCC
  55. should look for a different file for each language, but since only a
  56. C version of dcclibs.dat has so far been created, this has not been
  57. done.
  58. Prototype information for Turbo Pascal exists in the file turbo.tpl,
  59. at least for things like the graphics library, so it would be
  60. possible for MakeDsTp to produce a dcclibs.dat file as well as the
  61. signature file. However, the format of the turbo.tpl file is not
  62. documented by Borland; for details see
  63. W. L. Peavy, "Inside Turbo Pascal 6.0 Units", Public domain software
  64. file tpu6doc.txt in tpu6.zip. Anonymous ftp from garbo.uwasa.fi and
  65. mirrors, directory /pc/turbopas, 1991.
  66. 5 What is the structure of the dcclibs.dat file?
  67. ------------------------------------------------
  68. The first 4 bytes are "dccp", identifying it as a DCC prototype file.
  69. After this, there are two sections.
  70. The first section begins with "FN", for Function Names. It is
  71. followed by a two byte integer giving the number of function names
  72. stored. The remainder of this section is an array of structures, one
  73. per function name. Each has this structure:
  74. char Name[SYMLEN]; /* Name of the function, NULL terminated */
  75. int type; /* A 2 byte integer describing the return type */
  76. int numArg; /* The number of arguments */
  77. int firstArg; /* The index of the first arg, see below */
  78. char bVarArg; /* 1 if variable arguments, 0 otherwise */
  79. SYMLEN is 16, alowing 15 chars before the NULL. Therefore, the length
  80. of this structure is 23 bytes.
  81. The types are as defined in locident.h (actually a part of dcc), and
  82. at present are as follows:
  83. typedef enum {
  84. TYPE_UNKNOWN = 0, /* unknown so far 00 */
  85. TYPE_BYTE_SIGN, /* signed byte (8 bits) 01 */
  86. TYPE_BYTE_UNSIGN, /* unsigned byte 02 */
  87. TYPE_WORD_SIGN, /* signed word (16 bits) 03 */
  88. TYPE_WORD_UNSIGN, /* unsigned word (16 bits) 04 */
  89. TYPE_LONG_SIGN, /* signed long (32 bits) 05 */
  90. TYPE_LONG_UNSIGN, /* unsigned long (32 bits) 06 */
  91. TYPE_RECORD, /* record structure 07 */
  92. TYPE_PTR, /* pointer (32 bit ptr) 08 */
  93. TYPE_STR, /* string 09 */
  94. TYPE_CONST, /* constant (any type) 0A */
  95. TYPE_FLOAT, /* floating point 0B */
  96. TYPE_DOUBLE, /* double precision float 0C */
  97. } hlType;
  98. firstArg is an index into the array in the second section.
  99. The second section begins with "PM" (for Parameters). It is followed
  100. by a 2 byte integer giving the number of parameter records. After
  101. this is the array of parameter structures. Initially, the names of the
  102. parameters were being stored, but this has been removed at present.
  103. The parameter structure is therefore now just a single 2 byte
  104. integer, representing the type of that argument.
  105. The way it all fits together is perhaps best described by an example.
  106. Lets consider this entry in dcclibs.dat:
  107. 73 74 72 63 6D 70 00 ; "strcmp"
  108. 00 00 00 00 00 00 00 00 00 ; Padding to 16 bytes
  109. 03 00 ; Return type 3, TYPE_WORD_UNSIGN
  110. 02 00 ; 2 arguments
  111. 15 02 ; First arg is 0215
  112. 00 ; Not var args
  113. If we now skip to the "PM" part of the file, skip the number of
  114. arguments word, then skip 215*2 = 42A bytes, we find this:
  115. 09 00 09 00 09 00 ...
  116. The first 09 00 (TYPE_STR) refers to the type of the first parameter,
  117. and the second to the second parameter. There are only 2 arguments,
  118. so the third 09 00 refers to the first parameter of the next
  119. function. So both parameters are strings, as is expected.
  120. For functions with variable parameters, bVarArg is set to 01, and the
  121. number of parameters reported is the number of fixed parameters. Here
  122. is another example:
  123. 66 70 72 69 6E 74 66 00 ; "fprintf"
  124. 00 00 00 00 00 00 00 00 ; padding
  125. 03 00 ; return type 3, TYPE_WORD_UNSIGN
  126. 02 00 ; 2 fixed args
  127. 81 01 ; First arg at index 0181
  128. 01 ; Var args
  129. and in the "PM" section at offset 181*2 = 0302, we find 08 00 09 00
  130. 03 00 meaning that the first parameter is a pointer (in fact, we know
  131. it's a FILE *), and the second parameter is a string.
  132. 6 What are all these errors, and why do they happen?
  133. ----------------------------------------------------
  134. When you run ParseHdr, as well as the progress statements like
  135. Processing \tc\include\alloc.h ...
  136. you can get error messages. Basically, ignore these errors. They occur
  137. for a variety of reasons, most of which are detailed below.
  138. 1)
  139. Expected type: got ) (29)
  140. void __emit__()
  141. ^
  142. This include file contained a non ansi prototype. This is rare, and
  143. __emit__ is not a standard function anyway. If it really bothers you,
  144. you could add the word "void" to the empty parentheses in your
  145. include file.
  146. 2)
  147. Expected ',' between parameter defs: got ( (28)
  148. void _Cdecl ctrlbrk (int _Cdecl (*handler)(void))
  149. Here "handler" is a pointer to a function. Being a basically simple
  150. program, ParseHdr does not expand all typedef and #define statements,
  151. so it cannot distinguish between types and user defined function
  152. names. Therefore, it is not possible in general to parse any
  153. prototypes containing pointers to functions, so at this stage, any
  154. such prototypes will produce an error of some sort. DCC cannot
  155. currently make use of this type information anyway, so this is no
  156. real loss. There are typically half a dozen such errors.
  157. 3)
  158. Unknown type time_t
  159. Types (such as time_t) that are structures or pointers to structures
  160. are not handled by ParseHdr, since typedef and #define statements are
  161. ignored. Again, there are typically only about a dozen of these.