Contributor: PETER SAWATZKI
{$A+,B-,F-,G+,I-,P-,Q-,R-,S-,T-,V-,X+,Y+}
Program H2Pas;
{ Program: H2PAS
 Version: 1.21
 Purpose: convert C header files to some kind of Pascal units
 Developer: Peter Sawatzki (ps) (c) 1993
 Buchenhof 3, 58091 Hagen, Germany
 CompuServe: 100031,3002
 revision history:
 date version author modification
 11/03/93 1.00 ps written
 05/10/94 1.10 ps add EXEHDR import support
 06/29/94 1.2x ps minor modifications
}
Uses
 Objects,
 Strings;
Const
 Version = 'H2Pas v.1.21';
 H2PasIni= 'H2Pas.Ini';
 CRLF = #13#10;
 StdUses: pChar = 'Uses'+CRLF+
 ' WinTypes,'+CRLF+
 ' WinProcs;';
 HasImports: Boolean = False;
 WhichBlock: (Undefd, InConst, InType, InVar, InFunc) = Undefd;
Var
 DstName,
 Imports: String[67];
 Function WordCount(aStr, Delims: pChar): Integer;
 Var
 Count: Integer;
 EndStr: pChar;
 Begin
 EndStr:= StrEnd(aStr);
 Count:= 0;
 While aStr<=endstr Do Begin While (aStr<=endstr) And (StrScan(Delims, aStr[0])Nil) Do Inc(aStr);
 If aStr<=endstr Then Inc(Count); While (aStr<=endstr) And (StrScan(Delims, aStr[0])=Nil) Do Inc(aStr) End; WordCount:= Count End; Function WordPosition (aStr, Delims: pChar; No: Integer): pChar; Var Count: Integer; EndStr: pChar; Begin EndStr:= StrEnd(aStr); Count:= 0; WordPosition:= Nil; While (aStr<=endstr) And (CountNo) Do Begin
 While (aStr<=endstr) And (StrScan(Delims, aStr[0])Nil) Do Inc(aStr);
 If aStr<=endstr Then Inc(Count); If CountNo Then
 While (aStr<=endstr) And (StrScan(Delims, aStr[0])=Nil) Do Inc(aStr) Else WordPosition:= aStr End End; Function ExtractWord (aDst, aStr, Delims: pChar; No: Integer): pChar; Var EndStr: pChar; Begin ExtractWord:= aDst; aStr:= WordPosition(aStr, Delims, No); If Assigned(aStr) Then Begin EndStr:= StrEnd(aStr); While (aStr<=endstr) And (StrScan(Delims, aStr[0])=Nil) Do Begin aDst[0]:= aStr[0]; Inc(aStr); Inc(aDst) End End; aDst[0]:= #0 End; Function Trim (aDst, aSrc: pChar): pChar; Var EndStr: pChar; Begin Trim:= aDst; If Not Assigned(aSrc) Or (aSrc[0]=#0) Then aDst[0]:= #0 Else Begin EndStr:= StrEnd(aSrc); While (aSrcaDst) And (EndStr[0]<=' ') Do Begin EndStr[0]:= #0; Dec(EndStr) End End End; Function Pad (aDst, aSrc: pChar; Count: Integer): pChar; Begin Pad:= aDst; If aDstaSrc Then
 StrCopy(aDst, aSrc);
 Count:= Count-StrLen(aDst);
 aDst:= StrEnd(aDst);
 While Count>0 Do Begin
 aDst[0]:= ' ';
 Inc(aDst);
 Dec(Count)
 End;
 aDst[0]:= #0
 End;
Function StrIPos(Str1, Str2: PChar): PChar;
Var
 EndStr: pChar;
 Len: Integer;
Begin
 StrIPos:= Nil;
 EndStr:= StrEnd(Str1);
 Len:= StrLen(Str2);
 Repeat
 Str1:= StrScan(Str1, Str2[0]);
 If Str1=Nil Then Exit;
 If StrLIComp(Str1, Str2, Len)=0 Then Begin
 StrIPos:= Str1;
 Exit
 End;
 Inc(Str1)
 Until Str1>EndStr
