diff --git a/.gitattributes b/.gitattributes index 60aecf843a..ae40811bec 100644 --- a/.gitattributes +++ b/.gitattributes @@ -114,6 +114,8 @@ components/codetools/examples/listinterfaceclasses.lpi svneol=native#text/plain components/codetools/examples/listinterfaceclasses.pas svneol=native#text/plain components/codetools/examples/methodjumping.lpi svneol=native#text/plain components/codetools/examples/methodjumping.pas svneol=native#text/plain +components/codetools/examples/ppudependencies.lpi svneol=native#text/plain +components/codetools/examples/ppudependencies.lpr svneol=native#text/plain components/codetools/examples/reduceifdefs.lpi svneol=native#text/plain components/codetools/examples/reduceifdefs.lpr svneol=native#text/plain components/codetools/examples/removeemptymethods.lpi svneol=native#text/plain @@ -183,6 +185,7 @@ components/codetools/multikeywordlisttool.pas svneol=native#text/pascal components/codetools/nonpascalcodetools.pas svneol=native#text/plain components/codetools/pascalparsertool.pas svneol=native#text/pascal components/codetools/pascalreadertool.pas svneol=native#text/pascal +components/codetools/ppuparser.pas svneol=native#text/plain components/codetools/resourcecodetool.pas svneol=native#text/pascal components/codetools/sourcechanger.pas svneol=native#text/pascal components/codetools/sourcelog.pas svneol=native#text/pascal diff --git a/components/codetools/examples/ppudependencies.lpi b/components/codetools/examples/ppudependencies.lpi new file mode 100644 index 0000000000..3d09e0add0 --- /dev/null +++ b/components/codetools/examples/ppudependencies.lpi @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/codetools/examples/ppudependencies.lpr b/components/codetools/examples/ppudependencies.lpr new file mode 100644 index 0000000000..5106c5fef6 --- /dev/null +++ b/components/codetools/examples/ppudependencies.lpr @@ -0,0 +1,39 @@ +{ + *************************************************************************** + * * + * This source is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This code is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * A copy of the GNU General Public License is available on the World * + * Wide Web at . You can also * + * obtain it by writing to the Free Software Foundation, * + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + *************************************************************************** + + Author: Mattias Gaertner + + Abstract: + Demonstrating, how to parse a ppu file with the codetools. +} +program PPUDependencies; + +{$mode objfpc}{$H+} + +uses + Classes, SysUtils; + +const + ConfigFilename = 'codetools.config'; +begin + CodeToolBoss.SimpleInit(ConfigFilename); + +end. + diff --git a/components/codetools/ppuparser.pas b/components/codetools/ppuparser.pas new file mode 100644 index 0000000000..c52435e5b9 --- /dev/null +++ b/components/codetools/ppuparser.pas @@ -0,0 +1,258 @@ +{ + *************************************************************************** + * * + * This source is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This code is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * A copy of the GNU General Public License is available on the World * + * Wide Web at . You can also * + * obtain it by writing to the Free Software Foundation, * + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + *************************************************************************** + + Author: Mattias Gaertner + + Note: + This unit will move to the FCL when it has stabilized. + + Abstract: + Functions to classes to read ppu streams (Free Pascal compiled units) + of various versions. For example reading 2.3.1 ppus compiled for 64bit + with a lazarus compiled with fpc 2.2.2 i386. +} +unit PPUParser; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils; + +const + PPUIsEndianBig = {$IFDEF ENDIAN_BIG}True{$ELSE}False{$ENDIF}; + +const +{ppu entries} + mainentryid = 1; + subentryid = 2; + {special} + iberror = 0; + ibstartdefs = 248; + ibenddefs = 249; + ibstartsyms = 250; + ibendsyms = 251; + ibendinterface = 252; + ibendimplementation = 253; +// ibendbrowser = 254; + ibend = 255; + {general} + ibmodulename = 1; + ibsourcefiles = 2; + ibloadunit = 3; + ibinitunit = 4; + iblinkunitofiles = 5; + iblinkunitstaticlibs = 6; + iblinkunitsharedlibs = 7; + iblinkotherofiles = 8; + iblinkotherstaticlibs = 9; + iblinkothersharedlibs = 10; + ibImportSymbols = 11; + ibsymref = 12; + ibdefref = 13; +// ibendsymtablebrowser = 14; +// ibbeginsymtablebrowser = 15; + ibusedmacros = 16; + ibderefdata = 17; + ibexportedmacros = 18; + ibderefmap = 19; + {syms} + ibtypesym = 20; + ibprocsym = 21; + ibstaticvarsym = 22; + ibconstsym = 23; + ibenumsym = 24; +// ibtypedconstsym = 25; + ibabsolutevarsym = 26; + ibpropertysym = 27; + ibfieldvarsym = 28; + ibunitsym = 29; + iblabelsym = 30; + ibsyssym = 31; +// ibrttisym = 32; + iblocalvarsym = 33; + ibparavarsym = 34; + ibmacrosym = 35; + {definitions} + iborddef = 40; + ibpointerdef = 41; + ibarraydef = 42; + ibprocdef = 43; + ibshortstringdef = 44; + ibrecorddef = 45; + ibfiledef = 46; + ibformaldef = 47; + ibobjectdef = 48; + ibenumdef = 49; + ibsetdef = 50; + ibprocvardef = 51; + ibfloatdef = 52; + ibclassrefdef = 53; + iblongstringdef = 54; + ibansistringdef = 55; + ibwidestringdef = 56; + ibvariantdef = 57; + ibundefineddef = 58; + {implementation/ObjData} + ibnodetree = 80; + ibasmsymbols = 81; + ibresources = 82; + + ibmainname = 90; + { target-specific things } + iblinkotherframeworks = 100; + +{ unit flags } + uf_init = $1; + uf_finalize = $2; + uf_big_endian = $4; +// uf_has_browser = $10; + uf_in_library = $20; { is the file in another file than .* ? } + uf_smart_linked = $40; { the ppu can be smartlinked } + uf_static_linked = $80; { the ppu can be linked static } + uf_shared_linked = $100; { the ppu can be linked shared } +// uf_local_browser = $200; + uf_no_link = $400; { unit has no .o generated, but can still have + external linking! } + uf_has_resourcestrings = $800; { unit has resource string section } + uf_little_endian = $1000; + uf_release = $2000; { unit was compiled with -Ur option } + uf_threadvars = $4000; { unit has threadvars } + uf_fpu_emulation = $8000; { this unit was compiled with fpu emulation on } + uf_has_debuginfo = $10000; { this unit has debuginfo generated } + uf_local_symtable = $20000; { this unit has a local symtable stored } + uf_uses_variants = $40000; { this unit uses variants } + uf_has_resourcefiles = $80000; { this unit has external resources (using $R directive)} + uf_has_exports = $100000; { this module or a used unit has exports } + +const + PPU_ID_Size = 3; + PPU_Ver_Size = 3; + +type + tppuheader=packed record + id : array[1..PPU_ID_Size] of char; { = 'PPU' } + ver : array[1..PPU_Ver_Size] of char; + compiler : word; + cpu : word; + target : word; + flags : longint; + size : longint; { size of the ppufile without header } + checksum : cardinal; { checksum for this ppufile } + interface_checksum : cardinal; + deflistsize, + symlistsize : longint; + future : array[0..0] of longint; + end; + + tppuentry=packed record + size : longint; + id : byte; + nr : byte; + end; + + { TPPU } + + TPPU = class + private + fChangeEndian: boolean; + FInputStream: TStream; + FHeader: tppuheader; + procedure ReadHeader; + procedure InitInput(s: TStream); + procedure ReadBuf(Buf; Count: longint); + procedure ReadWord(out w: word); + public + constructor Create; + destructor Destroy; override; + procedure Clear; + procedure LoadFromStream(s: TStream); + property InputStream: TStream read FInputStream; + end; + +implementation + +{ TPPU } + +procedure TPPU.ReadHeader; +begin + // read ID + ReadBuf(FHeader.id,PPU_ID_Size); + // read version + ReadBuf(FHeader.ver,PPU_Ver_Size); + // read rest of header + ReadBuf(FHeader.compiler,SizeOf(tppuheader)-PPU_Ver_Size-PPU_ID_Size); + if fChangeEndian then begin + fHeader.compiler := swapendian(fHeader.compiler); + fHeader.cpu := swapendian(fHeader.cpu); + fHeader.target := swapendian(fHeader.target); + fHeader.flags := swapendian(fHeader.flags); + fHeader.size := swapendian(fHeader.size); + fHeader.checksum := swapendian(fHeader.checksum); + fHeader.interface_checksum := swapendian(fHeader.interface_checksum); + fHeader.deflistsize := swapendian(fHeader.deflistsize); + fHeader.symlistsize := swapendian(fHeader.symlistsize); + end; + fChangeEndian:=((FHeader.flags and uf_big_endian) = uf_big_endian)<>PPUIsEndianBig; +end; + +procedure TPPU.InitInput(s: TStream); +begin + FInputStream:=s; + fChangeEndian:=not PPUIsEndianBig; +end; + +procedure TPPU.ReadBuf(Buf; Count: longint); +begin + FInputStream.Read(Buf,Count); +end; + +procedure TPPU.ReadWord(out w: word); +begin + FInputStream.Read(w,2); + if fChangeEndian then + swapendian(w); +end; + +constructor TPPU.Create; +begin + +end; + +destructor TPPU.Destroy; +begin + inherited Destroy; +end; + +procedure TPPU.Clear; +begin + +end; + +procedure TPPU.LoadFromStream(s: TStream); +begin + Clear; + InitInput(s); + ReadHeader; +end; + +end. +