Browse Source

--- Merging r19621 into '.':
U packages/fcl-passrc/src/pastree.pp
U packages/fcl-passrc/src/pscanner.pp
U packages/fcl-passrc/src/pparser.pp
U packages/fcl-passrc/examples/test_parser.pp
U packages/fcl-passrc/examples/testunit1.pp
--- Merging r19622 into '.':
U utils/fpdoc/dw_html.pp
U utils/fpdoc/fpdoc.lpi
U utils/fpdoc/fpclasschart.pp
U utils/fpdoc/testunit.pp
U utils/fpdoc/fpdoc.pp
--- Merging r19623 into '.':
G packages/fcl-passrc/src/pastree.pp
--- Merging r19624 into '.':
G packages/fcl-passrc/src/pparser.pp
--- Merging r19625 into '.':
U utils/fpdoc/dglobals.pp
--- Merging r19626 into '.':
U utils/fpdoc/dwlinear.pp
--- Merging r19662 into '.':
G packages/fcl-passrc/src/pastree.pp
G packages/fcl-passrc/src/pscanner.pp
G packages/fcl-passrc/src/pparser.pp
--- Merging r19663 into '.':
G packages/fcl-passrc/examples/test_parser.pp
G packages/fcl-passrc/examples/testunit1.pp
--- Merging r19664 into '.':
G packages/fcl-passrc/examples/testunit1.pp
--- Merging r19669 into '.':
G utils/fpdoc/dwlinear.pp
U utils/fpdoc/dw_man.pp
G utils/fpdoc/dglobals.pp
G utils/fpdoc/dw_html.pp
--- Merging r19670 into '.':
G utils/fpdoc/dw_html.pp
--- Merging r19724 into '.':
U utils/fpdoc/fpdocxmlopts.pas
G utils/fpdoc/dglobals.pp
G utils/fpdoc/fpdoc.lpi
G utils/fpdoc/fpdoc.pp
--- Merging r19725 into '.':
A utils/fpdoc/mkfpdocproj.pp
A utils/fpdoc/mkfpdocproj.lpi
--- Merging r19730 into '.':
G utils/fpdoc/fpdocxmlopts.pas
A utils/fpdoc/mgrfpdocproj.pp
U utils/fpdoc/mkfpdocproj.pp
U utils/fpdoc/mkfpdocproj.lpi
--- Merging r19735 into '.':
G utils/fpdoc/fpdocxmlopts.pas
U utils/fpdoc/mgrfpdocproj.pp
G utils/fpdoc/mkfpdocproj.pp
G utils/fpdoc/mkfpdocproj.lpi
--- Merging r19752 into '.':
G packages/fcl-passrc/src/pscanner.pp
G packages/fcl-passrc/src/pparser.pp
--- Merging r19753 into '.':
U utils/fpdoc/dwriter.pp
G utils/fpdoc/dglobals.pp
G utils/fpdoc/dw_html.pp
G utils/fpdoc/fpdoc.lpi
A utils/fpdoc/mkfpdoc.pp
G utils/fpdoc/fpdoc.pp
--- Merging r19755 into '.':
G utils/fpdoc/dglobals.pp
G utils/fpdoc/fpdoc.pp
--- Merging r19761 into '.':
G utils/fpdoc/fpdocxmlopts.pas
G utils/fpdoc/mgrfpdocproj.pp
G utils/fpdoc/mkfpdocproj.pp
--- Merging r19776 into '.':
G utils/fpdoc/mkfpdocproj.pp
--- Merging r19786 into '.':
G packages/fcl-passrc/src/pparser.pp
--- Merging r19795 into '.':
G packages/fcl-passrc/src/pscanner.pp
--- Merging r19796 into '.':
G packages/fcl-passrc/src/pscanner.pp
--- Merging r19797 into '.':
G packages/fcl-passrc/src/pparser.pp
--- Merging r19798 into '.':
A packages/fcl-passrc/tests
A packages/fcl-passrc/tests/tcscanner.pas
A packages/fcl-passrc/tests/testpassrc.lpr
A packages/fcl-passrc/tests/testpassrc.lpi
--- Merging r19850 into '.':
U utils/fpdoc/unitdiff.pp
--- Merging r19884 into '.':
G utils/fpdoc/dglobals.pp
G utils/fpdoc/fpdoc.pp
--- Merging r19901 into '.':
U utils/fpdoc/Makefile.fpc
G utils/fpdoc/dwriter.pp
G utils/fpdoc/dw_html.pp
C utils/fpdoc/Makefile
--- Merging r19903 into '.':
G packages/fcl-passrc/src/pparser.pp
--- Merging r19951 into '.':
U utils/fpcm/fpcmake.ini
C utils/fpcm/fpcmake.inc
C packages/fcl-extra/Makefile
C packages/fcl-net/Makefile
C packages/fcl-res/Makefile
C packages/fcl-passrc/Makefile
C packages/fcl-registry/Makefile
C packages/fastcgi/Makefile
C packages/fcl-image/Makefile
C packages/fcl-web/Makefile
C packages/fcl-base/Makefile
C packages/fcl-async/Makefile
C packages/fcl-json/Makefile
C packages/fcl-js/Makefile
--- Merging r19993 into '.':
G packages/fcl-passrc/src/pastree.pp
G packages/fcl-passrc/src/pparser.pp
--- Merging r19996 into '.':
U packages/fcl-passrc/tests/tcscanner.pas
G packages/fcl-passrc/src/pscanner.pp
--- Merging r19997 into '.':
G packages/fcl-passrc/tests/tcscanner.pas
G packages/fcl-passrc/src/pscanner.pp
--- Merging r20005 into '.':
U utils/fpdoc/dw_dxml.pp
--- Merging r20009 into '.':
G utils/fpdoc/dw_html.pp
--- Merging r20011 into '.':
G packages/fcl-passrc/src/pscanner.pp
--- Merging r20012 into '.':
G packages/fcl-passrc/src/pastree.pp
--- Merging r20013 into '.':
G packages/fcl-passrc/src/pparser.pp
--- Merging r20014 into '.':
G packages/fcl-passrc/tests/tcscanner.pas
Summary of conflicts:
Text conflicts: 14