End;
 Function JustFilename(PathName : string) : string;
 {-Return just the filename of a pathname}
 Var
 I: Word;
 Begin
 I:= Succ(Word(Length(PathName)));
 Repeat
 Dec(I);
 Until (PathName[I] in ['\', ':', #0]) or (I = 0);
 JustFilename := Copy(PathName, Succ(I), 64);
 End;
 function JustName(PathName : string) : string;
 {-Return just the name (no extension, no path) of a pathname}
 var
 DotPos : Byte;
 begin
 PathName := JustFileName(PathName);
 DotPos := Pos('.', PathName);
 if DotPos> 0 then
 PathName := Copy(PathName, 1, DotPos-1);
 JustName := PathName;
 end;
 Function JustPath(aName: string): string;
 {-Return just the path of a filename}
 Var
 I: Word;
 Begin
 I:= Succ(Word(Length(aName)));
 Repeat
 Dec(I);
 Until (aName[I] in ['\', ':', #0]) or (I = 0);
 JustPath:= Copy(aName, 1, I)
 End;
 Procedure Fatal (aMsg: pChar);
 Begin
 WriteLn(aMsg);
 Halt(255)
 End;
 Function GetLine (aDst: pChar; Var aFile: Text): pChar;
 Var
 aString: String;
 p,i: Integer;
 Begin
 {$i-}
 ReadLn(aFile, aString);
 If IoResult0 Then Fatal('Read error.');
 p:= Pos('//', aString);
 If p>0 Then Begin
 aString[p+1]:= '*';
 aString:= aString+' */'
 End;
 p:= Pos(#9, aString);
 While p>0 Do Begin
 aString[p]:= ' ';
 For i:= 1 To 7-((p-1) Mod 8) Do
 Insert(' ', aString, p);
 p:= Pos(#9, aString)
 End;
 GetLine:= StrPCopy(aDst, aString)
 End;
 Procedure OutLn (Var aFile: Text; OutStr: pChar);
 Var
 oc: Char;
 Begin
 While OutStr[0]#0 Do Begin
 oc:= OutStr[0];
 Case oc Of
 '/': If OutStr[1]='*' Then Begin
 oc:= '{';
 Inc(OutStr,1)
 End;
 '*': If OutStr[1]='/' Then Begin
 oc:= '}';
 Inc(OutStr)
 End
 End;
 Write(aFile, oc);
 If IoResult0 Then Fatal('Write error.');
 Inc(OutStr)
 End;
 Write(aFile,CRLF);
 If IoResult0 Then Fatal('Write error.')
 End;
Procedure HeaderInfo (Var aFile: Text);
Var
 aLine: Array[0..100] Of Char;
Begin
 WriteLn(aFile, '{ Unit: ',DstName);
 WriteLn(aFile, ' Version: 1.00');
 WriteLn(aFile, ' translated from file ',DstName,'.H');
 WriteLn(aFile, ' raw translation using '+Version+', (c) Peter Sawatzki');
 WriteLn(aFile, ' fine tuned by:');
 WriteLn(aFile, ' (fill in)');
 WriteLn(aFile, ' ');
 WriteLn(aFile, ' revision history:');
 WriteLn(aFile, ' Date: Ver: Author: Mod:');
 WriteLn(aFile, ' xx/xx/94 1.00  ');
 WriteLn(aFile, '}');
 WriteLn(aFile, 'Unit ',DstName,';');
 WriteLn(aFile, 'Interface');
 If StrLen(StdUses)0 Then
 WriteLn(aFile, StdUses);
End;
{-the collection part}
Type
 pImportEntry = ^tImportEntry;
 tImportEntry = Record
 TheName,
 TheDLL,
 TheOrd: pChar
 End;
 pImportCollection = ^tImportCollection;
 tImportCollection = Object(tSortedCollection)
 Function KeyOf(Item: Pointer): Pointer; Virtual;
 Function Compare(Key1, Key2: Pointer): Integer; Virtual;
 Procedure FreeItem(Item: Pointer); Virtual;
 End;
 pTypeMap = ^tTypeMap;
 tTypeMap = Record
 F, T: pChar;
 End;
 pTypeMapCollection = ^tTypeMapCollection;
 tTypeMapCollection = Object(tSortedCollection)
 Function KeyOf(Item: Pointer): Pointer; Virtual;
 Function Compare(Key1, Key2: Pointer): Integer; Virtual;
 Procedure FreeItem(Item: Pointer); Virtual;
 End;
Function tImportCollection.KeyOf(Item: Pointer): Pointer;
Begin
 KeyOf:= pImportEntry(Item)^.TheName
End;
Function tImportCollection.Compare(Key1, Key2: Pointer): Integer;
Begin
 Compare:= StrIComp(Key1, Key2)
End;
Procedure TImportCollection.FreeItem(Item: Pointer);
Begin
 StrDispose(pImportEntry(Item)^.TheName);
 StrDispose(pImportEntry(Item)^.TheDLL);
 StrDispose(pImportEntry(Item)^.TheOrd);
 Dispose(pImportEntry(Item))
End;
Function tTypeMapCollection.KeyOf(Item: Pointer): Pointer;
Begin
 KeyOf:= pTypeMap(Item)^.F
End;
Function tTypeMapCollection.Compare(Key1, Key2: Pointer): Integer;
Begin
 Compare:= StrIComp(Key1, Key2)
End;
Procedure tTypeMapCollection.FreeItem(Item: Pointer);
Begin
 StrDispose(pTypeMap(Item)^.F);
 StrDispose(pTypeMap(Item)^.T);
 Dispose(pTypeMap(Item))
End;
Const
 TheImports: pImportCollection = Nil;
 TheFuncs: pStrCollection = Nil;
 TheStructs: pStrCollection = Nil;
 TheTypeMap: pTypeMapCollection = Nil;
 TheModMap: pStrCollection = Nil;
Procedure CreateCollections;
Begin
 TheImports:= New(pImportCollection, Init(100, 50));
 TheFuncs:= New(pStrCollection, Init(10, 20));
 TheStructs:= New(pStrCollection, Init(10, 20));
 TheTypeMap:= New(pTypeMapCollection, Init(10, 10));
 TheModMap:= New(pStrCollection, Init(10, 10));
End;
Procedure DestroyCollections;
Begin
 If Assigned(TheImports) Then Dispose(TheImports, Done);
 If Assigned(TheFuncs) Then Dispose(TheFuncs, Done);
 If Assigned(TheStructs) Then Dispose(TheStructs, Done);
 If Assigned(TheTypeMap) Then Dispose(TheTypeMap, Done);
 If Assigned(TheModMap) Then Dispose(TheModMap, Done);
End;
Procedure AddImport (aName, aDLL, anOrd: pChar);
Var
 anEntry: pImportEntry;
Begin
 anEntry:= New(pImportEntry);
 anEntry^.TheName:= StrNew(aName);
 anEntry^.TheDLL:= StrNew(aDLL);
 anEntry^.TheOrd:= StrNew(anOrd);
 TheImports^.Insert(anEntry)
End;
Procedure AddFunc (aName: pChar);
Begin
 TheFuncs^.Insert(StrNew(aName))
End;
Procedure AddStruct (aName: pChar);
Begin
 TheStructs^.Insert(StrNew(aName))
End;
Procedure AddType (aSrc, aDst: pChar);
Var
 anEntry: pTypeMap;
Begin
 anEntry:= New(pTypeMap);
 anEntry^.F:= StrNew(aSrc);
 anEntry^.T:= StrNew(aDst);
 TheTypeMap^.Insert(anEntry)
End;
Procedure AddMod (aName: pChar);
Begin
 TheModMap^.Insert(StrNew(aName))
End;
Function GetOrdDLL (aName, RetDLL, RetOrd: pChar): Boolean;
Var
 Index: Integer;
Begin
 If TheImports^.Search(aName, Index) Then
 With pImportEntry(TheImports^.At(Index))^ Do Begin
 GetOrdDLL:= True;
 StrCopy(RetDLL, TheDLL);
 StrCopy(RetOrd, TheOrd)
 End
 Else
 GetOrdDLL:= False
End;
Procedure ReadImports (aFileName: String);
Var
 aFile: Text;
 aLine: Array[0..500] Of Char;
 aName,
 aDLL,
 anOrd: Array[0..60] Of Char;
 aWord: Array[0..60] Of Char;
Begin
 {$i-} Assign(aFile, aFileName); Reset(aFile);
 If IoResult0 Then Exit;
 HasImports:= True;
 StrCopy(aDLL, '?');
 While Not Eof(aFile) Do Begin
 GetLine(aLine, aFile);
 If StrComp(ExtractWord(aWord, aLine, ' ', 1),'Library:')=0 Then
 ExtractWord(aDLL, aLine, ' ', 2)
 Else
 If StrComp(ExtractWord(aWord, aLine, ' ', 5),'exported,')=0 Then Begin
 ExtractWord(anOrd, aLine, ' ', 1);
 ExtractWord(aName, aLine, ' ', 4);
 AddImport(aName, aDLL, anOrd)
 End
 End;
 Close(aFile)
End;
Procedure ReadIni;
Var
 IniFile: Text;
 aStr: String;
 aLine, Word1, Word2: Array[0..255] Of Char;
 rm: (rmNone, rmTypeMap, rmModMap);
 p: Integer;
Begin
 {$i-}
 Assign(IniFile, H2PasIni); Reset(IniFile);
 If IoResult0 Then Begin
 Assign(IniFile, JustPath(ParamStr(0))+'\'+H2PasIni);
 Reset(IniFile);
 If IoResult0 Then
 Exit
 End;
 rm:= rmNone;
 While Not Eof(IniFile) Do Begin
 ReadLn(IniFile, aStr);
 p:= Pos(';', aStr); If (p>0) Then aStr[0]:= Chr(p-1);
 StrPCopy(aLine, aStr); Trim(aLine, aLine);
 If StrLen(aLine)=0 Then
 Continue;
 If aLine[0]='[' Then Begin
 If StrIComp(aLine, '[TypeMap]')=0 Then rm:= rmTypeMap Else
 If StrIComp(aLine, '[ModMap]')=0 Then rm:= rmModMap Else
 rm:= rmNone;
 Continue
 End;
 Case rm Of
 rmTypeMap: AddType(Trim(Word1, ExtractWord(Word1, aLine, '=', 1)),
 Trim(Word2, ExtractWord(Word2, aLine, '=', 2)));
 rmModMap: AddMod(aLine);
 End
 End;
 Close(IniFile)
End;
Function Modifier (aPart: pChar): Boolean;
Var
 Index: Integer;
Begin
 Modifier:= TheModMap^.Search(aPart, Index)
End;
Function TypeConvert (aDst, aSrc: pChar): pChar;
Var
 aWord, ToParse: Array[0..79] Of Char;
 i, anInt, anError: Integer;
 aTemp: Array[0..79] Of Char;
 Index: Integer;
Begin
 TypeConvert:= aDst;
 aDst[0]:= #0;
 ExtractWord(aTemp, aSrc, '[]', 2);
 If StrLen(aTemp)>0 Then Begin
 Val(aTemp, anInt, anError);
 If anError=0 Then Begin
 Str(anInt-1:0, aTemp);
 StrCat(StrCat(StrCat(aDst,'Array[0..'), aTemp),'] Of ');
 End Else
 StrCat(StrCat(StrCat(aDst,'?'), aTemp),'?')
 End;
 ExtractWord(ToParse, aSrc, '[]', 1);
 aTemp[0]:= #0;
 For i:= 1 To WordCount(ToParse, ' ') Do Begin
 ExtractWord(aWord, ToParse, ' ', i);
 If aWord[0]='*' Then Begin
 StrCat(aTemp,'* ');
 aWord[0]:= ' ';
 Trim(aWord, aWord)
 End;
 If (aWord[0]#0) And Not Modifier(aWord) Then
 StrCat(StrCat(aTemp, aWord),' ');
 End;
 Trim(aTemp, aTemp);
 If TheTypeMap^.Search(@aTemp, Index) Then
 With pTypeMap(TheTypeMap^.At(Index))^ Do
 StrCopy(aTemp, T);
 StrCat(aDst, aTemp)
End;
Const
 IdMax = 50;
Type
 tIdTable = Array[1..IdMax] Of
 Record
 TheId,
 TheType: Array[0..79] Of Char;
 TheComment: Array[0..300] Of Char
 End;
Var
 IdCnt: Integer;
 IdTable: tIdTable;
 Procedure InitId;
 Begin
 IdCnt:= 0
 End;
 Procedure AddId (anId, aType, aComment: pChar);
 Begin
 If IdCnt=IdMax Then Begin
 WriteLn('Error: Id Table full. HALT.');
 Halt(1)
 End;
 Inc(IdCnt);
 With IdTable[IdCnt] Do Begin
 Trim(TheId, anId);
 TypeConvert(TheType, aType);
 Trim(TheComment, aComment)
 End
 End;
 Function ParseComment(Var Inf: Text; InStr, OutStr: pChar): Boolean;
 Var
 aWord: Array[0..40] Of Char;
 Begin
 ParseComment:= False;
 If StrPos(StrLCopy(aWord, InStr, 5),'/*')=Nil Then Exit;
 While StrPos(InStr, '*/')=Nil Do Begin
 StrCat(OutStr, InStr);
 GetLine(InStr, Inf)
 End;
 StrCat(OutStr, InStr);
 ParseComment:= True
 End;
 Function ParseDefine(InStr, OutStr: pChar): Boolean;
 Const
 DefineDelim = ' ';
 Var
 aWord: Array[0..512] Of Char;
 Rest, p: pChar;
 isConst: Boolean;
 i: Integer;
 Begin
 ParseDefine:= False;
 If WordCount(InStr, DefineDelim)<3 Then Exit; If (ExtractWord(aWord, InStr, DefineDelim, 1)Nil)
 And (StrIComp(aWord, '#define')=0) Then Begin
 isConst:= False;
 If WhichBlockInConst Then
 StrCopy(OutStr,CRLF+'Const'+CRLF+' ')
 Else
 StrCopy(OutStr,' ');
 ExtractWord(StrEnd(OutStr), InStr, DefineDelim, 2);
 StrCat(Pad(OutStr, OutStr, 35), '= ');
 Rest:= WordPosition(InStr, DefineDelim, 3);
 StrCopy(aWord, Rest);
 p:= StrPos(aWord,'/*'); If Assigned(p) Then p^:= #0;
 Trim(aWord, aWord);
 If StrLen(aWord)>15 Then Exit;
 p:= StrPos(aWord, '0x');
 While Assigned(p) Do Begin
 isConst:= True;
 p[0]:= ' ';
 p[1]:= '$';
 p:= StrPos(p, '0x')
 End;
 p:= StrScan(aWord, 'L'); {get rid of the f*cking 'L'}
 While Assigned(p) Do Begin
 If (p>aWord) Then Begin
 Dec(p);
 If p^ In ['0'..'9','A'..'F','a'..'f'] Then Begin
 p[1]:= ' ';
 IsConst:= True
 End;
 Inc(p)
 End;
 p:= StrScan(p+1, 'L')
 End;
 If Not IsConst Then
 For i:= 0 To StrLen(aWord)-1 Do
 If aWord[i] In ['0'..'9'] Then Begin
 IsConst:= True;
 Break
 End;
 If Not IsConst Then
 Exit;
 Trim(aWord, aWord);
 StrCat(StrCat(OutStr, aWord), ';');
 p:= StrPos(Rest,'/*');
 If Assigned(p) Then
 StrCat(Pad(OutStr,OutStr, 60), p);
 WhichBlock:= InConst;
 ParseDefine:= True
 End
 End;
 Function ParseStruct(Var Inf: Text; InStr, OutStr: pChar): Boolean;
 Var
 aWord,
 aComment,
 RecComment,
 RecName,
 anId, aType,
 Rest: Array[0..300] Of Char;
 possibleArray: Array[0..60] Of Char;
 p, cp: pChar;
 i: Integer;
 Begin
 ParseStruct:= False;
 If (StrIComp(ExtractWord(aWord, Instr, ' ', 1), 'struct')0)
 And (StrIComp(ExtractWord(aWord, Instr, ' ', 2), 'struct')0) Then
 Exit;
 p:= Instr;
 Instr:= StrScan(InStr, '{');
 If Not Assigned(InStr) Then Exit;
 {-try to parse the structure}
 InStr^:= #0;
 ExtractWord(RecName, p, ' ', WordCount(p,' '));
 Inc(InStr);
 Trim(InStr, InStr);
 If (InStr[0]='/') And (InStr[1]='*') Then
 StrCopy(RecComment, InStr)
 Else
 RecComment[0]:= #0;
 InStr:= StrEnd(InStr);
 cp:= InStr;
 Repeat
 GetLine(cp, Inf);
 p:= StrScan(cp, '}');
 cp:= StrEnd(cp);
 cp^:= ' '; Inc(cp); cp^:= #0
 Until Assigned(p);
 If WordCount(p+1,' ;')>0 Then
 ExtractWord(RecName, p+1, ' ;', 1);
 pChar(p-1)^:= #0;
 InitId;
 p:= InStr;
 Repeat
 cp:= p;
 p:= StrScan(p, ';');
 If Assigned(p) Then Begin
 Trim(aWord, ExtractWord(aWord, cp, ';', 1));
 {extract possible comment}
 cp:= StrPos(aWord, '/*');
 If Assigned(cp) Then Begin
 StrCopy(aComment, cp);
 cp^:= #0
 End Else
 aComment[0]:= #0;
 {-extract id and type}
 cp:= WordPosition(aWord, ' *', WordCount(aWord, ' *')); {last word}
 StrCopy(anId, cp);
 ExtractWord(possibleArray, anId,'[]',2);
 ExtractWord(anId, anId, '[]', 1);
 cp^:= #0;
 StrCopy(aType, aWord);
 If StrLen(possibleArray)>0 Then
 StrCat(StrCat(StrCat(aType,'['),possibleArray),']');
 {-extract comment if after ';'}
 Inc(p);
 While p^=' ' Do Inc(p);
 While (p[0]='/') And (p[1]='*') Do Begin
 {append comment}
 cp:= StrEnd(aComment);
 Repeat
 cp^:= p^;
 Inc(p);
 Inc(cp)
 Until (p[0]=#0) Or ((p[0]='*') And (p[1]='/'));
 cp[0]:= #0; StrCat(Trim(aComment, aComment),' */');
 If p[0]#0 Then
 Inc(p,2);
 While p^=' ' Do Inc(p)
 End;
 AddId(anId, aType, aComment)
 End
 Until Not Assigned(p);
 {-output the structure}
 If WhichBlockInType Then Begin
 StrCopy(OutStr,CRLF+'Type'+CRLF);
 OutStr:= StrEnd(OutStr)
 End;
 StrCopy(OutStr,' ');
 StrCat(OutStr, RecName);
 StrCat(OutStr,' = Record');
 If RecComment[0]#0 Then
 StrCat(Pad(OutStr, OutStr, 40), RecComment);
 StrCat(OutStr,CRLF);
 For i:= 1 To IdCnt Do Begin
 OutStr:= StrEnd(OutStr);
 With IdTable[i] Do Begin
 StrCopy(OutStr,' ');
 {If StrIComp(TheId, TheType)=0 Then StrCat(OutStr, '_');} {it works as is}
 StrCat(OutStr, TheId);
 If (i#0 Then Begin
 Pad(OutStr, OutStr, 40);
 StrCat(OutStr, TheComment)
 End;
 StrCat(OutStr,CRLF)
 End
 End;
 StrCat(OutStr,' End;');
 AddStruct(RecName);
 WhichBlock:= InType;
 ParseStruct:= True
 End;
 Function ParseAPI(Var Inf: Text; InStr, OutStr: pChar): Boolean;
 Var
 FHead,
 aWord,
 Res,
 FuncComment,
 FuncName,
 anId, aType, aComment: Array[0..200] Of Char;
 p, cp, cp2, pStart: pChar;
 i, Indent: Integer;
 IsFunc: Boolean;
 Unknown: Integer;
 Function ParseWordAndComment (aComment, aWord, Src: pChar; Delim: Char): pChar;
 {parse Src, search for delim. append comments to aComment, source to aWord}
 Var
 cp: pChar;
 Begin
 Repeat
 While Src^=' ' Do Inc(Src);
 While (Src[0]='/') And (Src[1]='*') Do Begin
 {append comment}
 cp:= StrEnd(aComment);
 Repeat
 cp^:= Src^;
 Inc(Src);
 Inc(cp)
 Until (Src[0]=#0) Or ((Src[0]='*') And (Src[1]='/'));
 cp[0]:= #0; StrCat(Trim(aComment, aComment),' */');
 If Src[0]#0 Then
 Inc(Src,2);
 While Src^=' ' Do Inc(Src)
 End;
 cp:= StrEnd(aWord);
 While Not(Src^ In [#0,',','/']) Do Begin
 cp^:= Src^; Inc(Src); Inc(cp)
 End;
 cp^:= #0;
 If Src^=#0 Then Begin
 ParseWordAndComment:= Src;
 Exit
 End
 Until Src^=',';
 Inc(Src);
 While Src^=' ' Do Inc(Src);
 While (Src[0]='/') And (Src[1]='*') Do Begin
 {append comment}
 cp:= StrEnd(aComment);
 Repeat
 cp^:= Src^;
 Inc(Src);
 Inc(cp)
 Until (Src[0]=#0) Or ((Src[0]='*') And (Src[1]='/'));
 cp[0]:= #0; StrCat(Trim(aComment, aComment),' */');
 If Src[0]#0 Then
 Inc(Src,2);
 While Src^=' ' Do Inc(Src)
 End;
 ParseWordAndComment:= Src
 End;
 Begin
 ParseAPI:= False;
 IsFunc:= False;
 FuncName[0]:= #0;
 Res[0]:= #0;
 If (StrPos(InStr,'typedef')Nil)
 Or (StrPos(InStr,'#define')Nil)
 Or (StrPos(InStr,'#if')Nil)
 Or (StrPos(InStr,'#el')Nil) Then Exit;
 pStart:= StrScan(InStr, '(');
 If Not Assigned(pStart) Then Exit;
 pStart^:= #0;
 Trim(FuncName, ExtractWord(FuncName, InStr, ' ', WordCount(InStr, ' ')));
 cp:= WordPosition(InStr, ' ', WordCount(InStr, ' '));
 If Assigned(cp) Then Begin
 cp[0]:= #0;
 Trim(Res, TypeConvert(Res, InStr))
 End Else
 StrCopy(Res, '?????');
 InStr:= pStart+1;
 cp:= InStr;
 p:= StrScan(cp, ';');
 While Not Assigned(p) Do Begin
 cp:= StrEnd(cp);
 cp^:= ' '; Inc(cp);
 GetLine(cp, Inf);
 p:= StrScan(cp, ';')
 End;
 StrCopy(FuncComment, p+1);
 Repeat
 Dec(p)
 Until (p<=instr) Or (p^=')'); p^:= #0; InitId; Unknown:= 0; p:= InStr; While p^#0 Do Begin
 aComment[0]:= #0;
 aWord[0]:= #0;
 p:= ParseWordAndComment(aComment, aWord, p, ',');
 Trim(aWord, aWord);
 TypeConvert(aType, aWord);
 anId[0]:= #0;
 cp:= WordPosition(aWord, ' *', WordCount(aWord, ' *')); {last word}
 If (WordCount(aWord,' *')=1)
 Or (Assigned(cp) And (StrIComp(cp, TypeConvert(aType, cp))0)) Then Begin
 {non-Ansi declaration}
 Inc(Unknown);
 Str(Unknown, anId);
 Move(anId[0], anId[3], StrLen(anId)+1);
 anId[0]:= 'P'; anId[1]:= 'a'; anId[2]:= 'r';
 End Else Begin
 If Assigned(cp) Then Begin
 StrCopy(anId, cp);
 cp^:= #0
 End;
 TypeConvert(aType, aWord)
 End;
 AddId(anId, aType, aComment)
 End;
 StrCopy(OutStr, ' Function ');
 StrCat(OutStr, FuncName);
 StrCat(OutStr, ' (');
 Indent:= StrLen(OutStr);
 OutStr:= StrEnd(OutStr);
 aWord[0]:= #0;
 For i:= 1 To IdCnt Do
 With IdTable[i] Do Begin
 StrCat(aWord, TheId);
 If (i#0 Then
 StrCat(Pad(aWord, aWord, 60-Indent), TheComment);
 If (Indent+StrLen(aWord)>90) Or (TheComment[0]#0) Then Begin
 StrCopy(OutStr, aWord); OutStr:= StrEnd(OutStr);
 If i'+CRLF+
 '#include "'+DstName+'.h"'+CRLF+
 'void veri (char *aStr, int aSize)'+CRLF+
 '{ printf("Size of %s= %5i\n",aStr,aSize); }'+CRLF);
 WriteLn(Out,'void main (void)'+CRLF+
 '{ printf("verification of '+DstName+' for C:\n");');
 TheStructs^.ForEach(@VeriC);
 WriteLn(Out,'}');
 End;
Const
 LineBufSize = 5000;
 IoBufSize = 32*1024;
Type
 IoBuf = Array[0..IoBufSize-1] Of Char;
 pIoBuf = ^IoBuf;
Var
 Inf, Out: Text;
 InStr,
 OutStr: pChar;
Begin
 WriteLn(Version,', written 1993 by P. Sawatzki');
 If Not (ParamCount In [2,3]) Then Begin
 WriteLn('Usage: H2Pas InFile OutFile [ImportList]');
 Halt
 End;
 CreateCollections;
 ReadIni;
 If ParamStr(3)'' Then
 Imports:= ParamStr(3)
 Else
 Imports:= JustName(ParamStr(1))+'.Imp';
 {$i-}
 Assign(Inf, ParamStr(1)); Reset(Inf);
 If IoResult0 Then Fatal('Input file not found');
 Assign(Out, ParamStr(2)); ReWrite(Out);
 If IoResult0 Then Fatal('Unable to create output file');
 DstName:= JustName(ParamStr(2));
 GetMem(InStr, LineBufSize);
 GetMem(OutStr, LineBufSize);
 Write('Processing files...');
 HeaderInfo(Out);
 While Not Eof(Inf) Do Begin
 GetLine(InStr, Inf);
 OutStr[0]:= #0;
 If ParseComment(Inf, InStr, OutStr)
 Or ParseDefine(InStr, OutStr)
 Or ParseStruct(Inf, InStr, OutStr)
 Or ParseAPI(Inf, InStr, OutStr) Then
 OutLn(Out, OutStr)
 Else
 OutLn(Out, InStr)
 End;
 WriteLn('Done.');
 Write('Reading import file ',Imports,'...');
 ReadImports(Imports);
 If HasImports Then
 WriteLn('Done.')
 Else
 WriteLn('Not found.'+CRLF+
 '(generate an import file using "EXEHDR File.DLL>'+JustName(ParamStr(1))+
 '.Imp")');
 Write('Appending report...');
 GenerateReport(Out);
 WriteLn('Done.');
 DestroyCollections;
 FreeMem(InStr, LineBufSize);
 FreeMem(OutStr, LineBufSize);
 Close(Inf);
 Close(Out)
End.
{ ------------- INFO ON THIS PROGRAM ------------------ }
ReadMe.Txt for H2Pas
====================
H2Pas is a quick and dirty hack to convert C-Header files to Pascal units.
If you make modifications, please drop me a copy at
 Peter Sawatzki, CompuServe 100031,3002
In it's current implementation (1.20) H2Pas does the following:
- convert structs
- convert constant defines
- convert procedure/function headers
- 'convert' comments of style /* xxxx */ to { xxxx }
 and comments of style // yyyy to { yyy }
- make use of IMPort files to resolve DLL index entries
- output C and Pascal code to verify correctness of C and Pascal
 structure sizes
How to use and generate import files:
-------------------------------------
if a EXEHDR type .IMP file is present for the DLL with information
about the entry points of a function, H2Pas outputs an unit implementation
section with entries of the form:
 Function Ctl3DEnabled; External 'CTL3D' Index 5;
where the appropriate indices are resolved from information gathered
from the .IMP file.
To generate the .IMP file for a DLL -say CTL3D.DLL- one must do the following:
 EXEHDR CTL3D.DLL>CTL3D.IMP
How to execute H2Pas
--------------------
Usage:
H2Pas Ctl3D.H Ctl3D.Pas [Ctl3D.Imp]
where Ctl3D.H is the source C header file,
 Ctl3D.Pas is the destination pascal unit to be generated
 and Ctl3D.Imp is an optional import file generated from EXEHDR
H2Pas.Ini
---------
currently H2Pas.Ini has two areas for customization:
[TypeMap]
C-Type = Pascal-Type
maps a certain C-type to a Pascal type (see sample H2Pas.Ini)
[ModMap]
modifier
a list of modifiers that H2Pas should ignore (see sample H2Pas.Ini)
written by
 Peter Sawatzki
 Buchenhof 3
 58091 Hagen / Germany
 CompuServe: 100031,3002
 { ------------------ SAMPLE INI FILE NEED FOR THIS UNIT ---------- }
 { CUT and Save as H2PAS.INI }
[TypeMap]
unsigned = Word
unsigned int = Word
char = Char
unsigned long = LongInt
int = Integer
char far * = pChar
unsigned char = Byte
byte = Byte
char * = pChar
long = LongInt
WORD = Word
DWORD = LongInt
ULONG = LongInt
BOOL = Bool
UINT = Word
void * = Pointer
; Windows stuff
BITMAPINFO = tBitmapInfo
HANDLE = tHandle
HWINDOW = hWindow
COLORREF = tColorRef
[ModMap]
WINAPI
WINGAPI
APIENTRY
EXPENTRY
EXPORT
EXTERN
PASCAL
FAR
_FAR
const


AltStyle によって変換されたページ (->オリジナル) /