Browse Source

* Prevent writing pointer types twice

Michael VAN CANNEYT 2 years ago
parent
commit
30698ea06c
2 changed files with 107 additions and 75 deletions
  1. 32 42
      utils/h2pas/h2pbase.pp
  2. 75 33
      utils/h2pas/h2pout.pp

+ 32 - 42
utils/h2pas/h2pbase.pp

@@ -33,7 +33,6 @@ type
 
 
 
 
 var
 var
-  IsExtern : boolean;
   s,TN,PN  : String;
   s,TN,PN  : String;
 
 
 
 
@@ -84,7 +83,7 @@ function HandleDefine(dname : presobject) : presobject;
 Function CheckWideString(S : String) : presobject;
 Function CheckWideString(S : String) : presobject;
 function CheckUnderScore(pdecl : presobject) : presobject;
 function CheckUnderScore(pdecl : presobject) : presobject;
 
 
-Function NewCType(aID,aIntID : String) : PresObject;
+Function NewCType(aCType,aPascalType : String) : PresObject;
 
 
 Implementation
 Implementation
 
 
@@ -98,13 +97,13 @@ begin
 end;
 end;
 
 
 
 
-Function NewCType(aID,aIntID : String) : PresObject;
+Function NewCType(aCType,aPascalType : String) : PresObject;
 
 
 begin
 begin
   if UseCTypesUnit then
   if UseCTypesUnit then
-    Result:=NewID(aID)
+    Result:=NewID(aCType)
   else
   else
-    result:=NewIntID(aIntID);
+    result:=NewIntID(aPascalType);
 end;
 end;
 
 
 function HandleUnaryDefExpr(aExpr : presobject) : presobject;
 function HandleUnaryDefExpr(aExpr : presobject) : presobject;
@@ -164,53 +163,41 @@ function handleSpecialUnSignedType(aType : presobject) : presobject;
 
 
 var
 var
   hp : presobject;
   hp : presobject;
+  tc,tp : string;
 
 
 begin
 begin
   hp:=aType;
   hp:=aType;
   Result:=hp;
   Result:=hp;
   if Not assigned(hp) then
   if Not assigned(hp) then
     exit;
     exit;
-  s:=strpas(hp^.p);
+  tp:='';
+  tc:=strpas(hp^.p);
   if UseCTypesUnit then
   if UseCTypesUnit then
-    begin
-    if s=cint_STR then
-      s:=cuint_STR
-    else if s=cshort_STR then
-      s:=cushort_STR
-    else if s=cchar_STR then
-      s:=cuchar_STR
-    else if s=clong_STR then
-      s:=culong_STR
-    else if s=clonglong_STR then
-      s:=culonglong_STR
-    else if s=cint8_STR then
-      s:=cuint8_STR
-    else if s=cint16_STR then
-      s:=cuint16_STR
-    else if s=cint32_STR then
-      s:=cuint32_STR
-    else if s=cint64_STR then
-      s:=cuint64_STR
+    case tc of
+      cint_STR: tp:=cuint_STR;
+      cshort_STR: tp:=cushort_STR;
+      cchar_STR : tp:=cuchar_STR;
+      clong_STR : tp:=culong_STR;
+      clonglong_STR : tp:=culonglong_STR;
+      cint8_STR : tp:=cuint8_STR;
+      cint16_STR : tp:=cuint16_STR;
+      cint32_STR : tp:=cuint32_STR;
+      cint64_STR : tp:=cuint64_STR;
     else
     else
-      s:='';
+      tp:='';
     end
     end
   else
   else
-    begin
-    if s=INT_STR then
-      s:=UINT_STR
-    else if s=SHORT_STR then
-      s:=USHORT_STR
-    else if s=SMALL_STR then
-      s:=USMALL_STR
-    else if s=CHAR_STR then
-      s:=UCHAR_STR
-    else if s=INT64_STR then
-      s:=QWORD_STR
+    case tc of
+      INT_STR : tp:=UINT_STR;
+      SHORT_STR : tp:=USHORT_STR;
+      SMALL_STR : tp:=USMALL_STR;
+      CHAR_STR :  tp:=UCHAR_STR;
+      INT64_STR : tp:=QWORD_STR;
     else
     else
