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.
+