# revisions: 19621,19622,19623,19624,19625,19626,19662,19663,19664,19669,19670,19724,19725,19730,19735,19752,19753,19755,19761,19776,19786,19795,19796,19797,19798,19850,19884,19901,19903,19951,19993,19996,19997,20005,20009,20011,20012,20013,20014
r19621 | michael | 2011-11-11 16:08:17 +0100 (Fri, 11 Nov 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/examples/test_parser.pp
M /trunk/packages/fcl-passrc/examples/testunit1.pp
M /trunk/packages/fcl-passrc/src/pastree.pp
M /trunk/packages/fcl-passrc/src/pparser.pp
M /trunk/packages/fcl-passrc/src/pscanner.pp

* Support for generics
r19622 | michael | 2011-11-11 16:08:42 +0100 (Fri, 11 Nov 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dw_html.pp
M /trunk/utils/fpdoc/fpclasschart.pp
M /trunk/utils/fpdoc/fpdoc.lpi
M /trunk/utils/fpdoc/fpdoc.pp
M /trunk/utils/fpdoc/testunit.pp

* Support for generics
r19623 | michael | 2011-11-11 18:14:38 +0100 (Fri, 11 Nov 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pastree.pp

* Set declaration returns type of name if named enumeration
r19624 | michael | 2011-11-11 18:17:35 +0100 (Fri, 11 Nov 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pparser.pp

* Fixed some indentation
r19625 | michael | 2011-11-11 18:17:58 +0100 (Fri, 11 Nov 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp

* Removed debug statement
r19626 | michael | 2011-11-11 18:18:21 +0100 (Fri, 11 Nov 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dwlinear.pp

* Output table with enumerated explanations for set
r19662 | michael | 2011-11-20 23:46:54 +0100 (Sun, 20 Nov 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pastree.pp
M /trunk/packages/fcl-passrc/src/pparser.pp
M /trunk/packages/fcl-passrc/src/pscanner.pp

* Refactoring in preparation of extended features (nested type, extended records) support
r19663 | michael | 2011-11-20 23:48:29 +0100 (Sun, 20 Nov 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/examples/test_parser.pp
M /trunk/packages/fcl-passrc/examples/testunit1.pp

* More extensive examples taken from RTL
r19664 | michael | 2011-11-20 23:49:14 +0100 (Sun, 20 Nov 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/examples/testunit1.pp

* Uncommented some extra tests
r19669 | michael | 2011-11-22 19:15:28 +0100 (Tue, 22 Nov 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp
M /trunk/utils/fpdoc/dw_html.pp
M /trunk/utils/fpdoc/dw_man.pp
M /trunk/utils/fpdoc/dwlinear.pp

* TList -> TFPList to match latest changes in fcl-passrc
r19670 | michael | 2011-11-22 20:21:20 +0100 (Tue, 22 Nov 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dw_html.pp

* Missing conversion to TFPList
r19724 | michael | 2011-12-02 17:24:29 +0100 (Fri, 02 Dec 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp
M /trunk/utils/fpdoc/fpdoc.lpi
M /trunk/utils/fpdoc/fpdoc.pp
M /trunk/utils/fpdoc/fpdocxmlopts.pas

* Implemented project file writing functionality, based on patch from Hans-Peter Diettrich
r19725 | michael | 2011-12-02 19:44:58 +0100 (Fri, 02 Dec 2011) | 1 line
Changed paths:
A /trunk/utils/fpdoc/mkfpdocproj.lpi
A /trunk/utils/fpdoc/mkfpdocproj.pp

* Start of project file manipulation program
r19730 | michael | 2011-12-03 01:26:20 +0100 (Sat, 03 Dec 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/fpdocxmlopts.pas
A /trunk/utils/fpdoc/mgrfpdocproj.pp
M /trunk/utils/fpdoc/mkfpdocproj.lpi
M /trunk/utils/fpdoc/mkfpdocproj.pp

* Added lots of commands to fpdoc file manager, moved to separate class and unit for reuse
r19735 | michael | 2011-12-03 17:46:15 +0100 (Sat, 03 Dec 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/fpdocxmlopts.pas
M /trunk/utils/fpdoc/mgrfpdocproj.pp
M /trunk/utils/fpdoc/mkfpdocproj.lpi
M /trunk/utils/fpdoc/mkfpdocproj.pp

* Some fixes after first test round
r19752 | michael | 2011-12-04 19:15:55 +0100 (Sun, 04 Dec 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pparser.pp
M /trunk/packages/fcl-passrc/src/pscanner.pp

* Added logging options
r19753 | michael | 2011-12-04 19:16:51 +0100 (Sun, 04 Dec 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp
M /trunk/utils/fpdoc/dw_html.pp
M /trunk/utils/fpdoc/dwriter.pp
M /trunk/utils/fpdoc/fpdoc.lpi
M /trunk/utils/fpdoc/fpdoc.pp
A /trunk/utils/fpdoc/mkfpdoc.pp

Logging options implemented, and dry run. Separated out creation and logging logic
r19755 | michael | 2011-12-04 20:36:36 +0100 (Sun, 04 Dec 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp
M /trunk/utils/fpdoc/fpdoc.pp

* Implemented --descr-dir and --input-dir
r19761 | michael | 2011-12-05 20:30:22 +0100 (Mon, 05 Dec 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/fpdocxmlopts.pas
M /trunk/utils/fpdoc/mgrfpdocproj.pp
M /trunk/utils/fpdoc/mkfpdocproj.pp

* Save/load package imports to/from package description file
r19776 | michael | 2011-12-07 22:08:20 +0100 (Wed, 07 Dec 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/mkfpdocproj.pp

* Print usage message
r19786 | michael | 2011-12-09 11:54:07 +0100 (Fri, 09 Dec 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pparser.pp

* Fixed external name case for procedure
r19795 | michael | 2011-12-10 14:32:17 +0100 (Sat, 10 Dec 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pscanner.pp

* Fix bug #20791
r19796 | michael | 2011-12-10 15:03:13 +0100 (Sat, 10 Dec 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pscanner.pp

* Speed Improvements and option to use (virtual file) streams.
r19797 | michael | 2011-12-10 15:16:54 +0100 (Sat, 10 Dec 2011) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pparser.pp

* Forgot to commit
r19798 | michael | 2011-12-10 15:20:55 +0100 (Sat, 10 Dec 2011) | 1 line
Changed paths:
A /trunk/packages/fcl-passrc/tests
A /trunk/packages/fcl-passrc/tests/tcscanner.pas
A /trunk/packages/fcl-passrc/tests/testpassrc.lpi
A /trunk/packages/fcl-passrc/tests/testpassrc.lpr

* Unit Tests for scanner
r19850 | michael | 2011-12-14 23:34:05 +0100 (Wed, 14 Dec 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/unitdiff.pp

* Corrected program name clause
r19884 | michael | 2011-12-23 16:05:18 +0100 (Fri, 23 Dec 2011) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp
M /trunk/utils/fpdoc/fpdoc.pp

* Extended usage with additional options for project file
r19901 | marco | 2011-12-28 20:08:40 +0100 (Wed, 28 Dec 2011) | 4 lines
Changed paths:
M /trunk/utils/fpdoc/Makefile
M /trunk/utils/fpdoc/Makefile.fpc
M /trunk/utils/fpdoc/dw_html.pp
M /trunk/utils/fpdoc/dwriter.pp

* improved unknown link errormsg to list current module name.
* Added some new units to clean rules. rst and main program objectcode
are still not cleaned properly though
r19903 | marco | 2011-12-29 00:00:56 +0100 (Thu, 29 Dec 2011) | 10 lines
Changed paths:
M /trunk/packages/fcl-passrc/src/pparser.pp

* fix for crash while building LCL docs. Hopefully the last one.
The fix is an emergency fix only, disabling calling convention
registration for element types that not derive from TPasProcedure

The fix is in Parsprocedureorfunctionheader, second part that handles
modifiers and calling conventions. The parent was always typecasted
to TPasProcedure, but can also be TPasProcedureType and TPasFunctionType
that not derive from TPasProcedure.
r19951 | joost | 2012-01-02 16:16:52 +0100 (Mon, 02 Jan 2012) | 3 lines
Changed paths:
M /trunk/packages/fastcgi/Makefile
M /trunk/packages/fcl-async/Makefile
M /trunk/packages/fcl-base/Makefile
M /trunk/packages/fcl-extra/Makefile
M /trunk/packages/fcl-image/Makefile
M /trunk/packages/fcl-js/Makefile
M /trunk/packages/fcl-json/Makefile
M /trunk/packages/fcl-net/Makefile
M /trunk/packages/fcl-passrc/Makefile
M /trunk/packages/fcl-registry/Makefile
M /trunk/packages/fcl-res/Makefile
M /trunk/packages/fcl-web/Makefile
M /trunk/utils/fpcm/fpcmake.inc
M /trunk/utils/fpcm/fpcmake.ini

* Do not use the BINUTILSPREFIX when compiling fpmake files during a cross-
compile. It seems that CROSSBOOTSTRAP is never set(?)
r19993 | michael | 2012-01-07 16:20:43 +0100 (Sat, 07 Jan 2012) | 4 lines
Changed paths:
M /trunk/packages/fcl-passrc/src/pastree.pp
M /trunk/packages/fcl-passrc/src/pparser.pp

* Allow streams as source
* Improved range type parsing (handle deprecated etc.)
* Improvements in record type parsing type (handle deprecated etc.)
r19996 | michael | 2012-01-07 19:41:08 +0100 (Sat, 07 Jan 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pscanner.pp
M /trunk/packages/fcl-passrc/tests/tcscanner.pas

* Macro support. Fix for include support if not EOL
r19997 | michael | 2012-01-07 21:36:22 +0100 (Sat, 07 Jan 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pscanner.pp
M /trunk/packages/fcl-passrc/tests/tcscanner.pas

* $IFDEF also handles macros
r20005 | marco | 2012-01-08 01:46:57 +0100 (Sun, 08 Jan 2012) | 2 lines
Changed paths:
M /trunk/utils/fpdoc/dw_dxml.pp

* emergency fix for breakage (TPasResString.value was still used. Changed to getdeclaration for now)
r20009 | michael | 2012-01-08 15:52:18 +0100 (Sun, 08 Jan 2012) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dw_html.pp

* Fixed compilation with latest version of fcl-passrc
r20011 | michael | 2012-01-08 18:39:21 +0100 (Sun, 08 Jan 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pscanner.pp

* Handle* is now virtual.
r20012 | michael | 2012-01-08 18:42:50 +0100 (Sun, 08 Jan 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pastree.pp

* Added custom data object to TPasElement.
r20013 | michael | 2012-01-08 18:49:36 +0100 (Sun, 08 Jan 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pparser.pp

* TokenIsCallingConvention and TokenIsProcedureModifier introduced for implementation of custom modifiers and calling conventions
r20014 | michael | 2012-01-08 19:17:10 +0100 (Sun, 08 Jan 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/tests/tcscanner.pas

* Test for special macro handling

git-svn-id: branches/fixes_2_6@22301 -

marco 13 years ago
parent
commit
3cded64f99

+ 7 - 0
.gitattributes

@@ -2228,6 +2228,9 @@ packages/fcl-passrc/src/paswrite.pp svneol=native#text/plain
 packages/fcl-passrc/src/pparser.pp svneol=native#text/plain
 packages/fcl-passrc/src/pparser.pp svneol=native#text/plain
 packages/fcl-passrc/src/pscanner.pp svneol=native#text/plain
 packages/fcl-passrc/src/pscanner.pp svneol=native#text/plain
 packages/fcl-passrc/src/readme.txt svneol=native#text/plain
 packages/fcl-passrc/src/readme.txt svneol=native#text/plain
+packages/fcl-passrc/tests/tcscanner.pas svneol=native#text/plain
+packages/fcl-passrc/tests/testpassrc.lpi svneol=native#text/plain
+packages/fcl-passrc/tests/testpassrc.lpr svneol=native#text/plain
 packages/fcl-process/Makefile svneol=native#text/plain
 packages/fcl-process/Makefile svneol=native#text/plain
 packages/fcl-process/Makefile.fpc svneol=native#text/plain
 packages/fcl-process/Makefile.fpc svneol=native#text/plain
 packages/fcl-process/fpmake.pp svneol=native#text/plain
 packages/fcl-process/fpmake.pp svneol=native#text/plain
@@ -12903,6 +12906,10 @@ utils/fpdoc/intl/fpdocstr.de.po svneol=native#text/plain
 utils/fpdoc/intl/makeskel.de.po svneol=native#text/plain
 utils/fpdoc/intl/makeskel.de.po svneol=native#text/plain
 utils/fpdoc/makeskel.lpi svneol=native#text/plain
 utils/fpdoc/makeskel.lpi svneol=native#text/plain
 utils/fpdoc/makeskel.pp svneol=native#text/plain
 utils/fpdoc/makeskel.pp svneol=native#text/plain
+utils/fpdoc/mgrfpdocproj.pp svneol=native#text/plain
+utils/fpdoc/mkfpdoc.pp svneol=native#text/plain
+utils/fpdoc/mkfpdocproj.lpi svneol=native#text/plain
+utils/fpdoc/mkfpdocproj.pp svneol=native#text/plain
 utils/fpdoc/sample-project.xml svneol=native#text/plain
 utils/fpdoc/sample-project.xml svneol=native#text/plain
 utils/fpdoc/sh_pas.pp svneol=native#text/plain
 utils/fpdoc/sh_pas.pp svneol=native#text/plain
 utils/fpdoc/testunit.pp svneol=native#text/plain
 utils/fpdoc/testunit.pp svneol=native#text/plain

+ 165 - 129
packages/fcl-passrc/examples/test_parser.pp

@@ -107,7 +107,7 @@
 
 
     TPasPackage = class(TPasElement)
     TPasPackage = class(TPasElement)
       |
       |
-    Modules: TList;
+    Modules: TFPList;
 
 
     TPasModule = class(TPasElement)
     TPasModule = class(TPasElement)
       |-InterfaceSection: TInterfaceSection;
       |-InterfaceSection: TInterfaceSection;
@@ -115,27 +115,27 @@
       |
       |
       |-ImplementationSection: TImplementationSection;
       |-ImplementationSection: TImplementationSection;
       |  |-Declarations -> full declaration, unit and program
       |  |-Declarations -> full declaration, unit and program
-      |     |-Functions: TList;
+      |     |-Functions: TFPList;
       |        |-TPasFunction = class(TPasProcedureBase)
       |        |-TPasFunction = class(TPasProcedureBase)
       |           |-Body: TProcedureBody;
       |           |-Body: TProcedureBody;
       |              |-Declarations -> declaration and sub function
       |              |-Declarations -> declaration and sub function
       |              |-Body: TPasImplBlock; -> procedure block
       |              |-Body: TPasImplBlock; -> procedure block
       |
       |
       |-InitializationSection: TInitializationSection;
       |-InitializationSection: TInitializationSection;
-      |  |-TPasImplBlock.Elements: TList; -> main block
+      |  |-TPasImplBlock.Elements: TFPList; -> main block
       |
       |
       |-FinalizationSection: TFinalizationSection;
       |-FinalizationSection: TFinalizationSection;
-         |-TPasImplBlock.Elements: TList; -> unit only
+         |-TPasImplBlock.Elements: TFPList; -> unit only
 
 
     Declarations = class(TPasElement)
     Declarations = class(TPasElement)
-      |-Declarations: TList; -> the following are all in here
-      |-ResStrings: TList;
-      |-Types: TList;
-      |-Consts: TList;
-      |-Classes: TList;
-      |-Functions: TList;
-      |-Variables: TList;
-      |-Properties: TList;
+      |-Declarations: TFPList; -> the following are all in here
+      |-ResStrings: TFPList;
+      |-Types: TFPList;
+      |-Consts: TFPList;
+      |-Classes: TFPList;
+      |-Functions: TFPList;
+      |-Variables: TFPList;
+      |-Properties: TFPList;
     }
     }
 
 
 
 
@@ -859,7 +859,7 @@ procedure GetTPasVar(lpv:TPasVariable; lindent:integer; NoLF:boolean);//BUG stri
   
   
 //write out a list of variables only
 //write out a list of variables only
 //more compact than the output of seperate calls of GetTPasVar
 //more compact than the output of seperate calls of GetTPasVar
-procedure GetPasVariables(vl:TList; lindent:integer; NoLF,NoSEM:boolean);
+procedure GetPasVariables(vl:TFPList; lindent:integer; NoLF,NoSEM:boolean);
    var v,i,j:integer;
    var v,i,j:integer;
        s,s1:string;
        s,s1:string;
        prct:TPasRecordType;
        prct:TPasRecordType;
@@ -1021,6 +1021,96 @@ procedure GetPasVariables(vl:TList; lindent:integer; NoLF,NoSEM:boolean);
     if not NoLF then writeln;
     if not NoLF then writeln;
   end;  
   end;  
   
   
+function GetTPasArgumentAccess(acc:TArgumentAccess):String;
+
+begin
+  Result:='';
+  case acc of
+    //argDefault:Result:='default'; //normal proccall is default
+    argConst:Result:='const';
+    argVar:Result:='var';
+    argOut:Result:='out';
+  end;
+end;
+
+procedure GetTPasProcedureType(lppt:TPasProcedureType; indent:integer);
+
+Var
+  l : integer;
+  lpa:TPasArgument;
+  samevar:array of integer;//same index same type
+  aktaa:TArgumentAccess;
+  svi:integer;
+  same:boolean;
+  aktname,tmpname:String;
+
+begin
+  if assigned(lppt.Args) and (lppt.Args.Count > 0) then
+    begin
+    write('(');
+    if lppt.Args.Count > 0 then
+     begin
+      //produce more compact output than the commented block below
+      //>find same declaration
+      //look ahead what is the same
+      SetLength(samevar,lppt.Args.Count);
+      svi:=0;
+      aktname:='';
+      for l:=0 to lppt.Args.Count-1 do
+       begin
+        same:=true;
+        tmpname:='';
+        lpa:=TPasArgument(lppt.Args.Items[l]);
+        if assigned(lpa.ArgType) then
+         begin
+          if lpa.ArgType is TPasArrayType then
+           begin
+             if assigned(TPasArrayType(lpa.ArgType).ElType) then tmpname:=TPasArrayType(lpa.ArgType).ElType.Name;
+           end
+            else tmpname:=TPasType(lpa.ArgType).Name;
+         end;
+        if l=0 then begin aktaa:=lpa.Access; aktname:=tmpname; end;
+        if lpa.Access <> aktaa then begin same:=false; aktaa:=lpa.Access; end;//access type
+        if (tmpname = '')or(tmpname <> aktname) then begin same:=false; aktname:=tmpname; end;//type name
+        if lpa.Value <> '' then same:=false;//var=value
+        if not same then inc(svi);
+        samevar[l]:=svi;
+       end;
+     //find same declaration<
+     svi:=-1;
+     same:=false;
+     for l:=0 to lppt.Args.Count-1 do
+      begin
+       lpa:=TPasArgument(lppt.Args.Items[l]);
+       if svi <> samevar[l] then
+        begin
+         svi:=samevar[l];
+         if lpa.Access <> argDefault then write(GetTPasArgumentAccess(lpa.Access),' ');
+         write(lpa.Name);//variblenname
+        end
+          else write(lpa.Name);
+       if (l < lppt.Args.Count-1)and(samevar[l+1]=svi) then write(',')
+        else
+         begin
+          if assigned(lpa.ArgType) then
+           begin
+            write(': ');
+            if lpa.ArgType is TPasArrayType then
+             GetTPasArrayType(TPasArrayType(lpa.ArgType))
+              else write(TPasType(lpa.ArgType).Name);
+           end;
+          if lpa.Value <> '' then write('=',lpa.Value);
+          if l< lppt.Args.Count-1 then write('; ');
+        end;
+      end;
+    write(')');
+    end;
+    end;
+  if (lppt is TPasFunctionType) then
+      write(': ',TPasFunctionType(lppt).ResultEl.ResultType.Name);
+  if lppt.IsOfObject then
+    write(' of Object');
+end;
 
 
 procedure GetTypes(pe:TPasElement; lindent:integer);
 procedure GetTypes(pe:TPasElement; lindent:integer);
   var i,j,k:integer;
   var i,j,k:integer;
@@ -1110,7 +1200,12 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
    end
    end
   else if pe is TPasProcedureType then
   else if pe is TPasProcedureType then
    begin
    begin
-    writeln('procedure');
+   if pe is TPasFunctionType then
+     Write('function ')
+   else
+     Write('procedure ');
+   GetTPasProcedureType(TPasProcedureType(pe), lindent);
+   Writeln(';');
    end
    end
   else if pe is TPasPointerType then
   else if pe is TPasPointerType then
    begin
    begin
@@ -1166,27 +1261,29 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
     writeln('set of ',pst.EnumType.Name,';');
     writeln('set of ',pst.EnumType.Name,';');
    end
    end
   else if pe is TPasClassOfType then writeln('Class of ',TPasClassOfType(pe).DestType.Name,';')
   else if pe is TPasClassOfType then writeln('Class of ',TPasClassOfType(pe).DestType.Name,';')
+  else if pe is tPasAliasType then
+    begin
+    pe:=tPasAliasType(PE).DestType;
+    write(PE.name);
+    if pe is tPasStringType then
+      begin
+      if (TPasStringType(PE).LengthExpr<>'') then
+        Write('[',TPasStringType(PE).LengthExpr,']');
+      end;
+    Writeln(';');
+    end
+  else if pe is tPasUnresolvedTypeRef then writeln(TPasUnresolvedTypeRef(PE).name,';')
   else
   else
    begin
    begin
     
     
     writeln('{ Unknown TYPE(s): ');
     writeln('{ Unknown TYPE(s): ');
-    writeln(s,pe.Name);
+    writeln(s,pe.Name,' ',pe.classname);
     writeln('}');
     writeln('}');
     writeln;
     writeln;
    end;
    end;
  end;
  end;
 
 
 
 
- function GetTPasArgumentAccess(acc:TArgumentAccess):String;
-  begin
-   Result:='';
-   case acc of
-     //argDefault:Result:='default'; //normal proccall is default
-     argConst:Result:='const';
-     argVar:Result:='var';
-     argOut:Result:='out';
-   end;
-  end;
 
 
  procedure GetTCallingConvention(cc:TCallingConvention);  //TODO: test it
  procedure GetTCallingConvention(cc:TCallingConvention);  //TODO: test it
   begin
   begin
@@ -1213,14 +1310,8 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
   procedure GetTPasProcedure(lpp:TPasProcedure; indent:integer);
   procedure GetTPasProcedure(lpp:TPasProcedure; indent:integer);
    var l:integer;
    var l:integer;
        lppt:TPasProcedureType;
        lppt:TPasProcedureType;
-       lpa:TPasArgument;
        s:String;
        s:String;
        
        
-       same:boolean;
-       samevar:array of integer;//same index same type
-       aktaa:TArgumentAccess;
-       aktname,tmpname:String;
-       svi:integer;
 
 
   begin
   begin
    if not Assigned(lpp) then exit;
    if not Assigned(lpp) then exit;
@@ -1237,93 +1328,7 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
    if assigned(lpp.ProcType) then
    if assigned(lpp.ProcType) then
     begin
     begin
      lppt:=lpp.ProcType;
      lppt:=lpp.ProcType;
-     if assigned(lppt.Args) and (lppt.Args.Count > 0) then
-      begin
-       write('(');
-       if lppt.Args.Count > 0 then 
-        begin
-         //produce more compact output than the commented block below
-         //>find same declaration
-         //look ahead what is the same
-         SetLength(samevar,lppt.Args.Count);
-         svi:=0;
-         aktname:='';
-         for l:=0 to lppt.Args.Count-1 do
-          begin
-           same:=true;
-           tmpname:='';
-           lpa:=TPasArgument(lppt.Args.Items[l]);
-           if assigned(lpa.ArgType) then
-            begin
-             if lpa.ArgType is TPasArrayType then
-              begin
-                if assigned(TPasArrayType(lpa.ArgType).ElType) then tmpname:=TPasArrayType(lpa.ArgType).ElType.Name;
-              end
-               else tmpname:=TPasType(lpa.ArgType).Name;
-            end;
-           if l=0 then begin aktaa:=lpa.Access; aktname:=tmpname; end;   
-           if lpa.Access <> aktaa then begin same:=false; aktaa:=lpa.Access; end;//access type 
-           if (tmpname = '')or(tmpname <> aktname) then begin same:=false; aktname:=tmpname; end;//type name
-           if lpa.Value <> '' then same:=false;//var=value
-           if not same then inc(svi); 
-           samevar[l]:=svi;
-          end; 
-        //find same declaration<  
-        svi:=-1;
-        same:=false;
-        for l:=0 to lppt.Args.Count-1 do
-         begin
-          lpa:=TPasArgument(lppt.Args.Items[l]);
-          if svi <> samevar[l] then
-           begin
-            svi:=samevar[l];
-            if lpa.Access <> argDefault then write(GetTPasArgumentAccess(lpa.Access),' '); 
-            write(lpa.Name);//variblenname
-           end
-             else write(lpa.Name); 
-          if (l < lppt.Args.Count-1)and(samevar[l+1]=svi) then write(',')
-           else
-            begin
-             if assigned(lpa.ArgType) then
-              begin
-               write(': ');
-               if lpa.ArgType is TPasArrayType then
-                GetTPasArrayType(TPasArrayType(lpa.ArgType))
-                 else write(TPasType(lpa.ArgType).Name);
-              end;
-             if lpa.Value <> '' then write('=',lpa.Value);
-             if l< lppt.Args.Count-1 then write('; ');
-           end;    
-         end; 
-       {//simple version duplicates declarations of same type
-        for l:=0 to lppt.Args.Count-1 do
-        begin
-         lpa:=TPasArgument(lppt.Args.Items[l]);
-          if lpa.Access <> argDefault then write(GetTPasArgumentAccess(lpa.Access),' '); 
-         write(lpa.Name);//variblenname
-         if assigned(lpa.ArgType) then
-          begin
-           //if TPasType(lpa.ArgType).ElementTypeName <>'unresolved type reference' then
-           //,TPasType(lpa.ArgType).Name,' ');
-           //,TPasType(lpa.ArgType).FullName,TPasType(lpa.ArgType).ElementTypeName)
-           // PParser 2099: ArgType := nil; if IsUntyped then => Arg.ArgType := ArgType;
-           //     else write(':? ');
-           write(': ');
-           if lpa.ArgType is TPasArrayType then
-            begin
-             GetTPasArrayType(TPasArrayType(lpa.ArgType));
-            end
-             else  write(TPasType(lpa.ArgType).Name);
-          end;
-         if lpa.Value <> '' then write('=',lpa.Value);
-         if l< lppt.Args.Count-1 then write('; ');
-        end;}
-        end;
-       write(')');
-      end;
-     if lppt.IsOfObject then write(' of Object'); 
-     if (TPasElement(lpp) is TPasFunction)or(TPasElement(lpp) is TPasClassFunction) then 
-         write(': ',TPasFunctionType(lpp.ProcType).ResultEl.ResultType.Name);
+     GetTPasProcedureType(lppt,Indent);
     end;
     end;
    //writeln(';');
    //writeln(';');
    WriteFmt(false,'',true);
    WriteFmt(false,'',true);
@@ -1425,7 +1430,7 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
        lpp:TPasProperty;
        lpp:TPasProperty;
        lpa:TPasArgument;
        lpa:TPasArgument;
        vis:TPasMemberVisibility;
        vis:TPasMemberVisibility;
-       vars:TList;
+       vars:TFPList;
        IsVar:boolean;
        IsVar:boolean;
 
 
   procedure PrintVars;
   procedure PrintVars;
@@ -1439,32 +1444,63 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
    if assigned(pc) then
    if assigned(pc) then
     begin
     begin
      s:=GetIndent(indent);
      s:=GetIndent(indent);
-     write(s,pc.Name,'=');
+     if (pc.ObjKind=okGeneric) then
+       begin
+       write(s,'generic ',pc.Name);
+       for l:=0 to pc.GenericTemplateTypes.Count-1 do
+          begin
+          if l=0 then
+           Write('<')
+          else
+           Write(',');
+          Write(TPasGenericTemplateType(pc.GenericTemplateTypes[l]).Name);
+          end;
+       Write('> = ');
+       end
+     else
+       write(s,pc.Name,' = ');
      if pc.IsPacked then write('packed ');
      if pc.IsPacked then write('packed ');
      case pc.ObjKind of
      case pc.ObjKind of
       okObject:write('Object');
       okObject:write('Object');
       okClass:write('Class');
       okClass:write('Class');
       okInterface:write('Interface');
       okInterface:write('Interface');
+      okGeneric:write('class');
+      okspecialize : write('specialize');
      end;
      end;
      if assigned(pc.AncestorType) and (pc.AncestorType.ElementTypeName <> '') then
      if assigned(pc.AncestorType) and (pc.AncestorType.ElementTypeName <> '') then
-        write('(',pc.AncestorType.Name,')');
-
+        begin
+        if pc.ObjKind<>okspecialize then
+          write('(',pc.AncestorType.Name,')')
+        else
+          begin
+          write(' ',pc.AncestorType.Name);
+          for l:=0 to pc.GenericTemplateTypes.Count-1 do
+           begin
+           if l=0 then
+            Write('<')
+           else
+            Write(',');
+           Write(TPasGenericTemplateType(pc.GenericTemplateTypes[l]).Name);
+           end;
+          Write('>');
+          end;
+        end;
      if pc.IsForward or pc.IsShortDefinition then //pparser.pp: 3417 :class(anchestor); is allowed !
      if pc.IsForward or pc.IsShortDefinition then //pparser.pp: 3417 :class(anchestor); is allowed !
       begin
       begin
        writeln(';');
        writeln(';');
        exit;
        exit;
       end;  
       end;  
-    //Members: TList;
+    //Members: TFPList;
     //InterfaceGUID: String;
     //InterfaceGUID: String;
-    //ClassVars: TList; //is this always empty ?
+    //ClassVars: TFPList; //is this always empty ?
     //Modifiers: TStringList;
     //Modifiers: TStringList;
-    //Interfaces: TList;
+    //Interfaces: TFPList;
       s1:=GetIndent(indent+1);
       s1:=GetIndent(indent+1);
       s2:=GetIndent(indent+2);
       s2:=GetIndent(indent+2);
       if pc.Members.Count > 0 then
       if pc.Members.Count > 0 then
        begin
        begin
         writeln;
         writeln;
-        vars:=TList.Create;
+        vars:=TFPList.Create;
         IsVar:=false;
         IsVar:=false;
         for j:=0 to pc.Members.Count-1 do
         for j:=0 to pc.Members.Count-1 do
          begin
          begin
@@ -1562,6 +1598,7 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
          vars.free;
          vars.free;
        end
        end
         else  writeln;//(';'); //x=class(y);
         else  writeln;//(';'); //x=class(y);
+
      writeln(s,'end;');
      writeln(s,'end;');
     end;
     end;
   end;
   end;
@@ -1574,7 +1611,7 @@ procedure GetDecls(Decl:TPasDeclarations; indent:integer);
      ps:TPasSection;
      ps:TPasSection;
      s:string;
      s:string;
      x:(None,ResStrings,Types,Consts,Classes,Functions,Variables,Properties);
      x:(None,ResStrings,Types,Consts,Classes,Functions,Variables,Properties);
-     l:TList;
+     l:TFPList;
 
 
   procedure PrintVars;
   procedure PrintVars;
    begin
    begin
@@ -1586,7 +1623,7 @@ begin
  x:=None;
  x:=None;
  if assigned(Decl)then
  if assigned(Decl)then
   begin
   begin
-   l:=TList.Create;
+   l:=TFPList.Create;
    pe:=TPasElement(Decl);
    pe:=TPasElement(Decl);
    if pe is TPasSection then
    if pe is TPasSection then
     begin
     begin
@@ -1882,7 +1919,6 @@ begin
           raise;
           raise;
        end;
        end;
     end;
     end;
-
    if M is TPasProgram then
    if M is TPasProgram then
     begin
     begin
      writeln('Program ',M.Name,';');
      writeln('Program ',M.Name,';');

+ 332 - 81
packages/fcl-passrc/examples/testunit1.pp

@@ -12,6 +12,10 @@ interface
  uses 
  uses 
   SysUtils,Classes;
   SysUtils,Classes;
 
 
+
+resourcestring
+ SParserErrorAtToken = 'parser error at token';
+ 
  const
  const
   AnIntegerConst=1;
   AnIntegerConst=1;
   AStringConst='Hello, World!';
   AStringConst='Hello, World!';
@@ -24,11 +28,31 @@ interface
   ADeprecatedConst=1 deprecated;
   ADeprecatedConst=1 deprecated;
    
    
  Type
  Type
+  TLineEndStr = string [3];
+
+  TDeprecatedType = Integer deprecated;
+  TDeprecatedRecord = Record
+    x,Y : Integer; 
+  end deprecated;
+  TDeprecatedFieldsRecord = Record
+    x,Y : Integer deprecated; 
+  end;
+  TDeprecatedFieldsRecord2 = Record
+    x,Y : Integer deprecated
+  end;
   TAnEnumType=(one,two,three);
   TAnEnumType=(one,two,three);
   TASetType=set of TAnEnumType;
   TASetType=set of TAnEnumType;
+  TIntegerSet = Set of 0..SizeOf(Integer)*8-1;
   TAnArrayType=Array[1..10] of Integer;
   TAnArrayType=Array[1..10] of Integer;
   TASubRangeType=one..two;
   TASubRangeType=one..two;
   TABooleanArrayType=Array[Boolean] of Integer;  
   TABooleanArrayType=Array[Boolean] of Integer;  
+  TDay = (monday,tuesday,wednesday,thursday,friday,saturday,sunday);
+  TShortDay = (mon,tue,wed,thu,fri,sat,sun);
+  TShortDays = set of TShortDay;
+  TDays = set of TDay;
+  TMyInteger = Integer;
+  ADouble = type double;
+  arangetypealias = type 0..$FF;
   TARecordType=record
   TARecordType=record
                    X,Y: Integer;
                    X,Y: Integer;
                    Z: String;
                    Z: String;
@@ -54,9 +78,36 @@ interface
                  3 : (Z : Longint);  
                  3 : (Z : Longint);  
                  );  
                  );  
           end;                           
           end;                           
+
+TYPE
+   PPoint = ^TPoint;
+   TPoint = OBJECT
+      X, Y: Sw_Integer;
+   END;
+
+   PRect = ^TRect;
+   TRect = OBJECT
+      A, B: TPoint;                                { Corner points }
+      FUNCTION Empty: Boolean;
+      FUNCTION Equals (R: TRect): Boolean;
+      FUNCTION Contains (P: TPoint): Boolean;
+      PROCEDURE Copy (R: TRect);
+      PROCEDURE Union (R: TRect);
+      PROCEDURE Intersect (R: TRect);
+      PROCEDURE Move (ADX, ADY: Sw_Integer);
+      PROCEDURE Grow (ADX, ADY: Sw_Integer);
+      PROCEDURE Assign (XA, YA, XB, YB: Sw_Integer);
+   END;
+               
+
+  TNotifyEvent = Procedure (Sender : TObject) of object;
+  TNotifyEvent2 = Function (Sender : TObject) : Integer of object;
+ 
                           
                           
 //  TADeprecatedType = Integer deprecated;
 //  TADeprecatedType = Integer deprecated;
-
+  TMyChildClass = Class;
+  MyInterface = Interface;
+  
   { TMyParentClass }
   { TMyParentClass }
 
 
   TMyParentClass=Class(TComponent)
   TMyParentClass=Class(TComponent)
@@ -99,18 +150,47 @@ interface
   Published
   Published
     Property AProtectedProp;
     Property AProtectedProp;
   end;
   end;
-  
- TPasFunctionType=Class(TPasProcedureType)
+  TC = TMyChildClass;
+
+  TPasFunctionType=Class(TObject)
   public
   public
     destructor Destroy; override;
     destructor Destroy; override;
-    Class Function TypeName: string; override;
-    Function ElementTypeName: string; override;
-    Function GetDeclaration(Full: boolean): string; override;
+    Class Function TypeName: string;
+    Function ElementTypeName: string; 
+    Function GetDeclaration(Full: boolean): string; 
+    Procedure Something;  strict
+  Private  
+    Procedure SomethingElse;
   public
   public
-    ResultEl: TPasResultElement;
+    ResultEl: TObject;
   end; 
   end; 
-                        
- var
+
+  TPropModifiers = Class(TObject)
+  Private
+    FB : Integer;
+    Function IsStored : Boolean;
+    Function GetI(AI : Integer) : Integer;
+    Procedure SetI(AI : Integer; AVal : Integer);
+  Published
+    Property A : Integer Read FB Write FB Stored False;
+    Property B : Integer Read FB Write FB Stored True;
+    Property C : Integer Read FB Write FB Stored IsStored;
+    Property D : Integer Read FB Write FB Default 1;
+    Property E : Integer Read FB Write FB Stored True Default 1;
+  Public
+    Property Ints[AI : Integer] : Integer Read GetI Write SetI; default;
+  end;
+  
+  TPropModifiers2 = class(TPropModifiers)
+  Public
+    Property Ints[AI : Integer] : Integer Read GetI Write SetI; default; deprecated;
+  end;                          
+  
+  TEdit = Class(TObject)
+    Text : String;
+  end;
+  
+var
   ASimpleVar: Integer;  
   ASimpleVar: Integer;  
   ATypedVar: TMethod;
   ATypedVar: TMethod;
   ARecordVar: Record
   ARecordVar: Record
@@ -122,8 +202,16 @@ interface
   
   
   ADeprecatedVar: Integer deprecated;
   ADeprecatedVar: Integer deprecated;
   ACVarVar: Integer ; cvar;
   ACVarVar: Integer ; cvar;
-  AnExternalVar: Integer ;external name 'avar';
-  AnExternalLibVar: Integer ;external 'library' name 'avar';
+  AnExternalVar1: Integer; external;
+  AnExternalVar2: Integer; external name 'avar';
+  AnExternalLibVar: Integer; external 'library' name 'avar';
+  APublicVar : String; public;
+  APublicVar2 : String; public name 'ANAME';
+  APublicVar3 : String; export;
+  APublicVar4 : String; export name 'nono';
+  APublicVar5 : String; cvar; external;
+  APublicVar6 : String; external name 'me';
+  APublicVar7 : String deprecated; external name 'me';
       
       
  Procedure SimpleProc;
  Procedure SimpleProc;
  Procedure OverloadedProc(A: Integer);
  Procedure OverloadedProc(A: Integer);
@@ -146,17 +234,31 @@ interface
  Procedure externalproc; external;
  Procedure externalproc; external;
  Procedure externalnameProc; external name 'aname';
  Procedure externalnameProc; external name 'aname';
  Procedure externallibnameProc; external 'alibrary' name 'aname';
  Procedure externallibnameProc; external 'alibrary' name 'aname';
+ Function  hi(q : QWord) : DWord;   [INTERNPROC: fpc_in_hi_qword];
 
 
-  
+ 
+Type
+ generic TFPGListEnumerator<T> = class(TObject)
+ protected
+    FList: TFPList;
+    FPosition: Integer;
+    function GetCurrent: T;
+ end;                 
+ TFPGListEnumeratorSpec = specialize TFPGListEnumerator<TPasFunctionType>; 
+
+ 
 Implementation
 Implementation
 
 
 
 
  Procedure SimpleProc;
  Procedure SimpleProc;
 
 
- procedure  SubProc;
+  procedure  SubProc;
+  Var S : String;
   begin
   begin
    s:= s+'a';
    s:= s+'a';
   end;
   end;
+ Var
+   a,B,c,i : integer;
 
 
  begin
  begin
   a:= 1;
   a:= 1;
@@ -166,6 +268,8 @@ Implementation
  end;
  end;
 
 
  Procedure OverloadedProc(A: Integer);
  Procedure OverloadedProc(A: Integer);
+ Var
+   i : integer;
  begin
  begin
   if i=1 then ;
   if i=1 then ;
  end;
  end;
@@ -229,7 +333,11 @@ Implementation
  end;
  end;
 
 
  procedure TMyChildClass.AnAbstractProc;
  procedure TMyChildClass.AnAbstractProc;
+ 
  procedure  SubCProc;
  procedure  SubCProc;
+ 
+   Var sc : string;
+   
   begin
   begin
    sc:= sc+'ac';
    sc:= sc+'ac';
   end;
   end;
@@ -300,12 +408,142 @@ Implementation
  procedure TMyParentClass.SomePublishedMethod;
  procedure TMyParentClass.SomePublishedMethod;
  begin
  begin
  end;
  end;
- 
+
+
  Class Function TPasFunctionType.TypeName: String;
  Class Function TPasFunctionType.TypeName: String;
  begin
  begin
   Result:= 'Function';
   Result:= 'Function';
  end;
  end;
 
 
+Type
+  TI = Class(TComponent)
+  Public
+    FP : Integer;
+    Procedure SetP1(A : Integer); virtual;
+    Procedure M1;virtual;
+    Function F1  : Integer; virtual;
+    procedure test; virtual;
+    property P : Integer Read FP Write SetP1;
+  end;
+  
+  Procedure TI.M1;
+  begin
+  end;
+  Procedure TI.Test;
+  begin
+  end;
+  Function TI.F1 : Integer; 
+  begin
+  Result:=0;
+  end;
+  Procedure TI.SetP1(A : Integer);
+  begin
+    FP:=A;
+  end;
+  
+TYpe
+  TI2 = Class(TI)
+  procedure write(s : string);
+  Procedure SetP1(A : Integer); override;
+  Procedure M1;override;
+  Procedure Test;override;
+  Function F1 : integer; override;
+  procedure donothing;
+  property P : Integer Read F1 Write SetP1;
+  end;
+  Procedure TI2.M1;
+  begin
+    Inherited;
+  end;
+  Procedure TI2.Write(s : string);
+  begin
+    writeln(s);
+  end;
+  Function TI2.F1 :Integer; 
+  begin
+     Result:=0;
+  end;
+  Procedure TI2.Test;
+  begin
+  if true then
+    Inherited Test
+  else
+    DoNothing;
+    Inherited test;
+   if true then
+     Inherited
+   else
+     DoNothing;
+  end;
+  Procedure TI2.DoNothing;
+    function escapetext(s : string) : string;
+    begin
+    end;
+  var
+  Atext : string;
+  begin
+    Self.Write(EscapeText(AText)); 
+    TComponent.Create(Self);
+  end;
+  Procedure TI2.SetP1(A : Integer);
+  begin
+    FP:=A;
+    Inherited P:= 3;
+    Inherited SetP1(3);
+    Inherited P:= Ord(A);
+  end;
+
+
+ procedure usage;
+ begin
+ end;
+ Procedure DoSomething;
+ begin
+ end;
+ Procedure DoSomethingElse;
+ begin
+ end;
+ procedure stat1;
+ begin
+ end;
+ procedure stat2;
+ begin
+ end;
+ procedure stat3;
+ begin
+ end;
+ procedure stat4;
+ begin
+ end;
+ procedure stat5;
+ begin
+ end;
+ procedure stat6;
+ begin
+ end;
+ procedure stat7;
+ begin
+ end;
+  procedure stat8;
+ begin
+ end;
+ procedure stat9;
+ begin
+ end;
+ procedure doit;
+ begin
+ end;
+ procedure statement;
+ begin
+ end;
+ procedure work;
+ begin
+ end;
+ procedure kissdwarf(i : integer);
+ 
+ begin
+   writeln('kiss dwarf',i);
+ end;
  procedure Statements;
  procedure Statements;
  const
  const
   cint=1;
   cint=1;
@@ -340,14 +578,32 @@ Implementation
   AR=record
   AR=record
       X,Y: LongInt;
       X,Y: LongInt;
      end;
      end;
+  TScanner = record
+   currow,curcolumn : integer;
+   curfilename : string;
+  end;  
+
   //PAR = Record;
   //PAR = Record;
  var
  var
+  msg,curtokenname : string;
   TheCustomer: Passenger;
   TheCustomer: Passenger;
   L: ^LongInt;
   L: ^LongInt;
   P: PPChar;
   P: PPChar;
   S,T: Ar;
   S,T: Ar;
-      
+  M, X,Y : Double;
+  Done : Boolean;
+  Weather,Good: Boolean;  
+  c : char;
+  j,dwarfs,i,Number,Block : integer;
+  exp1,exp2,exp3,exp4,exp5,exp6,exp7,exp8,exp9 : boolean;
+  o : Tobject;
+  day,today : tday;
+  A,B,D : Passenger;
+  E : Exception;
+  scanner : tscanner;
+    
  begin
  begin
+  O:=Nil;
   X:= X+Y;
   X:= X+Y;
   //EparserError on C++ style
   //EparserError on C++ style
   //X+=Y;      { Same as X := X+Y, needs -Sc command line switch}
   //X+=Y;      { Same as X := X+Y, needs -Sc command line switch}
@@ -368,7 +624,7 @@ Implementation
   //Goto jumpto;
   //Goto jumpto;
 
 
   Case i of
   Case i of
-    3: DoSomething;
+    6: DoSomething;
     1..5: DoSomethingElse;
     1..5: DoSomethingElse;
   end;
   end;
 
 
@@ -426,19 +682,19 @@ Implementation
   else
   else
     stat2;
     stat2;
 
 
- if i is integer then
+ if o is TObject then
   begin
   begin
-    write('integer');
+    write('object');
   end
   end
   else 
   else 
-    if i is real then 
+    if o is TMyParentClass then 
   begin
   begin
     write('real');
     write('real');
   end
   end
   else 
   else 
     write('0'); 
     write('0'); 
 
 
-  if Today in[Monday..Friday] then
+  if Today in [Monday..Friday] then
     WriteLn('Must work harder')
     WriteLn('Must work harder')
   else
   else
     WriteLn('Take a day off.');
     WriteLn('Take a day off.');
@@ -472,21 +728,21 @@ Implementation
      I:= I+2;
      I:= I+2;
     end;
     end;
     X:= X/2;
     X:= X/2;
-    while x>=10e-3 do 
-      dec(x);
+    while i>=10e-3 do 
+      dec(i);
 
 
-    while x>0 do 
-    while y>0 do 
+    while i>0 do 
+    while j>0 do 
       begin
       begin
-	dec(x);
-	dec(y);
+	dec(i);
+	dec(j);
       end;
       end;
 
 
-    while x>0 do
-    if x>2 then 
-     dec(x)
+    while i>0 do
+    if i>2 then 
+     dec(i)
     else 
     else 
-     dec(x,2);
+     dec(i,2);
 
 
       X:= 2+3;
       X:= 2+3;
 
 
@@ -499,12 +755,11 @@ Implementation
        Flight:= 'PS901';
        Flight:= 'PS901';
       end;
       end;
 
 
-  With A,B,C,D do
+  With A,B,D do
    Statement;
    Statement;
 
 
     With A do
     With A do
      With B do
      With B do
-      With C do
        With D do 
        With D do 
         Statement;
         Statement;
 
 
@@ -521,60 +776,77 @@ Implementation
 
 
     try
     try
 	try
 	try
-	  M:= ParseSource(E,cmdl,'linux','i386');
+	  M:= Y;
 	except
 	except
 	  on excep: EParserError do
 	  on excep: EParserError do
 	    begin
 	    begin
-	      writeln(excep.message,' line:',excep.row,' column:',excep.column,' file:',excep.filename);
+	      writeln(excep.message,' : ',excep.classname);
 	      raise ;
 	      raise ;
 	  end;
 	  end;
 	end;
 	end;
-	Decls:= M.InterfaceSection.Declarations;
-	for I:= 0 to Decls.Count-1 do
-	  Writeln('Interface item ',I,': ');
-
 	FreeAndNil(M);
 	FreeAndNil(M);
     finally
     finally
 	FreeAndNil(E)
 	FreeAndNil(E)
    end;
    end;
    
    
-   raise EParserError.Create(Format(SParserErrorAtToken, [Msg, CurTokenName]) {$ifdef addlocation}+' ('+inttostr(scanner.currow)+' '+inttostr(scanner.curcolumn)+')'{$endif},Scanner.CurFilename, Scanner.CurRow, Scanner.CurColumn);
+   raise EParserError.Create(Format(SParserErrorAtToken, [Msg, CurTokenName]) {$ifdef addlocation}+' ('+inttostr(scanner.currow)+' '+inttostr(scanner.curcolumn)+')'{$endif});
     
     
     // try else
     // try else
  end;
  end;
 
 
+ function addone : integer;
+ begin
+ end;
+  procedure myproc;
+  begin
+  end;
  procedure Expression;
  procedure Expression;
+
+  Var
+    A,b,c,d,e,f,i,j : Integer;
+    x : double;
+    u : Boolean;
+    fu : function : integer;
+    ad : boolean;
+    z : tdays;
+    today,tomorrow : tday;
+    bs : set of byte;
+    cs : set of char;
+    cc : char;  
+    W : TShortDays;
+    buffer : array[1..10] of byte;
+    P : Pointer;
+    SErrMultipleSourceFiles,FileName,Dirname,S : string;
+    o,co : tobject;
+    
  begin
  begin
-  A:= a+b *c /(-e+f)*3 div 2 + 4 mod 5 - 2 shl 3 + 3 shr 1 ;
+  x:= a+b *c /(-e+f)*(3 div 2) + 4 mod 5 - 2 shl 3 + 3 shr 1 ;
   b:= (a and not b) or c xor d;
   b:= (a and not b) or c xor d;
-  u:= i<=2 or a<>b or j>=3;
-  u:= i=1 or a>b or b<a or i<>2;
+  u:= (i<=2) or (a<>b) or (j>=3);
+  u:= (i=1) or (a>b) or (b<a) or (i<>2);
   u:= i in [1..2];
   u:= i in [1..2];
 
 
- If F=@AddOne Then  
+ If Fu=@AddOne Then  
   WriteLn('Functions are equal');
   WriteLn('Functions are equal');
 
 
- If F()=Addone then  
+ If Fu()=Addone then  
   WriteLn('Functions return same values ');
   WriteLn('Functions return same values ');
 
 
  z:= [today,tomorrow];
  z:= [today,tomorrow];
  z:= [Monday..Friday,Sunday];
  z:= [Monday..Friday,Sunday];
- z:= [2,3*2,6*2,9*2];
- z:= ['A'..'Z','a'..'z','0'..'9'];
+ bs:= [2,3*2,6*2,9*2];
+ cs:= ['A'..'Z','a'..'z','0'..'9'];
 
 
- x:= Byte('A');
- x:= Char(48);
- x:= boolean(1);
- x:= longint(@Buffer);
- x:= Integer('A');
- x:= Char(4875);
- x:= Word(@Buffer);
+ i:= Byte('A');
+ cc:= Char(48);
+ ad:= boolean(1);
+ i:= longint(@Buffer);
+ i:= Integer('A');
+ cc:= Char(225);
+ i:= Word(@Buffer);
 
 
  B:= Byte(C);
  B:= Byte(C);
- Char(B):= C;
 
 
- TWordRec(W).L:= $FF;
- TWordRec(W).H:= 0;
  S:= TObject(P).ClassName;
  S:= TObject(P).ClassName;
 
 
  P:= @MyProc; //warum @ ? fix pparser 769 ?
  P:= @MyProc; //warum @ ? fix pparser 769 ?
@@ -585,31 +857,12 @@ Implementation
  W:= [mon,tue,wed]-[wed];     // equals [mon,tue]
  W:= [mon,tue,wed]-[wed];     // equals [mon,tue]
  W:= [mon,tue,wed]*[wed,thu,fri]; // equals [wed] warum * ?
  W:= [mon,tue,wed]*[wed,thu,fri]; // equals [wed] warum * ?
 
 
- (C as TEdit).Text:= 'Some text';
- C:= O as TComponent;
-
- if A is TComponent then ;
- If A is B then ;
-
- Inherited ;
- Inherited Test;
-
-  if true then
-    Inherited
-  else
-    DoNothing;
+ (Co as TEdit).Text:= 'Some text';
+ Co:= O as TComponent;
 
 
-  if true then
-    Inherited Test
-  else
-    DoNothing;
+ if co is TComponent then ;
+ If co is TC then ;
 
 
-   Inherited P:= 3;  
-   Inherited SetP1(3); 
-   Result:= Char(P and $FF);  
-   Result:= Char((Inherited P) and $FF);  
-   Inherited P:= Ord(AValue);
-   Result:= Inherited InterPretOption(Cmd,Arg);
 
 
   raise Exception.Create(SErrMultipleSourceFiles);
   raise Exception.Create(SErrMultipleSourceFiles);
 
 
@@ -621,8 +874,6 @@ Implementation
 	else
 	else
 	  Filename:= s;
 	  Filename:= s;
 
 
-  Self.Write(EscapeText(AText)); 
-  TObject.Create(Self);
  end;
  end;
 
 
  constructor TPasPackage.Create(const AName: String; AParent: TPasElement);
  constructor TPasPackage.Create(const AName: String; AParent: TPasElement);

+ 207 - 64
packages/fcl-passrc/src/pastree.pp

@@ -42,9 +42,12 @@ resourcestring
   SPasTreeEnumType = 'enumeration type';
   SPasTreeEnumType = 'enumeration type';
   SPasTreeSetType = 'set type';
   SPasTreeSetType = 'set type';
   SPasTreeRecordType = 'record type';
   SPasTreeRecordType = 'record type';
+  SPasStringType = 'string type';
   SPasTreeObjectType = 'object';
   SPasTreeObjectType = 'object';
   SPasTreeClassType = 'class';
   SPasTreeClassType = 'class';
   SPasTreeInterfaceType = 'interface';
   SPasTreeInterfaceType = 'interface';
+  SPasTreeGenericType = 'generic class';
+  SPasTreeSpecializedType = 'specialized class type';
   SPasTreeArgument = 'argument';
   SPasTreeArgument = 'argument';
   SPasTreeProcedureType = 'procedure type';
   SPasTreeProcedureType = 'procedure type';
   SPasTreeResultElement = 'function result';
   SPasTreeResultElement = 'function result';
@@ -83,6 +86,7 @@ type
     visStrictPrivate, visStrictProtected);
     visStrictPrivate, visStrictProtected);
 
 
   TCallingConvention = (ccDefault,ccRegister,ccPascal,ccCDecl,ccStdCall,ccOldFPCCall,ccSafeCall);
   TCallingConvention = (ccDefault,ccRegister,ccPascal,ccCDecl,ccStdCall,ccOldFPCCall,ccSafeCall);
+  TPackMode = (pmNone,pmPacked,pmBitPacked);
 
 
   TPasMemberVisibilities = set of TPasMemberVisibility;
   TPasMemberVisibilities = set of TPasMemberVisibility;
   TPasMemberHint = (hDeprecated,hLibrary,hPlatform,hExperimental,hUnimplemented);
   TPasMemberHint = (hDeprecated,hLibrary,hPlatform,hExperimental,hUnimplemented);
@@ -94,6 +98,7 @@ type
 
 
   TPasElement = class(TPasElementBase)
   TPasElement = class(TPasElementBase)
   private
   private
+    FData: TObject;
     FRefCount: LongWord;
     FRefCount: LongWord;
     FName: string;
     FName: string;
     FParent: TPasElement;
     FParent: TPasElement;
@@ -112,12 +117,14 @@ type
     function PathName: string;          // = Module.Name + FullName
     function PathName: string;          // = Module.Name + FullName
     function GetModule: TPasModule;
     function GetModule: TPasModule;
     function ElementTypeName: string; virtual;
     function ElementTypeName: string; virtual;
+    Function HintsString : String;
     function GetDeclaration(full : Boolean) : string; virtual;
     function GetDeclaration(full : Boolean) : string; virtual;
     procedure Accept(Visitor: TPassTreeVisitor); override;
     procedure Accept(Visitor: TPassTreeVisitor); override;
     property RefCount: LongWord read FRefCount;
     property RefCount: LongWord read FRefCount;
     property Name: string read FName write FName;
     property Name: string read FName write FName;
     property Parent: TPasElement read FParent;
     property Parent: TPasElement read FParent;
     Property Hints : TPasMemberHints Read FHints Write FHints;
     Property Hints : TPasMemberHints Read FHints Write FHints;
+    Property CustomData : TObject Read FData Write FData;
   end;
   end;
 
 
   TPasExprKind = (pekIdent, pekNumber, pekString, pekSet, pekNil, pekBoolConst, pekRange,
   TPasExprKind = (pekIdent, pekNumber, pekString, pekSet, pekNil, pekBoolConst, pekRange,
@@ -238,7 +245,7 @@ type
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
   public
   public
     Declarations, ResStrings, Types, Consts, Classes,
     Declarations, ResStrings, Types, Consts, Classes,
-    Functions, Variables, Properties: TList;
+    Functions, Variables, Properties: TFPList;
   end;
   end;
 
 
   { TPasSection }
   { TPasSection }
@@ -249,7 +256,7 @@ type
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddUnitToUsesList(const AUnitName: string);
     procedure AddUnitToUsesList(const AUnitName: string);
   public
   public
-    UsesList: TList;            // TPasUnresolvedTypeRef or TPasModule elements
+    UsesList: TFPList;            // TPasUnresolvedTypeRef or TPasModule elements
   end;
   end;
 
 
   { TInterfaceSection }
   { TInterfaceSection }
@@ -296,17 +303,18 @@ type
     destructor Destroy; override;
     destructor Destroy; override;
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
   public
   public
-    Modules: TList;     // List of TPasModule objects
+    Modules: TFPList;     // List of TPasModule objects
   end;
   end;
 
 
   { TPasResString }
   { TPasResString }
 
 
   TPasResString = class(TPasElement)
   TPasResString = class(TPasElement)
   public
   public
+    Destructor Destroy; override;
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
     function GetDeclaration(full : Boolean) : string; Override;
     function GetDeclaration(full : Boolean) : string; Override;
   public
   public
-    Value: string;
+    Expr: TPasExpr;
   end;
   end;
 
 
   { TPasType }
   { TPasType }
@@ -361,7 +369,10 @@ type
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
     function GetDeclaration(full : boolean) : string; override;
     function GetDeclaration(full : boolean) : string; override;
   public
   public
-    RangeStart, RangeEnd: string;
+    RangeExpr : TBinaryExpr;
+    Destructor Destroy; override;
+    Function RangeStart : String;
+    Function RangeEnd : String;
   end;
   end;
 
 
   { TPasArrayType }
   { TPasArrayType }
@@ -373,8 +384,9 @@ type
     function GetDeclaration(full : boolean) : string; override;
     function GetDeclaration(full : boolean) : string; override;
   public
   public
     IndexRange : string;
     IndexRange : string;
-    IsPacked : Boolean;          // 12/04/04 - Dave - Added
+    PackMode : TPackMode;
     ElType: TPasType;
     ElType: TPasType;
+    Function IsPacked : Boolean;
   end;
   end;
 
 
   { TPasFileType }
   { TPasFileType }
@@ -394,8 +406,8 @@ type
   public
   public
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
   public
   public
-    IsValueUsed: Boolean;
-    Value: Integer;
+//    IsValueUsed: Boolean;
+//    Value: Integer;
     AssignedValue : string;
     AssignedValue : string;
   end;
   end;
 
 
@@ -409,7 +421,7 @@ type
     function GetDeclaration(full : boolean) : string; override;
     function GetDeclaration(full : boolean) : string; override;
     Procedure GetEnumNames(Names : TStrings);
     Procedure GetEnumNames(Names : TStrings);
   public
   public
-    Values: TList;      // List of TPasEnumValue objects
+    Values: TFPList;      // List of TPasEnumValue objects
   end;
   end;
 
 
   { TPasSetType }
   { TPasSetType }
@@ -445,16 +457,17 @@ type
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
     function GetDeclaration(full : boolean) : string; override;
     function GetDeclaration(full : boolean) : string; override;
   public
   public
-    IsPacked: Boolean;
-    IsBitPacked : Boolean;
-    Members: TList;     // array of TPasVariable elements
+    PackMode : TPackMode;
+    Members: TFPList;     // array of TPasVariable elements
     VariantName: string;
     VariantName: string;
     VariantType: TPasType;
     VariantType: TPasType;
-    Variants: TList;	// array of TPasVariant elements, may be nil!
+    Variants: TFPList;	// array of TPasVariant elements, may be nil!
+    Function IsPacked: Boolean;
+    Function IsBitPacked : Boolean;
   end;
   end;
 
 
-
-  TPasObjKind = (okObject, okClass, okInterface);
+  TPasGenericTemplateType = Class(TPasElement);
+  TPasObjKind = (okObject, okClass, okInterface, okGeneric, okSpecialize);
 
 
   { TPasClassType }
   { TPasClassType }
 
 
@@ -464,19 +477,23 @@ type
     destructor Destroy; override;
     destructor Destroy; override;
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
   public
   public
+    PackMode : TPackMode;
     ObjKind: TPasObjKind;
     ObjKind: TPasObjKind;
     AncestorType: TPasType;     // TPasClassType or TPasUnresolvedTypeRef
     AncestorType: TPasType;     // TPasClassType or TPasUnresolvedTypeRef
-    IsPacked: Boolean;        // 12/04/04 - Dave - Added
     IsForward : Boolean;
     IsForward : Boolean;
     IsShortDefinition: Boolean;//class(anchestor); without end
     IsShortDefinition: Boolean;//class(anchestor); without end
-    Members: TList;     // array of TPasElement objects
+    Members: TFPList;     // array of TPasElement objects
     InterfaceGUID : string; // 15/06/07 - Inoussa
     InterfaceGUID : string; // 15/06/07 - Inoussa
 
 
-    ClassVars: TList;   // class vars
+    ClassVars: TFPList;   // class vars
     Modifiers: TStringList;
     Modifiers: TStringList;
-    Interfaces : TList;
+    Interfaces : TFPList;
+    GenericTemplateTypes : TFPList;
+    Function IsPacked : Boolean;
   end;
   end;
 
 
+
+
   TArgumentAccess = (argDefault, argConst, argVar, argOut);
   TArgumentAccess = (argDefault, argConst, argVar, argOut);
 
 
   { TPasArgument }
   { TPasArgument }
@@ -505,7 +522,8 @@ type
     function CreateArgument(const AName, AUnresolvedTypeName: string):TPasArgument;
     function CreateArgument(const AName, AUnresolvedTypeName: string):TPasArgument;
   public
   public
     IsOfObject: Boolean;
     IsOfObject: Boolean;
-    Args: TList;        // List of TPasArgument objects
+    Args: TFPList;        // List of TPasArgument objects
+    CallingConvention : TCallingConvention;
   end;
   end;
 
 
   { TPasResultElement }
   { TPasResultElement }
@@ -537,12 +555,19 @@ type
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
   end;
   end;
 
 
+  { TPasStringType }
+
+  TPasStringType = class(TPasUnresolvedTypeRef)
+  public
+    LengthExpr : String;
+    function ElementTypeName: string; override;
+  end;
+
   { TPasTypeRef }
   { TPasTypeRef }
 
 
   TPasTypeRef = class(TPasUnresolvedTypeRef)
   TPasTypeRef = class(TPasUnresolvedTypeRef)
   public
   public
   public
   public
-    // function GetDeclaration(full : Boolean): string; override;
     RefType: TPasType;
     RefType: TPasType;
   end;
   end;
 
 
@@ -578,7 +603,7 @@ type
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
     function GetDeclaration(full : boolean) : string; override;
     function GetDeclaration(full : boolean) : string; override;
   public
   public
-    Args: TList;        // List of TPasArgument objects
+    Args: TFPList;        // List of TPasArgument objects
     IndexValue, ReadAccessorName, WriteAccessorName,ImplementsName,
     IndexValue, ReadAccessorName, WriteAccessorName,ImplementsName,
       StoredAccessorName, DefaultValue: string;
       StoredAccessorName, DefaultValue: string;
     IsDefault, IsNodefault: Boolean;
     IsDefault, IsNodefault: Boolean;
@@ -600,13 +625,13 @@ type
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
     function TypeName: string; override;
     function TypeName: string; override;
   public
   public
-    Overloads: TList;           // List of TPasProcedure nodes
+    Overloads: TFPList;           // List of TPasProcedure nodes
   end;
   end;
 
 
   TProcedureModifier = (pmVirtual, pmDynamic, pmAbstract, pmOverride,
   TProcedureModifier = (pmVirtual, pmDynamic, pmAbstract, pmOverride,
                         pmExported, pmOverload, pmMessage, pmReintroduce,
                         pmExported, pmOverload, pmMessage, pmReintroduce,
                         pmStatic,pmInline,pmAssembler,pmVarargs,
                         pmStatic,pmInline,pmAssembler,pmVarargs,
-                        pmCompilerProc,pmExternal,pmExtdecl,pmForward);
+                        pmCompilerProc,pmExternal,pmForward);
   TProcedureModifiers = Set of TProcedureModifier;
   TProcedureModifiers = Set of TProcedureModifier;
   TProcedureMessageType = (pmtInteger,pmtString);
   TProcedureMessageType = (pmtInteger,pmtString);
                         
                         
@@ -614,10 +639,11 @@ type
 
 
   TPasProcedure = class(TPasProcedureBase)
   TPasProcedure = class(TPasProcedureBase)
   Private
   Private
-    FCallingConvention : TCallingConvention;
     FModifiers : TProcedureModifiers;
     FModifiers : TProcedureModifiers;
     FMessageName : String;
     FMessageName : String;
     FMessageType : TProcedureMessageType;
     FMessageType : TProcedureMessageType;
+    function GetCallingConvention: TCallingConvention;
+    procedure SetCallingConvention(AValue: TCallingConvention);
   public
   public
     destructor Destroy; override;
     destructor Destroy; override;
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
@@ -640,7 +666,7 @@ type
     Function IsStatic : Boolean;
     Function IsStatic : Boolean;
     Function IsForward: Boolean;
     Function IsForward: Boolean;
     Property Modifiers : TProcedureModifiers Read FModifiers Write FModifiers;
     Property Modifiers : TProcedureModifiers Read FModifiers Write FModifiers;
-    Property CallingConvention : TCallingConvention Read FCallingConvention Write FCallingConvention;
+    Property CallingConvention : TCallingConvention Read GetCallingConvention Write SetCallingConvention;
     Property MessageName : String Read FMessageName Write FMessageName;
     Property MessageName : String Read FMessageName Write FMessageName;
     property MessageType : TProcedureMessageType Read FMessageType Write FMessageType;
     property MessageType : TProcedureMessageType Read FMessageType Write FMessageType;
   end;
   end;
@@ -702,7 +728,7 @@ type
     constructor Create(const AName: string; AParent: TPasElement); override;
     constructor Create(const AName: string; AParent: TPasElement); override;
     destructor Destroy; override;
     destructor Destroy; override;
   public
   public
-    Labels: TList;
+    Labels: TFPList;
     Body: TPasImplBlock;
     Body: TPasImplBlock;
   end;
   end;
 
 
@@ -716,7 +742,7 @@ type
     function TypeName: string; virtual;
     function TypeName: string; virtual;
   public
   public
     ProcType: TPasProcedureType;
     ProcType: TPasProcedureType;
-    Locals: TList;
+    Locals: TFPList;
     Body: TPasImplBlock;
     Body: TPasImplBlock;
   end;
   end;
 
 
@@ -808,7 +834,7 @@ type
     function AddSimple(exp: TPasExpr): TPasImplSimple;
     function AddSimple(exp: TPasExpr): TPasImplSimple;
     function CloseOnSemicolon: boolean; virtual;
     function CloseOnSemicolon: boolean; virtual;
   public
   public
-    Elements: TList;    // TPasImplElement objects
+    Elements: TFPList;    // TPasImplElement objects
   end;
   end;
 
 
   { TPasImplStatement }
   { TPasImplStatement }
@@ -1012,7 +1038,7 @@ const
     'default', 'private', 'protected', 'public', 'published', 'automated','strict private', 'strict protected');
     'default', 'private', 'protected', 'public', 'published', 'automated','strict private', 'strict protected');
 
 
   ObjKindNames: array[TPasObjKind] of string = (
   ObjKindNames: array[TPasObjKind] of string = (
-    'object', 'class', 'interface');
+    'object', 'class', 'interface','class','class');
   
   
   OpcodeStrings : Array[TExprOpCode] of string = 
   OpcodeStrings : Array[TExprOpCode] of string = 
        ('','+','-','*','/','div','mod','**',
        ('','+','-','*','/','div','mod','**',
@@ -1026,11 +1052,16 @@ const
 
 
   cPasMemberHint : array[TPasMemberHint] of string =
   cPasMemberHint : array[TPasMemberHint] of string =
       ( 'deprecated', 'library', 'platform', 'experimental', 'unimplemented' );
       ( 'deprecated', 'library', 'platform', 'experimental', 'unimplemented' );
+  cCallingConventions : array[TCallingConvention] of string =
+      ( '', 'Register','Pascal','CDecl','StdCall','OldFPCCall','SafeCall');
 
 
 implementation
 implementation
 
 
 uses SysUtils;
 uses SysUtils;
 
 
+{ TPasStringType }
+
+
 {$IFNDEF FPC}
 {$IFNDEF FPC}
   const
   const
     LineEnding = sLineBreak;
     LineEnding = sLineBreak;
@@ -1039,6 +1070,23 @@ uses SysUtils;
 { Parse tree element type name functions }
 { Parse tree element type name functions }
 
 
 function TPasElement.ElementTypeName: string; begin Result := SPasTreeElement end;
 function TPasElement.ElementTypeName: string; begin Result := SPasTreeElement end;
+
+function TPasElement.HintsString: String;
+
+Var
+  H : TPasmemberHint;
+
+begin
+  Result:='';
+  For H := Low(TPasmemberHint) to High(TPasMemberHint) do
+    if H in Hints then
+      begin
+      If (Result<>'') then
+        Result:=Result+'; ';
+      Result:=Result+cPasMemberHint[h];
+      end;
+end;
+
 function TPasDeclarations.ElementTypeName: string; begin Result := SPasTreeSection end;
 function TPasDeclarations.ElementTypeName: string; begin Result := SPasTreeSection end;
 function TPasModule.ElementTypeName: string; begin Result := SPasTreeModule end;
 function TPasModule.ElementTypeName: string; begin Result := SPasTreeModule end;
 function TPasPackage.ElementTypeName: string; begin Result := SPasTreePackage end;
 function TPasPackage.ElementTypeName: string; begin Result := SPasTreePackage end;
@@ -1074,6 +1122,7 @@ function TPasDestructor.ElementTypeName: string; begin Result := SPasTreeDestruc
 function TPasProcedureImpl.ElementTypeName: string; begin Result := SPasTreeProcedureImpl end;
 function TPasProcedureImpl.ElementTypeName: string; begin Result := SPasTreeProcedureImpl end;
 function TPasConstructorImpl.ElementTypeName: string; begin Result := SPasTreeConstructorImpl end;
 function TPasConstructorImpl.ElementTypeName: string; begin Result := SPasTreeConstructorImpl end;
 function TPasDestructorImpl.ElementTypeName: string; begin Result := SPasTreeDestructorImpl end;
 function TPasDestructorImpl.ElementTypeName: string; begin Result := SPasTreeDestructorImpl end;
+function TPasStringType.ElementTypeName: string; begin Result:=SPasStringType;end;
 
 
 function TPasClassType.ElementTypeName: string;
 function TPasClassType.ElementTypeName: string;
 begin
 begin
@@ -1081,9 +1130,16 @@ begin
     okObject: Result := SPasTreeObjectType;
     okObject: Result := SPasTreeObjectType;
     okClass: Result := SPasTreeClassType;
     okClass: Result := SPasTreeClassType;
     okInterface: Result := SPasTreeInterfaceType;
     okInterface: Result := SPasTreeInterfaceType;
+    okGeneric : Result := SPasTreeGenericType;
+    okSpecialize : Result := SPasTreeSpecializedType;
   end;
   end;
 end;
 end;
 
 
+function TPasClassType.IsPacked: Boolean;
+begin
+  Result:=PackMode<>pmNone;
+end;
+
 
 
 
 
 { All other stuff: }
 { All other stuff: }
@@ -1091,17 +1147,18 @@ end;
 procedure TPasElement.ProcessHints(const ASemiColonPrefix: boolean; var AResult: string);
 procedure TPasElement.ProcessHints(const ASemiColonPrefix: boolean; var AResult: string);
 var
 var
   h: TPasMemberHint;
   h: TPasMemberHint;
+  S : String;
 begin
 begin
   if Hints <> [] then
   if Hints <> [] then
-  begin
+    begin
     if ASemiColonPrefix then
     if ASemiColonPrefix then
       AResult := AResult + ';';
       AResult := AResult + ';';
-    for h := Low(TPasMemberHint) to High(TPasMemberHint) do
-    begin
-      if h in Hints then
-        AResult := AResult + ' ' + cPasMemberHint[h] + ';'
+    S:=HintsString;
+    if (S<>'') then
+      AResult:=AResult+' '+S;
+    if ASemiColonPrefix then
+      AResult:=AResult+';';
     end;
     end;
-  end;
 end;
 end;
 
 
 constructor TPasElement.Create(const AName: string; AParent: TPasElement);
 constructor TPasElement.Create(const AName: string; AParent: TPasElement);
@@ -1132,7 +1189,7 @@ begin
   p := Parent;
   p := Parent;
   while Assigned(p) and not p.InheritsFrom(TPasDeclarations) do
   while Assigned(p) and not p.InheritsFrom(TPasDeclarations) do
   begin
   begin
-    if (p.ClassType <> TPasOverloadedProc) and (Length(p.Name) > 0) then
+    if (not (p is TPasOverloadedProc)) and (Length(p.Name) > 0) then
       if Length(Result) > 0 then
       if Length(Result) > 0 then
         Result := p.Name + '.' + Result
         Result := p.Name + '.' + Result
       else
       else
@@ -1149,7 +1206,7 @@ begin
   p := Parent;
   p := Parent;
   while Assigned(p) do
   while Assigned(p) do
   begin
   begin
-    if (p.ClassType <> TPasOverloadedProc) and (Length(p.Name) > 0) then
+    if (Not (p is TPasOverloadedProc)) and (Length(p.Name) > 0) then
       if Length(Result) > 0 then
       if Length(Result) > 0 then
         Result := p.Name + '.' + Result
         Result := p.Name + '.' + Result
       else
       else
@@ -1160,12 +1217,12 @@ end;
 
 
 function TPasElement.GetModule: TPasModule;
 function TPasElement.GetModule: TPasModule;
 begin
 begin
-  if ClassType = TPasPackage then
+  if self is  TPasPackage then
     Result := nil
     Result := nil
   else
   else
   begin
   begin
     Result := TPasModule(Self);
     Result := TPasModule(Self);
-    while Assigned(Result) and not (Result.ClassType = TPasModule) do
+    while Assigned(Result) and not (Result is TPasModule) do
       Result := TPasModule(Result.Parent);
       Result := TPasModule(Result.Parent);
   end;
   end;
 end;
 end;
@@ -1187,14 +1244,14 @@ end;
 constructor TPasDeclarations.Create(const AName: string; AParent: TPasElement);
 constructor TPasDeclarations.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Declarations := TList.Create;
-  ResStrings := TList.Create;
-  Types := TList.Create;
-  Consts := TList.Create;
-  Classes := TList.Create;
-  Functions := TList.Create;
-  Variables := TList.Create;
-  Properties := TList.Create;
+  Declarations := TFPList.Create;
+  ResStrings := TFPList.Create;
+  Types := TFPList.Create;
+  Consts := TFPList.Create;
+  Classes := TFPList.Create;
+  Functions := TFPList.Create;
+  Variables := TFPList.Create;
+  Properties := TFPList.Create;
 end;
 end;
 
 
 destructor TPasDeclarations.Destroy;
 destructor TPasDeclarations.Destroy;
@@ -1231,7 +1288,7 @@ begin
     inherited Create('#' + AName, AParent)
     inherited Create('#' + AName, AParent)
   else
   else
     inherited Create(AName, AParent);
     inherited Create(AName, AParent);
-  Modules := TList.Create;
+  Modules := TFPList.Create;
 end;
 end;
 
 
 destructor TPasPackage.Destroy;
 destructor TPasPackage.Destroy;
@@ -1279,7 +1336,7 @@ end;
 constructor TPasEnumType.Create(const AName: string; AParent: TPasElement);
 constructor TPasEnumType.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Values := TList.Create;
+  Values := TFPList.Create;
 end;
 end;
 
 
 destructor TPasEnumType.Destroy;
 destructor TPasEnumType.Destroy;
@@ -1332,7 +1389,7 @@ end;
 constructor TPasRecordType.Create(const AName: string; AParent: TPasElement);
 constructor TPasRecordType.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Members := TList.Create;
+  Members := TFPList.Create;
 end;
 end;
 
 
 destructor TPasRecordType.Destroy;
 destructor TPasRecordType.Destroy;
@@ -1360,12 +1417,14 @@ end;
 constructor TPasClassType.Create(const AName: string; AParent: TPasElement);
 constructor TPasClassType.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  IsPacked := False;                     // 12/04/04 - Dave - Added
+  PackMode:=pmNone;                     // 12/04/04 - Dave - Added
   IsShortDefinition := False;
   IsShortDefinition := False;
-  Members := TList.Create;
+  Members := TFPList.Create;
   Modifiers := TStringList.Create;
   Modifiers := TStringList.Create;
-  ClassVars := TList.Create;
-  Interfaces:= TList.Create;
+  ClassVars := TFPList.Create;
+  Interfaces:= TFPList.Create;
+  GenericTemplateTypes:=TFPList.Create;
+
 end;
 end;
 
 
 destructor TPasClassType.Destroy;
 destructor TPasClassType.Destroy;
@@ -1380,6 +1439,9 @@ begin
   Modifiers.Free;
   Modifiers.Free;
   ClassVars.Free;
   ClassVars.Free;
   Interfaces.Free;
   Interfaces.Free;
+  for i := 0 to GenericTemplateTypes.Count - 1 do
+    TPasElement(GenericTemplateTypes[i]).Release;
+  GenericTemplateTypes.Free;
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
@@ -1395,7 +1457,7 @@ end;
 constructor TPasProcedureType.Create(const AName: string; AParent: TPasElement);
 constructor TPasProcedureType.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Args := TList.Create;
+  Args := TFPList.Create;
 end;
 end;
 
 
 destructor TPasProcedureType.Destroy;
 destructor TPasProcedureType.Destroy;
@@ -1465,7 +1527,7 @@ end;
 constructor TPasProperty.Create(const AName: string; AParent: TPasElement);
 constructor TPasProperty.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Args := TList.Create;
+  Args := TFPList.Create;
 end;
 end;
 
 
 destructor TPasProperty.Destroy;
 destructor TPasProperty.Destroy;
@@ -1482,7 +1544,7 @@ end;
 constructor TPasOverloadedProc.Create(const AName: string; AParent: TPasElement);
 constructor TPasOverloadedProc.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Overloads := TList.Create;
+  Overloads := TFPList.Create;
 end;
 end;
 
 
 destructor TPasOverloadedProc.Destroy;
 destructor TPasOverloadedProc.Destroy;
@@ -1503,6 +1565,18 @@ begin
     SetLength(Result, 0);
     SetLength(Result, 0);
 end;
 end;
 
 
+function TPasProcedure.GetCallingConvention: TCallingConvention;
+begin
+  Result:=ccDefault;
+  if Assigned(ProcType) then
+    Result:=ProcType.CallingConvention;
+end;
+
+procedure TPasProcedure.SetCallingConvention(AValue: TCallingConvention);
+begin
+  if Assigned(ProcType) then
+    ProcType.CallingConvention:=AValue;
+end;
 
 
 destructor TPasProcedure.Destroy;
 destructor TPasProcedure.Destroy;
 begin
 begin
@@ -1521,7 +1595,7 @@ end;
 constructor TPasProcedureImpl.Create(const AName: string; AParent: TPasElement);
 constructor TPasProcedureImpl.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Locals := TList.Create;
+  Locals := TFPList.Create;
 end;
 end;
 
 
 destructor TPasProcedureImpl.Destroy;
 destructor TPasProcedureImpl.Destroy;
@@ -1617,7 +1691,7 @@ end;
 constructor TPasImplBlock.Create(const AName: string; AParent: TPasElement);
 constructor TPasImplBlock.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Elements := TList.Create;
+  Elements := TFPList.Create;
 end;
 end;
 
 
 destructor TPasImplBlock.Destroy;
 destructor TPasImplBlock.Destroy;
@@ -1777,37 +1851,75 @@ end;
 
 
 function TPasResString.GetDeclaration (full : boolean) : string;
 function TPasResString.GetDeclaration (full : boolean) : string;
 begin
 begin
-  Result:=Value;
+  Result:=Expr.GetDeclaration(true);
   If Full Then
   If Full Then
+    begin
     Result:=Name+' = '+Result;
     Result:=Name+' = '+Result;
+    ProcessHints(False,Result);
+    end;
+end;
+
+destructor TPasResString.Destroy;
+begin
+  If Assigned(Expr) then
+    Expr.Release;
+  inherited Destroy;
 end;
 end;
 
 
 function TPasPointerType.GetDeclaration (full : boolean) : string;
 function TPasPointerType.GetDeclaration (full : boolean) : string;
 begin
 begin
   Result:='^'+DestType.Name;
   Result:='^'+DestType.Name;
   If Full then
   If Full then
+    begin
     Result:=Name+' = '+Result;
     Result:=Name+' = '+Result;
+    ProcessHints(False,Result);
+    end;
 end;
 end;
 
 
 function TPasAliasType.GetDeclaration (full : boolean) : string;
 function TPasAliasType.GetDeclaration (full : boolean) : string;
 begin
 begin
   Result:=DestType.Name;
   Result:=DestType.Name;
   If Full then
   If Full then
+    begin
     Result:=Name+' = '+Result;
     Result:=Name+' = '+Result;
+    ProcessHints(False,Result);
+    end;
 end;
 end;
 
 
 function TPasClassOfType.GetDeclaration (full : boolean) : string;
 function TPasClassOfType.GetDeclaration (full : boolean) : string;
 begin
 begin
   Result:='Class of '+DestType.Name;
   Result:='Class of '+DestType.Name;
   If Full then
   If Full then
+    begin
     Result:=Name+' = '+Result;
     Result:=Name+' = '+Result;
+    ProcessHints(False,Result);
+    end;
 end;
 end;
 
 
 function TPasRangeType.GetDeclaration (full : boolean) : string;
 function TPasRangeType.GetDeclaration (full : boolean) : string;
 begin
 begin
   Result:=RangeStart+'..'+RangeEnd;
   Result:=RangeStart+'..'+RangeEnd;
   If Full then
   If Full then
+    begin
     Result:=Name+' = '+Result;
     Result:=Name+' = '+Result;
+    ProcessHints(False,Result);
+    end;
+end;
+
+destructor TPasRangeType.Destroy;
+begin
+  FreeAndNil(RangeExpr);
+  inherited Destroy;
+end;
+
+function TPasRangeType.RangeStart: String;
+begin
+  Result:=RangeExpr.Left.GetDeclaration(False);
+end;
+
+function TPasRangeType.RangeEnd: String;
+begin
+  Result:=RangeExpr.Right.GetDeclaration(False);
 end;
 end;
 
 
 function TPasArrayType.GetDeclaration (full : boolean) : string;
 function TPasArrayType.GetDeclaration (full : boolean) : string;
@@ -1823,7 +1935,15 @@ begin
   else
   else
     Result:=Result+'const';
     Result:=Result+'const';
   If Full Then
   If Full Then
+    begin
     Result:=Name+' = '+Result;
     Result:=Name+' = '+Result;
+    ProcessHints(False,Result);
+    end;
+end;
+
+function TPasArrayType.IsPacked: Boolean;
+begin
+  Result:=PackMode=pmPacked;
 end;
 end;
 
 
 function TPasFileType.GetDeclaration (full : boolean) : string;
 function TPasFileType.GetDeclaration (full : boolean) : string;
@@ -1832,7 +1952,10 @@ begin
   If Assigned(Eltype) then
   If Assigned(Eltype) then
     Result:=Result+' of '+ElType.Name;
     Result:=Result+' of '+ElType.Name;
   If Full Then
   If Full Then
+    begin
     Result:=Name+' = '+Result;
     Result:=Name+' = '+Result;
+    ProcessHints(False,Result);
+    end;
 end;
 end;
 
 
 Function IndentStrings(S : TStrings; indent : Integer) : string;
 Function IndentStrings(S : TStrings; indent : Integer) : string;
@@ -1876,6 +1999,8 @@ begin
       Result:=IndentStrings(S,Length(Name)+4)
       Result:=IndentStrings(S,Length(Name)+4)
     else
     else
       Result:=IndentStrings(S,1);
       Result:=IndentStrings(S,1);
+    if Full then
+      ProcessHints(False,Result);
   finally
   finally
     S.Free;
     S.Free;
   end;
   end;
@@ -1888,7 +2013,7 @@ Var
   i : Integer;
   i : Integer;
 
 
 begin
 begin
-  If EnumType is TPasEnumType then
+  If (EnumType is TPasEnumType) and (EnumType.Name='') then
     begin
     begin
     S:=TStringList.Create;
     S:=TStringList.Create;
     Try
     Try
@@ -1910,6 +2035,8 @@ begin
     If Full then
     If Full then
       Result:=Name+' = '+Result;
       Result:=Name+' = '+Result;
     end;
     end;
+  If Full then
+    ProcessHints(False,Result);
 end;
 end;
 
 
 function TPasRecordType.GetDeclaration (full : boolean) : string;
 function TPasRecordType.GetDeclaration (full : boolean) : string;
@@ -1956,6 +2083,16 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TPasRecordType.IsPacked: Boolean;
+begin
+  Result:=(PackMode <> pmNone);
+end;
+
+function TPasRecordType.IsBitPacked: Boolean;
+begin
+  Result:=(PackMode=pmBitPacked)
+end;
+
 procedure TPasProcedureType.GetArguments(List : TStrings);
 procedure TPasProcedureType.GetArguments(List : TStrings);
 
 
 Var
 Var
@@ -2037,6 +2174,9 @@ function TPasVariable.GetDeclaration (full : boolean) : string;
 Const
 Const
  Seps : Array[Boolean] of Char = ('=',':');
  Seps : Array[Boolean] of Char = ('=',':');
 
 
+Var
+  H : TPasMemberHint;
+  B : Boolean;
 begin
 begin
   if (Value = '') and Assigned(Expr) then
   if (Value = '') and Assigned(Expr) then
     Value := Expr.GetDeclaration(full);
     Value := Expr.GetDeclaration(full);
@@ -2053,7 +2193,10 @@ begin
   else
   else
     Result:=Value;
     Result:=Value;
   If Full then
   If Full then
+    begin
     Result:=Name+' '+Seps[Assigned(VarType)]+' '+Result;
     Result:=Name+' '+Seps[Assigned(VarType)]+' '+Result;
+    Result:=Result+HintsString;
+    end;
 end;
 end;
 
 
 function TPasProperty.GetDeclaration (full : boolean) : string;
 function TPasProperty.GetDeclaration (full : boolean) : string;
@@ -2315,7 +2458,7 @@ end;
 constructor TPasSection.Create(const AName: string; AParent: TPasElement);
 constructor TPasSection.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  UsesList := TList.Create;
+  UsesList := TFPList.Create;
 end;
 end;
 
 
 destructor TPasSection.Destroy;
 destructor TPasSection.Destroy;
@@ -2339,7 +2482,7 @@ end;
 constructor TProcedureBody.Create(const AName: string; AParent: TPasElement);
 constructor TProcedureBody.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Labels:=TList.Create;
+  Labels:=TFPList.Create;
 end;
 end;
 
 
 destructor TProcedureBody.Destroy;
 destructor TProcedureBody.Destroy;

File diff suppressed because it is too large
+ 638 - 291
packages/fcl-passrc/src/pparser.pp


File diff suppressed because it is too large
+ 675 - 131
packages/fcl-passrc/src/pscanner.pp


+ 1336 - 0
packages/fcl-passrc/tests/tcscanner.pas

@@ -0,0 +1,1336 @@
+unit tcscanner;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, typinfo, fpcunit, testutils, testregistry, pscanner, pparser;
+
+type
+
+  { TTestTokenFinder }
+
+  TTestTokenFinder = class(TTestCase)
+  Published
+    Procedure TestFind;
+  end;
+
+  { TTestStreamLineReader }
+
+
+  TTestStreamLineReader = class(TTestCase)
+  Private
+    FReader: TStreamLineReader;
+  Protected
+    procedure NewSource(Const Source : string);
+    Procedure TestLine(Const ALine : String; ExpectEOF : Boolean = True);
+    procedure TearDown; override;
+  Published
+    Procedure TestCreate;
+    Procedure TestEOF;
+    Procedure TestEmptyLine;
+    Procedure TestEmptyLineCR;
+    Procedure TestEmptyLineLF;
+    Procedure TestEmptyLineCRLF;
+    Procedure TestEmptyLineLFCR;
+    Procedure TestOneLine;
+    Procedure TestTwoLines;
+  end;
+
+  { TTestingPascalScanner }
+
+  TTestingPascalScanner = Class(TPascalScanner)
+  private
+    FDoSpecial: Boolean;
+  protected
+    function HandleMacro(AIndex: integer): TToken;override;
+  Public
+    Property DoSpecial : Boolean Read FDoSpecial Write FDoSpecial;
+  end;
+
+  { TTestScanner }
+  TTestScanner= class(TTestCase)
+  Private
+    FLI: String;
+    FScanner : TPascalScanner;
+    FResolver : TStreamResolver;
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+    Function TokenToString(tk : TToken) : string;
+    Procedure AssertEquals(Msg : String; Expected,Actual : TToken); overload;
+    procedure NewSource(Const Source : string; DoClear : Boolean = True);
+    Procedure DoTestToken(t : TToken; Const ASource : String; Const CheckEOF : Boolean = True);
+    Procedure TestToken(t : TToken; Const ASource : String; Const CheckEOF : Boolean = True);
+    Procedure TestTokens(t : array of TToken; Const ASource : String; Const CheckEOF : Boolean = True;Const DoClear : Boolean = True);
+    Property LastIDentifier : String Read FLI Write FLi;
+  published
+    procedure TestEOF;
+    procedure TestWhitespace;
+    procedure TestComment1;
+    procedure TestComment2;
+    procedure TestComment3;
+    procedure TestNestedComment1;
+    procedure TestNestedComment2;
+    procedure TestNestedComment3;
+    procedure TestNestedComment4;
+    procedure TestIdentifier;
+    procedure TestString;
+    procedure TestNumber;
+    procedure TestChar;
+    procedure TestBraceOpen;
+    procedure TestBraceClose;
+    procedure TestMul;
+    procedure TestPlus;
+    procedure TestComma;
+    procedure TestMinus;
+    procedure TestDot;
+    procedure TestDivision;
+    procedure TestColon;
+    procedure TestSemicolon;
+    procedure TestLessThan;
+    procedure TestEqual;
+    procedure TestGreaterThan;
+    procedure TestAt;
+    procedure TestSquaredBraceOpen;
+    procedure TestSquaredBraceClose;
+    procedure TestCaret;
+    procedure TestBackslash;
+    procedure TestDotDot;
+    procedure TestAssign;
+    procedure TestNotEqual;
+    procedure TestLessEqualThan;
+    procedure TestGreaterEqualThan;
+    procedure TestPower;
+    procedure TestSymmetricalDifference;
+    procedure TestAbsolute;
+    procedure TestAnd;
+    procedure TestArray;
+    procedure TestAs;
+    procedure TestAsm;
+    procedure TestBegin;
+    procedure TestBitpacked;
+    procedure TestCase;
+    procedure TestClass;
+    procedure TestConst;
+    procedure TestConstructor;
+    procedure TestDestructor;
+    procedure TestDiv;
+    procedure TestDo;
+    procedure TestDownto;
+    procedure TestElse;
+    procedure TestEnd;
+    procedure TestExcept;
+    procedure TestExports;
+    procedure TestFalse;
+    procedure TestFile;
+    procedure TestFinalization;
+    procedure TestFinally;
+    procedure TestFor;
+    procedure TestFunction;
+    procedure TestGeneric;
+    procedure TestGoto;
+    procedure TestIf;
+    procedure TestImplementation;
+    procedure TestIn;
+    procedure TestInherited;
+    procedure TestInitialization;
+    procedure TestInline;
+    procedure TestInterface;
+    procedure TestIs;
+    procedure TestLabel;
+    procedure TestLibrary;
+    procedure TestMod;
+    procedure TestNil;
+    procedure TestNot;
+    procedure TestObject;
+    procedure TestOf;
+    procedure TestOn;
+    procedure TestOperator;
+    procedure TestOr;
+    procedure TestPacked;
+    procedure TestProcedure;
+    procedure TestProgram;
+    procedure TestProperty;
+    procedure TestRaise;
+    procedure TestRecord;
+    procedure TestRepeat;
+    procedure TestResourceString;
+    procedure TestSelf;
+    procedure TestSet;
+    procedure TestShl;
+    procedure TestShr;
+    procedure TestSpecialize;
+    procedure TestThen;
+    procedure TestThreadvar;
+    procedure TestTo;
+    procedure TestTrue;
+    procedure TestTry;
+    procedure TestType;
+    procedure TestUnit;
+    procedure TestUntil;
+    procedure TestUses;
+    procedure TestVar;
+    procedure TestWhile;
+    procedure TestWith;
+    procedure TestXor;
+    procedure TestLineEnding;
+    procedure TestTab;
+    Procedure TestTokenSeries;
+    Procedure TestTokenSeriesNoWhiteSpace;
+    Procedure TestTokenSeriesComments;
+    Procedure TestTokenSeriesNoComments;
+    Procedure TestDefine1;
+    Procedure TestDefine2;
+    Procedure TestDefine3;
+    Procedure TestDefine4;
+    Procedure TestDefine5;
+    Procedure TestDefine6;
+    Procedure TestDefine7;
+    Procedure TestDefine8;
+    Procedure TestDefine9;
+    Procedure TestDefine10;
+    Procedure TestDefine11;
+    Procedure TestDefine12;
+    Procedure TestInclude;
+    Procedure TestInclude2;
+    Procedure TestMacro1;
+    procedure TestMacro2;
+    procedure TestMacro3;
+    procedure TestMacroHandling;
+  end;
+
+implementation
+
+{ TTestingPascalScanner }
+
+function TTestingPascalScanner.HandleMacro(AIndex: integer): TToken;
+begin
+  if DoSpecial then
+    begin
+    Result:=tkIdentifier;
+    SetCurTokenstring('somethingweird');
+    end
+  else
+    Result:=inherited HandleMacro(AIndex);
+end;
+
+{ TTestTokenFinder }
+
+procedure TTestTokenFinder.TestFind;
+
+Var
+  tk,tkr : TToken;
+  S : string;
+  B : Boolean;
+
+begin
+  For tk:=tkAbsolute to tkXor do
+    begin
+    S:=tokenInfos[tk];
+    B:=IsNamedToken(S,tkr);
+    AssertEquals('Token '+S+' is a token',true,B);
+    AssertEquals('Token '+S+' returns correct token',Ord(tk),Ord(tkr));
+    end;
+end;
+
+{ TTestStreamLineReader }
+
+procedure TTestStreamLineReader.NewSource(Const Source: string);
+begin
+  FReader:=TStringStreamLineReader.Create('afile',Source);
+end;
+
+procedure TTestStreamLineReader.TestLine(const ALine: String; ExpectEOF: Boolean);
+begin
+  AssertNotNull('Have reader',FReader);
+  AssertEquals('Reading source line',ALine,FReader.ReadLine);
+  if ExpectEOF then
+    AssertEquals('End of file reached',True,FReader.IsEOF);
+end;
+
+procedure TTestStreamLineReader.TearDown;
+begin
+  inherited TearDown;
+  If Assigned(FReader) then
+    FreeAndNil(Freader);
+end;
+
+procedure TTestStreamLineReader.TestCreate;
+begin
+  FReader:=TStreamLineReader.Create('afile');
+  AssertEquals('Correct filename','afile',FReader.FileName);
+  AssertEquals('Initially empty',True,FReader.isEOF);
+end;
+
+procedure TTestStreamLineReader.TestEOF;
+begin
+  NewSource('');
+  AssertEquals('Empty stream',True,FReader.IsEOF);
+end;
+
+procedure TTestStreamLineReader.TestEmptyLine;
+begin
+  NewSource('');
+  TestLine('');
+end;
+
+procedure TTestStreamLineReader.TestEmptyLineCR;
+begin
+  NewSource(#13);
+  TestLine('');
+end;
+
+procedure TTestStreamLineReader.TestEmptyLineLF;
+begin
+  NewSource(#10);
+  TestLine('');
+end;
+
+procedure TTestStreamLineReader.TestEmptyLineCRLF;
+begin
+  NewSource(#13#10);
+  TestLine('');
+end;
+
+procedure TTestStreamLineReader.TestEmptyLineLFCR;
+begin
+  NewSource(#10#13);
+  TestLine('',False);
+  TestLine('');
+end;
+
+procedure TTestStreamLineReader.TestOneLine;
+
+Const
+    S = 'a line with text';
+begin
+  NewSource(S);
+  TestLine(S);
+end;
+
+procedure TTestStreamLineReader.TestTwoLines;
+Const
+    S = 'a line with text';
+begin
+  NewSource(S+sLineBreak+S);
+  TestLine(S,False);
+  TestLine(S);
+end;
+
+{ ---------------------------------------------------------------------
+  TTestScanner
+  ---------------------------------------------------------------------}
+
+procedure TTestScanner.SetUp;
+begin
+  FResolver:=TStreamResolver.Create;
+  FResolver.OwnsStreams:=True;
+  FScanner:=TTestingPascalScanner.Create(FResolver);
+  // Do nothing
+end; 
+
+procedure TTestScanner.TearDown; 
+begin
+  FreeAndNil(FScanner);
+  FreeAndNil(FResolver);
+end;
+
+function TTestScanner.TokenToString(tk: TToken): string;
+begin
+  Result:=GetEnumName(TypeInfo(TToken),Ord(tk));
+end;
+
+procedure TTestScanner.AssertEquals(Msg: String; Expected, Actual: TToken);
+begin
+  AssertEquals(Msg,TokenToString(Expected),TokenToString(Actual));
+end;
+
+procedure TTestScanner.NewSource(const Source: string; DoClear : Boolean = True);
+begin
+  if DoClear then
+    FResolver.Clear;
+  FResolver.AddStream('afile.pp',TStringStream.Create(Source));
+  FScanner.OpenFile('afile.pp');
+end;
+
+procedure TTestScanner.DoTestToken(t: TToken; const ASource: String;
+  Const CheckEOF: Boolean);
+
+Var
+  tk : ttoken;
+
+begin
+  NewSource(ASource);
+  tk:=FScanner.FetchToken;
+  AssertEquals('Read token equals expected token.',t,tk);
+  if CheckEOF then
+    begin
+    tk:=FScanner.FetchToken;
+    if (tk=tkLineEnding) and not (t in [tkEOF,tkLineEnding]) then
+      tk:=FScanner.FetchToken;
+    AssertEquals('EOF reached.',tkEOF,FScanner.FetchToken);
+    end;
+end;
+
+procedure TTestScanner.TestToken(t: TToken; const ASource: String; Const CheckEOF: Boolean);
+Var
+  S : String;
+begin
+  DoTestToken(t,ASource);
+  if (ASource<>'') then
+    begin
+    S:=ASource;
+    S[1]:=Upcase(S[1]);
+    DoTestToken(t,S);
+    end;
+  DoTestToken(t,UpperCase(ASource));
+  DoTestToken(t,LowerCase(ASource));
+end;
+
+procedure TTestScanner.TestTokens(t: array of TToken; const ASource: String;
+  const CheckEOF: Boolean;Const DoClear : Boolean = True);
+Var
+  tk : ttoken;
+  i : integer;
+
+begin
+  NewSource(ASource,DoClear);
+  For I:=Low(t) to High(t) do
+    begin
+    tk:=FScanner.FetchToken;
+    AssertEquals(Format('Read token %d equals expected token.',[i]),t[i],tk);
+    if tk=tkIdentifier then
+      LastIdentifier:=FScanner.CurtokenString;
+    end;
+  if CheckEOF then
+    begin
+    tk:=FScanner.FetchToken;
+    if (tk=tkLineEnding) then
+      tk:=FScanner.FetchToken;
+    AssertEquals('EOF reached.',tkEOF,FScanner.FetchToken);
+    end;
+end;
+
+procedure TTestScanner.TestEOF;
+begin
+  TestToken(tkEOF,'')
+end;
+
+procedure TTestScanner.TestWhitespace;
+
+begin
+  TestToken(tkWhitespace,' ');
+  TestToken(tkWhitespace,' ');
+end;
+
+
+procedure TTestScanner.TestComment1;
+
+begin
+  TestToken(tkComment,'{ comment }');
+end;
+
+
+procedure TTestScanner.TestComment2;
+
+begin
+  TestToken(tkComment,'(* comment *)');
+end;
+
+
+procedure TTestScanner.TestComment3;
+
+begin
+  TestToken(tkComment,'//');
+end;
+
+procedure TTestScanner.TestNestedComment1;
+begin
+  TestToken(tkComment,'// { comment } ');
+end;
+
+procedure TTestScanner.TestNestedComment2;
+begin
+  TestToken(tkComment,'(* { comment } *)');
+end;
+
+procedure TTestScanner.TestNestedComment3;
+begin
+  TestToken(tkComment,'{ { comment } }');
+end;
+
+procedure TTestScanner.TestNestedComment4;
+begin
+  TestToken(tkComment,'{ (* comment *) }');
+end;
+
+
+procedure TTestScanner.TestIdentifier;
+
+begin
+  TestToken(tkIdentifier,'identifier');
+end;
+
+
+procedure TTestScanner.TestString;
+
+begin
+  TestToken(pscanner.tkString,'''A string''');
+end;
+
+
+procedure TTestScanner.TestNumber;
+
+begin
+  TestToken(tkNumber,'123');
+end;
+
+
+procedure TTestScanner.TestChar;
+
+begin
+  TestToken(pscanner.tkChar,'#65 ', false);
+end;
+
+
+procedure TTestScanner.TestBraceOpen;
+
+begin
+  TestToken(tkBraceOpen,'(');
+end;
+
+
+procedure TTestScanner.TestBraceClose;
+
+begin
+  TestToken(tkBraceClose,')');
+end;
+
+
+procedure TTestScanner.TestMul;
+
+begin
+  TestToken(tkMul,'*');
+end;
+
+
+procedure TTestScanner.TestPlus;
+
+begin
+  TestToken(tkPlus,'+');
+end;
+
+
+procedure TTestScanner.TestComma;
+
+begin
+  TestToken(tkComma,',');
+end;
+
+
+procedure TTestScanner.TestMinus;
+
+begin
+  TestToken(tkMinus,'-');
+end;
+
+
+procedure TTestScanner.TestDot;
+
+begin
+  TestToken(tkDot,'.');
+end;
+
+
+procedure TTestScanner.TestDivision;
+
+begin
+  TestToken(tkDivision,'/');
+end;
+
+
+procedure TTestScanner.TestColon;
+
+begin
+  TestToken(tkColon,':');
+end;
+
+
+procedure TTestScanner.TestSemicolon;
+
+begin
+  TestToken(tkSemicolon,';');
+end;
+
+
+procedure TTestScanner.TestLessThan;
+
+begin
+  TestToken(tkLessThan,'<');
+end;
+
+
+procedure TTestScanner.TestEqual;
+
+begin
+  TestToken(tkEqual,'=');
+end;
+
+
+procedure TTestScanner.TestGreaterThan;
+
+begin
+  TestToken(tkGreaterThan,'>');
+end;
+
+
+procedure TTestScanner.TestAt;
+
+begin
+  TestToken(tkAt,'@');
+end;
+
+
+procedure TTestScanner.TestSquaredBraceOpen;
+
+begin
+  TestToken(tkSquaredBraceOpen,'[');
+end;
+
+
+procedure TTestScanner.TestSquaredBraceClose;
+
+begin
+  TestToken(tkSquaredBraceClose,']');
+end;
+
+
+procedure TTestScanner.TestCaret;
+
+begin
+  TestToken(tkCaret,'^');
+end;
+
+
+procedure TTestScanner.TestBackslash;
+
+begin
+  TestToken(tkBackslash,'\');
+end;
+
+
+procedure TTestScanner.TestDotDot;
+
+begin
+  TestToken(tkDotDot,'..');
+end;
+
+
+procedure TTestScanner.TestAssign;
+
+begin
+  TestToken(tkAssign,':=');
+end;
+
+
+procedure TTestScanner.TestNotEqual;
+
+begin
+  TestToken(tkNotEqual,'<>');
+end;
+
+
+procedure TTestScanner.TestLessEqualThan;
+
+begin
+  TestToken(tkLessEqualThan,'<=');
+end;
+
+
+procedure TTestScanner.TestGreaterEqualThan;
+
+begin
+  TestToken(tkGreaterEqualThan,'>=');
+end;
+
+
+procedure TTestScanner.TestPower;
+
+begin
+  TestToken(tkPower,'**');
+end;
+
+
+procedure TTestScanner.TestSymmetricalDifference;
+
+begin
+  TestToken(tkSymmetricalDifference,'><');
+end;
+
+
+procedure TTestScanner.TestAbsolute;
+
+begin
+  TestToken(tkabsolute,'absolute');
+end;
+
+
+procedure TTestScanner.TestAnd;
+
+begin
+  TestToken(tkand,'and');
+end;
+
+
+procedure TTestScanner.TestArray;
+
+begin
+  TestToken(tkarray,'array');
+end;
+
+
+procedure TTestScanner.TestAs;
+
+begin
+  TestToken(tkas,'as');
+end;
+
+
+procedure TTestScanner.TestAsm;
+
+begin
+  TestToken(tkasm,'asm');
+end;
+
+
+procedure TTestScanner.TestBegin;
+
+begin
+  TestToken(tkbegin,'begin');
+end;
+
+
+procedure TTestScanner.TestBitpacked;
+
+begin
+  TestToken(tkbitpacked,'bitpacked');
+end;
+
+
+procedure TTestScanner.TestCase;
+
+begin
+  TestToken(tkcase,'case');
+end;
+
+
+procedure TTestScanner.TestClass;
+
+begin
+  TestToken(tkclass,'class');
+end;
+
+
+procedure TTestScanner.TestConst;
+
+begin
+  TestToken(tkconst,'const');
+end;
+
+
+procedure TTestScanner.TestConstructor;
+
+begin
+  TestToken(tkconstructor,'constructor');
+end;
+
+
+procedure TTestScanner.TestDestructor;
+
+begin
+  TestToken(tkdestructor,'destructor');
+end;
+
+
+procedure TTestScanner.TestDiv;
+
+begin
+  TestToken(tkdiv,'div');
+end;
+
+
+procedure TTestScanner.TestDo;
+
+begin
+  TestToken(tkdo,'do');
+end;
+
+
+procedure TTestScanner.TestDownto;
+
+begin
+  TestToken(tkdownto,'downto');
+end;
+
+
+procedure TTestScanner.TestElse;
+
+begin
+  TestToken(tkelse,'else');
+end;
+
+
+procedure TTestScanner.TestEnd;
+
+begin
+  TestToken(tkend,'end');
+end;
+
+
+procedure TTestScanner.TestExcept;
+
+begin
+  TestToken(tkexcept,'except');
+end;
+
+
+procedure TTestScanner.TestExports;
+
+begin
+  TestToken(tkexports,'exports');
+end;
+
+
+procedure TTestScanner.TestFalse;
+
+begin
+  TestToken(tkfalse,'false');
+end;
+
+
+procedure TTestScanner.TestFile;
+
+begin
+  TestToken(tkfile,'file');
+end;
+
+
+procedure TTestScanner.TestFinalization;
+
+begin
+  TestToken(tkfinalization,'finalization');
+end;
+
+
+procedure TTestScanner.TestFinally;
+
+begin
+  TestToken(tkfinally,'finally');
+end;
+
+
+procedure TTestScanner.TestFor;
+
+begin
+  TestToken(tkfor,'for');
+end;
+
+
+procedure TTestScanner.TestFunction;
+
+begin
+  TestToken(tkfunction,'function');
+end;
+
+
+procedure TTestScanner.TestGeneric;
+
+begin
+  TestToken(tkgeneric,'generic');
+end;
+
+
+procedure TTestScanner.TestGoto;
+
+begin
+  TestToken(tkgoto,'goto');
+end;
+
+
+procedure TTestScanner.TestIf;
+
+begin
+  TestToken(tkif,'if');
+end;
+
+
+procedure TTestScanner.TestImplementation;
+
+begin
+  TestToken(tkimplementation,'implementation');
+end;
+
+
+procedure TTestScanner.TestIn;
+
+begin
+  TestToken(tkin,'in');
+end;
+
+
+procedure TTestScanner.TestInherited;
+
+begin
+  TestToken(tkinherited,'inherited');
+end;
+
+
+procedure TTestScanner.TestInitialization;
+
+begin
+  TestToken(tkinitialization,'initialization');
+end;
+
+
+procedure TTestScanner.TestInline;
+
+begin
+  TestToken(tkinline,'inline');
+end;
+
+
+procedure TTestScanner.TestInterface;
+
+begin
+  TestToken(tkinterface,'interface');
+end;
+
+
+procedure TTestScanner.TestIs;
+
+begin
+  TestToken(tkis,'is');
+end;
+
+
+procedure TTestScanner.TestLabel;
+
+begin
+  TestToken(tklabel,'label');
+end;
+
+
+procedure TTestScanner.TestLibrary;
+
+begin
+  TestToken(tklibrary,'library');
+end;
+
+
+procedure TTestScanner.TestMod;
+
+begin
+  TestToken(tkmod,'mod');
+end;
+
+
+procedure TTestScanner.TestNil;
+
+begin
+  TestToken(tknil,'nil');
+end;
+
+
+procedure TTestScanner.TestNot;
+
+begin
+  TestToken(tknot,'not');
+end;
+
+
+procedure TTestScanner.TestObject;
+
+begin
+  TestToken(tkobject,'object');
+end;
+
+
+procedure TTestScanner.TestOf;
+
+begin
+  TestToken(tkof,'of');
+end;
+
+
+procedure TTestScanner.TestOn;
+
+begin
+  TestToken(tkon,'on');
+end;
+
+
+procedure TTestScanner.TestOperator;
+
+begin
+  TestToken(tkoperator,'operator');
+end;
+
+
+procedure TTestScanner.TestOr;
+
+begin
+  TestToken(tkor,'or');
+end;
+
+
+procedure TTestScanner.TestPacked;
+
+begin
+  TestToken(tkpacked,'packed');
+end;
+
+
+procedure TTestScanner.TestProcedure;
+
+begin
+  TestToken(tkprocedure,'procedure');
+end;
+
+
+procedure TTestScanner.TestProgram;
+
+begin
+  TestToken(tkprogram,'program');
+end;
+
+
+procedure TTestScanner.TestProperty;
+
+begin
+  TestToken(tkproperty,'property');
+end;
+
+
+procedure TTestScanner.TestRaise;
+
+begin
+  TestToken(tkraise,'raise');
+end;
+
+
+procedure TTestScanner.TestRecord;
+
+begin
+  TestToken(tkrecord,'record');
+end;
+
+
+procedure TTestScanner.TestRepeat;
+
+begin
+  TestToken(tkrepeat,'repeat');
+end;
+
+
+procedure TTestScanner.TestResourceString;
+
+begin
+  TestToken(tkResourceString,'resourcestring');
+end;
+
+
+procedure TTestScanner.TestSelf;
+
+begin
+  TestToken(tkself,'self');
+end;
+
+
+procedure TTestScanner.TestSet;
+
+begin
+  TestToken(tkset,'set');
+end;
+
+
+procedure TTestScanner.TestShl;
+
+begin
+  TestToken(tkshl,'shl');
+end;
+
+
+procedure TTestScanner.TestShr;
+
+begin
+  TestToken(tkshr,'shr');
+end;
+
+
+procedure TTestScanner.TestSpecialize;
+
+begin
+  TestToken(tkspecialize,'specialize');
+end;
+
+
+procedure TTestScanner.TestThen;
+
+begin
+  TestToken(tkthen,'then');
+end;
+
+
+procedure TTestScanner.TestThreadvar;
+
+begin
+  TestToken(tkthreadvar,'threadvar');
+end;
+
+
+procedure TTestScanner.TestTo;
+
+begin
+  TestToken(tkto,'to');
+end;
+
+
+procedure TTestScanner.TestTrue;
+
+begin
+  TestToken(tktrue,'true');
+end;
+
+
+procedure TTestScanner.TestTry;
+
+begin
+  TestToken(tktry,'try');
+end;
+
+
+procedure TTestScanner.TestType;
+
+begin
+  TestToken(tktype,'type');
+end;
+
+
+procedure TTestScanner.TestUnit;
+
+begin
+  TestToken(tkunit,'unit');
+end;
+
+
+procedure TTestScanner.TestUntil;
+
+begin
+  TestToken(tkuntil,'until');
+end;
+
+
+procedure TTestScanner.TestUses;
+
+begin
+  TestToken(tkuses,'uses');
+end;
+
+
+procedure TTestScanner.TestVar;
+
+begin
+  TestToken(tkvar,'var');
+end;
+
+
+procedure TTestScanner.TestWhile;
+
+begin
+  TestToken(tkwhile,'while');
+end;
+
+
+procedure TTestScanner.TestWith;
+
+begin
+  TestToken(tkwith,'with');
+end;
+
+
+procedure TTestScanner.TestXor;
+
+begin
+  TestToken(tkxor,'xor');
+end;
+
+
+procedure TTestScanner.TestLineEnding;
+
+begin
+  TestToken(tkLineEnding,#10);
+end;
+
+
+procedure TTestScanner.TestTab;
+
+begin
+  TestToken(tkTab,#9);
+end;
+
+procedure TTestScanner.TestTokenSeries;
+begin
+  TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkthen,tkWhiteSpace,tkIdentifier],'in of then aninteger')
+end;
+
+procedure TTestScanner.TestTokenSeriesNoWhiteSpace;
+begin
+  FScanner.SkipWhiteSpace:=True;
+  TestTokens([tkin,tkOf,tkthen,tkIdentifier],'in of then aninteger')
+end;
+
+procedure TTestScanner.TestTokenSeriesComments;
+begin
+  TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkComment,tkWhiteSpace,tkIdentifier],'in of {then} aninteger')
+end;
+
+procedure TTestScanner.TestTokenSeriesNoComments;
+begin
+  FScanner.SkipComments:=True;
+  TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkWhiteSpace,tkIdentifier],'in of {then} aninteger')
+end;
+
+procedure TTestScanner.TestDefine1;
+begin
+  TestTokens([tkComment],'{$IFDEF NEVER} of {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine2;
+
+begin
+  FSCanner.Defines.Add('ALWAYS');
+  TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine3;
+begin
+  FSCanner.Defines.Add('ALWAYS');
+  TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine4;
+begin
+  TestTokens([tkComment,tkWhitespace,tkin,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine5;
+begin
+  FScanner.SkipComments:=True;
+  TestTokens([tkLineEnding],'{$IFDEF NEVER} of {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine6;
+
+begin
+  FSCanner.Defines.Add('ALWAYS');
+  FScanner.SkipComments:=True;
+  TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine7;
+begin
+  FSCanner.Defines.Add('ALWAYS');
+  FScanner.SkipComments:=True;
+  TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine8;
+begin
+  FScanner.SkipComments:=True;
+  TestTokens([tkWhitespace,tkin,tkWhitespace],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine9;
+begin
+  FScanner.SkipWhiteSpace:=True;
+  TestTokens([],'{$IFDEF NEVER} of {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine10;
+
+begin
+  FSCanner.Defines.Add('ALWAYS');
+  FScanner.SkipComments:=True;
+  TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine11;
+begin
+  FSCanner.Defines.Add('ALWAYS');
+  FScanner.SkipComments:=True;
+  FScanner.SkipWhiteSpace:=True;
+  TestTokens([tkOf],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
+end;
+
+procedure TTestScanner.TestDefine12;
+begin
+  FScanner.SkipComments:=True;
+  FScanner.SkipWhiteSpace:=True;
+  TestTokens([tkin],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
+end;
+
+procedure TTestScanner.TestInclude;
+begin
+  FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'));
+  FScanner.SkipWhiteSpace:=True;
+  FScanner.SkipComments:=True;
+  TestTokens([tkIf,tkTrue,tkThen],'{$I myinclude.inc}',True,False);
+end;
+
+procedure TTestScanner.TestInclude2;
+begin
+  FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'));
+  FScanner.SkipWhiteSpace:=True;
+  FScanner.SkipComments:=True;
+  TestTokens([tkIf,tkTrue,tkThen,tkElse],'{$I myinclude.inc} else',True,False);
+end;
+
+procedure TTestScanner.TestMacro1;
+begin
+  FScanner.SkipWhiteSpace:=True;
+  FScanner.SkipComments:=True;
+  TestTokens([tkbegin,tkend,tkDot],'{$DEFINE MM:=begin end.}'#13#10'MM',True,False);
+end;
+
+procedure TTestScanner.TestMacro2;
+begin
+  FScanner.SkipWhiteSpace:=True;
+  FScanner.SkipComments:=True;
+  TestTokens([tkbegin,tkend,tkDot],'{$DEFINE MM:=begin end}'#13#10'MM .',True,False);
+end;
+
+procedure TTestScanner.TestMacro3;
+begin
+  FScanner.SkipComments:=True;
+  FScanner.SkipWhiteSpace:=True;
+  TestTokens([tkof],'{$DEFINE MM:=begin end}'#13#10'{$IFDEF MM} of {$ELSE} in {$ENDIF}');
+end;
+
+procedure TTestScanner.TestMacroHandling;
+begin
+  TTestingPascalScanner(FScanner).DoSpecial:=True;
+  FScanner.SkipComments:=True;
+  FScanner.SkipWhiteSpace:=True;
+  TestTokens([tkIdentifier],'{$DEFINE MM:=begin end}'#13#10'MM');
+  AssertEQuals('Correct identifier', 'somethingweird',LastIdentifier);
+end;
+
+
+
+
+initialization
+  RegisterTests([TTestTokenFinder,TTestStreamLineReader,TTestScanner]);
+end.
+

+ 82 - 0
packages/fcl-passrc/tests/testpassrc.lpi

@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <General>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="/usr/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="2">
+      <Item1>
+        <PackageName Value="FPCUnitConsoleRunner"/>
+      </Item1>
+      <Item2>
+        <PackageName Value="FCL"/>
+      </Item2>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="testpassrc.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="testpassrc"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="tcscanner.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcscanner"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Linking>
+      <Debugging>
+        <UseHeaptrc Value="True"/>
+      </Debugging>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 25 - 0
packages/fcl-passrc/tests/testpassrc.lpr

@@ -0,0 +1,25 @@
+program testpassrc;
+
+{$mode objfpc}{$H+}
+
+uses
+  Classes, consoletestrunner, tcscanner;
+
+type
+
+  { TLazTestRunner }
+
+  TMyTestRunner = class(TTestRunner)
+  protected
+  // override the protected methods of TTestRunner to customize its behavior
+  end;
+
+var
+  Application: TMyTestRunner;
+
+begin
+  Application := TMyTestRunner.Create(nil);
+  Application.Initialize;
+  Application.Run;
+  Application.Free;
+end.

+ 149 - 139
utils/fpcm/fpcmake.inc

@@ -1,7 +1,7 @@
 {$ifdef Delphi}
 {$ifdef Delphi}
-const fpcmakeini : array[0..215] of string[240]=(
+const fpcmakeini : array[0..216] of string[240]=(
 {$else Delphi}
 {$else Delphi}
-const fpcmakeini : array[0..215,1..240] of char=(
+const fpcmakeini : array[0..216,1..240] of char=(
 {$endif Delphi}
 {$endif Delphi}
   ';'#010+
   ';'#010+
   '; Templates used by fpcmake to create a Makefile from Makefile.fpc'#010+
   '; Templates used by fpcmake to create a Makefile from Makefile.fpc'#010+
@@ -1202,16 +1202,26 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'ifndef CROSSBOOTSTRAP'#010+
   'ifndef CROSSBOOTSTRAP'#010+
   'ifneq ($(BINUTILSPREFIX),)'#010+
   'ifneq ($(BINUTILSPREFIX),)'#010+
   'override FPCOP','T+=-XP$(BINUTILSPREFIX)'#010+
   'override FPCOP','T+=-XP$(BINUTILSPREFIX)'#010+
-  'override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)'#010+
   'endif'#010+
   'endif'#010+
   'ifneq ($(BINUTILSPREFIX),)'#010+
   'ifneq ($(BINUTILSPREFIX),)'#010+
   'override FPCOPT+=-Xr$(RLINKPATH)'#010+
   'override FPCOPT+=-Xr$(RLINKPATH)'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
+  '# When BINUTILSPREFIX is given and we are not cross-compiling then use'+
+  #010+
+  '# it while compiling the fpmake file. (For example to build i386-f','re'+
+  'ebsd'#010+
+  '# with BINUTILSPREFIX=i386-)'#010+
+  'ifndef CROSSCOMPILE'#010+
+  'ifneq ($(BINUTILSPREFIX),)'#010+
+  'override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)'#010+
+  'endif'#010+
+  'endif'#010+
+  #010+
   '# User dirs should be first, so they are looked at first'#010+
   '# User dirs should be first, so they are looked at first'#010+
   'ifdef UNITDIR'#010+
   'ifdef UNITDIR'#010+
-  'override FPCOPT+=$(addpr','efix -Fu,$(UNITDIR))'#010+
+  'override FPCOPT+=$(addprefix -F','u,$(UNITDIR))'#010+
   'endif'#010+
   'endif'#010+
   'ifdef LIBDIR'#010+
   'ifdef LIBDIR'#010+
   'override FPCOPT+=$(addprefix -Fl,$(LIBDIR))'#010+
   'override FPCOPT+=$(addprefix -Fl,$(LIBDIR))'#010+
@@ -1224,7 +1234,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   '# Smartlinking'#010+
   '# Smartlinking'#010+
-  'ifdef LI','NKSMART'#010+
+  'ifdef LINKSMART',#010+
   'override FPCOPT+=-XX'#010+
   'override FPCOPT+=-XX'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
@@ -1241,7 +1251,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   '# Release mode'#010+
   '# Release mode'#010+
   '# (strip, optimize and don'#039't load fpc.cfg)'#010+
   '# (strip, optimize and don'#039't load fpc.cfg)'#010+
-  '# ','fpc 2.1 has -O2 for all targets'#010+
+  '# fpc 2.1',' has -O2 for all targets'#010+
   'ifdef RELEASE'#010+
   'ifdef RELEASE'#010+
   'ifneq ($(findstring 2.0.,$(FPC_VERSION)),)'#010+
   'ifneq ($(findstring 2.0.,$(FPC_VERSION)),)'#010+
   'ifeq ($(CPU_TARGET),i386)'#010+
   'ifeq ($(CPU_TARGET),i386)'#010+
@@ -1253,7 +1263,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'else'#010+
   'else'#010+
   'FPCCPUOPT:=-O2'#010+
   'FPCCPUOPT:=-O2'#010+
   'endif'#010+
   'endif'#010+
-  'override FPCOPT+=-Ur -Xs',' $(FPCCPUOPT) -n'#010+
+  'override FPCOPT+=-Ur -Xs $(FPCC','PUOPT) -n'#010+
   'override FPCOPTDEF+=RELEASE'#010+
   'override FPCOPTDEF+=RELEASE'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
@@ -1272,7 +1282,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'override FPCOPT+=-vwni'#010+
   'override FPCOPT+=-vwni'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
-  '# ','Needed compiler options'#010+
+  '# Needed ','compiler options'#010+
   'ifdef COMPILER_OPTIONS'#010+
   'ifdef COMPILER_OPTIONS'#010+
   'override FPCOPT+=$(COMPILER_OPTIONS)'#010+
   'override FPCOPT+=$(COMPILER_OPTIONS)'#010+
   'endif'#010+
   'endif'#010+
@@ -1280,7 +1290,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))'#010+
   'override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))'#010+
   'endif'#010+
   'endif'#010+
   'ifdef COMPILER_LIBRARYDIR'#010+
   'ifdef COMPILER_LIBRARYDIR'#010+
-  'override FPCOPT+=$(addprefix -Fl,$(COMPIL','ER_LIBRARYDIR))'#010+
+  'override FPCOPT+=$(addprefix -Fl,$(COMPILER_LIBR','ARYDIR))'#010+
   'endif'#010+
   'endif'#010+
   'ifdef COMPILER_OBJECTDIR'#010+
   'ifdef COMPILER_OBJECTDIR'#010+
   'override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))'#010+
   'override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))'#010+
@@ -1290,8 +1300,8 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   '# Cross compiler utils'#010+
   '# Cross compiler utils'#010+
-  'ifdef CROSSBINDIR'#010,
-  'override FPCOPT+=-FD$(CROSSBINDIR)'#010+
+  'ifdef CROSSBINDIR'#010+
+  'overrid','e FPCOPT+=-FD$(CROSSBINDIR)'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   '# Target dirs and the prefix to use for clean/install'#010+
   '# Target dirs and the prefix to use for clean/install'#010+
@@ -1300,7 +1310,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'ifeq ($(COMPILER_TARGETDIR),.)'#010+
   'ifeq ($(COMPILER_TARGETDIR),.)'#010+
   'override TARGETDIRPREFIX='#010+
   'override TARGETDIRPREFIX='#010+
   'else'#010+
   'else'#010+
-  'override TARGET','DIRPREFIX=$(COMPILER_TARGETDIR)/'#010+
+  'override TARGETDIRPREF','IX=$(COMPILER_TARGETDIR)/'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
@@ -1310,7 +1320,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'ifeq ($(COMPILER_UNITTARGETDIR),.)'#010+
   'ifeq ($(COMPILER_UNITTARGETDIR),.)'#010+
   'override UNITTARGETDIRPREFIX='#010+
   'override UNITTARGETDIRPREFIX='#010+
   'else'#010+
   'else'#010+
-  'o','verride UNITTARGETDIRPREFIX=$(COMPILER_UNITTARGETDIR)/'#010+
+  'override',' UNITTARGETDIRPREFIX=$(COMPILER_UNITTARGETDIR)/'#010+
   'endif'#010+
   'endif'#010+
   'else'#010+
   'else'#010+
   'ifdef COMPILER_TARGETDIR'#010+
   'ifdef COMPILER_TARGETDIR'#010+
@@ -1320,8 +1330,8 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   'ifdef CREATESHARED'#010+
   'ifdef CREATESHARED'#010+
-  'override FPCOPT','+=-Cg'#010+
-  #010+
+  'override FPCOPT+=-Cg'#010+
+  #010,
   'ifeq ($(CPU_TARGET),i386)'#010+
   'ifeq ($(CPU_TARGET),i386)'#010+
   'override FPCOPT+=-Aas'#010+
   'override FPCOPT+=-Aas'#010+
   'endif'#010+
   'endif'#010+
@@ -1332,7 +1342,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'ifeq ($(findstring 2.0.,$(FPC_VERSION)),)'#010+
   'ifeq ($(findstring 2.0.,$(FPC_VERSION)),)'#010+
   'ifneq ($(findstring $(OS_TARGET),freebsd openbsd netbsd linux solaris)'+
   'ifneq ($(findstring $(OS_TARGET),freebsd openbsd netbsd linux solaris)'+
   ',)'#010+
   ',)'#010+
-  'ifeq ($(CPU_TARGET','),x86_64)'#010+
+  'ifeq ($(CPU_TARGET),x86_6','4)'#010+
   'override FPCOPT+=-Cg'#010+
   'override FPCOPT+=-Cg'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
@@ -1349,7 +1359,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'override FPCOPT+=-Fl$(GCCLIBDIR)'#010+
   'override FPCOPT+=-Fl$(GCCLIBDIR)'#010+
   'endif'#010+
   'endif'#010+
   'ifdef OTHERLIBDIR'#010+
   'ifdef OTHERLIBDIR'#010+
-  'o','verride FPCOPT+=$(addprefix -Fl,$(OTHERLIBDIR))'#010+
+  'override',' FPCOPT+=$(addprefix -Fl,$(OTHERLIBDIR))'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   #010+
   #010+
@@ -1361,7 +1371,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   '# Add defines from FPCOPTDEF to FPCOPT'#010+
   '# Add defines from FPCOPTDEF to FPCOPT'#010+
   'ifdef FPCOPTDEF'#010+
   'ifdef FPCOPTDEF'#010+
-  'override FPCOPT+=$(add','prefix -d,$(FPCOPTDEF))'#010+
+  'override FPCOPT+=$(addprefix ','-d,$(FPCOPTDEF))'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   '# Was a config file specified ?'#010+
   '# Was a config file specified ?'#010+
@@ -1373,7 +1383,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'ifdef USEENV'#010+
   'ifdef USEENV'#010+
   'override FPCEXTCMD:=$(FPCOPT)'#010+
   'override FPCEXTCMD:=$(FPCOPT)'#010+
   'override FPCOPT:=!FPCEXTCMD'#010+
   'override FPCOPT:=!FPCEXTCMD'#010+
-  'expor','t FPCEXTCMD'#010+
+  'export FPCEX','TCMD'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   'override AFULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)'#010+
   'override AFULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)'#010+
@@ -1385,9 +1395,9 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   'ifdef ACROSSCOMPILE'#010+
   'ifdef ACROSSCOMPILE'#010+
   'override FPCOPT+=$(CROSSOPT)'#010+
   'override FPCOPT+=$(CROSSOPT)'#010+
-  'e','ndif'#010+
+  'endif'#010+
   #010+
   #010+
-  '# Compiler commandline'#010+
+  '#',' Compiler commandline'#010+
   'override COMPILER:=$(FPC) $(FPCOPT)'#010+
   'override COMPILER:=$(FPC) $(FPCOPT)'#010+
   #010+
   #010+
   '# also call ppas if with command option -s'#010+
   '# also call ppas if with command option -s'#010+
@@ -1395,7 +1405,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'ifeq (,$(findstring -s ,$(COMPILER)))'#010+
   'ifeq (,$(findstring -s ,$(COMPILER)))'#010+
   'EXECPPAS='#010+
   'EXECPPAS='#010+
   'else'#010+
   'else'#010+
-  'ifeq ($(FULL_SOURCE),$','(FULL_TARGET))'#010+
+  'ifeq ($(FULL_SOURCE),$(FULL_T','ARGET))'#010+
   'ifdef RUNBATCH'#010+
   'ifdef RUNBATCH'#010+
   'EXECPPAS:=@$(RUNBATCH) $(PPAS)'#010+
   'EXECPPAS:=@$(RUNBATCH) $(PPAS)'#010+
   'else'#010+
   'else'#010+
@@ -1408,7 +1418,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '[loaderrules]'#010+
   '[loaderrules]'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
   '# Loaders'#010+
   '# Loaders'#010+
-  '#########################################','###########################'+
+  '################################################','####################'+
   '#'#010+
   '#'#010+
   #010+
   #010+
   '.PHONY: fpc_loaders'#010+
   '.PHONY: fpc_loaders'#010+
@@ -1418,7 +1428,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'override CLEANTARGET+=fpc_loaders_clean'#010+
   'override CLEANTARGET+=fpc_loaders_clean'#010+
   'override INSTALLTARGET+=fpc_loaders_install'#010+
   'override INSTALLTARGET+=fpc_loaders_install'#010+
   #010+
   #010+
-  'override LOADEROFILES:=$(addsuffix $(OEXT),$(','TARGET_LOADERS))'#010+
+  'override LOADEROFILES:=$(addsuffix $(OEXT),$(TARGET_','LOADERS))'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   '%$(OEXT): %$(LOADEREXT)'#010+
   '%$(OEXT): %$(LOADEREXT)'#010+
@@ -1430,7 +1440,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   'fpc_loaders: $(COMPILER_UNITTARGETDIR) $(LOADEROFILES)'#010+
   'fpc_loaders: $(COMPILER_UNITTARGETDIR) $(LOADEROFILES)'#010+
   #010+
   #010+
-  'fpc_loade','rs_clean:'#010+
+  'fpc_loaders_clea','n:'#010+
   'ifdef COMPILER_UNITTARGETDIR'#010+
   'ifdef COMPILER_UNITTARGETDIR'#010+
   '        -$(DEL) $(addprefix $(COMPILER_UNITTARGETDIR)/,$(LOADEROFILES)'+
   '        -$(DEL) $(addprefix $(COMPILER_UNITTARGETDIR)/,$(LOADEROFILES)'+
   ')'#010+
   ')'#010+
@@ -1440,18 +1450,17 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   'fpc_loaders_install:'#010+
   'fpc_loaders_install:'#010+
   '        $(MKDIR) $(INSTALL_UNITDIR)'#010+
   '        $(MKDIR) $(INSTALL_UNITDIR)'#010+
-  'ifdef COMPILER_UNITTARGETDIR',#010+
-  '        $(INSTALL) $(addprefix $(COMPILER_UNITTARGETDIR)/,$(LOADEROFIL'+
-  'ES)) $(INSTALL_UNITDIR)'#010+
+  'ifdef COMPILER_UNITTARGETDIR'#010+
+  '      ','  $(INSTALL) $(addprefix $(COMPILER_UNITTARGETDIR)/,$(LOADEROF'+
+  'ILES)) $(INSTALL_UNITDIR)'#010+
   'else'#010+
   'else'#010+
   '        $(INSTALL) $(LOADEROFILES) $(INSTALL_UNITDIR)'#010+
   '        $(INSTALL) $(LOADEROFILES) $(INSTALL_UNITDIR)'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   #010+
   #010+
   '[unitrules]'#010+
   '[unitrules]'#010+
-  '##################################################################','##'+
-  '#'#010+
-  '# Units'#010+
+  '#####################################################################'#010+
+  '# U','nits'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
   #010+
   #010+
   '.PHONY: fpc_units'#010+
   '.PHONY: fpc_units'#010+
@@ -1459,14 +1468,14 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'ifneq ($(TARGET_UNITS)$(TARGET_IMPLICITUNITS),)'#010+
   'ifneq ($(TARGET_UNITS)$(TARGET_IMPLICITUNITS),)'#010+
   'override ALLTARGET+=fpc_units'#010+
   'override ALLTARGET+=fpc_units'#010+
   #010+
   #010+
-  'override UNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_UNITS)',')'#010+
-  'override IMPLICITUNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_IMPLICITU'+
-  'NITS))'#010+
+  'override UNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_UNITS))'#010+
+  'overr','ide IMPLICITUNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_IMPLICI'+
+  'TUNITS))'#010+
   'override INSTALLPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES)'#010+
   'override INSTALLPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES)'#010+
   'override CLEANPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES)'#010+
   'override CLEANPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES)'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
-  'fpc_units: $(COMPILER_UN','ITTARGETDIR) $(UNITPPUFILES)'#010+
+  'fpc_units: $(COMPILER_UNITTARGE','TDIR) $(UNITPPUFILES)'#010+
   #010+
   #010+
   #010+
   #010+
   '[exerules]'#010+
   '[exerules]'#010+
@@ -1476,25 +1485,25 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   '.PHONY: fpc_exes'#010+
   '.PHONY: fpc_exes'#010+
   #010+
   #010+
-  '# Programs are not needed for a ','cross installation'#010+
+  '# Programs are not needed for a cross i','nstallation'#010+
   'ifndef CROSSINSTALL'#010+
   'ifndef CROSSINSTALL'#010+
   'ifneq ($(TARGET_PROGRAMS),)'#010+
   'ifneq ($(TARGET_PROGRAMS),)'#010+
   'override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))'#010+
   'override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))'#010+
   'override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefi'+
   'override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefi'+
-  'x $(STATICLIBPREFIX),$(addsuffix $(STATICLI','BEXT),$(TARGET_PROGRAMS))'+
+  'x $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$','(TARGET_PROGRAMS))'+
   ') $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_'+
   ') $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_'+
   'PROGRAMS)))'#010+
   'PROGRAMS)))'#010+
   'override EXEDBGFILES:=$(addsuffix $(EXEDBGEXT),$(TARGET_PROGRAMS))'#010+
   'override EXEDBGFILES:=$(addsuffix $(EXEDBGEXT),$(TARGET_PROGRAMS))'#010+
   #010+
   #010+
   'override ALLTARGET+=fpc_exes'#010+
   'override ALLTARGET+=fpc_exes'#010+
-  'override INSTALLEXEFILES+=$(EXEFILES',')'#010+
-  'override CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)'#010+
+  'override INSTALLEXEFILES+=$(EXEFILES)'#010+
+  'overr','ide CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)'#010+
   'override CLEANEXEDBGFILES+=$(EXEDBGFILES)'#010+
   'override CLEANEXEDBGFILES+=$(EXEDBGFILES)'#010+
   'ifeq ($(OS_TARGET),os2)'#010+
   'ifeq ($(OS_TARGET),os2)'#010+
   'override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))'#010+
   'override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))'#010+
   'endif'#010+
   'endif'#010+
   'ifeq ($(OS_TARGET),emx)'#010+
   'ifeq ($(OS_TARGET),emx)'#010+
-  'override CLEANEXEFILES+=$(','addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))'#010+
+  'override CLEANEXEFILES+=$(addsuff','ix $(AOUTEXT),$(TARGET_PROGRAMS))'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
@@ -1505,7 +1514,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '[rstrules]'#010+
   '[rstrules]'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
   '# Resource strings'#010+
   '# Resource strings'#010+
-  '########','############################################################'+
+  '###############','#####################################################'+
   '#'#010+
   '#'#010+
   #010+
   #010+
   'ifdef TARGET_RSTS'#010+
   'ifdef TARGET_RSTS'#010+
@@ -1516,7 +1525,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   #010+
   #010+
   '[examplerules]'#010+
   '[examplerules]'#010+
-  '###########################################','#########################'+
+  '##################################################','##################'+
   '#'#010+
   '#'#010+
   '# Examples'#010+
   '# Examples'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
@@ -1525,24 +1534,24 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   'ifneq ($(TARGET_EXAMPLES),)'#010+
   'ifneq ($(TARGET_EXAMPLES),)'#010+
   'HASEXAMPLES=1'#010+
   'HASEXAMPLES=1'#010+
-  'override EXAMPLESOURCEFILES:=$(wildcard $(addsuffix .pp,$(TARGET_EX','A'+
-  'MPLES)) $(addsuffix .pas,$(TARGET_EXAMPLES)) $(addsuffix .lpr,$(TARGET'+
+  'override EXAMPLESOURCEFILES:=$(wildcard $(addsuffix .pp,$(TARGET_EXAMP'+
+  'LES)',') $(addsuffix .pas,$(TARGET_EXAMPLES)) $(addsuffix .lpr,$(TARGET'+
   '_EXAMPLES)) $(addsuffix .dpr,$(TARGET_EXAMPLES)))'#010+
   '_EXAMPLES)) $(addsuffix .dpr,$(TARGET_EXAMPLES)))'#010+
   'override EXAMPLEFILES:=$(addsuffix $(EXEEXT),$(TARGET_EXAMPLES))'#010+
   'override EXAMPLEFILES:=$(addsuffix $(EXEEXT),$(TARGET_EXAMPLES))'#010+
-  'override EXAMPLEOFILES:=$(addsuffix $(OEXT),$(TARGET_E','XAMPLES)) $(ad'+
+  'override EXAMPLEOFILES:=$(addsuffix $(OEXT),$(TARGET_EXAMPLES',')) $(ad'+
   'dprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_EXAMPL'+
   'dprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_EXAMPL'+
   'ES))) $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TAR'+
   'ES))) $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TAR'+
   'GET_EXAMPLES)))'#010+
   'GET_EXAMPLES)))'#010+
-  'override EXAMPLEDBGFILES:=$(addsuffix $(EXEDBGEXT),$(TARGET_EXAMPLES))',
+  'override EXAMPLEDBGFILES:=$(addsuffix $(EXEDBGEXT),$(TARGET_EXAMPLES))'+
   #010+
   #010+
   #010+
   #010+
-  'override CLEANEXEFILES+=$(EXAMPLEFILES) $(EXAMPLEOFILES)'#010+
+  'overr','ide CLEANEXEFILES+=$(EXAMPLEFILES) $(EXAMPLEOFILES)'#010+
   'override CLEANEXEDBGFILES+=$(EXAMPLEDBGFILES)'#010+
   'override CLEANEXEDBGFILES+=$(EXAMPLEDBGFILES)'#010+
   'ifeq ($(OS_TARGET),os2)'#010+
   'ifeq ($(OS_TARGET),os2)'#010+
   'override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_EXAMPLES))'#010+
   'override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_EXAMPLES))'#010+
   'endif'#010+
   'endif'#010+
   'ifeq ($(OS_TARGET),emx)'#010+
   'ifeq ($(OS_TARGET),emx)'#010+
-  'override CLEAN','EXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_EXAMPLES))'#010+
+  'override CLEANEXEFILE','S+=$(addsuffix $(AOUTEXT),$(TARGET_EXAMPLES))'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'ifneq ($(TARGET_EXAMPLEDIRS),)'#010+
   'ifneq ($(TARGET_EXAMPLEDIRS),)'#010+
@@ -1554,7 +1563,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   #010+
   #010+
   '[compilerules]'#010+
   '[compilerules]'#010+
-  '################################','####################################'+
+  '#######################################','#############################'+
   '#'#010+
   '#'#010+
   '# General compile rules'#010+
   '# General compile rules'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
@@ -1562,7 +1571,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared'#010+
   '.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared'#010+
   #010+
   #010+
   '$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)'#010+
   '$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)'#010+
-  '   ','     @$(ECHOREDIR) Compiled > $(FPCMADE)'#010+
+  '        @$','(ECHOREDIR) Compiled > $(FPCMADE)'#010+
   #010+
   #010+
   'fpc_all: $(FPCMADE)'#010+
   'fpc_all: $(FPCMADE)'#010+
   #010+
   #010+
@@ -1575,7 +1584,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'fpc_release:'#010+
   'fpc_release:'#010+
   '        $(MAKE) all RELEASE=1'#010+
   '        $(MAKE) all RELEASE=1'#010+
   #010+
   #010+
-  '# General compile rules, available ','for both possible .pp and .pas ex'+
+  '# General compile rules, available for bot','h possible .pp and .pas ex'+
   'tensions'#010+
   'tensions'#010+
   #010+
   #010+
   '.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res'#010+
   '.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res'#010+
@@ -1584,7 +1593,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '        $(MKDIRTREE) $(COMPILER_UNITTARGETDIR)'#010+
   '        $(MKDIRTREE) $(COMPILER_UNITTARGETDIR)'#010+
   #010+
   #010+
   '$(COMPILER_TARGETDIR):'#010+
   '$(COMPILER_TARGETDIR):'#010+
-  '        $(MKDIRTREE) $(COMPILER','_TARGETDIR)'#010+
+  '        $(MKDIRTREE) $(COMPILER_TARGET','DIR)'#010+
   #010+
   #010+
   '%$(PPUEXT): %.pp'#010+
   '%$(PPUEXT): %.pp'#010+
   '        $(COMPILER) $<'#010+
   '        $(COMPILER) $<'#010+
@@ -1600,7 +1609,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   '%$(EXEEXT): %.pas'#010+
   '%$(EXEEXT): %.pas'#010+
   '        $(COMPILER) $<'#010+
   '        $(COMPILER) $<'#010+
-  '  ','      $(EXECPPAS)'#010+
+  '        $','(EXECPPAS)'#010+
   #010+
   #010+
   '%$(EXEEXT): %.lpr'#010+
   '%$(EXEEXT): %.lpr'#010+
   '        $(COMPILER) $<'#010+
   '        $(COMPILER) $<'#010+
@@ -1614,18 +1623,18 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '        windres -i $< -o $@'#010+
   '        windres -i $< -o $@'#010+
   #010+
   #010+
   '# Search paths for .ppu, .pp, .pas, .lpr, .dpr'#010+
   '# Search paths for .ppu, .pp, .pas, .lpr, .dpr'#010+
-  'vpath %.p','p $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)'#010+
+  'vpath %.pp $(COM','PILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)'#010+
   'vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)'#010+
   'vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)'#010+
   'vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)'#010+
   'vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)'#010+
   'vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)'#010+
   'vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)'#010+
-  'vpath %.inc $(COMPILER','_INCLUDEDIR)'#010+
+  'vpath %.inc $(COMPILER_INCLUD','EDIR)'#010+
   'vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)'#010+
   'vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)'#010+
   'vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)'#010+
   'vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)'#010+
   #010+
   #010+
   '[sharedrules]'#010+
   '[sharedrules]'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
   '# Library'#010+
   '# Library'#010+
-  '################################################','####################'+
+  '#######################################################','#############'+
   '#'#010+
   '#'#010+
   #010+
   #010+
   '.PHONY: fpc_shared'#010+
   '.PHONY: fpc_shared'#010+
@@ -1641,14 +1650,14 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   'ifndef SHARED_FULLNAME'#010+
   'ifndef SHARED_FULLNAME'#010+
-  'SHARE','D_FULLNAME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERS'+
+  'SHARED_FULLN','AME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERS'+
   'ION)$(SHAREDLIBEXT)'#010+
   'ION)$(SHAREDLIBEXT)'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   '# Default sharedlib units are all unit objects'#010+
   '# Default sharedlib units are all unit objects'#010+
   'ifndef SHARED_LIBUNITS'#010+
   'ifndef SHARED_LIBUNITS'#010+
   'SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS)'#010+
   'SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS)'#010+
-  'override SHARED_LIBUNIT','S:=$(filter-out $(INSTALL_BUILDUNIT),$(SHARED'+
+  'override SHARED_LIBUNITS:=$(fi','lter-out $(INSTALL_BUILDUNIT),$(SHARED'+
   '_LIBUNITS))'#010+
   '_LIBUNITS))'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
@@ -1656,7 +1665,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'ifdef HASSHAREDLIB'#010+
   'ifdef HASSHAREDLIB'#010+
   '        $(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1'#010+
   '        $(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1'#010+
   'ifneq ($(SHARED_BUILD),n)'#010+
   'ifneq ($(SHARED_BUILD),n)'#010+
-  '        $(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNI','TTARGETDIR)'+
+  '        $(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGET','DIR)'+
   ' -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)'#010+
   ' -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)'#010+
   'endif'#010+
   'endif'#010+
   'else'#010+
   'else'#010+
@@ -1666,7 +1675,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'fpc_shared_install:'#010+
   'fpc_shared_install:'#010+
   'ifneq ($(SHARED_BUILD),n)'#010+
   'ifneq ($(SHARED_BUILD),n)'#010+
   'ifneq ($(SHARED_LIBUNITS),)'#010+
   'ifneq ($(SHARED_LIBUNITS),)'#010+
-  'ifneq ($(wildcard $(COMPILER_UNITTARGET','DIR)/$(SHARED_FULLNAME)),)'#010+
+  'ifneq ($(wildcard $(COMPILER_UNITTARGETDIR)/$(','SHARED_FULLNAME)),)'#010+
   '        $(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INST'+
   '        $(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INST'+
   'ALL_SHAREDDIR)'#010+
   'ALL_SHAREDDIR)'#010+
   'endif'#010+
   'endif'#010+
@@ -1676,7 +1685,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '[installrules]'#010+
   '[installrules]'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
   '# Install rules'#010+
   '# Install rules'#010+
-  '########','############################################################'+
+  '###############','#####################################################'+
   '#'#010+
   '#'#010+
   #010+
   #010+
   '.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall'#010+
   '.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall'#010+
@@ -1686,18 +1695,18 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   'ifdef INSTALL_BUILDUNIT'#010+
   'ifdef INSTALL_BUILDUNIT'#010+
-  'ov','erride INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT)'+
+  'override ','INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT)'+
   ',$(INSTALLPPUFILES))'#010+
   ',$(INSTALLPPUFILES))'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   'ifdef INSTALLPPUFILES'#010+
   'ifdef INSTALLPPUFILES'#010+
   'override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFI'+
   'override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFI'+
-  'LES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT)',',$(STATICLIBEX'+
+  'LES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STAT','ICLIBEX'+
   'T),$(INSTALLPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEX'+
   'T),$(INSTALLPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEX'+
   'T),$(STATICLIBEXT),$(INSTALLPPUFILES)))'#010+
   'T),$(STATICLIBEXT),$(INSTALLPPUFILES)))'#010+
   'ifneq ($(UNITTARGETDIRPREFIX),)'#010+
   'ifneq ($(UNITTARGETDIRPREFIX),)'#010+
   'override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir '+
   'override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir '+
-  '$(INSTALLPPUFI','LES)))'#010+
+  '$(INSTALLPPUFILES)))'#010,
   'override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPR'+
   'override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPR'+
   'EFIX),$(notdir $(INSTALLPPULINKFILES))))'#010+
   'EFIX),$(notdir $(INSTALLPPULINKFILES))))'#010+
   'endif'#010+
   'endif'#010+
@@ -1706,7 +1715,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   'ifdef INSTALLEXEFILES'#010+
   'ifdef INSTALLEXEFILES'#010+
-  'ifneq ($(TARGETDIR','PREFIX),)'#010+
+  'ifneq ($(TARGETDIRPREFIX)',',)'#010+
   'override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(IN'+
   'override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(IN'+
   'STALLEXEFILES)))'#010+
   'STALLEXEFILES)))'#010+
   'endif'#010+
   'endif'#010+
@@ -1715,7 +1724,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'fpc_install: all $(INSTALLTARGET)'#010+
   'fpc_install: all $(INSTALLTARGET)'#010+
   'ifdef INSTALLEXEFILES'#010+
   'ifdef INSTALLEXEFILES'#010+
   '        $(MKDIR) $(INSTALL_BINDIR)'#010+
   '        $(MKDIR) $(INSTALL_BINDIR)'#010+
-  '        $(INSTALLEXE) $(INSTALLEXEFILES',') $(INSTALL_BINDIR)'#010+
+  '        $(INSTALLEXE) $(INSTALLEXEFILES) $(INS','TALL_BINDIR)'#010+
   'endif'#010+
   'endif'#010+
   'ifdef INSTALL_CREATEPACKAGEFPC'#010+
   'ifdef INSTALL_CREATEPACKAGEFPC'#010+
   'ifdef FPCMAKE'#010+
   'ifdef FPCMAKE'#010+
@@ -1723,7 +1732,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'c,'#010+
   'c,'#010+
   '# a safety check is done if Makefile.fpc is available'#010+
   '# a safety check is done if Makefile.fpc is available'#010+
   'ifdef PACKAGE_VERSION'#010+
   'ifdef PACKAGE_VERSION'#010+
-  'ifneq ($(wildcard Ma','kefile.fpc),)'#010+
+  'ifneq ($(wildcard Makefile.','fpc),)'#010+
   '        $(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc'#010+
   '        $(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc'#010+
   '        $(MKDIR) $(INSTALL_UNITDIR)'#010+
   '        $(MKDIR) $(INSTALL_UNITDIR)'#010+
   '        $(INSTALL) Package.fpc $(INSTALL_UNITDIR)'#010+
   '        $(INSTALL) Package.fpc $(INSTALL_UNITDIR)'#010+
@@ -1732,14 +1741,14 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'ifdef INSTALLPPUFILES'#010+
   'ifdef INSTALLPPUFILES'#010+
-  '        $(MKDIR) $(INSTALL_UNI','TDIR)'#010+
-  '        $(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)'#010+
+  '        $(MKDIR) $(INSTALL_UNITDIR)'#010+
+  ' ','       $(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)'#010+
   'ifneq ($(INSTALLPPULINKFILES),)'#010+
   'ifneq ($(INSTALLPPULINKFILES),)'#010+
   '        $(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)'#010+
   '        $(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)'#010+
   'endif'#010+
   'endif'#010+
   'ifneq ($(wildcard $(LIB_FULLNAME)),)'#010+
   'ifneq ($(wildcard $(LIB_FULLNAME)),)'#010+
   '        $(MKDIR) $(INSTALL_LIBDIR)'#010+
   '        $(MKDIR) $(INSTALL_LIBDIR)'#010+
-  '      ','  $(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)'#010+
+  '        $(INS','TALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)'#010+
   'ifdef inUnix'#010+
   'ifdef inUnix'#010+
   '        ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)'#010+
   '        ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)'#010+
   'endif'#010+
   'endif'#010+
@@ -1747,7 +1756,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   'ifdef INSTALL_FILES'#010+
   'ifdef INSTALL_FILES'#010+
   '        $(MKDIR) $(INSTALL_DATADIR)'#010+
   '        $(MKDIR) $(INSTALL_DATADIR)'#010+
-  '        $(INSTALL) $(INSTALL_FILES) $(INSTALL','_DATADIR)'#010+
+  '        $(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADI','R)'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   'fpc_sourceinstall: distclean'#010+
   'fpc_sourceinstall: distclean'#010+
@@ -1756,7 +1765,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   'fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))'#010+
   'fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))'#010+
   'ifdef HASEXAMPLES'#010+
   'ifdef HASEXAMPLES'#010+
-  '        $(MKDIR) ','$(INSTALL_EXAMPLEDIR)'#010+
+  '        $(MKDIR) $(INSTA','LL_EXAMPLEDIR)'#010+
   'endif'#010+
   'endif'#010+
   'ifdef EXAMPLESOURCEFILES'#010+
   'ifdef EXAMPLESOURCEFILES'#010+
   '        $(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)'#010+
   '        $(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)'#010+
@@ -1766,7 +1775,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'AMPLEDIR)'#010+
   'AMPLEDIR)'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
-  '[distinst','allrules]'#010+
+  '[distinstallrule','s]'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
   '# Dist Install'#010+
   '# Dist Install'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
@@ -1776,14 +1785,14 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'fpc_distinstall: install exampleinstall'#010+
   'fpc_distinstall: install exampleinstall'#010+
   #010+
   #010+
   #010+
   #010+
-  '[zipins','tallrules]'#010+
+  '[zipinstallrul','es]'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
   '# Zip'#010+
   '# Zip'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
   #010+
   #010+
   '.PHONY: fpc_zipinstall fpc_zipsourceinstall fpc_zipexampleinstall'#010+
   '.PHONY: fpc_zipinstall fpc_zipsourceinstall fpc_zipexampleinstall'#010+
   #010+
   #010+
-  '# Temporary pat','h to pack a file, can only use a single deep'#010+
+  '# Temporary path to pa','ck a file, can only use a single deep'#010+
   '# subdir, because the deltree can'#039't see the whole tree to remove'#010+
   '# subdir, because the deltree can'#039't see the whole tree to remove'#010+
   'ifndef PACKDIR'#010+
   'ifndef PACKDIR'#010+
   'ifndef inUnix'#010+
   'ifndef inUnix'#010+
@@ -1793,7 +1802,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
-  '# Maybe create default zipname',' from packagename'#010+
+  '# Maybe create default zipname from p','ackagename'#010+
   'ifndef ZIPNAME'#010+
   'ifndef ZIPNAME'#010+
   'ifdef DIST_ZIPNAME'#010+
   'ifdef DIST_ZIPNAME'#010+
   'ZIPNAME=$(DIST_ZIPNAME)'#010+
   'ZIPNAME=$(DIST_ZIPNAME)'#010+
@@ -1808,7 +1817,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   '# ZipTarget'#010+
   '# ZipTarget'#010+
   'ifndef ZIPTARGET'#010+
   'ifndef ZIPTARGET'#010+
-  'ifd','ef DIST_ZIPTARGET'#010+
+  'ifdef DIST','_ZIPTARGET'#010+
   'ZIPTARGET=DIST_ZIPTARGET'#010+
   'ZIPTARGET=DIST_ZIPTARGET'#010+
   'else'#010+
   'else'#010+
   'ZIPTARGET=install'#010+
   'ZIPTARGET=install'#010+
@@ -1825,9 +1834,9 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '# Use a wrapper script by default for Os/2'#010+
   '# Use a wrapper script by default for Os/2'#010+
   'ifndef inUnix'#010+
   'ifndef inUnix'#010+
   'USEZIPWRAPPER=1'#010+
   'USEZIPWRAPPER=1'#010+
-  'endif'#010,
+  'endif'#010+
   #010+
   #010+
-  '# We need to be able to run in the current OS so fix'#010+
+  '# We n','eed to be able to run in the current OS so fix'#010+
   '# the path separator'#010+
   '# the path separator'#010+
   'ifdef USEZIPWRAPPER'#010+
   'ifdef USEZIPWRAPPER'#010+
   'ZIPPATHSEP=$(PATHSEP)'#010+
   'ZIPPATHSEP=$(PATHSEP)'#010+
@@ -1836,13 +1845,13 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'ZIPPATHSEP=/'#010+
   'ZIPPATHSEP=/'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
-  '# Create commands to create ','the zip/tar file'#010+
+  '# Create commands to create the zip','/tar file'#010+
   'ZIPCMD_CDPACK:=cd $(subst /,$(ZIPPATHSEP),$(PACKDIR))'#010+
   'ZIPCMD_CDPACK:=cd $(subst /,$(ZIPPATHSEP),$(PACKDIR))'#010+
   'ZIPCMD_CDBASE:=cd $(subst /,$(ZIPPATHSEP),$(BASEDIR))'#010+
   'ZIPCMD_CDBASE:=cd $(subst /,$(ZIPPATHSEP),$(BASEDIR))'#010+
   'ifdef USETAR'#010+
   'ifdef USETAR'#010+
   'ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(TAREXT)'#010+
   'ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(TAREXT)'#010+
-  'ZIPCMD_ZIP:=$(TARPROG) c$(TAROPT)f $(ZIPDESTFILE)',' *'#010+
-  'else'#010+
+  'ZIPCMD_ZIP:=$(TARPROG) c$(TAROPT)f $(ZIPDESTFILE) *'#010+
+  'else',#010+
   'ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(ZIPEXT)'#010+
   'ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(ZIPEXT)'#010+
   'ZIPCMD_ZIP:=$(subst /,$(ZIPPATHSEP),$(ZIPPROG)) -Dr $(ZIPOPT) $(ZIPDES'+
   'ZIPCMD_ZIP:=$(subst /,$(ZIPPATHSEP),$(ZIPPROG)) -Dr $(ZIPOPT) $(ZIPDES'+
   'TFILE) *'#010+
   'TFILE) *'#010+
@@ -1850,21 +1859,21 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   'fpc_zipinstall:'#010+
   'fpc_zipinstall:'#010+
   '        $(MAKE) $(ZIPTARGET) INSTALL_PREFIX=$(PACKDIR) ZIPINSTALL=1'#010+
   '        $(MAKE) $(ZIPTARGET) INSTALL_PREFIX=$(PACKDIR) ZIPINSTALL=1'#010+
-  '        $','(MKDIR) $(DIST_DESTDIR)'#010+
+  '        $(MKDIR)',' $(DIST_DESTDIR)'#010+
   '        $(DEL) $(ZIPDESTFILE)'#010+
   '        $(DEL) $(ZIPDESTFILE)'#010+
   'ifdef USEZIPWRAPPER'#010+
   'ifdef USEZIPWRAPPER'#010+
   '# Handle gecho separate as we need to espace \ with \\'#010+
   '# Handle gecho separate as we need to espace \ with \\'#010+
   'ifneq ($(ECHOREDIR),echo)'#010+
   'ifneq ($(ECHOREDIR),echo)'#010+
   '        $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDPACK))" > $(ZIPWRAPPE'+
   '        $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDPACK))" > $(ZIPWRAPPE'+
   'R)'#010+
   'R)'#010+
-  '        $(EC','HOREDIR) -e "$(subst \,\\,$(ZIPCMD_ZIP))" >> $(ZIPWRAPPE'+
+  '        $(ECHOREDIR',') -e "$(subst \,\\,$(ZIPCMD_ZIP))" >> $(ZIPWRAPPE'+
   'R)'#010+
   'R)'#010+
   '        $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDBASE))" >> $(ZIPWRAPP'+
   '        $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDBASE))" >> $(ZIPWRAPP'+
   'ER)'#010+
   'ER)'#010+
   'else'#010+
   'else'#010+
   '        echo $(ZIPCMD_CDPACK) > $(ZIPWRAPPER)'#010+
   '        echo $(ZIPCMD_CDPACK) > $(ZIPWRAPPER)'#010+
   '        echo $(ZIPCMD_ZIP) >> $(ZIPWRAPPER)'#010+
   '        echo $(ZIPCMD_ZIP) >> $(ZIPWRAPPER)'#010+
-  '        echo',' $(ZIPCMD_CDBASE) >> $(ZIPWRAPPER)'#010+
+  '        echo $(ZIPC','MD_CDBASE) >> $(ZIPWRAPPER)'#010+
   'endif'#010+
   'endif'#010+
   'ifdef inUnix'#010+
   'ifdef inUnix'#010+
   '        /bin/sh $(ZIPWRAPPER)'#010+
   '        /bin/sh $(ZIPWRAPPER)'#010+
@@ -1877,7 +1886,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   '        $(DEL) $(ZIPWRAPPER)'#010+
   '        $(DEL) $(ZIPWRAPPER)'#010+
   'else'#010+
   'else'#010+
-  '        $(ZIPCMD_CDPACK) ; $(','ZIPCMD_ZIP) ; $(ZIPCMD_CDBASE)'#010+
+  '        $(ZIPCMD_CDPACK) ; $(ZIPCMD_','ZIP) ; $(ZIPCMD_CDBASE)'#010+
   'endif'#010+
   'endif'#010+
   '        $(DELTREE) $(PACKDIR)'#010+
   '        $(DELTREE) $(PACKDIR)'#010+
   #010+
   #010+
@@ -1887,7 +1896,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   'fpc_zipexampleinstall:'#010+
   'fpc_zipexampleinstall:'#010+
   'ifdef HASEXAMPLES'#010+
   'ifdef HASEXAMPLES'#010+
-  '        $(MAKE) fpc_zipi','nstall ZIPTARGET=exampleinstall ZIPSUFFIX=$('+
+  '        $(MAKE) fpc_zipinstall ','ZIPTARGET=exampleinstall ZIPSUFFIX=$('+
   'ZIPEXAMPLESUFFIX)'#010+
   'ZIPEXAMPLESUFFIX)'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
@@ -1897,23 +1906,24 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   '[cleanrules]'#010+
   '[cleanrules]'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
-  '# Clean rules',#010+
-  '#####################################################################'#010+
+  '# Clean rules'#010+
+  '######','##############################################################'+
+  '#'#010+
   #010+
   #010+
   '.PHONY: fpc_clean fpc_cleanall fpc_distclean'#010+
   '.PHONY: fpc_clean fpc_cleanall fpc_distclean'#010+
   #010+
   #010+
   'ifdef EXEFILES'#010+
   'ifdef EXEFILES'#010+
   'override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES'+
   'override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES'+
   '))'#010+
   '))'#010+
-  'override CLEANEXEDBGFILES:=$(addpr','efix $(TARGETDIRPREFIX),$(CLEANEXE'+
+  'override CLEANEXEDBGFILES:=$(addprefix $(','TARGETDIRPREFIX),$(CLEANEXE'+
   'DBGFILES))'#010+
   'DBGFILES))'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   'ifdef CLEAN_PROGRAMS'#010+
   'ifdef CLEAN_PROGRAMS'#010+
   'override CLEANEXEFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix $(E'+
   'override CLEANEXEFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix $(E'+
   'XEEXT), $(CLEAN_PROGRAMS)))'#010+
   'XEEXT), $(CLEAN_PROGRAMS)))'#010+
-  'override CLEANEXEDBGFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix',
-  ' $(EXEDBGEXT), $(CLEAN_PROGRAMS)))'#010+
+  'override CLEANEXEDBGFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix '+
+  '$(EXED','BGEXT), $(CLEAN_PROGRAMS)))'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   'ifdef CLEAN_UNITS'#010+
   'ifdef CLEAN_UNITS'#010+
@@ -1922,13 +1932,13 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   'ifdef CLEANPPUFILES'#010+
   'ifdef CLEANPPUFILES'#010+
   'override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)'+
   'override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)'+
-  ') $(addprefix $(STATI','CLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$'+
+  ') $(addprefix $(STATICLIBPRE','FIX),$(subst $(PPUEXT),$(STATICLIBEXT),$'+
   '(CLEANPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(S'+
   '(CLEANPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(S'+
   'TATICLIBEXT),$(CLEANPPUFILES)))'#010+
   'TATICLIBEXT),$(CLEANPPUFILES)))'#010+
   'ifdef DEBUGSYMEXT'#010+
   'ifdef DEBUGSYMEXT'#010+
   'override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPP'+
   'override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPP'+
-  'UFI','LES))'#010+
-  'endif'#010+
+  'UFILES))'#010+
+  'e','ndif'#010+
   'override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUF'+
   'override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUF'+
   'ILES))'#010+
   'ILES))'#010+
   'override CLEANPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREF'+
   'override CLEANPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREF'+
@@ -1937,7 +1947,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   'fpc_clean: $(CLEANTARGET)'#010+
   'fpc_clean: $(CLEANTARGET)'#010+
   'ifdef CLEANEXEFILES'#010+
   'ifdef CLEANEXEFILES'#010+
-  ' ','       -$(DEL) $(CLEANEXEFILES)'#010+
+  '        ','-$(DEL) $(CLEANEXEFILES)'#010+
   'endif'#010+
   'endif'#010+
   '# DELTREE instead of DEL because on Mac OS X these are directories'#010+
   '# DELTREE instead of DEL because on Mac OS X these are directories'#010+
   'ifdef CLEANEXEDBGFILES'#010+
   'ifdef CLEANEXEDBGFILES'#010+
@@ -1946,7 +1956,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'ifdef CLEANPPUFILES'#010+
   'ifdef CLEANPPUFILES'#010+
   '        -$(DEL) $(CLEANPPUFILES)'#010+
   '        -$(DEL) $(CLEANPPUFILES)'#010+
   'endif'#010+
   'endif'#010+
-  'ifneq (','$(CLEANPPULINKFILES),)'#010+
+  'ifneq ($(CLEAN','PPULINKFILES),)'#010+
   '        -$(DEL) $(CLEANPPULINKFILES)'#010+
   '        -$(DEL) $(CLEANPPULINKFILES)'#010+
   'endif'#010+
   'endif'#010+
   'ifdef CLEANRSTFILES'#010+
   'ifdef CLEANRSTFILES'#010+
@@ -1956,7 +1966,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '        -$(DEL) $(CLEAN_FILES)'#010+
   '        -$(DEL) $(CLEAN_FILES)'#010+
   'endif'#010+
   'endif'#010+
   'ifdef LIB_NAME'#010+
   'ifdef LIB_NAME'#010+
-  '        -','$(DEL) $(LIB_NAME) $(LIB_FULLNAME)'#010+
+  '        -$(DEL) ','$(LIB_NAME) $(LIB_FULLNAME)'#010+
   'endif'#010+
   'endif'#010+
   '        -$(DEL) $(FPCMADE) Package.fpc $(PPAS) script.res link.res $(F'+
   '        -$(DEL) $(FPCMADE) Package.fpc $(PPAS) script.res link.res $(F'+
   'PCEXTFILE) $(REDIRFILE)'#010+
   'PCEXTFILE) $(REDIRFILE)'#010+
@@ -1964,7 +1974,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   'fpc_cleanall: $(CLEANTARGET)'#010+
   'fpc_cleanall: $(CLEANTARGET)'#010+
   'ifdef CLEANEXEFILES'#010+
   'ifdef CLEANEXEFILES'#010+
-  '        -$','(DEL) $(CLEANEXEFILES)'#010+
+  '        -$(DEL) $','(CLEANEXEFILES)'#010+
   'endif'#010+
   'endif'#010+
   'ifdef COMPILER_UNITTARGETDIR'#010+
   'ifdef COMPILER_UNITTARGETDIR'#010+
   'ifdef CLEANPPUFILES'#010+
   'ifdef CLEANPPUFILES'#010+
@@ -1974,7 +1984,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '        -$(DEL) $(CLEANPPULINKFILES)'#010+
   '        -$(DEL) $(CLEANPPULINKFILES)'#010+
   'endif'#010+
   'endif'#010+
   'ifdef CLEANRSTFILES'#010+
   'ifdef CLEANRSTFILES'#010+
-  '        -$(DEL) $(addprefix $(','UNITTARGETDIRPREFIX),$(CLEANRSTFILES))'+
+  '        -$(DEL) $(addprefix $(UNITTAR','GETDIRPREFIX),$(CLEANRSTFILES))'+
   #010+
   #010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
   'endif'#010+
@@ -1984,7 +1994,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '        -$(DELTREE) units'#010+
   '        -$(DELTREE) units'#010+
   '        -$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIB'+
   '        -$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIB'+
   'EXT) *$(SHAREDLIBEXT) *$(PPLEXT)'#010+
   'EXT) *$(SHAREDLIBEXT) *$(PPLEXT)'#010+
-  'ifneq',' ($(PPUEXT),.ppu)'#010+
+  'ifneq ($(PPU','EXT),.ppu)'#010+
   '        -$(DEL) *.o *.ppu *.a'#010+
   '        -$(DEL) *.o *.ppu *.a'#010+
   'endif'#010+
   'endif'#010+
   '        -$(DELTREE) *$(SMARTEXT)'#010+
   '        -$(DELTREE) *$(SMARTEXT)'#010+
@@ -1992,7 +2002,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'CEXTFILE) $(REDIRFILE)'#010+
   'CEXTFILE) $(REDIRFILE)'#010+
   '        -$(DEL) *_ppas$(BATCHEXT)'#010+
   '        -$(DEL) *_ppas$(BATCHEXT)'#010+
   'ifdef AOUTEXT'#010+
   'ifdef AOUTEXT'#010+
-  '        -$(D','EL) *$(AOUTEXT)'#010+
+  '        -$(DEL) *$(','AOUTEXT)'#010+
   'endif'#010+
   'endif'#010+
   'ifdef DEBUGSYMEXT'#010+
   'ifdef DEBUGSYMEXT'#010+
   '        -$(DEL) *$(DEBUGSYMEXT)'#010+
   '        -$(DEL) *$(DEBUGSYMEXT)'#010+
@@ -2004,7 +2014,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '[baseinforules]'#010+
   '[baseinforules]'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
   '# Base info rules'#010+
   '# Base info rules'#010+
-  '###############################','#####################################'+
+  '######################################','##############################'+
   '#'#010+
   '#'#010+
   #010+
   #010+
   '.PHONY: fpc_baseinfo'#010+
   '.PHONY: fpc_baseinfo'#010+
@@ -2015,94 +2025,94 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  == Package info =='#010+
   '        @$(ECHO)  == Package info =='#010+
   '        @$(ECHO)  Package Name..... $(PACKAGE_NAME)'#010+
   '        @$(ECHO)  Package Name..... $(PACKAGE_NAME)'#010+
-  '        @$(ECHO)  Packag','e Version.. $(PACKAGE_VERSION)'#010+
+  '        @$(ECHO)  Package Versi','on.. $(PACKAGE_VERSION)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  == Configuration info =='#010+
   '        @$(ECHO)  == Configuration info =='#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  FPC.......... $(FPC)'#010+
   '        @$(ECHO)  FPC.......... $(FPC)'#010+
   '        @$(ECHO)  FPC Version.. $(FPC_VERSION)'#010+
   '        @$(ECHO)  FPC Version.. $(FPC_VERSION)'#010+
-  '        @$(ECHO)  Source CPU... $(CPU_SOURCE)'#010,
-  '        @$(ECHO)  Target CPU... $(CPU_TARGET)'#010+
+  '        @$(ECHO)  Source CPU... $(CPU_SOURCE)'#010+
+  '       ',' @$(ECHO)  Target CPU... $(CPU_TARGET)'#010+
   '        @$(ECHO)  Source OS.... $(OS_SOURCE)'#010+
   '        @$(ECHO)  Source OS.... $(OS_SOURCE)'#010+
   '        @$(ECHO)  Target OS.... $(OS_TARGET)'#010+
   '        @$(ECHO)  Target OS.... $(OS_TARGET)'#010+
   '        @$(ECHO)  Full Source.. $(FULL_SOURCE)'#010+
   '        @$(ECHO)  Full Source.. $(FULL_SOURCE)'#010+
   '        @$(ECHO)  Full Target.. $(FULL_TARGET)'#010+
   '        @$(ECHO)  Full Target.. $(FULL_TARGET)'#010+
-  '        @$','(ECHO)  SourceSuffix. $(SOURCESUFFIX)'#010+
+  '        @$(ECHO) ',' SourceSuffix. $(SOURCESUFFIX)'#010+
   '        @$(ECHO)  TargetSuffix. $(TARGETSUFFIX)'#010+
   '        @$(ECHO)  TargetSuffix. $(TARGETSUFFIX)'#010+
   '        @$(ECHO)  FPC fpmake... $(FPCFPMAKE)'#010+
   '        @$(ECHO)  FPC fpmake... $(FPCFPMAKE)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  == Directory info =='#010+
   '        @$(ECHO)  == Directory info =='#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
-  '        @$(ECHO)  Required pkgs... $','(REQUIRE_PACKAGES)'#010+
+  '        @$(ECHO)  Required pkgs... $(REQUIR','E_PACKAGES)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  Basedir......... $(BASEDIR)'#010+
   '        @$(ECHO)  Basedir......... $(BASEDIR)'#010+
   '        @$(ECHO)  FPCDir.......... $(FPCDIR)'#010+
   '        @$(ECHO)  FPCDir.......... $(FPCDIR)'#010+
   '        @$(ECHO)  CrossBinDir..... $(CROSSBINDIR)'#010+
   '        @$(ECHO)  CrossBinDir..... $(CROSSBINDIR)'#010+
   '        @$(ECHO)  UnitsDir........ $(UNITSDIR)'#010+
   '        @$(ECHO)  UnitsDir........ $(UNITSDIR)'#010+
-  '        @$(ECHO)','  PackagesDir..... $(PACKAGESDIR)'#010+
+  '        @$(ECHO)  Packa','gesDir..... $(PACKAGESDIR)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  GCC library..... $(GCCLIBDIR)'#010+
   '        @$(ECHO)  GCC library..... $(GCCLIBDIR)'#010+
   '        @$(ECHO)  Other library... $(OTHERLIBDIR)'#010+
   '        @$(ECHO)  Other library... $(OTHERLIBDIR)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  == Tools info =='#010+
   '        @$(ECHO)  == Tools info =='#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
-  '        @$(ECHO)  As..','...... $(AS)'#010+
+  '        @$(ECHO)  As........ ','$(AS)'#010+
   '        @$(ECHO)  Ld........ $(LD)'#010+
   '        @$(ECHO)  Ld........ $(LD)'#010+
   '        @$(ECHO)  Ar........ $(AR)'#010+
   '        @$(ECHO)  Ar........ $(AR)'#010+
   '        @$(ECHO)  Rc........ $(RC)'#010+
   '        @$(ECHO)  Rc........ $(RC)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  Mv........ $(MVPROG)'#010+
   '        @$(ECHO)  Mv........ $(MVPROG)'#010+
   '        @$(ECHO)  Cp........ $(CPPROG)'#010+
   '        @$(ECHO)  Cp........ $(CPPROG)'#010+
-  '        @$(ECHO)  Rm.......','. $(RMPROG)'#010+
+  '        @$(ECHO)  Rm........ $(RMP','ROG)'#010+
   '        @$(ECHO)  GInstall.. $(GINSTALL)'#010+
   '        @$(ECHO)  GInstall.. $(GINSTALL)'#010+
   '        @$(ECHO)  Echo...... $(ECHO)'#010+
   '        @$(ECHO)  Echo...... $(ECHO)'#010+
   '        @$(ECHO)  Shell..... $(SHELL)'#010+
   '        @$(ECHO)  Shell..... $(SHELL)'#010+
   '        @$(ECHO)  Date...... $(DATE)'#010+
   '        @$(ECHO)  Date...... $(DATE)'#010+
   '        @$(ECHO)  FPCMake... $(FPCMAKE)'#010+
   '        @$(ECHO)  FPCMake... $(FPCMAKE)'#010+
-  '        @$(ECHO)  PPUMove... $(PPUM','OVE)'#010+
-  '        @$(ECHO)  Zip....... $(ZIPPROG)'#010+
+  '        @$(ECHO)  PPUMove... $(PPUMOVE)'#010+
+  '  ','      @$(ECHO)  Zip....... $(ZIPPROG)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  == Object info =='#010+
   '        @$(ECHO)  == Object info =='#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  Target Loaders........ $(TARGET_LOADERS)'#010+
   '        @$(ECHO)  Target Loaders........ $(TARGET_LOADERS)'#010+
   '        @$(ECHO)  Target Units.......... $(TARGET_UNITS)'#010+
   '        @$(ECHO)  Target Units.......... $(TARGET_UNITS)'#010+
-  '        @','$(ECHO)  Target Implicit Units. $(TARGET_IMPLICITUNITS)'#010+
+  '        @$(ECHO)','  Target Implicit Units. $(TARGET_IMPLICITUNITS)'#010+
   '        @$(ECHO)  Target Programs....... $(TARGET_PROGRAMS)'#010+
   '        @$(ECHO)  Target Programs....... $(TARGET_PROGRAMS)'#010+
   '        @$(ECHO)  Target Dirs........... $(TARGET_DIRS)'#010+
   '        @$(ECHO)  Target Dirs........... $(TARGET_DIRS)'#010+
   '        @$(ECHO)  Target Examples....... $(TARGET_EXAMPLES)'#010+
   '        @$(ECHO)  Target Examples....... $(TARGET_EXAMPLES)'#010+
-  '        ','@$(ECHO)  Target ExampleDirs.... $(TARGET_EXAMPLEDIRS)'#010+
+  '        @$(ECHO',')  Target ExampleDirs.... $(TARGET_EXAMPLEDIRS)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  Clean Units......... $(CLEAN_UNITS)'#010+
   '        @$(ECHO)  Clean Units......... $(CLEAN_UNITS)'#010+
   '        @$(ECHO)  Clean Files......... $(CLEAN_FILES)'#010+
   '        @$(ECHO)  Clean Files......... $(CLEAN_FILES)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
-  '        @$(ECHO)  Install Units....... $(IN','STALL_UNITS)'#010+
+  '        @$(ECHO)  Install Units....... $(INSTALL_U','NITS)'#010+
   '        @$(ECHO)  Install Files....... $(INSTALL_FILES)'#010+
   '        @$(ECHO)  Install Files....... $(INSTALL_FILES)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  == Install info =='#010+
   '        @$(ECHO)  == Install info =='#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  DateStr.............. $(DATESTR)'#010+
   '        @$(ECHO)  DateStr.............. $(DATESTR)'#010+
-  '        @$(ECHO)  ZipName.............. $(ZIPNAME',')'#010+
-  '        @$(ECHO)  ZipPrefix............ $(ZIPPREFIX)'#010+
+  '        @$(ECHO)  ZipName.............. $(ZIPNAME)'#010+
+  '     ','   @$(ECHO)  ZipPrefix............ $(ZIPPREFIX)'#010+
   '        @$(ECHO)  ZipCrossPrefix....... $(ZIPCROSSPREFIX)'#010+
   '        @$(ECHO)  ZipCrossPrefix....... $(ZIPCROSSPREFIX)'#010+
   '        @$(ECHO)  ZipSuffix............ $(ZIPSUFFIX)'#010+
   '        @$(ECHO)  ZipSuffix............ $(ZIPSUFFIX)'#010+
   '        @$(ECHO)  FullZipName.......... $(FULLZIPNAME)'#010+
   '        @$(ECHO)  FullZipName.......... $(FULLZIPNAME)'#010+
-  '        @$(ECHO)  I','nstall FPC Package.. $(INSTALL_FPCPACKAGE)'#010+
+  '        @$(ECHO)  Install ','FPC Package.. $(INSTALL_FPCPACKAGE)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  Install base dir..... $(INSTALL_BASEDIR)'#010+
   '        @$(ECHO)  Install base dir..... $(INSTALL_BASEDIR)'#010+
   '        @$(ECHO)  Install binary dir... $(INSTALL_BINDIR)'#010+
   '        @$(ECHO)  Install binary dir... $(INSTALL_BINDIR)'#010+
   '        @$(ECHO)  Install library dir.. $(INSTALL_LIBDIR)'#010+
   '        @$(ECHO)  Install library dir.. $(INSTALL_LIBDIR)'#010+
-  '     ','   @$(ECHO)  Install units dir.... $(INSTALL_UNITDIR)'#010+
+  '        @$(E','CHO)  Install units dir.... $(INSTALL_UNITDIR)'#010+
   '        @$(ECHO)  Install source dir... $(INSTALL_SOURCEDIR)'#010+
   '        @$(ECHO)  Install source dir... $(INSTALL_SOURCEDIR)'#010+
   '        @$(ECHO)  Install doc dir...... $(INSTALL_DOCDIR)'#010+
   '        @$(ECHO)  Install doc dir...... $(INSTALL_DOCDIR)'#010+
   '        @$(ECHO)  Install example dir.. $(INSTALL_EXAMPLEDIR)'#010+
   '        @$(ECHO)  Install example dir.. $(INSTALL_EXAMPLEDIR)'#010+
-  '     ','   @$(ECHO)  Install data dir..... $(INSTALL_DATADIR)'#010+
+  '        @$(E','CHO)  Install data dir..... $(INSTALL_DATADIR)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  Dist destination dir. $(DIST_DESTDIR)'#010+
   '        @$(ECHO)  Dist destination dir. $(DIST_DESTDIR)'#010+
   '        @$(ECHO)  Dist zip name........ $(DIST_ZIPNAME)'#010+
   '        @$(ECHO)  Dist zip name........ $(DIST_ZIPNAME)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   #010+
   #010+
   '[inforules]'#010+
   '[inforules]'#010+
-  '###########################','#########################################'+
+  '##################################','##################################'+
   '#'#010+
   '#'#010+
   '# Info rules'#010+
   '# Info rules'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
@@ -2112,7 +2122,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'fpc_info: $(INFORULES)'#010+
   'fpc_info: $(INFORULES)'#010+
   #010+
   #010+
   '[makefilerules]'#010+
   '[makefilerules]'#010+
-  '#######################################################','#############'+
+  '##############################################################','######'+
   '#'#010+
   '#'#010+
   '# Rebuild Makefile'#010+
   '# Rebuild Makefile'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
@@ -2122,7 +2132,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '        fpc_makefile_dirs'#010+
   '        fpc_makefile_dirs'#010+
   #010+
   #010+
   'fpc_makefile:'#010+
   'fpc_makefile:'#010+
-  '        $(FPCMAKE) -w',' -T$(OS_TARGET) Makefile.fpc'#010+
+  '        $(FPCMAKE) -w -T$(OS','_TARGET) Makefile.fpc'#010+
   #010+
   #010+
   'fpc_makefile_sub1:'#010+
   'fpc_makefile_sub1:'#010+
   'ifdef TARGET_DIRS'#010+
   'ifdef TARGET_DIRS'#010+
@@ -2130,8 +2140,8 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'T_DIRS))'#010+
   'T_DIRS))'#010+
   'endif'#010+
   'endif'#010+
   'ifdef TARGET_EXAMPLEDIRS'#010+
   'ifdef TARGET_EXAMPLEDIRS'#010+
-  '        $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,','$(TAR'+
-  'GET_EXAMPLEDIRS))'#010+
+  '        $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGE',
+  'T_EXAMPLEDIRS))'#010+
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   'fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_'+
   'fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_'+
@@ -2142,7 +2152,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'fpc_makefiles: fpc_makefile fpc_makefile_dirs'#010+
   'fpc_makefiles: fpc_makefile fpc_makefile_dirs'#010+
   #010+
   #010+
   '[localmakefile]'#010+
   '[localmakefile]'#010+
-  '######','##############################################################'+
+  '#############','#######################################################'+
   '#'#010+
   '#'#010+
   '# Local Makefile'#010+
   '# Local Makefile'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
@@ -2153,7 +2163,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   #010+
   #010+
   '[userrules]'#010+
   '[userrules]'#010+
-  '###############','#####################################################'+
+  '######################','##############################################'+
   '#'#010+
   '#'#010+
   '# Users rules'#010+
   '# Users rules'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
@@ -2161,7 +2171,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '[lclrules]'#010+
   '[lclrules]'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
   '# LCL Rules'#010+
   '# LCL Rules'#010+
-  '#######','#############################################################'+
+  '##############','######################################################'+
   '#'#010+
   '#'#010+
   #010+
   #010+
   '# LCL Platform'#010+
   '# LCL Platform'#010+
@@ -2174,7 +2184,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   'export LCL_PLATFORM'#010+
   'export LCL_PLATFORM'#010+
   #010+
   #010+
-  '# Check if the spec','ified LCLDIR is correct'#010+
+  '# Check if the specified L','CLDIR is correct'#010+
   'ifdef LCLDIR'#010+
   'ifdef LCLDIR'#010+
   'override LCLDIR:=$(subst \,/,$(LCLDIR))'#010+
   'override LCLDIR:=$(subst \,/,$(LCLDIR))'#010+
   'ifeq ($(wildcard $(LCLDIR)/units/$(LCL_PLATFORM)),)'#010+
   'ifeq ($(wildcard $(LCLDIR)/units/$(LCL_PLATFORM)),)'#010+
@@ -2185,7 +2195,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   '# Check if the default LCLDIR is correct'#010+
   '# Check if the default LCLDIR is correct'#010+
-  'ifdef DE','FAULT_LCLDIR'#010+
+  'ifdef DEFAULT_L','CLDIR'#010+
   'override LCLDIR:=$(subst \,/,$(DEFAULT_LCLDIR))'#010+
   'override LCLDIR:=$(subst \,/,$(DEFAULT_LCLDIR))'#010+
   'ifeq ($(wildcard $(LCLDIR)/units/$(LCL_PLATFORM)),)'#010+
   'ifeq ($(wildcard $(LCLDIR)/units/$(LCL_PLATFORM)),)'#010+
   'override LCLDIR=wrong'#010+
   'override LCLDIR=wrong'#010+
@@ -2194,7 +2204,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   '# Check for development version'#010+
   '# Check for development version'#010+
   'ifeq ($(LCLDIR),wrong)'#010+
   'ifeq ($(LCLDIR),wrong)'#010+
-  'override LCLDIR=$(subst /units/$(LCL_','PLATFORM),,$(firstword $(wildca'+
+  'override LCLDIR=$(subst /units/$(LCL_PLATFOR','M),,$(firstword $(wildca'+
   'rd $(addsuffix /units/$(LCL_PLATFORM),$(BASEDIR)/lcl $(BASEDIR)))))'#010+
   'rd $(addsuffix /units/$(LCL_PLATFORM),$(BASEDIR)/lcl $(BASEDIR)))))'#010+
   'ifeq ($(LCLDIR),)'#010+
   'ifeq ($(LCLDIR),)'#010+
   'override LCLDIR=wrong'#010+
   'override LCLDIR=wrong'#010+
@@ -2203,7 +2213,7 @@ const fpcmakeini : array[0..215,1..240] of char=(
   #010+
   #010+
   '# Check for release version'#010+
   '# Check for release version'#010+
   'ifeq ($(LCLDIR),wrong)'#010+
   'ifeq ($(LCLDIR),wrong)'#010+
-  'override LCLDIR=$(subst /units/$(LCL_','PLATFORM),,$(firstword $(wildca'+
+  'override LCLDIR=$(subst /units/$(LCL_PLATFOR','M),,$(firstword $(wildca'+
   'rd $(addsuffix /lib/lazarus/units/$(LCL_PLATFORM),/usr/local /usr))))'#010+
   'rd $(addsuffix /lib/lazarus/units/$(LCL_PLATFORM),/usr/local /usr))))'#010+
   'ifeq ($(LCLDIR),)'#010+
   'ifeq ($(LCLDIR),)'#010+
   'override LCLDIR=wrong'#010+
   'override LCLDIR=wrong'#010+
@@ -2211,15 +2221,15 @@ const fpcmakeini : array[0..215,1..240] of char=(
   'endif'#010+
   'endif'#010+
   #010+
   #010+
   '# Generate dirs'#010+
   '# Generate dirs'#010+
-  'override LCLUNITDIR:=$(wildcard $(LCLDIR)/units/$(LCL_PLATFORM) $(LCLD',
-  'IR)/units)'#010+
+  'override LCLUNITDIR:=$(wildcard $(LCLDIR)/units/$(LCL_PLATFORM) $(LCLD'+
+  'IR)/uni','ts)'#010+
   'override LCLCOMPONENTDIR:=$(wildcard $(LCLDIR)/.. $(LCLDIR)/../compone'+
   'override LCLCOMPONENTDIR:=$(wildcard $(LCLDIR)/.. $(LCLDIR)/../compone'+
   'nts $(LCLDIR)/components)'#010+
   'nts $(LCLDIR)/components)'#010+
   'export LCLDIR LCLUNITDIR LCLCOMPONENTDIR'#010+
   'export LCLDIR LCLUNITDIR LCLCOMPONENTDIR'#010+
   #010+
   #010+
   '# Add LCL dirs to paths'#010+
   '# Add LCL dirs to paths'#010+
   'override REQUIRE_PACKAGESDIR+=$(LCLCOMPONENTDIR)'#010+
   'override REQUIRE_PACKAGESDIR+=$(LCLCOMPONENTDIR)'#010+
-  'override COMPILER_','UNITDIR+=$(LCLUNITDIR)'#010+
+  'override COMPILER_UNITDIR','+=$(LCLUNITDIR)'#010+
   #010+
   #010+
   '[lclinforules]'#010+
   '[lclinforules]'#010+
   '#####################################################################'#010+
   '#####################################################################'#010+
@@ -2227,14 +2237,14 @@ const fpcmakeini : array[0..215,1..240] of char=(
   '#####################################################################'#010+
   '#####################################################################'#010+
   'override INFORULES+=lclinfo'#010+
   'override INFORULES+=lclinfo'#010+
   #010+
   #010+
-  '.PHONY: lclinfo',#010+
+  '.PHONY: lclinfo'#010+
   #010+
   #010+
-  'lclinfo:'#010+
+  'lclin','fo:'#010+
   '        @$(ECHO)  == LCL info =='#010+
   '        @$(ECHO)  == LCL info =='#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)'#010+
   '        @$(ECHO)  Platform............. $(LCL_PLATFORM)'#010+
   '        @$(ECHO)  Platform............. $(LCL_PLATFORM)'#010+
   '        @$(ECHO)  LCLDIR............... $(LCLDIR)'#010+
   '        @$(ECHO)  LCLDIR............... $(LCLDIR)'#010+
   '        @$(ECHO)  LCL Unit dir......... $(LCLUNITDIR)'#010+
   '        @$(ECHO)  LCL Unit dir......... $(LCLUNITDIR)'#010+
-  '        @$(ECHO)  L','CL Component dir.... $(LCLCOMPONENTDIR)'#010+
+  '        @$(ECHO)  LCL Comp','onent dir.... $(LCLCOMPONENTDIR)'#010+
   '        @$(ECHO)'#010
   '        @$(ECHO)'#010
 );
 );

+ 9 - 1
utils/fpcm/fpcmake.ini

@@ -1152,13 +1152,21 @@ endif
 ifndef CROSSBOOTSTRAP
 ifndef CROSSBOOTSTRAP
 ifneq ($(BINUTILSPREFIX),)
 ifneq ($(BINUTILSPREFIX),)
 override FPCOPT+=-XP$(BINUTILSPREFIX)
 override FPCOPT+=-XP$(BINUTILSPREFIX)
-override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
 endif
 endif
 ifneq ($(BINUTILSPREFIX),)
 ifneq ($(BINUTILSPREFIX),)
 override FPCOPT+=-Xr$(RLINKPATH)
 override FPCOPT+=-Xr$(RLINKPATH)
 endif
 endif
 endif
 endif
 
 
+# When BINUTILSPREFIX is given and we are not cross-compiling then use
+# it while compiling the fpmake file. (For example to build i386-freebsd
+# with BINUTILSPREFIX=i386-)
+ifndef CROSSCOMPILE
+ifneq ($(BINUTILSPREFIX),)
+override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
+endif
+endif
+
 # User dirs should be first, so they are looked at first
 # User dirs should be first, so they are looked at first
 ifdef UNITDIR
 ifdef UNITDIR
 override FPCOPT+=$(addprefix -Fu,$(UNITDIR))
 override FPCOPT+=$(addprefix -Fu,$(UNITDIR))

+ 166 - 128
utils/fpdoc/Makefile

@@ -1,8 +1,8 @@
 #
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2011/12/30]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2012/06/26]
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-solaris x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded mipsel-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded mipsel-linux
 BSDs = freebsd netbsd openbsd darwin
 BSDs = freebsd netbsd openbsd darwin
 UNIXs = linux $(BSDs) solaris qnx haiku
 UNIXs = linux $(BSDs) solaris qnx haiku
 LIMIT83fs = go32v2 os2 emx watcom
 LIMIT83fs = go32v2 os2 emx watcom
@@ -420,9 +420,15 @@ endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 override TARGET_PROGRAMS+=fpdoc makeskel unitdiff fpclasschart
 override TARGET_PROGRAMS+=fpdoc makeskel unitdiff fpclasschart
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+override TARGET_PROGRAMS+=fpdoc makeskel unitdiff fpclasschart
+endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
 override TARGET_PROGRAMS+=fpdoc makeskel unitdiff fpclasschart
 override TARGET_PROGRAMS+=fpdoc makeskel unitdiff fpclasschart
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+override TARGET_PROGRAMS+=fpdoc makeskel unitdiff fpclasschart
+endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
 override TARGET_PROGRAMS+=fpdoc makeskel unitdiff fpclasschart
 override TARGET_PROGRAMS+=fpdoc makeskel unitdiff fpclasschart
 endif
 endif
@@ -478,382 +484,394 @@ ifeq ($(FULL_TARGET),mipsel-linux)
 override TARGET_PROGRAMS+=fpdoc makeskel unitdiff fpclasschart
 override TARGET_PROGRAMS+=fpdoc makeskel unitdiff fpclasschart
 endif
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 ifeq ($(FULL_TARGET),i386-nativent)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 ifeq ($(FULL_TARGET),powerpc-wii)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 ifeq ($(FULL_TARGET),mipsel-linux)
-override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf
+override CLEAN_UNITS+=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 ifeq ($(FULL_TARGET),i386-nativent)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 ifeq ($(FULL_TARGET),powerpc-wii)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 ifeq ($(FULL_TARGET),mipsel-linux)
-override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+override CLEAN_FILES+=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 endif
 endif
 override INSTALL_FPCPACKAGE=y
 override INSTALL_FPCPACKAGE=y
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
@@ -988,9 +1006,15 @@ endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
@@ -1994,6 +2018,13 @@ REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_CHM=1
+endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
@@ -2001,6 +2032,13 @@ REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_CHM=1
+endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_UNIVINT=1
 REQUIRE_PACKAGES_UNIVINT=1

+ 3 - 3
utils/fpdoc/Makefile.fpc

@@ -12,7 +12,7 @@ packages_darwin=univint
 
 
 [target]
 [target]
 programs=fpdoc makeskel unitdiff fpclasschart
 programs=fpdoc makeskel unitdiff fpclasschart
-rst=dwriter fpdoc dglobals makeskel dwlinear
+rst=dwriter fpdoc dglobals makeskel dwlinear 
 # removed to reduce dependencies of rpm.
 # removed to reduce dependencies of rpm.
 #dirs_linux_i386=fpde
 #dirs_linux_i386=fpde
 #dirs_win32=fpde
 #dirs_win32=fpde
@@ -27,8 +27,8 @@ fpcpackage=y
 fpcdir=../..
 fpcdir=../..
 
 
 [clean]
 [clean]
-units=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf 
-files=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst
+units=dglobals dwriter dw_xml sh_pas dw_html dw_latex dw_ipf dw_txt dw_man dwlinear dw_linrtf dw_dxml fpdocproj fpdocxmlopts mkfpdoc
+files=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 
 
 [rules]
 [rules]
 .NOTPARALLEL:
 .NOTPARALLEL:

+ 55 - 34
utils/fpdoc/dglobals.pp

@@ -145,11 +145,20 @@ resourcestring
   SUsageOption130  = '--output=name     use name as the output name.';
   SUsageOption130  = '--output=name     use name as the output name.';
   SUsageOption140  = '                  Each backend interpretes this as needed.';
   SUsageOption140  = '                  Each backend interpretes this as needed.';
   SUsageOption150  = '--package=name    Set the package name for which to create output';
   SUsageOption150  = '--package=name    Set the package name for which to create output';
+  SUsageOption155  = '--project=file    Use file as project file';  
   SUsageOption160  = '--show-private    Show private methods.';
   SUsageOption160  = '--show-private    Show private methods.';
   SUsageOption170  = '--warn-no-node    Warn if no documentation node was found.';
   SUsageOption170  = '--warn-no-node    Warn if no documentation node was found.';
   SUsageOption180  = '--mo-dir=dir      Set directory where language files reside to dir';
   SUsageOption180  = '--mo-dir=dir      Set directory where language files reside to dir';
   SUsageOption190  = '--parse-impl      (Experimental) try to parse implementation too';
   SUsageOption190  = '--parse-impl      (Experimental) try to parse implementation too';
   SUsageOption200 =  '--dont-trim	Don''t trim XML contents';
   SUsageOption200 =  '--dont-trim	Don''t trim XML contents';
+  SUsageOption210 =  '--write-project=file Do not write documentation, create project file instead';
+  SUsageOption220 =  '--verbose         Write more information on the screen';
+  SUsageOption230 =  '--dry-run         Only parse sources and XML, do not create output';
+  SUsageOption240 =  '--descr-dir=Dir   Add All XML files in Dir to list of description files';
+  SUsageOption250 =  '--input-dir=Dir   Add All *.pp and *.pas files in Dir to list of input files';
+  SUsageOption260 =  '--write-project=file Write all command-line options to a project file';
+  
+
   SUsageFormats        = 'The following output formats are supported by this fpdoc:';
   SUsageFormats        = 'The following output formats are supported by this fpdoc:';
   SUsageBackendHelp    = 'Specify an output format, combined with --help to get more help for this backend.';
   SUsageBackendHelp    = 'Specify an output format, combined with --help to get more help for this backend.';
   SUsageFormatSpecific = 'Output format "%s" supports the following options:';
   SUsageFormatSpecific = 'Output format "%s" supports the following options:';
@@ -173,7 +182,7 @@ type
 
 
   // Assumes a list of TObject instances and frees them on destruction
   // Assumes a list of TObject instances and frees them on destruction
 
 
-  TObjectList = class(TList)
+  TObjectList = class(TFPList)
   public
   public
     destructor Destroy; override;
     destructor Destroy; override;
   end;
   end;
@@ -261,19 +270,24 @@ type
 
 
 
 
   // The main FPDoc engine
   // The main FPDoc engine
+  TFPDocLogLevel = (dleWarnNoNode);
+  TFPDocLogLevels = set of TFPDocLogLevel;
 
 
   { TFPDocEngine }
   { TFPDocEngine }
-
   TFPDocEngine = class(TPasTreeContainer)
   TFPDocEngine = class(TPasTreeContainer)
   private
   private
+    FDocLogLevels: TFPDocLogLevels;
   protected
   protected
     DescrDocs: TObjectList;             // List of XML documents
     DescrDocs: TObjectList;             // List of XML documents
     DescrDocNames: TStringList;         // Names of the XML documents
     DescrDocNames: TStringList;         // Names of the XML documents
     FRootLinkNode: TLinkNode;
     FRootLinkNode: TLinkNode;
     FRootDocNode: TDocNode;
     FRootDocNode: TDocNode;
-    FPackages: TList;                   // List of TFPPackage objects
+    FPackages: TFPList;                   // List of TFPPackage objects
     CurModule: TPasModule;
     CurModule: TPasModule;
     CurPackageDocNode: TDocNode;
     CurPackageDocNode: TDocNode;
+    Function LogEvent(E : TFPDocLogLevel) : Boolean;
+    Procedure DoLog(Const Msg : String);overload;
+    Procedure DoLog(Const Fmt : String; Args : Array of const);overload;
   public
   public
     Output: String;
     Output: String;
     HasContentFile: Boolean;
     HasContentFile: Boolean;
@@ -313,7 +327,7 @@ type
 
 
     property RootLinkNode: TLinkNode read FRootLinkNode;
     property RootLinkNode: TLinkNode read FRootLinkNode;
     property RootDocNode: TDocNode read FRootDocNode;
     property RootDocNode: TDocNode read FRootDocNode;
-    property Package: TPasPackage read FPackage;
+    Property DocLogLevels : TFPDocLogLevels Read FDocLogLevels Write FDocLogLevels;
   end;
   end;
 
 
 
 
@@ -325,6 +339,7 @@ Function IsExampleNode(Example : TDomNode) : Boolean;
 // returns true is link is an absolute URI
 // returns true is link is an absolute URI
 Function IsLinkAbsolute(ALink: String): boolean;
 Function IsLinkAbsolute(ALink: String): boolean;
 
 
+
 implementation
 implementation
 
 
 uses SysUtils, Gettext, XMLRead;
 uses SysUtils, Gettext, XMLRead;
@@ -430,7 +445,7 @@ begin
     { No child found, let's create one if we are at the end of the path }
     { No child found, let's create one if we are at the end of the path }
     if DotPos > 0 then
     if DotPos > 0 then
       // !!!: better throw an exception
       // !!!: better throw an exception
-      WriteLn('Link path does not exist: ', APathName);
+      Raise Exception.CreateFmt('Link path does not exist: %s',[APathName]);
     Result := TLinkNode.Create(ChildName, ALinkTo);
     Result := TLinkNode.Create(ChildName, ALinkTo);
     if Assigned(LastChild) then
     if Assigned(LastChild) then
       LastChild.FNextSibling := Result
       LastChild.FNextSibling := Result
@@ -545,6 +560,22 @@ end;
 
 
 { TFPDocEngine }
 { TFPDocEngine }
 
 
+function TFPDocEngine.LogEvent(E: TFPDocLogLevel): Boolean;
+begin
+  Result:=E in FDocLogLevels;
+end;
+
+procedure TFPDocEngine.DoLog(const Msg: String);
+begin
+  If Assigned(OnLog) then
+    OnLog(Self,Msg);
+end;
+
+procedure TFPDocEngine.DoLog(const Fmt: String; Args: array of const);
+begin
+  DoLog(Format(Fmt,Args));
+end;
+
 constructor TFPDocEngine.Create;
 constructor TFPDocEngine.Create;
 begin
 begin
   inherited Create;
   inherited Create;
@@ -554,7 +585,7 @@ begin
   FRootDocNode := TDocNode.Create('', nil);
   FRootDocNode := TDocNode.Create('', nil);
   HidePrivate := True;
   HidePrivate := True;
   InterfaceOnly:=True;
   InterfaceOnly:=True;
-  FPackages := TList.Create;
+  FPackages := TFPList.Create;
 end;
 end;
 
 
 destructor TFPDocEngine.Destroy;
 destructor TFPDocEngine.Destroy;
@@ -696,7 +727,7 @@ var
      result:=Copy(AName, DotPos2 + 1, length(AName)-dotpos2);
      result:=Copy(AName, DotPos2 + 1, length(AName)-dotpos2);
   end;
   end;
 
 
-  function SearchInList(clslist:TList;s:string):TPasElement;
+  function SearchInList(clslist:TFPList;s:string):TPasElement;
   var i : integer;
   var i : integer;
       ClassEl: TPasElement;
       ClassEl: TPasElement;
   begin
   begin
@@ -793,7 +824,7 @@ var
        end
        end
      else
      else
        if cls<>result then
        if cls<>result then
-         writeln('Warning : ancestor class ',clname,' of class ',cls.name,' could not be resolved');
+         DoLog('Warning : ancestor class %s of class %s could not be resolved',[clname,cls.name]);
 end;
 end;
 
 
 function CreateAliasType (alname,clname : string;parentclass:TPasClassType; out cl2 :TPasClassType):TPasAliasType;
 function CreateAliasType (alname,clname : string;parentclass:TPasClassType; out cl2 :TPasClassType):TPasAliasType;
@@ -853,7 +884,7 @@ end;
                  begin
                  begin
                    // writeln('Found alias pair ',clname,' = ',alname);   
                    // writeln('Found alias pair ',clname,' = ',alname);   
                    if not assigned(CreateAliasType(alname,clname,cls,cls2)) then
                    if not assigned(CreateAliasType(alname,clname,cls,cls2)) then
-                      writeln('Warning: creating alias ',alname,' for ',clname,' failed!');
+                      DoLog('Warning: creating alias %s for %s failed!',[alname,clname]);
                  end 
                  end 
                else
                else
                  cls2:=ResolveAndLinkClass(clname,j=0,cls);
                  cls2:=ResolveAndLinkClass(clname,j=0,cls);
@@ -1084,7 +1115,7 @@ function TFPDocEngine.FindElement(const AName: String): TPasElement;
   function FindInModule(AModule: TPasModule; const LocalName: String): TPasElement;
   function FindInModule(AModule: TPasModule; const LocalName: String): TPasElement;
   
   
   var
   var
-    l: TList;
+    l: TFPList;
     i: Integer;
     i: Integer;
     
     
   begin
   begin
@@ -1104,30 +1135,20 @@ function TFPDocEngine.FindElement(const AName: String): TPasElement;
 
 
 var
 var
   i: Integer;
   i: Integer;
-  //ModuleName, LocalName: String;
   Module: TPasElement;
   Module: TPasElement;
 begin
 begin
-{!!!: Don't know if we ever will have to use the following:
-  i := Pos('.', AName);
-  if i <> 0 then
-  begin
-    WriteLn('Dot found in name: ', AName);
-    Result := nil;
-  end else
-  begin}
-    Result := FindInModule(CurModule, AName);
-    if not Assigned(Result) then
-      for i := CurModule.InterfaceSection.UsesList.Count - 1 downto 0 do
+  Result := FindInModule(CurModule, AName);
+  if not Assigned(Result) then
+    for i := CurModule.InterfaceSection.UsesList.Count - 1 downto 0 do
+    begin
+      Module := TPasElement(CurModule.InterfaceSection.UsesList[i]);
+      if Module.ClassType = TPasModule then
       begin
       begin
-        Module := TPasElement(CurModule.InterfaceSection.UsesList[i]);
-        if Module.ClassType = TPasModule then
-        begin
-          Result := FindInModule(TPasModule(Module), AName);
-          if Assigned(Result) then
-            exit;
-        end;
+        Result := FindInModule(TPasModule(Module), AName);
+        if Assigned(Result) then
+          exit;
       end;
       end;
-  {end;}
+    end;
 end;
 end;
 
 
 function TFPDocEngine.FindModule(const AName: String): TPasModule;
 function TFPDocEngine.FindModule(const AName: String): TPasModule;
@@ -1181,7 +1202,7 @@ function TFPDocEngine.ResolveLink(AModule: TPasModule;
 var
 var
   i: Integer;
   i: Integer;
   ThisPackage: TLinkNode;
   ThisPackage: TLinkNode;
-  UnitList: TList;
+  UnitList: TFPList;
 
 
   function CanWeExit(AResult: string): boolean;
   function CanWeExit(AResult: string): boolean;
   var
   var
@@ -1192,7 +1213,7 @@ var
   end;
   end;
 
 
 begin
 begin
-  system.WriteLn('ResolveLink(', AModule.Name, ' - ', ALinkDest, ')... ');
+  // system.WriteLn('ResolveLink(', AModule.Name, ' - ', ALinkDest, ')... ');
   if Length(ALinkDest) = 0 then
   if Length(ALinkDest) = 0 then
   begin
   begin
     SetLength(Result, 0);
     SetLength(Result, 0);
@@ -1414,7 +1435,7 @@ begin
        WarnNoNode and
        WarnNoNode and
        (Length(AElement.PathName)>0) and
        (Length(AElement.PathName)>0) and
        (AElement.PathName[1]='#') then
        (AElement.PathName[1]='#') then
-      Writeln('No documentation node found for identifier : ',AElement.PathName);
+      DoLog(Format('No documentation node found for identifier : %s',[AElement.PathName]));
     end;
     end;
 end;
 end;
 
 
@@ -1422,7 +1443,7 @@ function TFPDocEngine.FindDocNode(ARefModule: TPasModule;
   const AName: String): TDocNode;
   const AName: String): TDocNode;
 var
 var
   CurPackage: TDocNode;
   CurPackage: TDocNode;
-  UnitList: TList;
+  UnitList: TFPList;
   i: Integer;
   i: Integer;
 begin
 begin
   if Length(AName) = 0 then
   if Length(AName) = 0 then

+ 1 - 1
utils/fpdoc/dw_dxml.pp

@@ -465,7 +465,7 @@ procedure TDocumentation.DoVisit(obj: TPasResString);
 begin
 begin
   WriteLn(f, ' ': lvl * 2, '<resourceString name="' + obj.Name + '">');
   WriteLn(f, ' ': lvl * 2, '<resourceString name="' + obj.Name + '">');
   WriteLn(f, ' ': lvl * 2 + 2, '<value>');
   WriteLn(f, ' ': lvl * 2 + 2, '<value>');
-  WriteLn(f, ' ': lvl * 2 + 4, EscapeXml(obj.Value));
+  WriteLn(f, ' ': lvl * 2 + 4, EscapeXml(obj.GetDeclaration(false)));
   WriteLn(f, ' ': lvl * 2 + 2, '</value>');
   WriteLn(f, ' ': lvl * 2 + 2, '</value>');
   WriteLn(f, ' ': lvl * 2, '</resourceString>');
   WriteLn(f, ' ': lvl * 2, '</resourceString>');
 end;
 end;

+ 71 - 30
utils/fpdoc/dw_html.pp

@@ -503,7 +503,7 @@ constructor THTMLWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
   end;
   end;
 
 
   procedure AddPages(AElement: TPasElement; ASubpageIndex: Integer;
   procedure AddPages(AElement: TPasElement; ASubpageIndex: Integer;
-    AList: TList);
+    AList: TFPList);
   var
   var
     i: Integer;
     i: Integer;
   begin
   begin
@@ -739,7 +739,7 @@ begin
           WriteHTMLFile(PageDoc, Filename);
           WriteHTMLFile(PageDoc, Filename);
         except
         except
 	  on E: Exception do
 	  on E: Exception do
-            WriteLn(Format(SErrCouldNotCreateFile, [FileName, e.Message]));
+            DoLog(SErrCouldNotCreateFile, [FileName, e.Message]);
         end;
         end;
       finally
       finally
         PageDoc.Free;
         PageDoc.Free;
@@ -750,7 +750,7 @@ begin
   begin
   begin
     if not FileExists(FCSSFile) Then
     if not FileExists(FCSSFile) Then
       begin
       begin
-        Writeln(stderr,'Can''t find CSS file "',FCSSFILE,'"');
+        DoLog('Can''t find CSS file "%s"',[FCSSFILE]);
         halt(1);
         halt(1);
       end;
       end;
     TempStream := TMemoryStream.Create;
     TempStream := TMemoryStream.Create;
@@ -1096,8 +1096,12 @@ begin
   s := ResolveLinkID(a);
   s := ResolveLinkID(a);
   if Length(s) = 0 then
   if Length(s) = 0 then
   begin
   begin
-
-    WriteLn(Format(SErrUnknownLinkID, [a]));
+    if assigned(module) then
+      s:=module.name
+    else
+      s:='?';
+    if a='' then a:='<empty>';
+    DoLog(SErrUnknownLinkID, [s,a]);
     PushOutputNode(CreateEl(CurOutputNode, 'b'));
     PushOutputNode(CreateEl(CurOutputNode, 'b'));
   end else
   end else
     PushOutputNode(CreateLink(CurOutputNode, s));
     PushOutputNode(CreateLink(CurOutputNode, s));
@@ -1507,7 +1511,7 @@ function THTMLWriter.AppendHyperlink(Parent: TDOMNode;
   Element: TPasElement): TDOMElement;
   Element: TPasElement): TDOMElement;
 var
 var
   s: String;
   s: String;
-  UnitList: TList;
+  UnitList: TFPList;
   i: Integer;
   i: Integer;
   ThisPackage: TLinkNode;
   ThisPackage: TLinkNode;
 begin
 begin
@@ -2046,7 +2050,12 @@ begin
        s:= ResolveLinkID(l);
        s:= ResolveLinkID(l);
        if Length(s)=0 then
        if Length(s)=0 then
          begin
          begin
-         WriteLn(Format(SErrUnknownLinkID, [l]));
+         if assigned(module) then
+           s:=module.name
+         else
+           s:='?';
+         if l='' then l:='<empty>';
+         DoLog(SErrUnknownLinkID, [s,l]);
          NewEl := CreateEl(ParaEl,'b')
          NewEl := CreateEl(ParaEl,'b')
          end
          end
        else
        else
@@ -2346,7 +2355,7 @@ end;
 
 
 procedure THTMLWriter.AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
 procedure THTMLWriter.AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
 
 
-  Procedure AddElementsFromList(L : TStrings; List : TList);
+  Procedure AddElementsFromList(L : TStrings; List : TFPList);
   
   
   Var
   Var
     I : Integer;
     I : Integer;
@@ -2539,12 +2548,12 @@ procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
       end;
       end;
   end;
   end;
 
 
-  procedure CreateSimpleSubpage(const ATitle: DOMString; AList: TList);
+  procedure CreateSimpleSubpage(const ATitle: DOMString; AList: TFPList);
   var
   var
     TableEl, TREl, TDEl, CodeEl: TDOMElement;
     TableEl, TREl, TDEl, CodeEl: TDOMElement;
     i, j: Integer;
     i, j: Integer;
     Decl: TPasElement;
     Decl: TPasElement;
-    SortedList: TList;
+    SortedList: TFPList;
     DocNode: TDocNode;
     DocNode: TDocNode;
     S : String;
     S : String;
 
 
@@ -2552,7 +2561,7 @@ procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
     AppendMenuBar(ASubpageIndex);
     AppendMenuBar(ASubpageIndex);
     S:=ATitle;
     S:=ATitle;
     AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, S]));
     AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, S]));
-    SortedList := TList.Create;
+    SortedList := TFPList.Create;
     try
     try
       for i := 0 to AList.Count - 1 do
       for i := 0 to AList.Count - 1 do
       begin
       begin
@@ -2598,7 +2607,7 @@ procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
       ParaEl := CreatePara(BodyElement);
       ParaEl := CreatePara(BodyElement);
       AppendText(CreateCode(ParaEl), Decl.Name);
       AppendText(CreateCode(ParaEl), Decl.Name);
       CreateEl(ParaEl, 'br');
       CreateEl(ParaEl, 'br');
-      AppendText(ParaEl, Decl.Value);
+      AppendText(ParaEl, Decl.Expr.getDeclaration(true));
     end;
     end;
   end;
   end;
   
   
@@ -2709,8 +2718,8 @@ begin
         AppendShortDescrCell(TREl, EnumValue);
         AppendShortDescrCell(TREl, EnumValue);
         AppendNbSp(CodeEl, 2);
         AppendNbSp(CodeEl, 2);
         s := EnumValue.Name;
         s := EnumValue.Name;
-        if EnumValue.IsValueUsed then
-          s := s + ' = ' + IntToStr(EnumValue.Value);
+        if EnumValue.AssignedValue<>'' then
+          s := s + ' = ' + EnumValue.AssignedValue;
         if i < TPasEnumType(AType).Values.Count - 1 then
         if i < TPasEnumType(AType).Values.Count - 1 then
           s := s + ',';
           s := s + ',';
         AppendPasSHFragment(CodeEl, s, 0);
         AppendPasSHFragment(CodeEl, s, 0);
@@ -2754,8 +2763,8 @@ begin
           AppendShortDescrCell(TREl, EnumValue);
           AppendShortDescrCell(TREl, EnumValue);
           AppendNbSp(CodeEl, 2);
           AppendNbSp(CodeEl, 2);
           s := EnumValue.Name;
           s := EnumValue.Name;
-          if EnumValue.IsValueUsed then
-            s := s + ' = ' + IntToStr(EnumValue.Value);
+          if (EnumValue.AssignedValue<>'') then
+            s := s + ' = ' + EnumValue.AssignedValue;
           if i < EnumType.Values.Count - 1 then
           if i < EnumType.Values.Count - 1 then
             s := s + ',';
             s := s + ',';
           AppendPasSHFragment(CodeEl, s, 0);
           AppendPasSHFragment(CodeEl, s, 0);
@@ -2828,6 +2837,22 @@ var
     AppendText(ParaEl, '] ');
     AppendText(ParaEl, '] ');
   end;
   end;
 
 
+  procedure AppendGenericTypes(CodeEl : TDomElement; AList : TFPList; isSpecialize : Boolean);
+
+  Var
+    I : integer;
+  begin
+    for I:=0 to AList.Count-1 do
+      begin
+      if I=0 then
+        AppendSym(CodeEl, '<')
+      else
+        AppendSym(CodeEl, ',');
+      AppendText(CodeEl,TPasGenericTemplateType(AList[i]).Name);
+      end;
+    AppendSym(CodeEl, '>');
+  end;
+
   procedure CreateMainPage;
   procedure CreateMainPage;
   var
   var
     TableEl, TREl, TDEl, CodeEl: TDOMElement;
     TableEl, TREl, TDEl, CodeEl: TDOMElement;
@@ -2858,24 +2883,39 @@ var
     TDEl := CreateTD(TREl);
     TDEl := CreateTD(TREl);
     CodeEl := CreateCode(CreatePara(TDEl));
     CodeEl := CreateCode(CreatePara(TDEl));
     AppendKw(CodeEl, 'type');
     AppendKw(CodeEl, 'type');
+    if AClass.ObjKind=okGeneric then
+      AppendKw(CodeEl, ' generic ');
     AppendText(CodeEl, ' ' + AClass.Name + ' ');
     AppendText(CodeEl, ' ' + AClass.Name + ' ');
+    if AClass.ObjKind=okGeneric then
+      AppendGenericTypes(CodeEl,AClass.GenericTemplateTypes,false);
     AppendSym(CodeEl, '=');
     AppendSym(CodeEl, '=');
     AppendText(CodeEl, ' ');
     AppendText(CodeEl, ' ');
-    AppendKw(CodeEl, ObjKindNames[AClass.ObjKind]);
+    if AClass.ObjKind<>okSpecialize then
+      AppendKw(CodeEl, ObjKindNames[AClass.ObjKind])
+    else
+      AppendKw(CodeEl, ' specialize ');
 
 
     if Assigned(AClass.AncestorType) then
     if Assigned(AClass.AncestorType) then
     begin
     begin
-      AppendSym(CodeEl, '(');
-      AppendHyperlink(CodeEl, AClass.AncestorType);
-      if AClass.Interfaces.count>0 Then
+      if AClass.ObjKind=okSpecialize then
+        begin
+        AppendHyperlink(CodeEl, AClass.AncestorType);
+        AppendGenericTypes(CodeEl,AClass.GenericTemplateTypes,true)
+        end
+      else
         begin
         begin
-          for i:=0 to AClass.interfaces.count-1 do
-           begin
-             AppendSym(CodeEl, ', ');
-             AppendHyperlink(CodeEl,TPasClassType(AClass.Interfaces[i]));
-           end; 
+        AppendSym(CodeEl, '(');
+        AppendHyperlink(CodeEl, AClass.AncestorType);
+        if AClass.Interfaces.count>0 Then
+          begin
+            for i:=0 to AClass.interfaces.count-1 do
+             begin
+               AppendSym(CodeEl, ', ');
+               AppendHyperlink(CodeEl,TPasClassType(AClass.Interfaces[i]));
+             end;
+          end;
+        AppendSym(CodeEl, ')');
         end;
         end;
-      AppendSym(CodeEl, ')');
     end;
     end;
 
 
     if AClass.Members.Count > 0 then
     if AClass.Members.Count > 0 then
@@ -2965,7 +3005,8 @@ var
     end;
     end;
 
 
     AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
     AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
-    AppendKw(CodeEl, 'end');
+    if not AClass.IsShortDefinition then
+      AppendKw(CodeEl, 'end');
     AppendSym(CodeEl, ';');
     AppendSym(CodeEl, ';');
 
 
 
 
@@ -3093,13 +3134,13 @@ var
 
 
   procedure CreateSortedSubpage(AFilter: TMemberFilter);
   procedure CreateSortedSubpage(AFilter: TMemberFilter);
   var
   var
-    List: TList;
+    List: TFPList;
     ThisClass: TPasClassType;
     ThisClass: TPasClassType;
     i, j: Integer;
     i, j: Integer;
     Member: TPasElement;
     Member: TPasElement;
     TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
     TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
   begin
   begin
-    List := TList.Create;
+    List := TFPList.Create;
     try
     try
       ThisClass := AClass;
       ThisClass := AClass;
       while True do
       while True do
@@ -3393,7 +3434,7 @@ end;
 
 
 procedure THTMLWriter.WriteDoc;
 procedure THTMLWriter.WriteDoc;
 begin
 begin
-   WriteLn(Format(SWritingPages, [PageCount]));
+   DoLog(SWritingPages, [PageCount]);
    WriteHTMLPages;
    WriteHTMLPages;
 end;
 end;
 
 

+ 3 - 3
utils/fpdoc/dw_man.pp

@@ -91,7 +91,7 @@ Type
     procedure WriteManRef(APasElement : TPasElement; Comma : Boolean);
     procedure WriteManRef(APasElement : TPasElement; Comma : Boolean);
     procedure WriteModuleSeealso(Comma : Boolean);
     procedure WriteModuleSeealso(Comma : Boolean);
 
 
-    procedure SortElementList(List : TList);
+    procedure SortElementList(List : TFPList);
     Function  GetDescrString(AContext: TPasElement; DescrNode: TDOMElement) : String;
     Function  GetDescrString(AContext: TPasElement; DescrNode: TDOMElement) : String;
     function  ConstValue(ConstDecl: TPasConst): String; virtual;
     function  ConstValue(ConstDecl: TPasConst): String; virtual;
     procedure WriteCommentLine;
     procedure WriteCommentLine;
@@ -192,7 +192,7 @@ constructor TManWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
     Engine.AddLink(AElement.PathName, ElementToManPage(AElement));
     Engine.AddLink(AElement.PathName, ElementToManPage(AElement));
   end;
   end;
 
 
-  procedure AddList(AElement: TPasElement; AList: TList);
+  procedure AddList(AElement: TPasElement; AList: TFPList);
   var
   var
     i: Integer;
     i: Integer;
   begin
   begin
@@ -1722,7 +1722,7 @@ begin
   Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
   Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
 end;
 end;
 
 
-procedure TManWriter.SortElementList(List : TList);
+procedure TManWriter.SortElementList(List : TFPList);
 
 
 begin
 begin
   List.Sort(@CompareElements);
   List.Sort(@CompareElements);

+ 9 - 7
utils/fpdoc/dwlinear.pp

@@ -34,7 +34,7 @@ Type
     // Auxiliary routines
     // Auxiliary routines
     procedure DescrBeginURL(const AURL: DOMString); override; // Provides a default implementation
     procedure DescrBeginURL(const AURL: DOMString); override; // Provides a default implementation
     procedure DescrEndURL; override;
     procedure DescrEndURL; override;
-    procedure SortElementList(List : TList);
+    procedure SortElementList(List : TFPList);
     procedure StartListing(Frames: Boolean);
     procedure StartListing(Frames: Boolean);
     Function  ShowMember(M : TPasElement) : boolean;
     Function  ShowMember(M : TPasElement) : boolean;
     procedure StartChapter(ChapterName : String; ChapterLabel : String); virtual;
     procedure StartChapter(ChapterName : String; ChapterLabel : String); virtual;
@@ -877,10 +877,12 @@ begin
       WriteLabel(TypeDecl);
       WriteLabel(TypeDecl);
       WriteIndex(TypeDecl);
       WriteIndex(TypeDecl);
       If TypeDecl is TPasEnumType then
       If TypeDecl is TPasEnumType then
-        begin
-        WriteENumElements(TypeDecl as TPasEnumType);
-        end;
-      WriteDescr(TypeDecl);
+        WriteENumElements(TypeDecl as TPasEnumType)
+      else If (TypeDecl is TPasSetType)
+              and (TPasSetType(TypeDecl).EnumType is TPasEnumType)
+              and (TPasSetType(TypeDecl).EnumType.Name='') then
+        WriteENumElements(TPasSetType(TypeDecl).EnumType as TPasEnumType);
+      WriteDescr(TypeDecl,DocNode);
       If Assigned(DocNode) and Assigned(DocNode.Version) then
       If Assigned(DocNode) and Assigned(DocNode.Version) then
         begin
         begin
         Writeln(Format('%s : ',[SDocVersion]));
         Writeln(Format('%s : ',[SDocVersion]));
@@ -1152,7 +1154,7 @@ begin
   Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
   Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
 end;
 end;
 
 
-procedure TLinearWriter.SortElementList(List : TList);
+procedure TLinearWriter.SortElementList(List : TFPList);
 
 
 begin
 begin
   List.Sort(@CompareElements);
   List.Sort(@CompareElements);
@@ -1227,7 +1229,7 @@ constructor TLinearWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
     Engine.AddLink(AElement.PathName, GetLabel(AElement));
     Engine.AddLink(AElement.PathName, GetLabel(AElement));
   end;
   end;
 
 
-  procedure AddList(AElement: TPasElement; AList: TList);
+  procedure AddList(AElement: TPasElement; AList: TFPList);
   var
   var
     i: Integer;
     i: Integer;
   begin
   begin

+ 19 - 4
utils/fpdoc/dwriter.pp

@@ -45,7 +45,7 @@ resourcestring
 
 
   SErrDescrTagUnknown = 'Warning: Unknown tag "%s" in description';
   SErrDescrTagUnknown = 'Warning: Unknown tag "%s" in description';
   SErrUnknownEntityReference = 'Warning: Unknown entity reference "&%s;" found';
   SErrUnknownEntityReference = 'Warning: Unknown entity reference "&%s;" found';
-  SErrUnknownLinkID = 'Warning: Target ID of <link> is unknown: "%s"';
+  SErrUnknownLinkID = 'Warning: Target ID of <link> in unit "%s" is unknown: "%s"';
   SErrUnknownPrintShortID = 'Warning: Target ID of <printshort> is unknown: "%s"';
   SErrUnknownPrintShortID = 'Warning: Target ID of <printshort> is unknown: "%s"';
   SErrUnknownLink = 'Could not resolve link to "%s"';
   SErrUnknownLink = 'Could not resolve link to "%s"';
   SErralreadyRegistered = 'Class for output format "%s" already registered';
   SErralreadyRegistered = 'Class for output format "%s" already registered';
@@ -63,6 +63,8 @@ type
     Destructor Destroy; override;
     Destructor Destroy; override;
   end;
   end;
 
 
+  TWriterLogEvent = Procedure(Sender : TObject; Const Msg : String) of object;
+
   { TFPDocWriter }
   { TFPDocWriter }
 
 
   TFPDocWriter = class
   TFPDocWriter = class
@@ -74,6 +76,8 @@ type
     procedure ConvertURL(AContext: TPasElement; El: TDOMElement);
     procedure ConvertURL(AContext: TPasElement; El: TDOMElement);
     
     
   protected
   protected
+    Procedure DoLog(Const Msg : String);
+    Procedure DoLog(Const Fmt : String; Args : Array of const);
     procedure Warning(AContext: TPasElement; const AMsg: String);
     procedure Warning(AContext: TPasElement; const AMsg: String);
     procedure Warning(AContext: TPasElement; const AMsg: String;
     procedure Warning(AContext: TPasElement; const AMsg: String;
       const Args: array of const);
       const Args: array of const);
@@ -370,7 +374,7 @@ end;
 Procedure TFPDocWriter.DescrWriteImageEl(const AFileName, ACaption,ALinkName : DOMString); 
 Procedure TFPDocWriter.DescrWriteImageEl(const AFileName, ACaption,ALinkName : DOMString); 
 
 
 begin
 begin
-  system.writeln(ClassName,': No support for images yet: ',AFileName,' (caption: "',ACaption,'")');
+  DoLog('%s : No support for images yet: %s (caption: "%s")',[ClassName,AFileName,ACaption]);
 end;
 end;
 
 
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
@@ -388,9 +392,9 @@ end;
 procedure TFPDocWriter.Warning(AContext: TPasElement; const AMsg: String);
 procedure TFPDocWriter.Warning(AContext: TPasElement; const AMsg: String);
 begin
 begin
   if (AContext<>nil) then
   if (AContext<>nil) then
-    WriteLn('[', AContext.PathName, '] ', AMsg)
+    DoLog('[%s] %s',[AContext.PathName,AMsg])
   else
   else
-    WriteLn('[<no context>] ', AMsg);
+    DoLog('[<no context>] %s', [AMsg]);
 end;
 end;
 
 
 procedure TFPDocWriter.Warning(AContext: TPasElement; const AMsg: String;
 procedure TFPDocWriter.Warning(AContext: TPasElement; const AMsg: String;
@@ -612,6 +616,17 @@ begin
   DescrEndURL;
   DescrEndURL;
 end;
 end;
 
 
+procedure TFPDocWriter.DoLog(const Msg: String);
+begin
+  If Assigned(FEngine.OnLog) then
+    FEngine.OnLog(Self,Msg);
+end;
+
+procedure TFPDocWriter.DoLog(const Fmt: String; Args: array of const);
+begin
+  DoLog(Format(Fmt,Args));
+end;
+
 function TFPDocWriter.ConvertExtShort(AContext: TPasElement;
 function TFPDocWriter.ConvertExtShort(AContext: TPasElement;
   Node: TDOMNode): Boolean;
   Node: TDOMNode): Boolean;
 begin
 begin

+ 1 - 1
utils/fpdoc/fpclasschart.pp

@@ -35,7 +35,7 @@ resourcestring
 
 
 Const
 Const
   RootNames : Array[TPasObjKind] of string
   RootNames : Array[TPasObjKind] of string
-            = ('Objects', 'Classes', 'Interfaces');
+            = ('Objects', 'Classes', 'Interfaces','Generics','Specializations');
 
 
 type
 type
 
 

+ 12 - 8
utils/fpdoc/fpdoc.lpi

@@ -13,7 +13,6 @@
       <Title Value="FPDoc Documentation generator"/>
       <Title Value="FPDoc Documentation generator"/>
       <ResourceType Value="res"/>
       <ResourceType Value="res"/>
       <UseXPManifest Value="True"/>
       <UseXPManifest Value="True"/>
-      <Icon Value="0"/>
     </General>
     </General>
     <i18n>
     <i18n>
       <EnableI18N LFM="False"/>
       <EnableI18N LFM="False"/>
@@ -41,7 +40,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item1>
       </Item1>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="14">
+    <Units Count="15">
       <Unit0>
       <Unit0>
         <Filename Value="fpdoc.pp"/>
         <Filename Value="fpdoc.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -60,7 +59,7 @@
       <Unit3>
       <Unit3>
         <Filename Value="dw_html.pp"/>
         <Filename Value="dw_html.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="dw_html"/>
+        <UnitName Value="dw_HTML"/>
       </Unit3>
       </Unit3>
       <Unit4>
       <Unit4>
         <Filename Value="dw_ipflin.pas"/>
         <Filename Value="dw_ipflin.pas"/>
@@ -70,7 +69,7 @@
       <Unit5>
       <Unit5>
         <Filename Value="dw_latex.pp"/>
         <Filename Value="dw_latex.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="dw_latex"/>
+        <UnitName Value="dw_LaTeX"/>
       </Unit5>
       </Unit5>
       <Unit6>
       <Unit6>
         <Filename Value="dwlinear.pp"/>
         <Filename Value="dwlinear.pp"/>
@@ -80,7 +79,7 @@
       <Unit7>
       <Unit7>
         <Filename Value="dw_linrtf.pp"/>
         <Filename Value="dw_linrtf.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="dw_linrtf"/>
+        <UnitName Value="dw_LinRTF"/>
       </Unit7>
       </Unit7>
       <Unit8>
       <Unit8>
         <Filename Value="dw_man.pp"/>
         <Filename Value="dw_man.pp"/>
@@ -90,7 +89,7 @@
       <Unit9>
       <Unit9>
         <Filename Value="dwriter.pp"/>
         <Filename Value="dwriter.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="dwriter"/>
+        <UnitName Value="dWriter"/>
       </Unit9>
       </Unit9>
       <Unit10>
       <Unit10>
         <Filename Value="dw_txt.pp"/>
         <Filename Value="dw_txt.pp"/>
@@ -100,7 +99,7 @@
       <Unit11>
       <Unit11>
         <Filename Value="dw_xml.pp"/>
         <Filename Value="dw_xml.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="dw_xml"/>
+        <UnitName Value="dw_XML"/>
       </Unit11>
       </Unit11>
       <Unit12>
       <Unit12>
         <Filename Value="fpdocproj.pas"/>
         <Filename Value="fpdocproj.pas"/>
@@ -112,10 +111,15 @@
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="fpdocxmlopts"/>
         <UnitName Value="fpdocxmlopts"/>
       </Unit13>
       </Unit13>
+      <Unit14>
+        <Filename Value="mkfpdoc.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="mkfpdoc"/>
+      </Unit14>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>
-    <Version Value="9"/>
+    <Version Value="11"/>
     <Target>
     <Target>
       <Filename Value="fpdoc"/>
       <Filename Value="fpdoc"/>
     </Target>
     </Target>

+ 88 - 110
utils/fpdoc/fpdoc.pp

@@ -16,7 +16,7 @@
 program FPDoc;
 program FPDoc;
 
 
 uses
 uses
-  SysUtils, Classes, Gettext, DOM, XMLWrite, PasTree, PParser, custapp,
+  SysUtils, Classes, Gettext, custapp,
   dGlobals,  // GLobal definitions, constants.
   dGlobals,  // GLobal definitions, constants.
   dwriter,   // TFPDocWriter definition.
   dwriter,   // TFPDocWriter definition.
   dwlinear,  // Linear (abstract) writer
   dwlinear,  // Linear (abstract) writer
@@ -27,13 +27,8 @@ uses
   dw_ipflin, // IPF writer (new linear output)
   dw_ipflin, // IPF writer (new linear output)
   dw_man,    // Man page writer
   dw_man,    // Man page writer
   dw_linrtf, // linear RTF writer
   dw_linrtf, // linear RTF writer
-  dw_txt, fpdocproj, fpdocxmlopts;    // TXT writer
+  dw_txt, fpdocproj, mkfpdoc;    // TXT writer
 
 
-const
-  DefOSTarget    = {$I %FPCTARGETOS%};
-  DefCPUTarget   = {$I %FPCTARGETCPU%};
-  DefFPCVersion  = {$I %FPCVERSION%};
-  DefFPCDate     = {$I %FPCDATE%};
 
 
 Type
 Type
 
 
@@ -41,14 +36,16 @@ Type
 
 
   TFPDocAplication = Class(TCustomApplication)
   TFPDocAplication = Class(TCustomApplication)
   private
   private
-    FProject : TFPDocProject;
-    FProjectFile : Boolean;
+    FCreator : TFPDocCreator;
     FPackage : TFPDocPackage;
     FPackage : TFPDocPackage;
+    FDryRun,
+    FProjectFile : Boolean;
+    FWriteProjectFile : String;
   Protected
   Protected
+    procedure OutputLog(Sender: TObject; const Msg: String);
     procedure ParseCommandLine;
     procedure ParseCommandLine;
     procedure Parseoption(const S: String);
     procedure Parseoption(const S: String);
     Procedure Usage(AnExitCode : Byte);
     Procedure Usage(AnExitCode : Byte);
-    procedure CreateDocumentation(APackage : TFPDocPackage; Options : TEngineOptions);
     Procedure DoRun; override;
     Procedure DoRun; override;
   Public
   Public
     Constructor Create(AOwner : TComponent); override;
     Constructor Create(AOwner : TComponent); override;
@@ -83,14 +80,21 @@ begin
   Writeln(SUsageOption130);
   Writeln(SUsageOption130);
   Writeln(SUsageOption140);
   Writeln(SUsageOption140);
   Writeln(SUsageOption150);
   Writeln(SUsageOption150);
+  Writeln(SUsageOption155);
   Writeln(SUsageOption160);
   Writeln(SUsageOption160);
   Writeln(SUsageOption170);
   Writeln(SUsageOption170);
   Writeln(SUsageOption180);
   Writeln(SUsageOption180);
   Writeln(SUsageOption190);
   Writeln(SUsageOption190);
   Writeln(SUsageOption200);
   Writeln(SUsageOption200);
+  Writeln(SUsageOption210);
+  Writeln(SUsageOption220);
+  Writeln(SUsageOption230);
+  Writeln(SUsageOption240);
+  Writeln(SUsageOption250);
+  Writeln(SUsageOption260);
   L:=TStringList.Create;
   L:=TStringList.Create;
   Try
   Try
-    Backend:=FProject.OPtions.Backend;
+    Backend:=FCreator.OPtions.Backend;
     If (Backend='') then
     If (Backend='') then
       begin
       begin
       Writeln;
       Writeln;
@@ -126,7 +130,7 @@ end;
 destructor TFPDocAplication.Destroy;
 destructor TFPDocAplication.Destroy;
 
 
 begin
 begin
-  FreeAndNil(FProject);
+  FreeAndNil(FCreator);
   Inherited;
   Inherited;
 end;
 end;
 
 
@@ -140,6 +144,10 @@ begin
     end;
     end;
 end;
 end;
 
 
+procedure TFPDocAplication.OutputLog(Sender: TObject; const Msg: String);
+begin
+  Writeln(StdErr,Msg);
+end;
 
 
 procedure TFPDocAplication.ParseCommandLine;
 procedure TFPDocAplication.ParseCommandLine;
 
 
@@ -166,14 +174,14 @@ begin
     s:=ParamStr(I);
     s:=ParamStr(I);
     If ProjectOpt(S) then
     If ProjectOpt(S) then
       ParseOption(s);
       ParseOption(s);
-    If (FProject.Packages.Count=1) then
-      FPackage:=FProject.Packages[0]
-    else if (FProject.Options.DefaultPackageName<>'') then
-      Fpackage:=FProject.Packages.FindPackage(FProject.Options.DefaultPackageName);
+    If (FCreator.Packages.Count=1) then
+      FPackage:=FCreator.Packages[0]
+    else if (FCreator.Options.DefaultPackageName<>'') then
+      Fpackage:=FCreator.Packages.FindPackage(FCreator.Options.DefaultPackageName);
     end;
     end;
-  If FProject.Packages.Count=0 then
+  If FCreator.Project.Packages.Count=0 then
     begin
     begin
-    FPackage:=FProject.Packages.Add as  TFPDocPackage;
+    FPackage:=FCreator.Packages.Add as  TFPDocPackage;
     end;
     end;
   // Check package
   // Check package
   for i := 1 to ParamCount do
   for i := 1 to ParamCount do
@@ -188,15 +196,38 @@ begin
     If Not (ProjectOpt(s) or PackageOpt(S)) then
     If Not (ProjectOpt(s) or PackageOpt(S)) then
       ParseOption(s);
       ParseOption(s);
     end;
     end;
-  if (FPackage=Nil) or (FPackage.Name='') then
-    begin
-    Writeln(SNeedPackageName);
-    Usage(1);
-    end;
+  SelectedPackage; // Will print error if none available.
 end;
 end;
 
 
 procedure TFPDocAplication.Parseoption(Const S : String);
 procedure TFPDocAplication.Parseoption(Const S : String);
 
 
+  procedure AddDirToFileList(List: TStrings; const ADirName, AMask: String);
+
+  Var
+    Info : TSearchRec;
+    D : String;
+
+  begin
+    if (ADirName<>'') and not DirectoryExists(ADirName) then
+       OutputLog(Self,'Directory '+ADirName+' does not exist')
+    else
+      begin
+      if (ADirName='.') or (ADirName='') then
+        D:=''
+      else
+        D:=IncludeTrailingPathDelimiter(ADirName);
+      If (FindFirst(D+AMask,0,Info)=0) then
+        try
+          Repeat
+            If (Info.Attr and faDirectory)=0 then
+              List.Add(D+Info.name);
+          Until FindNext(Info)<>0;
+        finally
+          FindClose(Info);
+        end;
+      end;
+  end;
+
   procedure AddToFileList(List: TStrings; const FileName: String);
   procedure AddToFileList(List: TStrings; const FileName: String);
   var
   var
     f: Text;
     f: Text;
@@ -224,15 +255,15 @@ begin
   if (s = '-h') or (s = '--help') then
   if (s = '-h') or (s = '--help') then
     Usage(0)
     Usage(0)
   else if s = '--hide-protected' then
   else if s = '--hide-protected' then
-    FProject.Options.HideProtected := True
+    FCreator.Options.HideProtected := True
   else if s = '--warn-no-node' then
   else if s = '--warn-no-node' then
-    FProject.Options.WarnNoNode := True
+    FCreator.Options.WarnNoNode := True
   else if s = '--show-private' then
   else if s = '--show-private' then
-    FProject.Options.ShowPrivate := False
+    FCreator.Options.ShowPrivate := False
   else if s = '--stop-on-parser-error' then
   else if s = '--stop-on-parser-error' then
-    FProject.Options.StopOnParseError := True
+    FCreator.Options.StopOnParseError := True
   else if s = '--dont-trim' then
   else if s = '--dont-trim' then
-    FProject.Options.donttrim := True
+    FCreator.Options.donttrim := True
   else
   else
     begin
     begin
     i := Pos('=', s);
     i := Pos('=', s);
@@ -249,29 +280,35 @@ begin
     if (Cmd = '--project') or (Cmd='-p') then
     if (Cmd = '--project') or (Cmd='-p') then
       begin
       begin
       FProjectFile:=True;
       FProjectFile:=True;
-      With TXMLFPDocOptions.Create(self) do
-        try
-          LoadOptionsFromFile(FProject,Arg);
-        finally
-          Free;
-        end;
+      FCreator.LoadProjectFile(Arg);
       end
       end
     else if (Cmd = '--descr') then
     else if (Cmd = '--descr') then
       AddToFileList(SelectedPackage.Descriptions, Arg)
       AddToFileList(SelectedPackage.Descriptions, Arg)
+    else if (Cmd = '--descr-dir') then
+      AddDirToFileList(SelectedPackage.Descriptions, Arg, '*.xml')
     else if (Cmd = '-f') or (Cmd = '--format') then
     else if (Cmd = '-f') or (Cmd = '--format') then
       begin
       begin
       Arg:=UpperCase(Arg);
       Arg:=UpperCase(Arg);
       If FindWriterClass(Arg)=-1 then
       If FindWriterClass(Arg)=-1 then
         WriteLn(StdErr, Format(SCmdLineInvalidFormat, [Arg]))
         WriteLn(StdErr, Format(SCmdLineInvalidFormat, [Arg]))
       else
       else
-        FProject.Options.BackEnd:=Arg;
+        FCreator.Options.BackEnd:=Arg;
       end
       end
     else if (Cmd = '-l') or (Cmd = '--lang') then
     else if (Cmd = '-l') or (Cmd = '--lang') then
-      FProject.Options.Language := Arg
+      FCreator.Options.Language := Arg
     else if (Cmd = '-i') or (Cmd = '--input') then
     else if (Cmd = '-i') or (Cmd = '--input') then
       AddToFileList(SelectedPackage.Inputs, Arg)
       AddToFileList(SelectedPackage.Inputs, Arg)
+    else if (Cmd = '--input-dir') then
+      begin
+      AddDirToFileList(SelectedPackage.Inputs, Arg,'*.pp');
+      AddDirToFileList(SelectedPackage.Inputs, Arg,'*.pas');
+      end
     else if (Cmd = '-o') or (Cmd = '--output') then
     else if (Cmd = '-o') or (Cmd = '--output') then
       SelectedPackage.Output := Arg
       SelectedPackage.Output := Arg
+    else if (Cmd = '-v') or (Cmd = '--verbose') then
+      FCreator.Verbose:=true
+    else if (Cmd = '-n') or (Cmd = '--dry-run') then
+      FDryRun:=True
     else if Cmd = '--content' then
     else if Cmd = '--content' then
       SelectedPackage.ContentFile := Arg
       SelectedPackage.ContentFile := Arg
     else if Cmd = '--import' then
     else if Cmd = '--import' then
@@ -279,88 +316,28 @@ begin
     else if Cmd = '--package' then
     else if Cmd = '--package' then
       begin
       begin
       If FProjectFile then
       If FProjectFile then
-        FPackage:=FProject.Packages.FindPackage(Arg)
+        FPackage:=FCreator.Packages.FindPackage(Arg)
       else
       else
         FPackage.Name:=Arg;
         FPackage.Name:=Arg;
       end
       end
     else if Cmd = '--ostarget' then
     else if Cmd = '--ostarget' then
-      FProject.Options.OSTarget := Arg
+      FCreator.Options.OSTarget := Arg
     else if Cmd = '--cputarget' then
     else if Cmd = '--cputarget' then
-      FProject.Options.CPUTarget := Arg
+      FCreator.Options.CPUTarget := Arg
     else if Cmd = '--mo-dir' then
     else if Cmd = '--mo-dir' then
-      FProject.Options.modir := Arg
+      FCreator.Options.modir := Arg
     else if Cmd = '--parse-impl' then
     else if Cmd = '--parse-impl' then
-      FProject.Options.InterfaceOnly:=false
+      FCreator.Options.InterfaceOnly:=false
+    else if Cmd = '--write-project' then
+      FWriteProjectFile:=Arg
     else
     else
       begin
       begin
-      FProject.Options.BackendOptions.Add(Cmd);
-      FProject.Options.BackendOptions.Add(Arg);
+      FCreator.Options.BackendOptions.Add(Cmd);
+      FCreator.Options.BackendOptions.Add(Arg);
       end;
       end;
     end;
     end;
 end;
 end;
 
 
-
-procedure TFPDocAplication.CreateDocumentation(APackage : TFPDocPackage; Options : TEngineOptions);
-
-var
-  i,j: Integer;
-  WriterClass : TFPDocWriterClass;
-  Writer : TFPDocWriter;
-  Engine : TFPDocEngine;
-  Cmd,Arg : String;
-
-begin
-  Engine:=TFPDocEngine.Create;
-  try
-    For J:=0 to Apackage.Imports.Count-1 do
-      begin
-      Arg:=Apackage.Imports[j];
-      i := Pos(',', Arg);
-      Engine.ReadContentFile(Copy(Arg,1,i-1),Copy(Arg,i+1,Length(Arg)));
-      end;
-    for i := 0 to APackage.Descriptions.Count - 1 do
-      Engine.AddDocFile(APackage.Descriptions[i],Options.donttrim);
-    Engine.SetPackageName(APackage.Name);
-    Engine.Output:=APackage.Output;
-    Engine.HideProtected:=Options.HideProtected;
-    Engine.HidePrivate:=Not Options.ShowPrivate;
-    if Length(Options.Language) > 0 then
-      TranslateDocStrings(Options.Language);
-    for i := 0 to Fpackage.Inputs.Count - 1 do
-      try
-        ParseSource(Engine, APackage.Inputs[i], Options.OSTarget, Options.CPUTarget);
-      except
-        on e: EParserError do
-          If Options.StopOnParseError then
-            Raise
-          else
-            WriteLn(StdErr, Format('%s(%d,%d): %s',
-                    [e.Filename, e.Row, e.Column, e.Message]));
-      end;
-    WriterClass:=GetWriterClass(Options.Backend);
-    Writer:=WriterClass.Create(Engine.Package,Engine);
-    With Writer do
-      Try
-        If Options.BackendOptions.Count>0 then
-          for I:=0 to ((Options.BackendOptions.Count-1) div 2) do
-            begin
-            Cmd:=Options.BackendOptions[I*2];
-            Arg:=Options.BackendOptions[I*2+1];
-            If not InterPretOption(Cmd,Arg) then
-              WriteLn(StdErr, Format(SCmdLineInvalidOption,[Cmd+'='+Arg]));
-            end;
-        WriteDoc;
-      Finally
-        Free;
-      end;
-    if Length(FPackage.ContentFile) > 0 then
-      Engine.WriteContentFile(FPackage.ContentFile);
-  finally
-    FreeAndNil(Engine);
-  end;
-end;
-
-
 Procedure TFPDocAplication.DoRun;
 Procedure TFPDocAplication.DoRun;
 
 
 begin
 begin
@@ -374,7 +351,10 @@ begin
   WriteLn(SCopyright);
   WriteLn(SCopyright);
   WriteLn;
   WriteLn;
   ParseCommandLine;
   ParseCommandLine;
-  CreateDocumentation(FPackage,FProject.Options);
+  if (FWriteProjectFile<>'') then
+    FCreator.CreateProjectFile(FWriteProjectFile)
+  else
+    FCreator.CreateDocumentation(FPackage,FDryRun);
   WriteLn(SDone);
   WriteLn(SDone);
   Terminate;
   Terminate;
 end;
 end;
@@ -383,10 +363,8 @@ constructor TFPDocAplication.Create(AOwner: TComponent);
 begin
 begin
   inherited Create(AOwner);
   inherited Create(AOwner);
   StopOnException:=true;
   StopOnException:=true;
-  FProject:=TFPDOCproject.Create(Nil);
-  FProject.Options.StopOnParseError:=False;
-  FProject.Options.CPUTarget:=DefCPUTarget;
-  FProject.Options.OSTarget:=DefOSTarget;
+  FCreator:=TFPDocCreator.Create(Self);
+  FCreator.OnLog:=@OutputLog;
 end;
 end;
 
 
 begin
 begin

+ 239 - 28
utils/fpdoc/fpdocxmlopts.pas

@@ -5,36 +5,53 @@ unit fpdocxmlopts;
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, fpdocproj, dom;
+  Classes, SysUtils, fpdocproj, dom, fptemplate;
 
 
 Type
 Type
-
-  { TXMLFPocOptions }
-
   { TXMLFPDocOptions }
   { TXMLFPDocOptions }
 
 
   TXMLFPDocOptions = Class(TComponent)
   TXMLFPDocOptions = Class(TComponent)
+  private
   Protected
   Protected
     Procedure Error(Const Msg : String);
     Procedure Error(Const Msg : String);
     Procedure Error(Const Fmt : String; Args : Array of Const);
     Procedure Error(Const Fmt : String; Args : Array of Const);
     Procedure LoadPackage(APackage : TFPDocPackage; E : TDOMElement); virtual;
     Procedure LoadPackage(APackage : TFPDocPackage; E : TDOMElement); virtual;
     Procedure LoadPackages(Packages : TFPDocPackages; E : TDOMElement);
     Procedure LoadPackages(Packages : TFPDocPackages; E : TDOMElement);
     Procedure LoadEngineOptions(Options : TEngineOptions; E : TDOMElement); virtual;
     Procedure LoadEngineOptions(Options : TEngineOptions; E : TDOMElement); virtual;
+    Procedure SaveEngineOptions(Options : TEngineOptions; XML : TXMLDocument; AParent : TDOMElement); virtual;
+    procedure SaveDescription(const ADescription: String; XML: TXMLDocument;  AParent: TDOMElement); virtual;
+    procedure SaveImportFile(const AImportFile: String; XML: TXMLDocument; AParent: TDOMElement);virtual;
+    procedure SaveInputFile(const AInputFile: String; XML: TXMLDocument; AParent: TDOMElement);virtual;
+    Procedure SavePackage(APackage : TFPDocPackage; XML : TXMLDocument; AParent : TDOMElement); virtual;
   Public
   Public
     Procedure LoadOptionsFromFile(AProject : TFPDocProject; Const AFileName : String);
     Procedure LoadOptionsFromFile(AProject : TFPDocProject; Const AFileName : String);
     Procedure LoadFromXML(AProject : TFPDocProject; XML : TXMLDocument); virtual;
     Procedure LoadFromXML(AProject : TFPDocProject; XML : TXMLDocument); virtual;
+    Procedure SaveOptionsToFile(AProject : TFPDocProject; Const AFileName : String);
+    procedure SaveToXML(AProject : TFPDocProject; ADoc: TXMLDocument); virtual;
   end;
   end;
   EXMLFPdoc = Class(Exception);
   EXMLFPdoc = Class(Exception);
 
 
+Function IndexOfString(S : String; List : Array of string) : Integer;
+
+Const
+  OptionCount = 11;
+  OptionNames : Array[0..OptionCount] of string
+         = ('hide-protected','warn-no-node','show-private',
+            'stop-on-parser-error', 'ostarget','cputarget',
+            'mo-dir','parse-impl','format', 'language',
+            'package','dont-trim');
+
 implementation
 implementation
 
 
-Uses XMLRead;
+Uses XMLRead, XMLWrite;
 
 
 Resourcestring
 Resourcestring
   SErrInvalidRootNode = 'Invalid options root node: Got "%s", expected "docproject"';
   SErrInvalidRootNode = 'Invalid options root node: Got "%s", expected "docproject"';
   SErrNoPackagesNode = 'No "packages" node found in docproject';
   SErrNoPackagesNode = 'No "packages" node found in docproject';
   SErrNoInputFile = 'unit tag without file attribute found';
   SErrNoInputFile = 'unit tag without file attribute found';
   SErrNoDescrFile = 'description tag without file attribute';
   SErrNoDescrFile = 'description tag without file attribute';
+  SErrNoImportFile = 'Import tag without file attribute';
+  SErrNoImportPrefix = 'Import tag without prefix attribute';
 
 
 { TXMLFPDocOptions }
 { TXMLFPDocOptions }
 
 
@@ -47,6 +64,7 @@ begin
     Dec(Result);
     Dec(Result);
 end;
 end;
 
 
+
 procedure TXMLFPDocOptions.Error(Const Msg: String);
 procedure TXMLFPDocOptions.Error(Const Msg: String);
 begin
 begin
   Raise EXMLFPDoc.Create(Msg);
   Raise EXMLFPDoc.Create(Msg);
@@ -77,19 +95,26 @@ procedure TXMLFPDocOptions.LoadPackage(APackage: TFPDocPackage; E: TDOMElement);
 
 
   Function LoadDescription(I : TDOMElement) : String;
   Function LoadDescription(I : TDOMElement) : String;
 
 
+  begin
+    Result:=I['file'];
+    If (Result='') then
+      Error(SErrNoDescrFile);
+  end;
+
+  Function LoadImport(I : TDOMElement) : String;
+
   Var
   Var
     S : String;
     S : String;
-
   begin
   begin
     Result:=I['file'];
     Result:=I['file'];
     If (Result='') then
     If (Result='') then
-      Error(SErrNoDescrFile);
+      Error(SErrNoImportFile);
+    S:=I['prefix'];
+    If (S='') then
+      Error(SErrNoImportPrefix);
+    Result:=Result+','+S;
   end;
   end;
 
 
-Const
-  OpCount = 0;
-  OpNames : Array[0..OpCount] of string
-          = ('');
 Var
 Var
   N,S : TDOMNode;
   N,S : TDOMNode;
   O : TDomElement;
   O : TDomElement;
@@ -97,7 +122,7 @@ Var
 begin
 begin
   APackage.Name:=E['name'];
   APackage.Name:=E['name'];
   APackage.output:=E['output'];
   APackage.output:=E['output'];
-  APackage.ContentFile:=E['contentfile'];
+  APackage.ContentFile:=E['content'];
   N:=E.FirstChild;
   N:=E.FirstChild;
   While (N<>Nil) do
   While (N<>Nil) do
     begin
     begin
@@ -124,6 +149,16 @@ begin
           S:=S.NextSibling;
           S:=S.NextSibling;
           end;
           end;
         end
         end
+      else If (O.NodeName='imports') then
+        begin
+        S:=O.FirstChild;
+        While (S<>Nil) do
+          begin
+          If (S.NodeType=Element_Node) and (S.NodeName='import') then
+            APackage.Imports.add(LoadImport(S as TDomElement));
+          S:=S.NextSibling;
+          end;
+        end
       end;
       end;
     N:=N.NextSibling;
     N:=N.NextSibling;
     end;
     end;
@@ -155,13 +190,6 @@ procedure TXMLFPDocOptions.LoadEngineOptions(Options: TEngineOptions;
     Result:=(v='true') or (v='1') or (v='yes');
     Result:=(v='true') or (v='1') or (v='yes');
   end;
   end;
 
 
-Const
-  NCount = 11;
-  ONames : Array[0..NCount] of string
-         = ('hide-protected','warn-no-node','show-private',
-            'stop-on-parser-error', 'ostarget','cputarget',
-            'mo-dir','parse-impl','format', 'language',
-            'package','dont-trim');
 
 
 Var
 Var
   O : TDOMnode;
   O : TDOMnode;
@@ -175,7 +203,7 @@ begin
       begin
       begin
       N:=LowerCase(TDOMElement(o)['name']);
       N:=LowerCase(TDOMElement(o)['name']);
       V:=TDOMElement(o)['value'];
       V:=TDOMElement(o)['value'];
-      Case IndexOfString(N,ONames) of
+      Case IndexOfString(N,OptionNames) of
         0 : Options.HideProtected:=TrueValue(v);
         0 : Options.HideProtected:=TrueValue(v);
         1 : Options.WarnNoNode:=TrueValue(v);
         1 : Options.WarnNoNode:=TrueValue(v);
         2 : Options.ShowPrivate:=TrueValue(v);
         2 : Options.ShowPrivate:=TrueValue(v);
@@ -197,19 +225,187 @@ begin
     end;
     end;
 end;
 end;
 
 
-procedure TXMLFPDocOptions.LoadOptionsFromFile(AProject: TFPDocProject;
-  const AFileName: String);
+procedure TXMLFPDocOptions.SaveToXML(AProject: TFPDocProject; ADoc: TXMLDocument);
+
+var
+  i: integer;
+  E,PE: TDOMElement;
+
+begin
+  E:=ADoc.CreateElement('docproject');
+  ADoc.AppendChild(E);
+  E:=ADoc.CreateElement('options');
+  ADoc.DocumentElement.AppendChild(E);
+  SaveEngineOptions(AProject.Options,ADoc,E);
+  E:=ADoc.CreateElement('packages');
+  ADoc.DocumentElement.AppendChild(E);
+  for i := 0 to AProject.Packages.Count - 1 do
+    begin
+    PE:=ADoc.CreateElement('package');
+    E.AppendChild(PE);
+    SavePackage(AProject.Packages[i],ADoc,PE);
+    end;
+end;
+
+Procedure TXMLFPDocOptions.SaveEngineOptions(Options : TEngineOptions; XML : TXMLDocument; AParent : TDOMElement);
+
+  procedure AddStr(const n, v: string);
+  var
+    E : TDOMElement;
+  begin
+    if (v='') then
+      Exit;
+    E:=XML.CreateElement('option');
+    AParent.AppendChild(E);
+    E['name'] := n;
+    E['value'] := v;
+  end;
+
+  procedure AddBool(const AName: string; B: Boolean);
+
+  begin
+    if B then
+      AddStr(Aname,'true')
+    else
+      AddStr(Aname,'false');
+  end;
+
+begin
+  AddStr('ostarget', Options.OSTarget);
+  AddStr('cputarget', Options.CPUTarget);
+  AddStr('mo-dir', Options.MoDir);
+  AddStr('format', Options.Backend);
+  AddStr('language', Options.Language);
+  AddStr('package', Options.DefaultPackageName);
+  AddBool('hide-protected', Options.HideProtected);
+  AddBool('warn-no-node', Options.WarnNoNode);
+  AddBool('show-private', Options.ShowPrivate);
+  AddBool('stop-on-parser-error', Options.StopOnParseError);
+  AddBool('parse-impl', Options.InterfaceOnly);
+  AddBool('dont-trim', Options.DontTrim);
+end;
+
+Procedure TXMLFPDocOptions.SaveInputFile(Const AInputFile : String; XML : TXMLDocument; AParent: TDOMElement);
+
+  Function GetNextWord(Var s : string) : String;
+
+  Const
+    WhiteSpace = [' ',#9,#10,#13];
+
+  var
+    i,j: integer;
+
+  begin
+    I:=1;
+    While (I<=Length(S)) and (S[i] in WhiteSpace) do
+      Inc(I);
+    J:=I;
+    While (J<=Length(S)) and (not (S[J] in WhiteSpace)) do
+      Inc(J);
+    if (I<=Length(S)) then
+      Result:=Copy(S,I,J-I);
+    Delete(S,1,J);
+  end;
+
+
+Var
+  S,W,F,O : String;
+
+begin
+  S:=AInputFile;
+  O:='';
+  F:='';
+  While (S<>'') do
+    begin
+    W:=GetNextWord(S);
+    If (W<>'') then
+      begin
+      if W[1]='-' then
+        begin
+        if (O<>'') then
+          O:=O+' ';
+        o:=O+W;
+        end
+      else
+        F:=W;
+      end;
+    end;
+  AParent['file']:=F;
+  AParent['options']:=O;
+end;
+
+Procedure TXMLFPDocOptions.SaveDescription(Const ADescription : String; XML : TXMLDocument; AParent: TDOMElement);
+
+begin
+  AParent['file']:=ADescription;
+end;
+
+procedure TXMLFPDocOptions.SaveImportFile(const AImportFile: String;
+  XML: TXMLDocument; AParent: TDOMElement);
+
+Var
+  I : integer;
+
+begin
+  I:=Pos(',',AImportFile);
+  AParent['file']:=Copy(AImportFile,1,I-1);
+  AParent['prefix']:=Copy(AImportFile,i+1,Length(AImportFile));
+end;
+
+Procedure TXMLFPDocOptions.SavePackage(APackage: TFPDocPackage; XML : TXMLDocument; AParent: TDOMElement);
+
+
+var
+  i: integer;
+  E,PE : TDomElement;
+
+begin
+  AParent['name']:=APackage.Name;
+  AParent['output']:=APackage.Output;
+  AParent['content']:=APackage.ContentFile;
+  // Units
+  PE:=XML.CreateElement('units');
+  AParent.AppendChild(PE);
+  for i:=0 to APackage.Inputs.Count-1 do
+    begin
+    E:=XML.CreateElement('unit');
+    PE.AppendChild(E);
+    SaveInputFile(APackage.Inputs[i],XML,E);
+    end;
+  // Descriptions
+  PE:=XML.CreateElement('descriptions');
+  AParent.AppendChild(PE);
+  for i:=0 to APackage.Descriptions.Count-1 do
+    begin
+    E:=XML.CreateElement('description');
+    PE.AppendChild(E);
+    SaveDescription(APackage.Descriptions[i],XML,E);
+    end;
+  // Imports
+  PE:=XML.CreateElement('imports');
+  AParent.AppendChild(PE);
+  for i:=0 to APackage.Imports.Count-1 do
+    begin
+    E:=XML.CreateElement('import');
+    PE.AppendChild(E);
+    SaveImportFile(APackage.Imports[i],XML,E);
+    end;
+end;
+
+
+
+procedure TXMLFPDocOptions.LoadOptionsFromFile(AProject: TFPDocProject; const AFileName: String);
 
 
 Var
 Var
   XML : TXMLDocument;
   XML : TXMLDocument;
 
 
 begin
 begin
-   XMLRead.ReadXMLFile(XML,AFileName);
-   try
-     LoadFromXML(AProject,XML);
-   finally
-     FreeAndNil(XML);
-   end;
+  ReadXMLFile(XML,AFileName);
+  try
+    LoadFromXML(AProject,XML);
+  finally
+    FreeAndNil(XML);
+  end;
 end;
 end;
 
 
 procedure TXMLFPDocOptions.LoadFromXML(AProject: TFPDocProject;
 procedure TXMLFPDocOptions.LoadFromXML(AProject: TFPDocProject;
@@ -232,5 +428,20 @@ begin
     LoadEngineOptions(AProject.Options,N as TDOMElement);
     LoadEngineOptions(AProject.Options,N as TDOMElement);
 end;
 end;
 
 
+Procedure TXMLFPDocOptions.SaveOptionsToFile(AProject: TFPDocProject; const AFileName: String);
+
+Var
+  XML : TXMLDocument;
+
+begin
+  XML:=TXMLDocument.Create;
+  try
+    SaveToXML(AProject,XML);
+    WriteXMLFile(XML, AFileName);
+  finally
+    XML.Free;
+  end;
+end;
+
 end.
 end.
 
 

+ 335 - 0
utils/fpdoc/mgrfpdocproj.pp

@@ -0,0 +1,335 @@
+unit mgrfpdocproj;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpdocproj, fpdocxmlopts;
+
+Type
+  { TFPDocProjectManager }
+
+  TFPDocProjectManager = Class(TComponent)
+  Private
+    FProject : TFPDocProject;
+    FPackage : TFPDocPackage;
+    FExpandMacros: Boolean;
+    FMacros: TStrings;
+    procedure SetMacros(AValue: TStrings);
+  protected
+    Procedure CheckPackage;
+    procedure GetItemsFromDirectory(AList: TStrings; ADirectory, AMask: String; ARecurse: Boolean);
+    procedure DoMacro(Sender: TObject; const TagString: String; TagParams: TStringList; out ReplaceText: String); virtual;
+    function ExpandMacrosInFile(AFileName: String): TStream; virtual;
+  Public
+    Constructor Create(AOwner : TComponent); override;
+    Destructor Destroy; override;
+    procedure AddDescrFilesFromDirectory(Const ADirectory, AMask : String; ARecurse: Boolean);
+    procedure AddInputFilesFromDirectory(Const ADirectory, AMask, AOptions: String; ARecurse: Boolean);
+    procedure AddInputFile(Const AFile : String; AOptions : String = '');
+    procedure AddImportFile(Const AFile,APrefix : String);
+    procedure AddDescrFile(Const AFile : String);
+    procedure RemoveInputFile(Const AFile : String);
+    procedure RemoveDescrFile(Const AFile : String);
+    procedure WriteOptionFile(const AFileName: String);
+    procedure ReadOptionFile(const AFileName: String);
+    Procedure Selectpackage(Const APackageName : String);
+    Procedure AddPackage (Const APackageName : String);
+    procedure SetOption(Const AOption : String; Enable : Boolean = True);
+    Property Project : TFPDocProject Read FProject;
+    Property SelectedPackage : TFPDocPackage Read FPackage;
+    Property Macros : TStrings Read FMacros Write SetMacros;
+    Property ExpandMacros : Boolean Read FExpandMacros Write FExpandMacros;
+  end;
+  EMgrFPDoc = Class(Exception);
+
+implementation
+
+uses dom,xmlread,fptemplate;
+
+procedure TFPDocProjectManager.SetMacros(AValue: TStrings);
+begin
+  if FMacros=AValue then Exit;
+  FMacros.Assign(AValue);
+end;
+
+procedure TFPDocProjectManager.DoMacro(Sender: TObject; const TagString: String;
+  TagParams: TStringList; out ReplaceText: String);
+begin
+  ReplaceText:=FMacros.Values[TagString];
+end;
+
+
+Procedure TFPDocProjectManager.GetItemsFromDirectory(AList : TStrings; ADirectory,AMask : String; ARecurse : Boolean);
+
+Var
+  D : String;
+  Info : TSearchRec;
+
+begin
+  D:=ADirectory;
+  if (D='.') then
+    D:='';
+  if (D<>'') then
+    D:=includeTrailingPathDelimiter(D);
+  If FindFirst(D+AMask,0,info)=0 then
+    try
+      Repeat
+      if ((Info.Attr and faDirectory)=0) then
+        AList.add(D+Info.Name);
+      Until (FindNext(Info)<>0);
+    finally
+      FindClose(Info);
+    end;
+  If ARecurse and (FindFirst(ADirectory+AMask,0,info)=0) then
+    try
+      Repeat
+      if ((Info.Attr and faDirectory)<>0) then
+        GetItemsFromDirectory(Alist,IncludeTrailingPathDelimiter(D+Info.Name),AMask,ARecurse);
+      Until (FindNext(Info)<>0);
+    finally
+      FindClose(Info);
+    end;
+end;
+
+constructor TFPDocProjectManager.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  FProject:=TFPDocProject.Create(Self);
+  FMacros:=TStringList.Create;
+end;
+
+destructor TFPDocProjectManager.Destroy;
+begin
+  FreeAndNil(FMacros);
+  FreeAndNil(FProject);
+  inherited Destroy;
+end;
+
+Function TFPDocProjectManager.ExpandMacrosInFile(AFileName : String) : TStream;
+
+Var
+  F : TFileStream;
+  T : TTemplateParser;
+
+begin
+  F:=TFileStream.Create(AFileName,fmOpenRead or fmShareDenyWrite);
+  try
+    Result:=TMemoryStream.Create;
+    try
+      T:=TTemplateParser.Create;
+      try
+        T.StartDelimiter:='$(';
+        T.EndDelimiter:=')';
+        T.AllowTagParams:=true;
+        T.OnReplaceTag:=@DoMacro;
+        T.ParseStream(F,Result);
+      finally
+        T.Free;
+      end;
+      Result.Position:=0;
+    except
+      FreeAndNil(Result);
+      Raise;
+    end;
+  finally
+    F.Free;
+  end;
+end;
+
+Procedure TFPDocProjectManager.AddDescrFilesFromDirectory(const ADirectory,AMask : String; ARecurse : Boolean);
+
+Var
+  L : TStringList;
+  M : String;
+
+begin
+  CheckPackage;
+  M:=AMask;
+  if (M='') then
+    M:='*.xml';
+  L:=TStringList.Create;
+  try
+    GetItemsFromDirectory(L,ADirectory,M,ARecurse);
+    FPackage.Descriptions.AddStrings(L);
+  finally
+    L.Free;
+  end;
+end;
+
+Procedure TFPDocProjectManager.AddInputFilesFromDirectory(Const ADirectory,AMask,AOptions : String; ARecurse : Boolean);
+
+Var
+  L : TStringList;
+  I : integer;
+  M : String;
+
+begin
+  CheckPackage;
+  M:=AMask;
+  if (M='') then
+    M:='*.pp';
+  L:=TStringList.Create;
+  try
+    GetItemsFromDirectory(L,ADirectory,M,ARecurse);
+    For I:=0 to L.Count-1 do
+      AddInputFile(L[i],AOPtions);
+  finally
+    L.Free;
+  end;
+end;
+
+procedure TFPDocProjectManager.AddInputFile(const AFile: String; AOptions : String = '');
+
+Var
+  S : String;
+
+begin
+  CheckPackage;
+  S:=AFile;
+  If (AOptions<>'') then
+    S:=AOptions+' '+S;
+  FPackage.Inputs.Add(S);
+end;
+
+procedure TFPDocProjectManager.AddImportFile(const AFile, APrefix: String);
+
+begin
+  CheckPackage;
+  FPackage.Imports.Add(AFile+','+APrefix);
+end;
+
+procedure TFPDocProjectManager.AddDescrFile(const AFile: String);
+
+begin
+  CheckPackage;
+  if FPackage.Descriptions.IndexOf(AFile)<>-1 then
+    Raise EMgrFPDoc.Createfmt('Duplicate description file : "%s"',[AFile]);
+  FPackage.Descriptions.Add(AFile);
+end;
+
+procedure TFPDocProjectManager.RemoveInputFile(const AFile: String);
+
+Var
+  I : Integer;
+
+begin
+  I:=FPackage.Inputs.IndexOf(AFile);
+  If (I<>-1) then
+    FPackage.Inputs.Delete(I);
+end;
+
+procedure TFPDocProjectManager.RemoveDescrFile(const AFile: String);
+
+Var
+  I : Integer;
+
+begin
+  I:=FPackage.Descriptions.IndexOf(AFile);
+  If (I<>-1) then
+    FPackage.Descriptions.Delete(I);
+end;
+
+procedure TFPDocProjectManager.ReadOptionFile(Const AFileName : String);
+
+Var
+  XML : TXMLDocument;
+  S : TStream;
+
+begin
+  With TXMLFPDocOptions.Create(Self) do
+    try
+      if not (ExpandMacros) then
+        LoadOptionsFromFile(FProject,AFileName)
+      else
+        begin
+        S:=ExpandMacrosInFile(AFileName);
+        try
+          ReadXMLFile(XML,S,AFileName);
+          try
+            LoadFromXml(FProject,XML)
+          finally
+            XML.Free;
+          end;
+        finally
+          S.Free;
+        end;
+        end;
+    finally
+      Free;
+    end;
+end;
+
+procedure TFPDocProjectManager.Selectpackage(const APackageName: String);
+begin
+  FPackage:=FProject.Packages.FindPackage(APackageName);
+  If (FPackage=Nil) then
+    Raise EMgrFPDoc.CreateFmt('Unknown package : "%s"',[APackageName]);
+end;
+
+procedure TFPDocProjectManager.AddPackage(const APackageName: String);
+begin
+  if FProject.Packages.FindPackage(APackageName)<>Nil then
+    Raise EMgrFPDoc.CreateFmt('Duplicate package : "%s"',[APackageName]);
+  FPackage:=FProject.Packages.Add as TFPDocPackage;
+  FPackage.Name:=APackageName;
+end;
+
+procedure TFPDocProjectManager.SetOption(const AOption: String;
+  Enable: Boolean = true);
+
+Var
+  O,V : String;
+  P : Integer;
+  EO : TEngineOptions;
+
+begin
+  V:=LowerCase(AOption);
+  P:=Pos('=',V);
+  If (P=0) then
+    P:=Length(V)+1;
+  O:=Copy(V,1,P-1);
+  Delete(V,1,P);
+  EO:=FProject.Options;
+  Case IndexOfString(o,OptionNames) of
+    0 : EO.HideProtected:=Enable;
+    1 : EO.WarnNoNode:=Enable;
+    2 : EO.ShowPrivate:=Enable;
+    3 : EO.StopOnParseError:=Enable;
+    4 : EO.ostarget:=v;
+    5 : EO.cputarget:=v;
+    6 : EO.MoDir:=V;
+    7 : EO.InterfaceOnly:=Not Enable;
+    8 : EO.Backend:=V;
+    9 : EO.Language:=v;
+    10 : EO.DefaultPackageName:=V;
+    11 : EO.DontTrim:=Enable;
+  else
+    EO.BackendOptions.add('--'+O);
+    EO.BackendOptions.add(v);
+  end;
+end;
+
+procedure TFPDocProjectManager.WriteOptionFile(Const AFileName : String);
+
+begin
+  With TXMLFPDocOptions.Create(Self) do
+    try
+      SaveOptionsToFile(FProject,AFileName);
+    finally
+      Free;
+    end;
+end;
+
+procedure TFPDocProjectManager.CheckPackage;
+
+begin
+  if (FPackage=Nil) then
+    Raise EMgrFPDoc.Create('Error: No package selected');
+end;
+
+
+
+end.
+

+ 204 - 0
utils/fpdoc/mkfpdoc.pp

@@ -0,0 +1,204 @@
+unit mkfpdoc;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, dglobals, fpdocxmlopts, dwriter, pscanner, pparser, fpdocproj;
+
+const
+  DefOSTarget    = {$I %FPCTARGETOS%};
+  DefCPUTarget   = {$I %FPCTARGETCPU%};
+  DefFPCVersion  = {$I %FPCVERSION%};
+  DefFPCDate     = {$I %FPCDATE%};
+
+Type
+
+  { TFPDocCreator }
+
+  TFPDocCreator = Class(TComponent)
+  Private
+    FOnLog: TPasParserLogHandler;
+    FPParserLogEvents: TPParserLogEvents;
+    FProject : TFPDocProject;
+    FScannerLogEvents: TPScannerLogEvents;
+    FVerbose: Boolean;
+    function GetOptions: TEngineOptions;
+    function GetPackages: TFPDocPackages;
+  Protected
+    procedure SetVerbose(AValue: Boolean); virtual;
+    Procedure DoLog(Const Msg : String);
+    procedure DoLog(Const Fmt : String; Args : Array of Const);
+    procedure CreateOutput(APackage: TFPDocPackage; Engine: TFPDocEngine); virtual;
+  Public
+    Constructor Create(AOwner : TComponent); override;
+    Destructor Destroy; override;
+    Procedure CreateDocumentation(APackage : TFPDocPackage; ParseOnly : Boolean); virtual;
+    Procedure CreateProjectFile(Const AFileName : string);
+    Procedure LoadProjectFile(Const AFileName: string);
+    Property Project : TFPDocProject Read FProject;
+    Property ScannerLogEvents : TPScannerLogEvents Read FScannerLogEvents Write FScannerLogEvents;
+    Property ParserLogEvents : TPParserLogEvents Read FPParserLogEvents Write FPParserLogEvents;
+    Property Verbose : Boolean Read FVerbose Write SetVerbose;
+    Property OnLog : TPasParserLogHandler Read FOnLog Write FOnLog;
+    // Easy access
+    Property Options : TEngineOptions Read GetOptions;
+    Property Packages : TFPDocPackages Read GetPackages;
+
+  end;
+
+implementation
+
+{ TFPDocCreator }
+
+procedure TFPDocCreator.SetVerbose(AValue: Boolean);
+begin
+  if FVerbose=AValue then Exit;
+  FVerbose:=AValue;
+  if FVerbose then
+    begin
+    ScannerLogEvents:=[sleFile];
+    ParserLogEvents:=[];
+    end
+  else
+    begin
+    ScannerLogEvents:=[];
+    ParserLogEvents:=[];
+    end;
+end;
+
+procedure TFPDocCreator.DoLog(const Msg: String);
+begin
+  If Assigned(OnLog) then
+    OnLog(Self,Msg);
+end;
+
+procedure TFPDocCreator.DoLog(const Fmt: String; Args: array of const);
+begin
+  DoLog(Format(Fmt,Args));
+end;
+
+function TFPDocCreator.GetOptions: TEngineOptions;
+begin
+  Result:=FProject.Options;
+end;
+
+function TFPDocCreator.GetPackages: TFPDocPackages;
+begin
+  Result:=FProject.Packages;
+end;
+
+constructor TFPDocCreator.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  FProject:=TFPDocProject.Create(Self);
+  FProject.Options.StopOnParseError:=False;
+  FProject.Options.CPUTarget:=DefCPUTarget;
+  FProject.Options.OSTarget:=DefOSTarget;
+end;
+
+destructor TFPDocCreator.Destroy;
+begin
+  FreeAndNil(FProject);
+  inherited Destroy;
+end;
+
+procedure TFPDocCreator.CreateOutput(APackage: TFPDocPackage;Engine : TFPDocEngine);
+
+Var
+  WriterClass : TFPDocWriterClass;
+  Writer : TFPDocWriter;
+  I : Integer;
+  Cmd,Arg : String;
+
+begin
+  WriterClass:=GetWriterClass(Options.Backend);
+  Writer:=WriterClass.Create(Engine.Package,Engine);
+  With Writer do
+    Try
+      If FVerbose then
+        DoLog('Writing documentation');
+      OnLog:=Self.OnLog;
+      If Options.BackendOptions.Count>0 then
+        for I:=0 to ((Options.BackendOptions.Count-1) div 2) do
+          begin
+          Cmd:=Options.BackendOptions[I*2];
+          Arg:=Options.BackendOptions[I*2+1];
+          If not InterPretOption(Cmd,Arg) then
+            DoLog(SCmdLineInvalidOption,[Cmd+'='+Arg]);
+          end;
+      WriteDoc;
+    Finally
+      Free;
+    end;
+  if Length(APackage.ContentFile) > 0 then
+    Engine.WriteContentFile(APackage.ContentFile);
+end;
+
+procedure TFPDocCreator.CreateDocumentation(APackage: TFPDocPackage; ParseOnly : Boolean);
+
+var
+  i,j: Integer;
+  Engine : TFPDocEngine;
+  Cmd,Arg : String;
+
+begin
+  Engine:=TFPDocEngine.Create;
+  try
+    For J:=0 to Apackage.Imports.Count-1 do
+      begin
+      Arg:=Apackage.Imports[j];
+      i := Pos(',', Arg);
+      Engine.ReadContentFile(Copy(Arg,1,i-1),Copy(Arg,i+1,Length(Arg)));
+      end;
+    for i := 0 to APackage.Descriptions.Count - 1 do
+      Engine.AddDocFile(APackage.Descriptions[i],Options.donttrim);
+    Engine.SetPackageName(APackage.Name);
+    Engine.Output:=APackage.Output;
+    Engine.OnLog:=Self.OnLog;
+    Engine.ScannerLogEvents:=Self.ScannerLogEvents;
+    Engine.ParserLogEvents:=Self.ParserLogEvents;
+    Engine.HideProtected:=Options.HideProtected;
+    Engine.HidePrivate:=Not Options.ShowPrivate;
+    if Length(Options.Language) > 0 then
+      TranslateDocStrings(Options.Language);
+    for i := 0 to APackage.Inputs.Count - 1 do
+      try
+        ParseSource(Engine, APackage.Inputs[i], Options.OSTarget, Options.CPUTarget);
+      except
+        on e: EParserError do
+          If Options.StopOnParseError then
+            Raise
+          else
+            DoLog('%s(%d,%d): %s',[e.Filename, e.Row, e.Column, e.Message]);
+      end;
+    if Not ParseOnly then
+      CreateOutput(APackage,Engine);
+  finally
+    FreeAndNil(Engine);
+  end;
+end;
+
+procedure TFPDocCreator.CreateProjectFile(Const AFileName: string);
+begin
+  With TXMLFPDocOptions.Create(Self) do
+  try
+    SaveOptionsToFile(FProject,AFileName);
+  finally
+    Free;
+  end;
+end;
+
+procedure TFPDocCreator.LoadProjectFile(const AFileName: string);
+begin
+  With TXMLFPDocOptions.Create(self) do
+    try
+      LoadOptionsFromFile(FProject,AFileName);
+    finally
+      Free;
+    end;
+end;
+
+end.
+

+ 70 - 0
utils/fpdoc/mkfpdocproj.lpi

@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <CommandLineParams Value="--input=test.xml --output=test.xml --package=test add-input-files -o me testunit3.pp"/>
+        <LaunchingApplication PathPlusParams="/usr/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="mkfpdocproj.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="mkfpdocproj"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="mgrfpdocproj.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="mgrfpdocproj"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 428 - 0
utils/fpdoc/mkfpdocproj.pp

@@ -0,0 +1,428 @@
+program mkfpdocproj;
+
+{$mode objfpc}{$H+}
+
+uses
+  Classes, SysUtils, CustApp, mgrfpdocproj;
+
+type
+
+  { TManageFPDocProjectApplication }
+
+  TManageFPDocProjectApplication = class(TCustomApplication)
+  private
+    FMGR : TFPDocProjectManager;
+    FPackageName,
+    FInputFileName,
+    FOutputFileName,
+    FCmd : String;
+    FCmdArgs,
+    FCmdOptions: TStrings;
+    procedure AddDescrFiles;
+    procedure AddDescriptionDirs;
+    procedure AddInputDirs;
+    procedure AddInputFiles;
+    procedure AddImportFiles;
+    function CmdNeedsPackage: Boolean;
+    procedure RemoveInputFiles;
+    procedure RemoveDescrFiles;
+    procedure AddPackages;
+    function CheckCmdOption(C: Char; S: String): Boolean;
+    function GetCmdOption(C: Char; S: String): String;
+    procedure SetOptions(Enable: Boolean);
+  protected
+    procedure ParseOptions;
+    Procedure Error(Const Msg : String);
+    procedure Usage(AExitCode: Integer);
+    procedure DoRun; override;
+  public
+    constructor Create(TheOwner: TComponent); override;
+    Destructor Destroy; override;
+  end;
+
+Resourcestring
+  SErrNeedArgument = 'Option at position %d needs an argument: %s';
+
+{ TManageFPDocProjectApplication }
+
+procedure TManageFPDocProjectApplication.Usage(AExitCode : Integer);
+
+Var
+  FN : String;
+  I : Integer;
+
+begin
+  FN:=ChangeFileExt(ExtractFileName(ParamStr(0)),'');
+  Writeln('Usage ',FN,' [options] command [command-options] command-args');
+  Writeln('Where options is one of ');
+  Writeln('  -i --input=file   Initialize project from named file.');
+  Writeln('  -o --output=file  Write project to named file. Default is input file.');
+  Writeln('  -p --package=name Package to perform operation on.');
+  Writeln('command is one of:');
+  Writeln('  add-packages');
+  Writeln('    Add arguments as package definitions to the file.');
+  Writeln('  add-description-dirs');
+  Writeln('    Scan directories for XML files to add as descriptions of selected package.');
+  Writeln('  add-input-dirs');
+  Writeln('    Scan directories for .pp or .pas files to add as inputs of selected package.');
+  Writeln('  add-input-files');
+  Writeln('    Add files as inputs of selected package.');
+  Writeln('  add-import-files');
+  Writeln('    Add files (format: "filename,prefix") to imports of selected package.');
+  Writeln('  add-descr-files');
+  Writeln('    Add files as description files of selected package.');
+  Writeln('  expand-macros');
+  Writeln('    read file and expand macros. Arguments specify macro values as Name=Value pairs');
+  Writeln('  remove-descr-files');
+  Writeln('    Remove files from description files of selected package.');
+  Writeln('  remove-input-files');
+  Writeln('    Remove files from input files of selected package.');
+  Writeln('  set-options');
+  Writeln('    Set named options (true) for project file.');
+  Writeln('    Valid option names : ');
+  Writeln('      hide-protected , warn-no-node, show-private, stop-on-parser-error,');
+  Writeln('      parse-impl, dont-trim');
+  Writeln('  unset-options');
+  Writeln('    UnSet named options (false) for project file.');
+  Halt(AExitCode);
+end;
+
+Function CheckOptionStr(O : String;Short : Char;Long : String): Boolean;
+begin
+  Result:=(O='-'+short) or (O='--'+long) or (copy(O,1,Length(Long)+3)=('--'+long+'='));
+end;
+
+function TManageFPDocProjectApplication.CmdNeedsPackage : Boolean;
+
+begin
+ Result:=(FCMd<>'expand-macros') and (FCMD<>'set-options') and (FCmd<>'unset-options');
+end;
+
+procedure TManageFPDocProjectApplication.ParseOptions;
+
+  Function CheckOption(Index : Integer;Short : char;Long : String): Boolean;
+  begin
+    Result:=CheckOptionStr(ParamStr(Index),Short,Long);
+  end;
+
+  Function OptionArg(Var Index : Integer) : String;
+  Var
+    P : Integer;
+  begin
+    if (Length(ParamStr(Index))>1) and (Paramstr(Index)[2]<>'-') then
+      begin
+        If Index<ParamCount then
+          begin
+            Inc(Index);
+            Result:=Paramstr(Index);
+          end
+        else
+          Error(Format(SErrNeedArgument,[Index,ParamStr(Index)]));
+      end
+    else If length(ParamStr(Index))>2 then
+      begin
+        P:=Pos('=',Paramstr(Index));
+        If (P=0) then
+          Error(Format(SErrNeedArgument,[Index,ParamStr(Index)]))
+        else
+          begin
+            Result:=Paramstr(Index);
+            Delete(Result,1,P);
+          end;
+      end;
+  end;
+
+Var
+  I : Integer;
+  S : String;
+
+begin
+  I:=0;
+  // We can't use the TCustomApplication option handling,
+  // because they cannot handle [general opts] [command] [cmd-opts] [args]
+  While (I<ParamCount) do
+    begin
+    Inc(I);
+    if (FCmd='') then
+      begin
+      if Checkoption(I,'i','input') then
+        FInputFileName:=OptionArg(i)
+      else if Checkoption(I,'o','output') then
+        FOutputFileName:=OptionArg(i)
+      else if CheckOption(I,'p','package') then
+        FPackageName:=OptionArg(i)
+      else if CheckOption(I,'h','help') then
+        Usage(0)
+      else if (ParamStr(i)<>'') then
+        begin
+        S:=ParamStr(i);
+        if (S[1]='-') then
+          Error('Unknown option : '+S)
+        else
+          FCmd:=lowercase(S)
+        end
+      end
+    else
+      begin
+      S:=ParamStr(I);
+      if (S<>'') then
+         if (S[1]<>'-') then
+           FCmdArgs.Add(S)
+         else
+           FCmdOptions.Add(S);
+      end;
+    end;
+  if (FOutputFileName='') then
+    FOutputFileName:=FInputFileName;
+  If (FOutputFileName='') then
+    Error('Need an output filename');
+  if (FPackageName='') and CmdNeedsPackage then
+    Error('Need a package name');
+  if (FCmd='') then
+    Error('Need a command');
+end;
+
+procedure TManageFPDocProjectApplication.Error(Const Msg: String);
+begin
+  Writeln('Error : ',Msg);
+  Usage(1);
+end;
+
+
+Function TManageFPDocProjectApplication.CheckCmdOption(C : Char; S : String) : Boolean;
+
+Var
+  I : integer;
+
+begin
+  I:=0;
+  Result:=False;
+  While (Not Result) and (I<FCmdOptions.Count) do
+    begin
+    Result:=CheckOptionStr(FCmdOptions[i],C,S);
+    Inc(I);
+    end;
+end;
+
+Function TManageFPDocProjectApplication.GetCmdOption(C : Char; S : String) : String;
+
+Var
+  I,P : integer;
+  B : Boolean;
+
+begin
+  I:=0;
+  B:=False;
+  While (Not B) and (I<FCmdOptions.Count) do
+    begin
+    B:=CheckOptionStr(FCmdOptions[i],C,S);
+    if B then
+      begin
+      Result:=FCmdOptions[I];
+      if (Length(Result)>1) and (Result[2]<>'-') then
+        begin
+        If I<FCmdOptions.Count-1 then
+          begin
+          Inc(I);
+          Result:=FCmdOptions[I];
+          end
+        else
+          Error(Format(SErrNeedArgument,[I,Result]));
+        end
+      else If length(Result)>2 then
+        begin
+        P:=Pos('=',Result);
+        If (P=0) then
+          Error(Format(SErrNeedArgument,[I,Result]))
+        else
+          Delete(Result,1,P);
+        end;
+      end;
+    Inc(I);
+    end;
+end;
+
+procedure TManageFPDocProjectApplication.AddDescriptionDirs;
+
+Var
+  Recursive: Boolean;
+  Mask : String;
+  I : Integer;
+begin
+  Recursive:=CheckCmdOption('r','recursive');
+  Mask:=GetCmdOption('m','mask');
+  if FCmdArgs.Count=0 then
+    FMGr.AddDescrFilesFromDirectory('',Mask,Recursive)
+  else
+    For I:=0 to FCmdArgs.Count-1 do
+      FMGr.AddDescrFilesFromDirectory(FCmdArgs[i],Mask,Recursive);
+end;
+
+procedure TManageFPDocProjectApplication.AddInputDirs;
+
+Var
+  Recursive: Boolean;
+  Options,Mask : String;
+  I : Integer;
+begin
+  Recursive:=CheckCmdOption('r','recursive');
+  Mask:=GetCmdOption('m','mask');
+  Options:=GetCmdOption('o','options');
+  if FCmdArgs.Count=0 then
+    FMGr.AddInputFilesFromDirectory('',Mask,Options,Recursive)
+  else
+    For I:=0 to FCmdArgs.Count-1 do
+      FMGr.AddInputFilesFromDirectory(FCmdArgs[i],Mask,Options,Recursive);
+end;
+
+procedure TManageFPDocProjectApplication.AddInputFiles;
+
+Var
+  Options : String;
+  I : Integer;
+
+begin
+  Options:=GetCmdOption('o','options');
+  For I:=0 to FCmdArgs.Count-1 do
+    FMGr.AddInputFile(FCmdArgs[i],Options);
+end;
+
+procedure TManageFPDocProjectApplication.AddImportFiles;
+
+Var
+  I,J : Integer;
+  F,P : String;
+
+begin
+  For I:=0 to FCmdArgs.Count-1 do
+    begin
+    P:=FCmdArgs[i];
+    J:=Pos(',',P);
+    F:=Copy(P,1,J-1);
+    Delete(P,1,J);
+    FMGr.AddImportFile(F,P);
+    end;
+end;
+
+procedure TManageFPDocProjectApplication.RemoveInputFiles;
+
+Var
+  I : Integer;
+
+begin
+  For I:=0 to FCmdArgs.Count-1 do
+    FMGr.RemoveInputFile(FCmdArgs[i]);
+end;
+
+procedure TManageFPDocProjectApplication.RemoveDescrFiles;
+Var
+  I : Integer;
+
+begin
+  For I:=0 to FCmdArgs.Count-1 do
+    FMGr.RemoveDescrFile(FCmdArgs[i]);
+end;
+
+procedure TManageFPDocProjectApplication.AddPackages;
+
+var
+  I : Integer;
+
+begin
+  For I:=0 to FCmdArgs.Count-1 do
+    FMgr.AddPackage(FCmdArgs[i]);
+end;
+
+procedure TManageFPDocProjectApplication.AddDescrFiles;
+
+Var
+  I : Integer;
+
+begin
+  For I:=0 to FCmdArgs.Count-1 do
+    FMGr.AddDescrFile(FCmdArgs[i]);
+end;
+
+procedure TManageFPDocProjectApplication.SetOptions(Enable : Boolean);
+
+Var
+  I : Integer;
+
+begin
+  For I:=0 to FCmdArgs.Count-1 do
+    FMgr.SetOption(FCmdArgs[i],Enable);
+end;
+
+procedure TManageFPDocProjectApplication.DoRun;
+
+begin
+  ParseOptions;
+  if (FInputFileName='') then
+    FMGR.AddPackage(FPackageName)
+  else
+    begin
+    if (FCmd='expand-macros') then
+      begin
+      FMGR.Macros:=FCmdArgs;
+      FMGR.ExpandMacros:=true;
+      FMGR.ReadOptionFile(FInputFileName)
+      end
+    else
+      begin
+      FMGR.ReadOptionFile(FInputFileName);
+      if CmdNeedsPackage then
+        FMGR.SelectPackage(FPackageName);
+      end
+    end;
+  if (FCmd='add-packages') then
+    AddPackages
+  else if (FCmd='add-description-dirs') then
+    AddDescriptionDirs
+  else if (FCmd='add-input-dirs') then
+    AddInputDirs
+  else if (FCmd='add-input-files') then
+    AddInputFiles
+  else if (FCmd='add-import-files') then
+    AddImportFiles
+  else if (FCmd='add-description-files') then
+    AddDescrFiles
+  else if (FCmd='remove-input-files') then
+    RemoveInputFiles
+  else if (FCmd='remove-descr-files') then
+    RemoveDescrFiles
+  else if (FCmd='set-options') then
+    SetOptions(True)
+  else if (FCmd='unset-options') then
+    SetOptions(False)
+  else if (FCMd<>'expand-macros') then
+    Error(Format('Unknown command : "%s"',[FCmd]));
+  FMgr.WriteOptionFile(FOutputFileName);
+  Terminate;
+end;
+
+constructor TManageFPDocProjectApplication.Create(TheOwner: TComponent);
+begin
+  inherited Create(TheOwner);
+  StopOnException:=True;
+  FCmdArgs:=TStringList.Create;
+  FCmdOptions:=TStringList.Create;
+  FMGR:=TFPDocProjectManager.Create(Self);
+ end;
+
+destructor TManageFPDocProjectApplication.Destroy;
+begin
+  FreeAndNil(FMGR);
+  FreeAndNil(FCmdArgs);
+  FreeAndNil(FCmdOptions);
+  inherited Destroy;
+end;
+
+var
+  Application: TManageFPDocProjectApplication;
+begin
+  Application:=TManageFPDocProjectApplication.Create(nil);
+  Application.Title:='Program to manipulate FPDoc project files';
+  Application.Run;
+  Application.Free;
+end.
+

+ 1 - 1
utils/fpdoc/testunit.pp

@@ -40,7 +40,7 @@ Type
                             2 : (phi,Omega : Real);
                             2 : (phi,Omega : Real);
                           end; 
                           end; 
                           
                           
-//  TADeprecatedType = Integer deprecated;
+  TADeprecatedType = Integer deprecated;
                         
                         
 Var
 Var
   ASimpleVar : Integer;  
   ASimpleVar : Integer;  

+ 1 - 1
utils/fpdoc/unitdiff.pp

@@ -13,7 +13,7 @@
 }
 }
 
 
 
 
-program MakeSkel;
+program unitdiff;
 
 
 uses
 uses
   SysUtils, Classes, Gettext,
   SysUtils, Classes, Gettext,

Some files were not shown because too many files changed in this diff