-      s:='';
+      tp:='';
   end;
   end;
-  if s<>'' then
-    hp^.setstr(s);
+  if tp<>'' then
+    hp^.setstr(tp);
 end;
 end;
 
 
 function handleSizedArrayDecl(aType,aSizeExpr: presobject): presobject;
 function handleSizedArrayDecl(aType,aSizeExpr: presobject): presobject;
@@ -452,6 +439,7 @@ function HandleDeclarationStatement(decl, type_spec, modifier_spec,
   decllist_spec, block_spec: presobject): presobject;
   decllist_spec, block_spec: presobject): presobject;
 var
 var
   hp : presobject;
   hp : presobject;
+  IsExtern : boolean;
 
 
 begin
 begin
   HandleDeclarationStatement:=Nil;
   HandleDeclarationStatement:=Nil;
@@ -650,6 +638,7 @@ function HandleDeclarationSysTrap(decl, type_spec, modifier_spec,
 
 
 var
 var
   hp : presobject;
   hp : presobject;
+  IsExtern : boolean;
 
 
 begin
 begin
   HandleDeclarationSysTrap:=Nil;
   HandleDeclarationSysTrap:=Nil;
@@ -942,6 +931,8 @@ end;
 
 
 function HandleTypedefList(type_spec,dec_modifier,declarator_list: presobject) : presobject;
 function HandleTypedefList(type_spec,dec_modifier,declarator_list: presobject) : presobject;
 
 
+(* TYPEDEF type_specifier dec_modifier declarator_list SEMICOLON *)
+
 var
 var
   hp,ph : presobject;
   hp,ph : presobject;
 
 
@@ -949,7 +940,6 @@ var
 begin
 begin
   HandleTypedefList:=Nil;
   HandleTypedefList:=Nil;
   ph:=nil;
   ph:=nil;
-  (* TYPEDEF type_specifier dec_modifier declarator_list SEMICOLON *)
   if block_type<>bt_type then
   if block_type<>bt_type then
     begin
     begin
       if not(compactmode) then
       if not(compactmode) then
@@ -983,7 +973,7 @@ begin
   PN:=PointerName(ph^.p);
   PN:=PointerName(ph^.p);
   if UsePPointers and (Uppercase(tn)<>Uppercase(pn)) and
   if UsePPointers and (Uppercase(tn)<>Uppercase(pn)) and
     assigned(type_spec) and (type_spec^.typ<>t_procdef) then
     assigned(type_spec) and (type_spec^.typ<>t_procdef) then
-    writeln(outfile,aktspace,PN,' = ^',TN,';');
+    WritePointerTypeDef(outfile,PN,TN);
   (* write new type name *)
   (* write new type name *)
   write(outfile,aktspace,TN,' = ');
   write(outfile,aktspace,TN,' = ');
   shift(2);
   shift(2);

+ 75 - 33
utils/h2pas/h2pout.pp

@@ -1,5 +1,7 @@
 unit h2pout;
 unit h2pout;
 
 
+{$modeswitch result}
+
 interface
 interface
 
 
 uses
 uses
@@ -12,6 +14,9 @@ procedure CloseTempFiles;
 procedure WriteFileHeader(var headerfile: Text);
 procedure WriteFileHeader(var headerfile: Text);
 procedure WriteLibraryInitialization;
 procedure WriteLibraryInitialization;
 
 
+// This will write each pointer type only once.
+function WritePointerTypeDef(var aFile : text; const PN,TN : AnsiString) : Boolean;
+
 procedure write_statement_block(var outfile:text; p : presobject);
 procedure write_statement_block(var outfile:text; p : presobject);
 procedure write_type_specifier(var outfile:text; p : presobject);
 procedure write_type_specifier(var outfile:text; p : presobject);
 procedure write_p_a_def(var outfile:text; p,simple_type : presobject);
 procedure write_p_a_def(var outfile:text; p,simple_type : presobject);
@@ -55,7 +60,8 @@ Var
 implementation
 implementation
 
 
 var
 var
-  tempfile : text;
+  WrittenPointers : TStringList;
+ tempfile : text;
   space_array : array [0..255] of integer;
   space_array : array [0..255] of integer;
   space_index : integer;
   space_index : integer;
   _NeedEllipsisOverload : boolean;
   _NeedEllipsisOverload : boolean;
@@ -209,7 +215,7 @@ the correct syntax.
 function FixId(const s:string):string;
 function FixId(const s:string):string;
 
 
 const
 const
-  maxtokens = 16;
+  maxtokens = 17;
   reservedid: array[1..maxtokens] of string[14] = (
   reservedid: array[1..maxtokens] of string[14] = (
     'CLASS',
     'CLASS',
     'DISPOSE',
     'DISPOSE',
@@ -226,7 +232,8 @@ const
     'TYPE',
     'TYPE',
     'TRUE',
     'TRUE',
     'UNTIL',
     'UNTIL',
-    'VAR'
+    'VAR',
+    'OBJECT'
     );
     );
 
 
 var
 var
@@ -310,7 +317,7 @@ begin
   else
   else
     PointerName:=Copy(s,i,255);
     PointerName:=Copy(s,i,255);
   if PointerPrefix then
   if PointerPrefix then
-      PTypeList.Add('P'+s);
+    PTypeList.Add('P'+s);
 end;
 end;
 
 
 
 
@@ -715,11 +722,6 @@ begin
     else
     else
       begin
       begin
       (* generate a call by reference parameter ?       *)
       (* generate a call by reference parameter ?       *)
-//     varpara:=usevarparas and
-//              assigned(p^.p1^.p2^.p1) and
-//              (p^.p1^.p2^.p1^.typ in [t_addrdef,t_pointerdef]) and
-//               assigned(p^.p1^.p2^.p1^.p1) and
-//               (p^.p1^.p2^.p1^.p1^.typ<>t_procdef);
       varpara:=IsVarPara(p);
       varpara:=IsVarPara(p);
       if varpara then
       if varpara then
         begin
         begin
@@ -776,6 +778,7 @@ begin
 end;
 end;
 
 
 
 
+
 Procedure write_pointerdef(var outfile:text; p,simple_type : presobject);
 Procedure write_pointerdef(var outfile:text; p,simple_type : presobject);
 
 
 var
 var
@@ -928,7 +931,7 @@ begin
       begin
       begin
       PTypeList.Add('P'+p^.str);
       PTypeList.Add('P'+p^.str);
       end;
       end;
-  if p^.intname then
+  if p^.skiptprefix then
     write(outfile,p^.p)
     write(outfile,p^.p)
   else
   else
     write(outfile,TypeName(p^.p));
     write(outfile,TypeName(p^.p));
@@ -1332,6 +1335,22 @@ begin
   end;
   end;
 end;
 end;
 
 
+function MayWritePointerTypeDef(const PN: AnsiString): Boolean;
+
+begin
+  Result:=WrittenPointers.IndexOf(PN)=-1;
+end;
+
+function WritePointerTypeDef(var aFile : text; const PN, TN: AnsiString): Boolean;
+
+begin
+  Result:=MayWritePointerTypeDef(PN);;
+  if Result then
+    begin
+    WrittenPointers.Add(PN);
+    Writeln(aFile,aktspace,PN,' = ^',TN,';');
+   end;
+end;
 
 
 procedure write_statement_block(var outfile:text; p : presobject);
 procedure write_statement_block(var outfile:text; p : presobject);
 
 
@@ -1362,7 +1381,32 @@ begin
   writeln(outfile,aktspace,'end;');
   writeln(outfile,aktspace,'end;');
 end;
 end;
 
 
+procedure WritePointerList(var headerfile: Text);
 
 
+var
+  I : Integer;
+  MustWritePointers : Boolean;
+  originalstr : String;
+
+begin
+  I:=PTypeList.count-1;
+  MustWritePointers:=False;
+  While (Not MustWritePointers) and (I>=0) do
+    begin
+    MustWritePointers:=MayWritePointerTypeDef(PTypelist[i]);
+    Dec(I);
+    end;
+  if not MustWritePointers then
+    exit;
+  Writeln(headerfile,'Type');
+  for i:=0 to (PTypeList.Count-1) do
+     begin
+       originalstr:=copy(PTypelist[i],2,length(PTypeList[i]));
+       if PrependTypes then
+         originalstr:='T'+originalstr;
+       WritePointerTypeDef(HeaderFile,PTypeList[i],OriginalStr);
+     end;
+end;
 
 
 procedure WriteFileHeader(var headerfile: Text);
 procedure WriteFileHeader(var headerfile: Text);
 var
 var
@@ -1393,31 +1437,13 @@ begin
    end;
    end;
   if UseName then
   if UseName then
    begin
    begin
-     writeln(headerfile,aktspace,'const');
-     writeln(headerfile,aktspace,'  External_library=''',libfilename,'''; {Setup as you need}');
+     writeln(headerfile,'const');
+     writeln(headerfile,'  External_library=''',libfilename,'''; {Setup as you need}');
      writeln(headerfile);
      writeln(headerfile);
    end;
    end;
-  if UsePPointers then
-   begin
-     Writeln(headerfile,aktspace,'{ Pointers to basic pascal types, inserted by h2pas conversion program.}');
-     Writeln(headerfile,aktspace,'Type');
-     Writeln(headerfile,aktspace,'  PLongint  = ^Longint;');
-     Writeln(headerfile,aktspace,'  PSmallInt = ^SmallInt;');
-     Writeln(headerfile,aktspace,'  PByte     = ^Byte;');
-     Writeln(headerfile,aktspace,'  PWord     = ^Word;');
-     Writeln(headerfile,aktspace,'  PDWord    = ^DWord;');
-     Writeln(headerfile,aktspace,'  PDouble   = ^Double;');
-     Writeln(headerfile);
-   end;
   if PTypeList.count <> 0 then
   if PTypeList.count <> 0 then
-   Writeln(headerfile,aktspace,'Type');
-  for i:=0 to (PTypeList.Count-1) do
-   begin
-     originalstr:=copy(PTypelist[i],2,length(PTypeList[i]));
-     if PrependTypes then
-       originalstr:='T'+originalstr;
-     Writeln(headerfile,aktspace,'  '+PTypeList[i],'  = ^',originalstr,';');
-   end;
+    WritePointerList(headerfile);
+  writeln(headerfile);
   if not packrecords then
   if not packrecords then
    begin
    begin
       writeln(headerfile,'{$IFDEF FPC}');
       writeln(headerfile,'{$IFDEF FPC}');
@@ -1501,5 +1527,21 @@ begin
   writeln(outfile,'  Free',unitname,';');
   writeln(outfile,'  Free',unitname,';');
 end;
 end;
 
 
-
+initialization
+  WrittenPointers:=TStringList.Create;
+  WrittenPointers.Sorted:=true;
+  // We must never write these, they are defined in the system unit
+  WrittenPointers.Add('pansichar');
+  WrittenPointers.Add('pchar');
+  WrittenPointers.Add('pdouble');
+  WrittenPointers.Add('plongint');
+  WrittenPointers.Add('psmallint');
+  WrittenPointers.Add('pshortint');
+  WrittenPointers.Add('pbyte');
+  WrittenPointers.Add('pint64');
+  WrittenPointers.Add('pword');
+  WrittenPointers.Add('pqword');
+
+finalization
+  WrittenPointers.Free;
 end.
 end.