codetools: started ppu parser

git-svn-id: trunk@15579 -
This commit is contained in:
mattias 2008-06-26 16:54:02 +00:00
parent 5e85db3260
commit f32d59efb7
4 changed files with 343 additions and 0 deletions

3
.gitattributes vendored
View File

@ -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

View File

@ -0,0 +1,43 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
<PathDelim Value="/"/>
<Version Value="6"/>
<General>
<SessionStorage Value="InIDEConfig"/>
<MainUnit Value="0"/>
<TargetFileExt Value=""/>
</General>
<VersionInfo>
<ProjectVersion Value=""/>
</VersionInfo>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
<ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
</local>
</RunParams>
<Units Count="1">
<Unit0>
<Filename Value="ppudependencies.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="PPUDependencies"/>
</Unit0>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="5"/>
<CodeGeneration>
<Generate Value="Faster"/>
</CodeGeneration>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</CONFIG>

View File

@ -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 <http://www.gnu.org/copyleft/gpl.html>. 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.

View File

@ -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 <http://www.gnu.org/copyleft/gpl.html>. 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 <ppufile>.* ? }
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.