Browse Source

* all fpdoc/passrc fixes merged, and makefiles adapted.

--- Merging r22005 into '.':
A    packages/fcl-passrc/tests/tctypeparser.pas
U    packages/fcl-passrc/tests/testpassrc.lpr
A    packages/fcl-passrc/tests/tconstparser.pas
A    packages/fcl-passrc/tests/tcmoduleparser.pas
A    packages/fcl-passrc/tests/tcvarparser.pas
U    packages/fcl-passrc/tests/testpassrc.lpi
A    packages/fcl-passrc/tests/tcbaseparser.pas
A    packages/fcl-passrc/tests/tcstatements.pas
--- Merging r22006 into '.':
U    packages/fcl-passrc/src/pparser.pp
U    packages/fcl-passrc/src/pastree.pp
--- Merging r22028 into '.':
G    packages/fcl-passrc/src/pparser.pp
G    packages/fcl-passrc/src/pastree.pp
--- Merging r22029 into '.':
U    packages/fcl-passrc/tests/tcstatements.pas
--- Merging r22030 into '.':
G    packages/fcl-passrc/src/pparser.pp
G    packages/fcl-passrc/src/pastree.pp
--- Merging r22031 into '.':
G    packages/fcl-passrc/tests/tcstatements.pas
--- Merging r22051 into '.':
G    packages/fcl-passrc/src/pastree.pp
G    packages/fcl-passrc/src/pparser.pp
--- Merging r22052 into '.':
G    packages/fcl-passrc/tests/tcstatements.pas
--- Merging r22053 into '.':
U    packages/fcl-passrc/examples/test_parser.pp
--- Merging r22078 into '.':
U    utils/fpdoc/testunit.xml
U    utils/fpdoc/makeskel.pp
U    utils/fpdoc/dglobals.pp
U    utils/fpdoc/fpdoc.pp
--- Merging r22079 into '.':
U    utils/fpdoc/dw_html.pp
C    utils/fpdoc/Makefile
A    utils/fpdoc/css.inc
U    utils/fpdoc/Makefile.fpc
--- Merging r22082 into '.':
G    packages/fcl-passrc/src/pparser.pp
G    packages/fcl-passrc/src/pastree.pp
--- Merging r22083 into '.':
G    packages/fcl-passrc/src/pparser.pp
G    packages/fcl-passrc/src/pastree.pp
--- Merging r22084 into '.':
G    packages/fcl-passrc/src/pparser.pp
G    packages/fcl-passrc/src/pastree.pp
--- Merging r22085 into '.':
G    packages/fcl-passrc/tests/tcstatements.pas
U    packages/fcl-passrc/tests/tctypeparser.pas
U    packages/fcl-passrc/tests/tcvarparser.pas
--- Merging r22088 into '.':
G    packages/fcl-passrc/tests/tcstatements.pas
--- Merging r22092 into '.':
G    utils/fpdoc/dw_html.pp
--- Merging r22094 into '.':
G    packages/fcl-passrc/src/pastree.pp
--- Merging r22129 into '.':
G    packages/fcl-passrc/src/pastree.pp
U    packages/fcl-passrc/src/pscanner.pp
G    packages/fcl-passrc/src/pparser.pp
--- Merging r22130 into '.':
U    packages/fcl-passrc/tests/tcmoduleparser.pas
G    packages/fcl-passrc/tests/tcvarparser.pas
U    packages/fcl-passrc/tests/tcbaseparser.pas
G    packages/fcl-passrc/tests/tcstatements.pas
U    packages/fcl-passrc/tests/tcscanner.pas
G    packages/fcl-passrc/tests/tctypeparser.pas
U    packages/fcl-passrc/tests/tconstparser.pas
--- Merging r22131 into '.':
G    packages/fcl-passrc/tests/testpassrc.lpr
G    packages/fcl-passrc/tests/testpassrc.lpi
A    packages/fcl-passrc/tests/tcclasstype.pas
--- Merging r22135 into '.':
G    packages/fcl-passrc/tests/tcbaseparser.pas
G    packages/fcl-passrc/tests/tcstatements.pas
G    packages/fcl-passrc/tests/tcscanner.pas
G    packages/fcl-passrc/src/pastree.pp
--- Merging r22136 into '.':
G    packages/fcl-passrc/src/pparser.pp
G    packages/fcl-passrc/src/pscanner.pp
--- Merging r22140 into '.':
G    utils/fpdoc/dw_html.pp
--- Merging r22144 into '.':
A    packages/fcl-passrc/tests/tcexprparser.pas
G    packages/fcl-passrc/tests/testpassrc.lpr
G    packages/fcl-passrc/tests/testpassrc.lpi
G    packages/fcl-passrc/tests/tcbaseparser.pas
U    packages/fcl-passrc/tests/tcclasstype.pas
G    packages/fcl-passrc/tests/tcstatements.pas
G    packages/fcl-passrc/tests/tcscanner.pas
G    packages/fcl-passrc/src/pastree.pp
G    packages/fcl-passrc/src/pparser.pp
--- Merging r22150 into '.':
U    utils/fpdoc/dwriter.pp
U    utils/fpdoc/mkfpdoc.pp
--- Merging r22151 into '.':
U    utils/fpdoc/dw_htmlchm.inc
G    utils/fpdoc/dw_html.pp
--- Merging r22152 into '.':
G    packages/fcl-passrc/tests/tcclasstype.pas
G    packages/fcl-passrc/src/pparser.pp
--- Merging r22157 into '.':
G    packages/fcl-passrc/src/pparser.pp
G    packages/fcl-passrc/src/pastree.pp
G    packages/fcl-passrc/examples/test_parser.pp
G    packages/fcl-passrc/tests/tcbaseparser.pas
G    packages/fcl-passrc/tests/tcclasstype.pas
G    packages/fcl-passrc/tests/testpassrc.lpr
A    packages/fcl-passrc/tests/tcprocfunc.pas
G    packages/fcl-passrc/tests/testpassrc.lpi
--- Merging r22164 into '.':
A    packages/fcl-passrc/src/pastounittest.pp
U    packages/fcl-passrc/fpmake.pp
--- Merging r22165 into '.':
A    utils/pas2ut
A    utils/pas2ut/pas2ut.lpi
A    utils/pas2ut/Makefile.fpc
A    utils/pas2ut/pas2ut.pp
A    utils/pas2ut/Makefile
--- Merging r22170 into '.':
G    packages/fcl-passrc/tests/tcbaseparser.pas
G    packages/fcl-passrc/tests/tcclasstype.pas
G    packages/fcl-passrc/tests/tcstatements.pas
G    packages/fcl-passrc/tests/tcscanner.pas
U    packages/fcl-passrc/tests/tcexprparser.pas
G    packages/fcl-passrc/src/pparser.pp
G    packages/fcl-passrc/src/pastree.pp
G    packages/fcl-passrc/src/pscanner.pp
--- Merging r22172 into '.':
G    packages/fcl-passrc/fpmake.pp
A    packages/fcl-passrc/tests/tcpassrcutil.pas
G    packages/fcl-passrc/tests/testpassrc.lpr
G    packages/fcl-passrc/tests/testpassrc.lpi
A    packages/fcl-passrc/src/passrcutil.pp
G    packages/fcl-passrc/src/pparser.pp
--- Merging r22173 into '.':
A    utils/pas2fpm
A    utils/pas2fpm/pas2fpm.pp
A    utils/pas2fpm/pas2fpm.lpi
A    utils/pas2fpm/Makefile
A    utils/pas2fpm/Makefile.fpc
C    utils/Makefile
U    utils/Makefile.fpc
--- Merging r22174 into '.':
U    utils/fpdoc/fpclasschart.pp
--- Merging r22197 into '.':
U    utils/pas2fpm/Makefile
U    utils/pas2fpm/Makefile.fpc
--- Merging r22198 into '.':
G    utils/pas2fpm/Makefile.fpc
G    utils/pas2fpm/Makefile
--- Merging r22199 into '.':
U    utils/pas2ut/Makefile.fpc
U    utils/pas2ut/Makefile
--- Merging r22205 into '.':
G    utils/pas2fpm/Makefile.fpc
G    utils/pas2fpm/Makefile
G    utils/pas2ut/Makefile.fpc
G    utils/pas2ut/Makefile
--- Merging r22210 into '.':
G    packages/fcl-passrc/tests/tcexprparser.pas
G    packages/fcl-passrc/src/pparser.pp
U    packages/fcl-passrc/src/passrcutil.pp
G    packages/fcl-passrc/src/pscanner.pp
--- Merging r22211 into '.':
U    utils/pas2fpm/pas2fpm.pp
--- Merging r22214 into '.':
G    utils/pas2fpm/pas2fpm.pp
--- Merging r22404 into '.':
U    utils/pas2ut/pas2ut.pp
--- Merging r22405 into '.':
U    packages/fcl-passrc/src/pastounittest.pp
G    utils/pas2ut/pas2ut.pp
--- Merging r22406 into '.':
G    packages/fcl-passrc/src/pastounittest.pp
--- Merging r23171 into '.':
G    utils/fpdoc/dwriter.pp
G    utils/fpdoc/dglobals.pp
U    utils/fpdoc/fpdocproj.pas
G    utils/fpdoc/mkfpdoc.pp
U    utils/fpdoc/dw_xml.pp
G    utils/fpdoc/fpdoc.pp
--- Merging r23172 into '.':
U    utils/fpdoc/dwlinear.pp
G    utils/fpdoc/dglobals.pp
U    utils/fpdoc/dw_ipflin.pas
--- Merging r23193 into '.':
G    utils/fpdoc/dw_html.pp
C    utils/fpdoc/Makefile
U    utils/fpdoc/fpdoc.lpi
G    utils/fpdoc/fpclasschart.pp
G    utils/fpdoc/fpdoc.pp
A    utils/fpdoc/fpdocclasstree.pp
U    utils/fpdoc/fpdoc.css
G    utils/fpdoc/Makefile.fpc
A    utils/fpdoc/plusimage.inc
U    utils/fpdoc/css.inc
U    utils/fpdoc/fpclasschart.lpi
G    utils/fpdoc/dglobals.pp
A    utils/fpdoc/minusimage.inc
--- Merging r23194 into '.':
G    utils/fpdoc/dglobals.pp
G    utils/fpdoc/dw_html.pp
U    utils/fpdoc/fpdocclasstree.pp
--- Merging r23195 into '.':
G    utils/fpdoc/fpdocclasstree.pp
G    utils/fpdoc/dw_html.pp
--- Merging r23196 into '.':
A    utils/fpdoc/images
A    utils/fpdoc/images/plus.png
A    utils/fpdoc/images/minus.png
--- Merging r23222 into '.':
G    utils/fpdoc/dwlinear.pp
U    utils/fpdoc/dw_latex.pp
G    utils/fpdoc/dw_ipflin.pas
--- Merging r23225 into '.':
G    packages/fcl-passrc/src/pparser.pp
U    packages/fcl-passrc/examples/testunit1.pp
G    utils/fpdoc/dw_html.pp
G    utils/fpdoc/dglobals.pp
--- Merging r23368 into '.':
G    utils/fpdoc/fpdocclasstree.pp
--- Merging r23369 into '.':
G    utils/fpdoc/dglobals.pp
--- Merging r23469 into '.':
G    packages/fcl-passrc/src/pscanner.pp
--- Merging r23470 into '.':
G    packages/fcl-passrc/src/pastree.pp
--- Merging r23471 into '.':
G    utils/fpdoc/dwriter.pp
--- Merging r23472 into '.':
G    utils/fpdoc/dglobals.pp
--- Merging r23473 into '.':
G    utils/fpdoc/dw_html.pp
--- Merging r23476 into '.':
G    utils/fpdoc/dglobals.pp
--- Merging r23536 into '.':
G    packages/fcl-passrc/src/pparser.pp
--- Merging r23537 into '.':
G    utils/fpdoc/dw_html.pp
--- Merging r23734 into '.':
U    packages/fcl-passrc/src/paswrite.pp
--- Merging r23760 into '.':
G    packages/fcl-passrc/src/pparser.pp
G    packages/fcl-passrc/src/pastree.pp
--- Merging r23763 into '.':
G    utils/fpdoc/dw_html.pp
--- Merging r23765 into '.':
G    utils/fpdoc/dw_htmlchm.inc
--- Merging r24089 into '.':
G    utils/fpdoc/dglobals.pp
--- Merging r24099 into '.':
G    utils/fpdoc/dw_html.pp
--- Merging r24132 into '.':
G    utils/fpdoc/dw_ipflin.pas
--- Merging r24171 into '.':
U    utils/fpdoc/README.txt
G    utils/fpdoc/testunit.xml
A    utils/fpdoc/fpdocstripper.pp
A    utils/fpdoc/fpdocstripper.lpi
--- Merging r24273 into '.':
G    utils/fpdoc/dglobals.pp
--- Merging r24275 into '.':
G    utils/fpdoc/fpdocclasstree.pp
--- Merging r24276 into '.':
G    utils/fpdoc/dw_html.pp
G    utils/fpdoc/dw_htmlchm.inc
G    utils/fpdoc/dglobals.pp
--- Merging r24277 into '.':
G    utils/fpdoc/dglobals.pp
--- Merging r24278 into '.':
G    utils/fpdoc/dw_html.pp
--- Merging r24289 into '.':
G    utils/fpdoc/dwriter.pp
--- Merging r24293 into '.':
G    utils/fpdoc/dw_html.pp
--- Merging r24294 into '.':
U    rtl/objpas/classes/classesh.inc
Summary of conflicts:
  Text conflicts: 3

# revisions: 22005,22006,22028,22029,22030,22031,22051,22052,22053,22078,22079,22082,22083,22084,22085,22088,22092,22094,22129,22130,22131,22135,22136,22140,22144,22150,22151,22152,22157,22164,22165,22170,22172,22173,22174,22197,22198,22199,22205,22210,22211,22214,22404,22405,22406,23171,23172,23193,23194,23195,23196,23222,23225,23368,23369,23469,23470,23471,23472,23473,23476,23536,23537,23734,23760,23763,23765,24089,24099,24132,24171,24273,24275,24276,24277,24278,24289,24293,24294
r22005 | michael | 2012-08-04 10:48:23 +0200 (Sat, 04 Aug 2012) | 1 line
Changed paths:
   A /trunk/packages/fcl-passrc/tests/tcbaseparser.pas
   A /trunk/packages/fcl-passrc/tests/tcmoduleparser.pas
   A /trunk/packages/fcl-passrc/tests/tconstparser.pas
   A /trunk/packages/fcl-passrc/tests/tcstatements.pas
   A /trunk/packages/fcl-passrc/tests/tctypeparser.pas
   A /trunk/packages/fcl-passrc/tests/tcvarparser.pas
   M /trunk/packages/fcl-passrc/tests/testpassrc.lpi
   M /trunk/packages/fcl-passrc/tests/testpassrc.lpr

* Test cases for types, var, const, resource string. Start of statement tests
r22006 | michael | 2012-08-04 11:16:54 +0200 (Sat, 04 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp

* IF condition expression is now a real expression, not a string
r22028 | michael | 2012-08-07 22:57:35 +0200 (Tue, 07 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp

Conditions in for/while/repeat are now expression elements
r22029 | michael | 2012-08-07 22:58:03 +0200 (Tue, 07 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/tests/tcstatements.pas

* Tests for loop structures
r22030 | michael | 2012-08-07 23:16:01 +0200 (Tue, 07 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp

* Use expressions in with statement
r22031 | michael | 2012-08-07 23:16:19 +0200 (Tue, 07 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/tests/tcstatements.pas

* with statement tests
r22051 | michael | 2012-08-09 21:24:02 +0200 (Thu, 09 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp

* Case statement labels are now expressions
r22052 | michael | 2012-08-09 21:24:37 +0200 (Thu, 09 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/tests/tcstatements.pas

* Case statement tests
r22053 | michael | 2012-08-09 21:31:36 +0200 (Thu, 09 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/examples/test_parser.pp

* Fixed to take expressions into account
r22078 | michael | 2012-08-14 20:27:46 +0200 (Tue, 14 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp
   M /trunk/utils/fpdoc/fpdoc.pp
   M /trunk/utils/fpdoc/makeskel.pp
   M /trunk/utils/fpdoc/testunit.xml

* Patch from Reinier Olislagers to update copyright and emit a more friendly message if an input file is not found (bug ID 22639)
r22079 | michael | 2012-08-14 20:47:57 +0200 (Tue, 14 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/Makefile
   M /trunk/utils/fpdoc/Makefile.fpc
   A /trunk/utils/fpdoc/css.inc
   M /trunk/utils/fpdoc/dw_html.pp

* Added functionality to create fpdoc.css from internal copy
r22082 | michael | 2012-08-15 11:01:11 +0200 (Wed, 15 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp

* Reworked raise parsing, now also supports raise X at Addr
r22083 | michael | 2012-08-15 12:52:21 +0200 (Wed, 15 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp

* Better Except handling
r22084 | michael | 2012-08-15 14:21:22 +0200 (Wed, 15 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp

* Use expression objects in case and constants
r22085 | michael | 2012-08-15 14:21:52 +0200 (Wed, 15 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/tests/tcstatements.pas
   M /trunk/packages/fcl-passrc/tests/tctypeparser.pas
   M /trunk/packages/fcl-passrc/tests/tcvarparser.pas

* Adapted tests to use expression objects where needed
r22088 | michael | 2012-08-15 17:02:05 +0200 (Wed, 15 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/tests/tcstatements.pas

* Finished try/except statements
r22092 | michael | 2012-08-15 18:00:51 +0200 (Wed, 15 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dw_html.pp

* Fixed to conform to new structures in pastree
r22094 | michael | 2012-08-15 18:14:09 +0200 (Wed, 15 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp

* Fixed memory leak in classes with interfaces
r22129 | michael | 2012-08-19 18:36:26 +0200 (Sun, 19 Aug 2012) | 4 lines
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

* Remove ParseExpression, changed everywhere to DoParseExpression
* Fix handling of procedure modifiers
* Solved all hints/warnings
r22130 | michael | 2012-08-19 18:40:52 +0200 (Sun, 19 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/tests/tcbaseparser.pas
   M /trunk/packages/fcl-passrc/tests/tcmoduleparser.pas
   M /trunk/packages/fcl-passrc/tests/tconstparser.pas
   M /trunk/packages/fcl-passrc/tests/tcscanner.pas
   M /trunk/packages/fcl-passrc/tests/tcstatements.pas
   M /trunk/packages/fcl-passrc/tests/tctypeparser.pas
   M /trunk/packages/fcl-passrc/tests/tcvarparser.pas

* Fixed warnings/hints
r22131 | michael | 2012-08-19 18:45:44 +0200 (Sun, 19 Aug 2012) | 1 line
Changed paths:
   A /trunk/packages/fcl-passrc/tests/tcclasstype.pas
   M /trunk/packages/fcl-passrc/tests/testpassrc.lpi
   M /trunk/packages/fcl-passrc/tests/testpassrc.lpr

* Class parsing tests (preparing for nested types)
r22135 | michael | 2012-08-19 23:57:55 +0200 (Sun, 19 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp
   M /trunk/packages/fcl-passrc/tests/tcbaseparser.pas
   M /trunk/packages/fcl-passrc/tests/tcscanner.pas
   M /trunk/packages/fcl-passrc/tests/tcstatements.pas

* Added support for C-style assignments
r22136 | michael | 2012-08-20 00:01:36 +0200 (Mon, 20 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pparser.pp
   M /trunk/packages/fcl-passrc/src/pscanner.pp

* Support for C-style assignments (bug 22007)
r22140 | michael | 2012-08-20 00:17:29 +0200 (Mon, 20 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dw_html.pp

* Patch from Graeme Geldenhuys to fix some tab->spaces (bug 22658)
r22144 | michael | 2012-08-20 18:36:18 +0200 (Mon, 20 Aug 2012) | 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/tests/tcbaseparser.pas
   M /trunk/packages/fcl-passrc/tests/tcclasstype.pas
   A /trunk/packages/fcl-passrc/tests/tcexprparser.pas
   M /trunk/packages/fcl-passrc/tests/tcscanner.pas
   M /trunk/packages/fcl-passrc/tests/tcstatements.pas
   M /trunk/packages/fcl-passrc/tests/testpassrc.lpi
   M /trunk/packages/fcl-passrc/tests/testpassrc.lpr

* Expression parsing tests, nested types
r22150 | michael | 2012-08-21 00:24:57 +0200 (Tue, 21 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dwriter.pp
   M /trunk/utils/fpdoc/mkfpdoc.pp

* Patch from DoDi to allow easy import
r22151 | michael | 2012-08-21 00:26:57 +0200 (Tue, 21 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dw_html.pp
   M /trunk/utils/fpdoc/dw_htmlchm.inc

* Write class local consts and types in correct way
r22152 | michael | 2012-08-21 00:28:25 +0200 (Tue, 21 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pparser.pp
   M /trunk/packages/fcl-passrc/tests/tcclasstype.pas

* Fix parsing of class local consts
r22157 | michael | 2012-08-21 15:24:37 +0200 (Tue, 21 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/examples/test_parser.pp
   M /trunk/packages/fcl-passrc/src/pastree.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp
   M /trunk/packages/fcl-passrc/tests/tcbaseparser.pas
   M /trunk/packages/fcl-passrc/tests/tcclasstype.pas
   A /trunk/packages/fcl-passrc/tests/tcprocfunc.pas
   M /trunk/packages/fcl-passrc/tests/testpassrc.lpi
   M /trunk/packages/fcl-passrc/tests/testpassrc.lpr

* Tests for procedure/function declarations, fixes in parsing of those
r22164 | michael | 2012-08-21 21:42:40 +0200 (Tue, 21 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/fpmake.pp
   A /trunk/packages/fcl-passrc/src/pastounittest.pp

* pastounittest added.
r22165 | michael | 2012-08-21 21:43:26 +0200 (Tue, 21 Aug 2012) | 1 line
Changed paths:
   A /trunk/utils/pas2ut
   A /trunk/utils/pas2ut/Makefile
   A /trunk/utils/pas2ut/Makefile.fpc
   A /trunk/utils/pas2ut/pas2ut.lpi
   A /trunk/utils/pas2ut/pas2ut.pp

* pas2ut, initial version (create unit tests from pascal unit)
r22170 | michael | 2012-08-22 13:25:59 +0200 (Wed, 22 Aug 2012) | 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
   M /trunk/packages/fcl-passrc/tests/tcbaseparser.pas
   M /trunk/packages/fcl-passrc/tests/tcclasstype.pas
   M /trunk/packages/fcl-passrc/tests/tcexprparser.pas
   M /trunk/packages/fcl-passrc/tests/tcscanner.pas
   M /trunk/packages/fcl-passrc/tests/tcstatements.pas

* For in construct and class/record helpers implemented
r22172 | michael | 2012-08-22 18:43:14 +0200 (Wed, 22 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/fpmake.pp
   A /trunk/packages/fcl-passrc/src/passrcutil.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp
   A /trunk/packages/fcl-passrc/tests/tcpassrcutil.pas
   M /trunk/packages/fcl-passrc/tests/testpassrc.lpi
   M /trunk/packages/fcl-passrc/tests/testpassrc.lpr

* Added passrcutil easy-use unit and component
r22173 | michael | 2012-08-22 18:45:57 +0200 (Wed, 22 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/Makefile
   M /trunk/utils/Makefile.fpc
   A /trunk/utils/pas2fpm
   A /trunk/utils/pas2fpm/Makefile
   A /trunk/utils/pas2fpm/Makefile.fpc
   A /trunk/utils/pas2fpm/pas2fpm.lpi
   A /trunk/utils/pas2fpm/pas2fpm.pp

* Added pas2fpm
r22174 | michael | 2012-08-22 18:49:47 +0200 (Wed, 22 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/fpclasschart.pp

* Fixed compilation
r22197 | michael | 2012-08-23 10:04:36 +0200 (Thu, 23 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/pas2fpm/Makefile
   M /trunk/utils/pas2fpm/Makefile.fpc

* Fixed makefile
r22198 | michael | 2012-08-23 10:21:07 +0200 (Thu, 23 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/pas2fpm/Makefile
   M /trunk/utils/pas2fpm/Makefile.fpc

* Dependency on fcl-base added
r22199 | michael | 2012-08-23 10:21:34 +0200 (Thu, 23 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/pas2ut/Makefile
   M /trunk/utils/pas2ut/Makefile.fpc

* Dependency on fcl-base added
r22205 | jonas | 2012-08-23 11:49:29 +0200 (Thu, 23 Aug 2012) | 4 lines
Changed paths:
   M /trunk/utils/pas2fpm/Makefile
   M /trunk/utils/pas2fpm/Makefile.fpc
   M /trunk/utils/pas2ut/Makefile
   M /trunk/utils/pas2ut/Makefile.fpc

  * like other applications that custapp, these also depend on univint on
    the Darwin/iphonesim platforms
  * regenerated using a current version of fpcmake
r22210 | michael | 2012-08-23 14:56:19 +0200 (Thu, 23 Aug 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/passrcutil.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp
   M /trunk/packages/fcl-passrc/src/pscanner.pp
   M /trunk/packages/fcl-passrc/tests/tcexprparser.pas

* Some small fixes so sdo is parsed
r22211 | michael | 2012-08-23 14:56:53 +0200 (Thu, 23 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/pas2fpm/pas2fpm.pp

* Improvements so package name can be specified, fpmake is excluded
r22214 | michael | 2012-08-23 17:27:00 +0200 (Thu, 23 Aug 2012) | 1 line
Changed paths:
   M /trunk/utils/pas2fpm/pas2fpm.pp

* Interdependency reduction, verbosity introduced
r22404 | michael | 2012-09-16 16:53:50 +0200 (Sun, 16 Sep 2012) | 1 line
Changed paths:
   M /trunk/utils/pas2ut/pas2ut.pp

* Fixed error in --limit and --defaultclasstest
r22405 | michael | 2012-09-16 17:06:12 +0200 (Sun, 16 Sep 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastounittest.pp
   M /trunk/utils/pas2ut/pas2ut.pp

* Implemented coCreateDeclaration
r22406 | michael | 2012-09-16 17:59:21 +0200 (Sun, 16 Sep 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastounittest.pp

* Add inherited to setup/teardown
r23171 | michael | 2012-12-18 12:06:01 +0100 (Tue, 18 Dec 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp
   M /trunk/utils/fpdoc/dw_xml.pp
   M /trunk/utils/fpdoc/dwriter.pp
   M /trunk/utils/fpdoc/fpdoc.pp
   M /trunk/utils/fpdoc/fpdocproj.pas
   M /trunk/utils/fpdoc/mkfpdoc.pp

* Patch from Reinier Olislaghers - some cosmetic changes (Bug ID 23506)
r23172 | michael | 2012-12-18 14:03:53 +0100 (Tue, 18 Dec 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp
   M /trunk/utils/fpdoc/dw_ipflin.pas
   M /trunk/utils/fpdoc/dwlinear.pp

* Patch from Graeme geldenhuys to introduce class hierarchy in IPF
r23193 | michael | 2012-12-20 16:00:10 +0100 (Thu, 20 Dec 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/Makefile
   M /trunk/utils/fpdoc/Makefile.fpc
   M /trunk/utils/fpdoc/css.inc
   M /trunk/utils/fpdoc/dglobals.pp
   M /trunk/utils/fpdoc/dw_html.pp
   M /trunk/utils/fpdoc/fpclasschart.lpi
   M /trunk/utils/fpdoc/fpclasschart.pp
   M /trunk/utils/fpdoc/fpdoc.css
   M /trunk/utils/fpdoc/fpdoc.lpi
   M /trunk/utils/fpdoc/fpdoc.pp
   A /trunk/utils/fpdoc/fpdocclasstree.pp
   A /trunk/utils/fpdoc/minusimage.inc
   A /trunk/utils/fpdoc/plusimage.inc

* Added ability to create class chart
r23194 | michael | 2012-12-20 16:54:24 +0100 (Thu, 20 Dec 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp
   M /trunk/utils/fpdoc/dw_html.pp
   M /trunk/utils/fpdoc/fpdocclasstree.pp

* Added ability to create class chart
r23195 | michael | 2012-12-20 17:21:14 +0100 (Thu, 20 Dec 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dw_html.pp
   M /trunk/utils/fpdoc/fpdocclasstree.pp

* Fixed unresolved elements in tree
r23196 | michael | 2012-12-20 18:16:17 +0100 (Thu, 20 Dec 2012) | 1 line
Changed paths:
   A /trunk/utils/fpdoc/images
   A /trunk/utils/fpdoc/images/minus.png
   A /trunk/utils/fpdoc/images/plus.png

* Forgot to commit images
r23222 | michael | 2012-12-26 15:13:10 +0100 (Wed, 26 Dec 2012) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dw_ipflin.pas
   M /trunk/utils/fpdoc/dw_latex.pp
   M /trunk/utils/fpdoc/dwlinear.pp

* Patch by Graeme Geldenhuys to fix various issues (bug ID 23432)
r23225 | michael | 2012-12-26 19:09:11 +0100 (Wed, 26 Dec 2012) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/examples/testunit1.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp
   M /trunk/utils/fpdoc/dglobals.pp
   M /trunk/utils/fpdoc/dw_html.pp

* Patch from Anton to support dotted unit names (Bug ID 22919)
r23368 | michael | 2013-01-12 16:16:48 +0100 (Sat, 12 Jan 2013) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/fpdocclasstree.pp

* remove debug output
r23369 | michael | 2013-01-12 17:08:40 +0100 (Sat, 12 Jan 2013) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp

* Undid patch to resolve dotted unit names, it breaks generation of FPC documentation
r23469 | michael | 2013-01-21 11:53:22 +0100 (Mon, 21 Jan 2013) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pscanner.pp

* Set read buffer size to 4K (speeds up)
r23470 | michael | 2013-01-21 11:54:00 +0100 (Mon, 21 Jan 2013) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp

mechanism to resolve members in ancestors
r23471 | michael | 2013-01-21 11:55:00 +0100 (Mon, 21 Jan 2013) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dwriter.pp

* Add context info to unresolved links, for better error info
r23472 | michael | 2013-01-21 11:56:07 +0100 (Mon, 21 Jan 2013) | 3 lines
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp

* Speed up read/write content file
* Configurable ResolveLink (strict or not)
r23473 | michael | 2013-01-21 11:57:54 +0100 (Mon, 21 Jan 2013) | 4 lines
Changed paths:
   M /trunk/utils/fpdoc/dw_html.pp

* use global resolveID (better result)
* Better link info in case of error
* Resolve property type to ancestors.
r23476 | michael | 2013-01-21 13:07:52 +0100 (Mon, 21 Jan 2013) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp

* Refactoring for better readability
r23536 | michael | 2013-01-29 20:00:00 +0100 (Tue, 29 Jan 2013) | 1 line
Changed paths:
   M /trunk/packages/fcl-passrc/src/pparser.pp

* assign name to anonymous string type
r23537 | michael | 2013-01-29 20:01:39 +0100 (Tue, 29 Jan 2013) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/dw_html.pp

* Strict resolving
r23734 | marco | 2013-03-08 23:38:34 +0100 (Fri, 08 Mar 2013) | 3 lines
Changed paths:
   M /trunk/packages/fcl-passrc/src/paswrite.pp

 * fix for #23915, use inheritsfrom instead of classtype = xxx because
    more types now have derivatives. As suggested by Daniel Gaspary.
r23760 | marco | 2013-03-09 23:07:33 +0100 (Sat, 09 Mar 2013) | 15 lines
Changed paths:
   M /trunk/packages/fcl-passrc/src/pastree.pp
   M /trunk/packages/fcl-passrc/src/pparser.pp

 * fixed 3 problems in fcl-passrc found when searching why fcl.chm
    didn't build for 2.6.2
   1. The nested function in findmemberancestors didn't set result.
       Possibily sleeping bug triggered by -gttt
   2. TPasmodule.Getelement crashed for some classes loaded from .xct
         (code assuming they were pasmodule derivatives)
         This probably touches a deeper lying problem where the 
	 (new) classtree doesn't validate nodetypes properly, and loaded
	 classes end up as modules in one or the other overview
   3. *Visibility functions had an out parameter that was not set
	 in all cases. Changed to VAR. (see mail fpc-devel from today).
         Another -gttt sleeper bug.
    
  (2) probably was the main problem of the initial crash.
r23763 | marco | 2013-03-10 00:37:59 +0100 (Sun, 10 Mar 2013) | 2 lines
Changed paths:
   M /trunk/utils/fpdoc/dw_html.pp

 * another small bug caught by -CROriot
r23765 | marco | 2013-03-10 00:54:13 +0100 (Sun, 10 Mar 2013) | 2 lines
Changed paths:
   M /trunk/utils/fpdoc/dw_htmlchm.inc

 * another minor problem found with -CR
r24089 | marco | 2013-03-31 15:05:36 +0200 (Sun, 31 Mar 2013) | 2 lines
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp

 * throw warning when there is a space in the XCT imported link.
r24099 | marco | 2013-04-01 00:01:52 +0200 (Mon, 01 Apr 2013) | 2 lines
Changed paths:
   M /trunk/utils/fpdoc/dw_html.pp

 * avoid prepending unitname with abs paths.
r24132 | marco | 2013-04-02 17:37:59 +0200 (Tue, 02 Apr 2013) | 5 lines
Changed paths:
   M /trunk/utils/fpdoc/dw_ipflin.pas

 * committed Graeme's IPF patches, mantis #24084:
	- Fixes the resolving of links issues in the Class Hierarchy output for IPF
	- Implements BeginURL and EndURL methods for the IPF writer. Now it correctly
	     handles the [url] tag in fpdoc XML files.
r24171 | michael | 2013-04-07 10:49:03 +0200 (Sun, 07 Apr 2013) | 1 line
Changed paths:
   M /trunk/utils/fpdoc/README.txt
   A /trunk/utils/fpdoc/fpdocstripper.lpi
   A /trunk/utils/fpdoc/fpdocstripper.pp
   M /trunk/utils/fpdoc/testunit.xml

* modified Docstripper by Reinier Olislagers (bug 23988)
r24273 | marco | 2013-04-20 01:50:43 +0200 (Sat, 20 Apr 2013) | 2 lines
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp

 * don't crash on inclusion of fpmake.pp
r24275 | marco | 2013-04-20 14:46:50 +0200 (Sat, 20 Apr 2013) | 2 lines
Changed paths:
   M /trunk/utils/fpdoc/fpdocclasstree.pp

 * work arounds the worst of the classtree bugs. LCL now compiles.
r24276 | marco | 2013-04-20 17:31:56 +0200 (Sat, 20 Apr 2013) | 3 lines
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp
   M /trunk/utils/fpdoc/dw_html.pp
   M /trunk/utils/fpdoc/dw_htmlchm.inc

 * Various small changes. LCL compiles again, but is 10% smaller.
    tree inheritance still not fully linked.
r24277 | marco | 2013-04-20 22:53:59 +0200 (Sat, 20 Apr 2013) | 7 lines
Changed paths:
   M /trunk/utils/fpdoc/dglobals.pp

 * fixed a bug in resolving external references for classtree and whatever else
   uses findelement.
   
   A reference was checked against TPasModule with "=", ruling out descendants
   like TPasExternalModule. All "content" (.xct) symbols are in externalmodules
r24278 | marco | 2013-04-21 00:27:06 +0200 (Sun, 21 Apr 2013) | 3 lines
Changed paths:
   M /trunk/utils/fpdoc/dw_html.pp

 * more inheritsfrom fixes. This time for the inheritance pages. 
 (    [properties (by name)] etc )
r24289 | marco | 2013-04-21 19:39:48 +0200 (Sun, 21 Apr 2013) | 2 lines
Changed paths:
   M /trunk/utils/fpdoc/dwriter.pp

 * fix for shortdescrs. Refmodule was unassigned if the target of the shortdescr was not a module.
r24293 | marco | 2013-04-21 22:20:21 +0200 (Sun, 21 Apr 2013) | 2 lines
Changed paths:
   M /trunk/utils/fpdoc/dw_html.pp

 * two more "getmodule" fixes.
r24294 | marco | 2013-04-21 23:33:10 +0200 (Sun, 21 Apr 2013) | 2 lines
Changed paths:
   M /trunk/rtl/objpas/classes/classesh.inc

 * removed a workaround for pre 2.6.0 fpdocs

git-svn-id: branches/fixes_2_6@24556 -
marco 12 years ago
parent
commit
de82339f4a
64 changed files with 21128 additions and 1169 deletions
  1. 28 0
      .gitattributes
  2. 130 130
      packages/fcl-passrc/Makefile
  3. 2 2
      packages/fcl-passrc/Makefile.fpc
  4. 6 6
      packages/fcl-passrc/examples/test_parser.pp
  5. 11 2
      packages/fcl-passrc/examples/testunit1.pp
  6. 21 4
      packages/fcl-passrc/fpmake.pp
  7. 301 0
      packages/fcl-passrc/src/passrcutil.pp
  8. 745 0
      packages/fcl-passrc/src/pastounittest.pp
  9. 369 74
      packages/fcl-passrc/src/pastree.pp
  10. 3 3
      packages/fcl-passrc/src/paswrite.pp
  11. 314 267
      packages/fcl-passrc/src/pparser.pp
  12. 62 12
      packages/fcl-passrc/src/pscanner.pp
  13. 496 0
      packages/fcl-passrc/tests/tcbaseparser.pas
  14. 1432 0
      packages/fcl-passrc/tests/tcclasstype.pas
  15. 910 0
      packages/fcl-passrc/tests/tcexprparser.pas
  16. 377 0
      packages/fcl-passrc/tests/tcmoduleparser.pas
  17. 631 0
      packages/fcl-passrc/tests/tconstparser.pas
  18. 422 0
      packages/fcl-passrc/tests/tcpassrcutil.pas
  19. 1121 0
      packages/fcl-passrc/tests/tcprocfunc.pas
  20. 39 1
      packages/fcl-passrc/tests/tcscanner.pas
  21. 1402 0
      packages/fcl-passrc/tests/tcstatements.pas
  22. 2839 0
      packages/fcl-passrc/tests/tctypeparser.pas
  23. 300 0
      packages/fcl-passrc/tests/tcvarparser.pas
  24. 53 2
      packages/fcl-passrc/tests/testpassrc.lpi
  25. 5 1
      packages/fcl-passrc/tests/testpassrc.lpr
  26. 0 4
      rtl/objpas/classes/classesh.inc
  27. 285 65
      utils/Makefile
  28. 1 1
      utils/Makefile.fpc
  29. 113 2
      utils/fpdoc/Makefile
  30. 14 2
      utils/fpdoc/Makefile.fpc
  31. 8 0
      utils/fpdoc/README.txt
  32. 135 0
      utils/fpdoc/css.inc
  33. 115 96
      utils/fpdoc/dglobals.pp
  34. 526 249
      utils/fpdoc/dw_html.pp
  35. 23 2
      utils/fpdoc/dw_htmlchm.inc
  36. 119 10
      utils/fpdoc/dw_ipflin.pas
  37. 1 1
      utils/fpdoc/dw_latex.pp
  38. 4 2
      utils/fpdoc/dw_xml.pp
  39. 15 4
      utils/fpdoc/dwlinear.pp
  40. 89 56
      utils/fpdoc/dwriter.pp
  41. 18 6
      utils/fpdoc/fpclasschart.lpi
  42. 11 108
      utils/fpdoc/fpclasschart.pp
  43. 20 26
      utils/fpdoc/fpdoc.css
  44. 7 2
      utils/fpdoc/fpdoc.lpi
  45. 41 19
      utils/fpdoc/fpdoc.pp
  46. 182 0
      utils/fpdoc/fpdocclasstree.pp
  47. 2 2
      utils/fpdoc/fpdocproj.pas
  48. 89 0
      utils/fpdoc/fpdocstripper.lpi
  49. 191 0
      utils/fpdoc/fpdocstripper.pp
  50. BIN
      utils/fpdoc/images/minus.png
  51. BIN
      utils/fpdoc/images/plus.png
  52. 18 3
      utils/fpdoc/makeskel.pp
  53. 20 0
      utils/fpdoc/minusimage.inc
  54. 7 4
      utils/fpdoc/mkfpdoc.pp
  55. 21 0
      utils/fpdoc/plusimage.inc
  56. 3 1
      utils/fpdoc/testunit.xml
  57. 2974 0
      utils/pas2fpm/Makefile
  58. 30 0
      utils/pas2fpm/Makefile.fpc
  59. 72 0
      utils/pas2fpm/pas2fpm.lpi
  60. 560 0
      utils/pas2fpm/pas2fpm.pp
  61. 2974 0
      utils/pas2ut/Makefile
  62. 30 0
      utils/pas2ut/Makefile.fpc
  63. 77 0
      utils/pas2ut/pas2ut.lpi
  64. 314 0
      utils/pas2ut/pas2ut.pp

+ 28 - 0
.gitattributes

@@ -2234,12 +2234,24 @@ packages/fcl-passrc/Makefile.fpc svneol=native#text/plain
 packages/fcl-passrc/examples/test_parser.pp svneol=native#text/plain
 packages/fcl-passrc/examples/test_parser.pp svneol=native#text/plain
 packages/fcl-passrc/examples/testunit1.pp svneol=native#text/plain
 packages/fcl-passrc/examples/testunit1.pp svneol=native#text/plain
 packages/fcl-passrc/fpmake.pp svneol=native#text/plain
 packages/fcl-passrc/fpmake.pp svneol=native#text/plain
+packages/fcl-passrc/src/passrcutil.pp svneol=native#text/plain
+packages/fcl-passrc/src/pastounittest.pp svneol=native#text/plain
 packages/fcl-passrc/src/pastree.pp svneol=native#text/plain
 packages/fcl-passrc/src/pastree.pp svneol=native#text/plain
 packages/fcl-passrc/src/paswrite.pp svneol=native#text/plain
 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/tcbaseparser.pas svneol=native#text/plain
+packages/fcl-passrc/tests/tcclasstype.pas svneol=native#text/plain
+packages/fcl-passrc/tests/tcexprparser.pas svneol=native#text/plain
+packages/fcl-passrc/tests/tcmoduleparser.pas svneol=native#text/plain
+packages/fcl-passrc/tests/tconstparser.pas svneol=native#text/plain
+packages/fcl-passrc/tests/tcpassrcutil.pas svneol=native#text/plain
+packages/fcl-passrc/tests/tcprocfunc.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcscanner.pas svneol=native#text/plain
 packages/fcl-passrc/tests/tcscanner.pas svneol=native#text/plain
+packages/fcl-passrc/tests/tcstatements.pas svneol=native#text/plain
+packages/fcl-passrc/tests/tctypeparser.pas svneol=native#text/plain
+packages/fcl-passrc/tests/tcvarparser.pas svneol=native#text/plain
 packages/fcl-passrc/tests/testpassrc.lpi 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-passrc/tests/testpassrc.lpr svneol=native#text/plain
 packages/fcl-process/Makefile svneol=native#text/plain
 packages/fcl-process/Makefile svneol=native#text/plain
@@ -12872,6 +12884,7 @@ utils/fpdoc/COPYING.txt svneol=native#text/plain
 utils/fpdoc/Makefile svneol=native#text/plain
 utils/fpdoc/Makefile svneol=native#text/plain
 utils/fpdoc/Makefile.fpc svneol=native#text/plain
 utils/fpdoc/Makefile.fpc svneol=native#text/plain
 utils/fpdoc/README.txt svneol=native#text/plain
 utils/fpdoc/README.txt svneol=native#text/plain
+utils/fpdoc/css.inc svneol=native#text/plain
 utils/fpdoc/dglobals.pp svneol=native#text/plain
 utils/fpdoc/dglobals.pp svneol=native#text/plain
 utils/fpdoc/dw_dxml.pp svneol=native#text/plain
 utils/fpdoc/dw_dxml.pp svneol=native#text/plain
 utils/fpdoc/dw_html.pp svneol=native#text/plain
 utils/fpdoc/dw_html.pp svneol=native#text/plain
@@ -12921,8 +12934,13 @@ utils/fpdoc/fpde/xpms.pp svneol=native#text/plain
 utils/fpdoc/fpdoc.css -text
 utils/fpdoc/fpdoc.css -text
 utils/fpdoc/fpdoc.lpi svneol=native#text/plain
 utils/fpdoc/fpdoc.lpi svneol=native#text/plain
 utils/fpdoc/fpdoc.pp svneol=native#text/plain
 utils/fpdoc/fpdoc.pp svneol=native#text/plain
+utils/fpdoc/fpdocclasstree.pp svneol=native#text/plain
 utils/fpdoc/fpdocproj.pas svneol=native#text/plain
 utils/fpdoc/fpdocproj.pas svneol=native#text/plain
+utils/fpdoc/fpdocstripper.lpi svneol=native#text/plain
+utils/fpdoc/fpdocstripper.pp svneol=native#text/plain
 utils/fpdoc/fpdocxmlopts.pas svneol=native#text/plain
 utils/fpdoc/fpdocxmlopts.pas svneol=native#text/plain
+utils/fpdoc/images/minus.png -text svneol=unset#image/png
+utils/fpdoc/images/plus.png -text svneol=unset#image/png
 utils/fpdoc/intl/Makefile svneol=native#text/plain
 utils/fpdoc/intl/Makefile svneol=native#text/plain
 utils/fpdoc/intl/dglobals.de.po svneol=native#text/plain
 utils/fpdoc/intl/dglobals.de.po svneol=native#text/plain
 utils/fpdoc/intl/dglobals.sk.po svneol=native#text/plain
 utils/fpdoc/intl/dglobals.sk.po svneol=native#text/plain
@@ -12934,9 +12952,11 @@ 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/mgrfpdocproj.pp svneol=native#text/plain
+utils/fpdoc/minusimage.inc svneol=native#text/plain
 utils/fpdoc/mkfpdoc.pp svneol=native#text/plain
 utils/fpdoc/mkfpdoc.pp svneol=native#text/plain
 utils/fpdoc/mkfpdocproj.lpi svneol=native#text/plain
 utils/fpdoc/mkfpdocproj.lpi svneol=native#text/plain
 utils/fpdoc/mkfpdocproj.pp svneol=native#text/plain
 utils/fpdoc/mkfpdocproj.pp svneol=native#text/plain
+utils/fpdoc/plusimage.inc 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
@@ -13050,6 +13070,14 @@ utils/mksymbian/mksymbian.lpi svneol=native#text/plain
 utils/mksymbian/mksymbian.pas svneol=native#text/plain
 utils/mksymbian/mksymbian.pas svneol=native#text/plain
 utils/mksymbian/projectparser.pas svneol=native#text/plain
 utils/mksymbian/projectparser.pas svneol=native#text/plain
 utils/mksymbian/sdkutil.pas svneol=native#text/plain
 utils/mksymbian/sdkutil.pas svneol=native#text/plain
+utils/pas2fpm/Makefile svneol=native#text/plain
+utils/pas2fpm/Makefile.fpc svneol=native#text/plain
+utils/pas2fpm/pas2fpm.lpi svneol=native#text/plain
+utils/pas2fpm/pas2fpm.pp svneol=native#text/plain
+utils/pas2ut/Makefile svneol=native#text/plain
+utils/pas2ut/Makefile.fpc svneol=native#text/plain
+utils/pas2ut/pas2ut.lpi svneol=native#text/plain
+utils/pas2ut/pas2ut.pp svneol=native#text/plain
 utils/postw32.pp svneol=native#text/plain
 utils/postw32.pp svneol=native#text/plain
 utils/ppdep.pp svneol=native#text/plain
 utils/ppdep.pp svneol=native#text/plain
 utils/ptop.pp svneol=native#text/plain
 utils/ptop.pp svneol=native#text/plain

+ 130 - 130
packages/fcl-passrc/Makefile

@@ -289,394 +289,394 @@ endif
 override PACKAGE_NAME=fcl-passrc
 override PACKAGE_NAME=fcl-passrc
 override PACKAGE_VERSION=2.6.3
 override PACKAGE_VERSION=2.6.3
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
 ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
 ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
 ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
 ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 endif
 override INSTALL_FPCPACKAGE=y
 override INSTALL_FPCPACKAGE=y
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)

+ 2 - 2
packages/fcl-passrc/Makefile.fpc

@@ -7,8 +7,8 @@ name=fcl-passrc
 version=2.6.3
 version=2.6.3
 
 
 [target]
 [target]
-units=pastree pscanner pparser paswrite
-rsts=pscanner pparser pastree
+units=pastree pscanner pparser paswrite pastounittest passrcutil
+rsts=pscanner pparser pastree pastounittest
 
 
 [compiler]
 [compiler]
 options=-S2h
 options=-S2h

+ 6 - 6
packages/fcl-passrc/examples/test_parser.pp

@@ -488,8 +488,8 @@ begin
       begin
       begin
        write(s);
        write(s);
        for l:=0 to lics.Expressions.Count-2 do
        for l:=0 to lics.Expressions.Count-2 do
-          write(DelQuot(lics.Expressions[l]),',');
-       write(DelQuot(lics.Expressions[lics.Expressions.Count-1]),': '); // !!bug too much ' in expression
+          write(DelQuot(TPasExpr(lics.Expressions[l]).GetDeclaration(True)),',');
+       write(DelQuot(TPasExpr(lics.Expressions[lics.Expressions.Count-1]).GetDeclaration(True)),': '); // !!bug too much ' in expression
        //if not assigned(lics.Body) then writeln('TPasImplCaseStatement missing BODY');
        //if not assigned(lics.Body) then writeln('TPasImplCaseStatement missing BODY');
        //if assigned(lics.Body) and (TPasImplBlock(lics.Body).Elements.Count >0) then
        //if assigned(lics.Body) and (TPasImplBlock(lics.Body).Elements.Count >0) then
        //  GetTPasImplBlock(TPasImplBlock(lics.Body),lindent+1,0,false,true)
        //  GetTPasImplBlock(TPasImplBlock(lics.Body),lindent+1,0,false,true)
@@ -509,8 +509,8 @@ begin
      if liwd.Expressions.Count>0 then
      if liwd.Expressions.Count>0 then
       begin
       begin
        for l:=0 to liwd.Expressions.Count-2 do
        for l:=0 to liwd.Expressions.Count-2 do
-         write(liwd.Expressions[l],',');
-       write(liwd.Expressions[liwd.Expressions.Count-1]);
+         write(TPasExpr(liwd.Expressions[l]).GetDeclaration(true),',');
+       write(TPasExpr(liwd.Expressions[liwd.Expressions.Count-1]).GetDeclaration(true));
       end;
       end;
      writeln(' do');
      writeln(' do');
      //if TPasImplBlock(liwd.Body).Elements.Count >0  then
      //if TPasImplBlock(liwd.Body).Elements.Count >0  then
@@ -1157,7 +1157,7 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
           begin
           begin
            pv:=TPasVariant(prct.Variants[i]);
            pv:=TPasVariant(prct.Variants[i]);
            write(s1,pv.Name);
            write(s1,pv.Name);
-           for k:=0 to pv.Values.Count-1 do write(pv.Values[k]);
+           for k:=0 to pv.Values.Count-1 do write(TPasElement(pv.Values[k]).GetDeclaration(true));
            write(': (');
            write(': (');
            if GetVariantRecord(TPasElement(pv.Members),j+1) then
            if GetVariantRecord(TPasElement(pv.Members),j+1) then
              writeln(s1,');')
              writeln(s1,');')
@@ -1245,7 +1245,7 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
           begin
           begin
            pv:=TPasVariant(prct.Variants[i]);
            pv:=TPasVariant(prct.Variants[i]);
            write(s2,pv.Name);
            write(s2,pv.Name);
-           for k:=0 to pv.Values.Count-1 do write(pv.Values[k]);
+           for k:=0 to pv.Values.Count-1 do write(TPasElement(pv.Values[k]).GetDeclaration(true));
            write(': (');
            write(': (');
            if GetVariantRecord(TPasElement(pv.Members),j+2) then
            if GetVariantRecord(TPasElement(pv.Members),j+2) then
              writeln(s2,');')
              writeln(s2,');')

+ 11 - 2
packages/fcl-passrc/examples/testunit1.pp

@@ -26,7 +26,8 @@ resourcestring
   ARecordConst: TMethod=(Code:nil;Data:nil);
   ARecordConst: TMethod=(Code:nil;Data:nil);
   ASetConst=[true,false];
   ASetConst=[true,false];
   ADeprecatedConst=1 deprecated;
   ADeprecatedConst=1 deprecated;
-   
+  ADeprecatedConst2 = 2 deprecated 'use another const';
+     
  Type
  Type
   TLineEndStr = string [3];
   TLineEndStr = string [3];
 
 
@@ -41,6 +42,7 @@ resourcestring
     x,Y : Integer deprecated
     x,Y : Integer deprecated
   end;
   end;
   TAnEnumType=(one,two,three);
   TAnEnumType=(one,two,three);
+  arangetypealias = type 0..$FF;
   TASetType=set of TAnEnumType;
   TASetType=set of TAnEnumType;
   TIntegerSet = Set of 0..SizeOf(Integer)*8-1;
   TIntegerSet = Set of 0..SizeOf(Integer)*8-1;
   TAnArrayType=Array[1..10] of Integer;
   TAnArrayType=Array[1..10] of Integer;
@@ -52,7 +54,6 @@ resourcestring
   TDays = set of TDay;
   TDays = set of TDay;
   TMyInteger = Integer;
   TMyInteger = Integer;
   ADouble = type double;
   ADouble = type double;
-  arangetypealias = type 0..$FF;
   TARecordType=record
   TARecordType=record
                    X,Y: Integer;
                    X,Y: Integer;
                    Z: String;
                    Z: String;
@@ -101,6 +102,9 @@ TYPE
                
                
 
 
   TNotifyEvent = Procedure (Sender : TObject) of object;
   TNotifyEvent = Procedure (Sender : TObject) of object;
+
+  TNestedProcedure = Procedure (Sender : TObject) is nested;
+
   TNotifyEvent2 = Function (Sender : TObject) : Integer of object;
   TNotifyEvent2 = Function (Sender : TObject) : Integer of object;
  
  
                           
                           
@@ -236,6 +240,11 @@ var
  Procedure externallibnameProc; external 'alibrary' name 'aname';
  Procedure externallibnameProc; external 'alibrary' name 'aname';
  Function  hi(q : QWord) : DWord;   [INTERNPROC: fpc_in_hi_qword];
  Function  hi(q : QWord) : DWord;   [INTERNPROC: fpc_in_hi_qword];
 
 
+{$define extdecl:=cdecl}
+Type
+  FontEnumProc = function (var ELogFont:TEnumLogFont; var Metric:TNewTextMetric;
+      FontType:longint; Data:LParam):longint; extdecl;
+      
  
  
 Type
 Type
  generic TFPGListEnumerator<T> = class(TObject)
  generic TFPGListEnumerator<T> = class(TObject)

+ 21 - 4
packages/fcl-passrc/fpmake.pp

@@ -29,20 +29,37 @@ begin
 
 
     T:=P.Targets.AddUnit('pastree.pp');
     T:=P.Targets.AddUnit('pastree.pp');
     T.ResourceStrings := True;
     T.ResourceStrings := True;
-    T:=P.Targets.AddUnit('paswrite.pp');
+    T:=P.Targets.AddUnit('pscanner.pp');
+    T.ResourceStrings := True;
+    T:=P.Targets.AddUnit('pparser.pp');
       with T.Dependencies do
       with T.Dependencies do
         begin
         begin
           AddUnit('pastree');
           AddUnit('pastree');
+          AddUnit('pscanner');
         end;
         end;
-    T:=P.Targets.AddUnit('pparser.pp');
+    T.ResourceStrings := True;
+    T:=P.Targets.AddUnit('pastounittest.pp');
       with T.Dependencies do
       with T.Dependencies do
         begin
         begin
+          AddUnit('pparser');
           AddUnit('pastree');
           AddUnit('pastree');
           AddUnit('pscanner');
           AddUnit('pscanner');
         end;
         end;
     T.ResourceStrings := True;
     T.ResourceStrings := True;
-    T:=P.Targets.AddUnit('pscanner.pp');
-    T.ResourceStrings := True;
+    T:=P.Targets.AddUnit('passrcutil.pp');
+      with T.Dependencies do
+        begin
+          AddUnit('pparser');
+          AddUnit('pastree');
+          AddUnit('pscanner');
+        end;
+    T.ResourceStrings := False;
+
+    T:=P.Targets.AddUnit('paswrite.pp');
+      with T.Dependencies do
+        begin
+          AddUnit('pastree');
+        end;
 
 
 {$ifndef ALLPACKAGES}
 {$ifndef ALLPACKAGES}
     Run;
     Run;

+ 301 - 0
packages/fcl-passrc/src/passrcutil.pp

@@ -0,0 +1,301 @@
+unit passrcutil;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, pscanner, pparser, pastree;
+
+Type
+
+  { TPasSrcAnalysis }
+
+  TPasSrcAnalysis = class(TComponent)
+  private
+    FFilename : string;
+    FResolver : TBaseFileResolver;
+    FScanner  : TPascalScanner;
+    FParser   : TPasParser;
+    FModule   : TPasModule;
+    FContainer : TPasTreeContainer;
+    FStream: TStream;
+    procedure SetFileName(AValue: string);
+    Function ResourceStringCount(Section : TPasSection) : Integer;
+  Protected
+    Procedure FreeParser;
+    Procedure CheckParser;
+    Procedure Parse;
+    procedure GetRecordFields(Rec: TPasrecordType; List: TStrings; const APrefix: String = ''); virtual;
+    procedure GetClassMembers(AClass: TPasClassType; List: TStrings; AVisibilities : TPasMemberVisibilities; const APrefix: String = ''); virtual;
+    procedure GetEnumValues(Enum: TPasEnumType; List: TStrings; const APrefix: String = ''); virtual;
+    procedure GetIdentifiers(Section: TPasSection; List: TStrings; Recurse: Boolean);virtual;
+    procedure GetUses(ASection: TPasSection; List: TStrings);virtual;
+  Public
+    Destructor Destroy; override;
+    Procedure GetInterfaceUnits(List : TStrings);
+    Procedure GetImplementationUnits(List : TStrings);
+    Procedure GetUsedUnits(List : TStrings);
+    Procedure GetInterfaceIdentifiers(List : TStrings; Recurse : Boolean = False);
+    Procedure GetImplementationIdentifiers(List : TStrings; Recurse : Boolean = False);
+    Procedure GetAllIdentifiers(List : TStrings; Recurse : Boolean = False);
+    Function InterfaceHasResourcestrings : Boolean;
+    Function ImplementationHasResourcestrings : Boolean;
+    Function HasResourcestrings : Boolean;
+    Property Stream : TStream Read FStream Write FStream;
+  Published
+    Property FileName : string Read FFilename Write SetFileName;
+  end;
+
+
+
+implementation
+
+Type
+  { TSrcContainer }
+  TSrcContainer = Class(TPasTreeContainer)
+  Public
+    function CreateElement(AClass: TPTreeElement; const AName: String;
+      AParent: TPasElement; AVisibility: TPasMemberVisibility;
+      const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;overload; override;
+    function FindElement(const AName: String): TPasElement; override;
+  end;
+  { TSrcContainer }
+
+function TSrcContainer.CreateElement(AClass: TPTreeElement;
+  const AName: String; AParent: TPasElement; AVisibility: TPasMemberVisibility;
+  const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;
+begin
+  Result:=AClass.Create(AName,AParent);
+  Result.Visibility:=AVisibility;
+  Result.SourceFilename:=ASourceFileName;
+  Result.SourceLinenumber:=ASourceLineNumber;
+end;
+
+function TSrcContainer.FindElement(const AName: String): TPasElement;
+begin
+  Result:=Nil;
+end;
+
+{ TPasSrcAnalysis }
+
+procedure TPasSrcAnalysis.SetFileName(AValue: string);
+begin
+  if FFilename=AValue then Exit;
+  FFilename:=AValue;
+  FreeParser;
+end;
+
+function TPasSrcAnalysis.ResourceStringCount(Section: TPasSection): Integer;
+begin
+  Result:=0;
+  If Assigned(Section) and Assigned(Section.ResStrings) then
+   Result:=Section.ResStrings.Count;;
+end;
+
+procedure TPasSrcAnalysis.FreeParser;
+
+begin
+  FreeAndNil(FParser);
+  FreeAndNil(FScanner);
+  FreeAndNil(FContainer);
+  FreeAndNil(FResolver);
+  FreeAndNil(FModule);
+end;
+
+procedure TPasSrcAnalysis.CheckParser;
+
+Var
+  D : String;
+
+begin
+  If (FParser<>Nil) then
+    exit;
+  Try
+    If Assigned(Stream) then
+      begin
+      FResolver:=TStreamResolver.Create;
+      TStreamResolver(Fresolver).AddStream(FileName,Stream);
+      end
+    else
+      FResolver:=TFileResolver.Create;
+    D:=ExtractFilePath(FileName);
+    If (D='') then
+      D:='.';
+    FResolver.BaseDirectory:=D;
+    FResolver.AddIncludePath(D);
+    FScanner:=TPascalScanner.Create(FResolver);
+    FScanner.OpenFile(FileName);
+    FContainer:=TSrcContainer.Create;
+    FParser:=TPasParser.Create(FScanner,FResolver,FContainer);
+    FScanner.AddDefine('FPC');
+  except
+    FreeParser;
+    Raise;
+  end;
+end;
+
+procedure TPasSrcAnalysis.Parse;
+begin
+  If FModule<>Nil then exit;
+  CheckParser;
+  FParser.ParseMain(FModule);
+end;
+
+procedure TPasSrcAnalysis.GetRecordFields(Rec: TPasrecordType; List: TStrings;
+  const APrefix: String = '');
+
+Var
+  I : Integer;
+  E : TPasElement;
+  V : TPasVariant;
+
+begin
+  For I:=0 to Rec.Members.Count-1 do
+    begin
+    E:=TPasElement(Rec.Members[I]);
+    if E<>Nil then
+      List.Add(APrefix+E.Name);
+    end;
+  If Assigned(Rec.Variants) then
+    For I:=0 to Rec.Variants.Count-1 do
+      begin
+      V:=TPasVariant(Rec.Variants[I]);
+      if (v<>Nil) and (V.members<>Nil) then
+        GetRecordFields(V.Members,List,APrefix);
+      end;
+end;
+
+procedure TPasSrcAnalysis.GetClassMembers(AClass: TPasClassType; List: TStrings;
+  AVisibilities: TPasMemberVisibilities; const APrefix: String);
+Var
+  I : Integer;
+  E : TPasElement;
+  V : TPasVariant;
+
+begin
+  For I:=0 to AClass.Members.Count-1 do
+    begin
+    E:=TPasElement(AClass.Members[I]);
+    if (E<>Nil) and ((AVisibilities=[]) or (E.Visibility in AVisibilities)) then
+      List.Add(APrefix+E.Name);
+    end;
+end;
+
+destructor TPasSrcAnalysis.Destroy;
+begin
+  FreeParser;
+  inherited Destroy;
+end;
+
+procedure TPasSrcAnalysis.GetUses(ASection : TPasSection; List: TStrings);
+
+Var
+  I : Integer;
+begin
+  If Assigned(ASection) and Assigned(ASection.UsesList) then
+    For I:=0 to ASection.UsesList.Count-1 do
+      List.Add(TPasElement(ASection.UsesList[i]).Name);
+end;
+
+procedure TPasSrcAnalysis.GetInterfaceUnits(List: TStrings);
+begin
+  Parse;
+  GetUses(Fmodule.InterfaceSection,List);
+end;
+
+procedure TPasSrcAnalysis.GetImplementationUnits(List: TStrings);
+begin
+  Parse;
+  GetUses(Fmodule.ImplementationSection,List);
+end;
+
+procedure TPasSrcAnalysis.GetUsedUnits(List: TStrings);
+begin
+  Parse;
+  GetUses(Fmodule.InterfaceSection,List);
+  GetUses(Fmodule.ImplementationSection,List);
+end;
+
+procedure TPasSrcAnalysis.GetEnumValues(Enum : TPasEnumType;List : TStrings; Const APrefix : String = '');
+
+Var
+  I : Integer;
+  E : TPasElement;
+
+begin
+  For I:=0 to Enum.Values.Count-1 do
+    begin
+    E:=TPasElement(Enum.Values[I]);
+    If (E<>Nil) then
+      List.Add(APrefix+E.Name);
+    end;
+end;
+
+procedure TPasSrcAnalysis.GetIdentifiers(Section : TPasSection; List: TStrings; Recurse : Boolean);
+
+Var
+  I : Integer;
+  E : TPasElement;
+
+begin
+  if not (Assigned(Section) and Assigned(Section.Declarations)) then
+    Exit;
+  For I:=0 to Section.Declarations.Count-1 do
+    begin
+    E:=TPasElement(Section.Declarations[I]);
+    If (E.Name<>'') then
+      List.Add(E.Name);
+    if Recurse then
+      begin
+      If E is TPasEnumType then
+        GetEnumValues(TPasEnumType(E),List,E.Name+'.')
+      else if E is TPasRecordType then
+        GetRecordFields(TPasRecordType(E),List,E.Name+'.')
+      else if E is TPasClassType then
+        GetClassMembers(TPasClassType(E),List,[],E.Name+'.')
+      end;
+    end;
+end;
+
+procedure TPasSrcAnalysis.GetInterfaceIdentifiers(List: TStrings; Recurse : Boolean = False);
+begin
+  Parse;
+  GetIdentifiers(Fmodule.InterfaceSection,List,Recurse);
+end;
+
+procedure TPasSrcAnalysis.GetImplementationIdentifiers(List: TStrings;
+  Recurse: Boolean);
+begin
+  Parse;
+  GetIdentifiers(Fmodule.ImplementationSection,List,Recurse);
+end;
+
+procedure TPasSrcAnalysis.GetAllIdentifiers(List: TStrings; Recurse: Boolean);
+begin
+  Parse;
+  GetIdentifiers(Fmodule.InterfaceSection,List,Recurse);
+  GetIdentifiers(Fmodule.ImplementationSection,List,Recurse);
+end;
+
+function TPasSrcAnalysis.InterfaceHasResourcestrings: Boolean;
+begin
+  Parse;
+  Result:=ResourceStringCount(Fmodule.InterfaceSection)>0;
+end;
+
+function TPasSrcAnalysis.ImplementationHasResourcestrings: Boolean;
+begin
+  Parse;
+  Result:=ResourceStringCount(Fmodule.ImplementationSection)>0;
+end;
+
+function TPasSrcAnalysis.HasResourcestrings: Boolean;
+begin
+  Parse;
+  Result:=(ResourceStringCount(Fmodule.InterfaceSection)>0)
+           or (ResourceStringCount(Fmodule.ImplementationSection)>0);
+end;
+
+end.
+

+ 745 - 0
packages/fcl-passrc/src/pastounittest.pp

@@ -0,0 +1,745 @@
+{
+    This file is part of the Free Component Library
+    Copyright (c) 2012 by the Free Pascal team
+
+    Pascal source to FPC Unit test generator
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+unit pastounittest;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, PScanner, pparser, pastree;
+
+
+Type
+
+
+  TTestMemberType = (tmtMethods,   // Generate tests for methods
+                     tmtFields,    // Generate tests for fields
+                     tmtProperties // Generate tests for properties
+                     );
+  TTestMemberTypes = set of TTestmemberType;
+  TTestPropertyOption = (tDefault,    // Generate default test for a property
+                         tGetBounds,  // Generate Property GetBounds test (tiOPF)
+                         tRequired,   // Generate Property Required test (tiOPF)
+                         tNotify,     // Generate Property change notification test (tiOPF)
+                         tMaxLen);    // Generate property MaxLen (tiOPF)
+  TTestpropertyOptions = set of TTestpropertyOption;
+  TTestCodeOption = (coCreateDeclaration, // Generate declaration of test cases. 
+                     coImplementation,  // generate (empty) implementation of tests
+                     coDefaultFail,     // Insert Fail() statement in tests
+                     coSingleClass,     // Use a single test class for all tests
+                     coCreateUnit,      // Generate complete unit source
+                     coSetup,           // Generate Setup() method for all test classes
+                     coTearDown,        // Generate TearDown() method for all test classes
+                     coFunctions,       // Generate tests for functions
+                     coClasses,         // Generate tests for classes
+                     coRegisterTests);  // Register all generated test classes
+  TTestCodeOptions = set of TTestCodeOption;
+
+  { TFPTestCodeCreator }
+
+  TFPTestCodeCreator = Class(TComponent)
+  private
+    FCO: TTestCodeOptions;
+    FDCT: TStrings;
+    FDestUnitName: string;
+    FFailMessage: String;
+    FLimits: TStrings;
+    FMemberTypes: TTestmemberTypes;
+    FPO: TTestpropertyOptions;
+    FTCP: String;
+    FTP: String;
+    FUTC: String;
+    FVisibilities: TPasMemberVisibilities;
+    FTests : TStrings;
+    FM : String;
+    procedure SetDCT(AValue: TStrings);
+    procedure SetFailMessage(Const AValue: String);
+    procedure SetLimits(AValue: TStrings);
+    procedure StartTestClassImpl(C: TStrings; Const AClassName: String);
+  protected
+    // Split test name S in class name and method name.
+    procedure ExtractClassMethod(S: string; out CN, MN: String);virtual;
+    // Return classname for testcase for a class.
+    Function GetTestClassName(CT : TPasClassType) : String; virtual;
+    // Should this identifier be tested ? Only called for global identifiers.
+    function AllowIdentifier(S: TPasElement): boolean;
+    // Should return true if a variable/property type is a string type.
+    function IsStringType(T:  TPasType): Boolean;virtual;
+    // Add a test to the list of tests.
+    // If ATestClass is empty, test is added to the global unit test class.
+    // If coSingleClass is in the options, all tests are added to this class
+    // and ATestClass is prefixed to the test name.
+    Procedure AddTest(Const ATestClass,ATestName : String); virtual;
+    // Create implementation of test code. After 'Implementation' keyword was added
+    procedure CreateImplementationCode(C: TStrings); virtual;
+    // Add a test method body to the implementation. AddFail=True adds a Fail statement.
+    procedure AddMethodImpl(C: TStrings; Const AClassName, AMethodName: String; AddFail: Boolean; AddInherited : Boolean = false);virtual;
+    // Called when all the methods of a class have been emitted. Empty.
+    procedure EndTestClassImpl(C: TStrings; Const AClassName: String);virtual;
+    // Create interface test code. After uses clause of interface section.
+    procedure CreateInterfaceCode(C: TStrings);virtual;
+    // Called whenever a new test class declaration is started.
+    procedure StartTestClassDecl(C: TStrings; AClassName: String); virtual;
+    // Called whenever a test class declaration is finished (adds end;)
+    procedure EndTestClassDecl(C: TStrings; AClassName: String); virtual;
+    // Called to add default test methods for a class.
+    procedure AddDefaultMethodDecl(C: TStrings; Const AClassName: String);virtual;
+    // Create test code based on tests
+    procedure CreateTestCode(Dest: TStream; const InputUnitName: string);virtual;
+    // Calls DoCreateTests for the interface section of the module.
+    procedure DoCreateTests(M: TPasModule);virtual;
+    // Create tests for a modult. Creates tests for functions/procedures and classes.
+    procedure DoCreateTests(S: TPasSection);virtual;
+    // Called for each function/procedure in a section to create tests for it.
+    procedure DoCreateTests(P: TPasProcedure);virtual;
+    // Called for each overloaded function/procedure in a section to create tests for it.
+    procedure DoCreateTests(P: TPasOverloadedProc);virtual;
+    // Called for each class in a section to create tests for the class.
+    procedure DoCreateTests(CT: TPasClasstype);virtual;
+    // Called for each overloaded method in a class to create tests for it (within visibilities).
+    procedure DoCreateTests(const TCN: String; CT: TPasClasstype; P: TPasOverloadedProc);virtual;
+    // Called for each method in a class to create tests for it (within visibilities)
+    procedure DoCreateTests(const TCN: String; CT: TPasClasstype; P: TPasprocedure);virtual;
+    // Called for each field in a class to create tests for it (within visibilities).
+    procedure DoCreateTests(const TCN: String; CT: TPasClasstype; P: TPasVariable);virtual;
+    // Called for each property in a class to create tests for it(within visibilities).
+    procedure DoCreateTests(const TCN: String; CT: TPasClasstype; P: TPasProperty);virtual;
+    // Parse the actual source and return module.
+    function ParseSource(const ASourceStream : TStream): TPasModule;
+    // Main entry to create tests.
+    procedure CreateTests(M: TPasModule; Dest : TStream);
+    // List of test names in the form ClassName.MethodName. Setup and Teardown are not in the list.
+    Property Tests : TStrings Read FTests;
+  Public
+    Constructor Create(AOwner :TComponent); override;
+    Destructor Destroy; override;
+    // Create test unit cases in dest (file/stream/tstrings) based on
+    // Code in source
+    Procedure Execute(Const ASourceFileName,ADestFileName : String);
+    Procedure Execute(Const ASourceStream,ADestStream : TStream);
+    Procedure Execute(Const ASourceCode,ADestCode : TStrings);
+  Published
+    // If not empty, tests will be generated only for the global identifiers in this list
+    Property LimitIdentifiers : TStrings Read FLimits Write SetLimits;
+    // List of names of tests which are always generated for each test.
+    Property DefaultClassTests : TStrings Read FDCT Write SetDCT;
+    // For class members, member visibilities for which to generate tests.
+    Property Visibilities : TPasMemberVisibilities Read FVisibilities Write FVisibilities;
+    // For which class members should tests be generated
+    Property MemberTypes : TTestmemberTypes Read FMemberTypes Write FMemberTypes;
+    // What default tests should be generated for properties/fields in a class
+    Property PropertyOptions : TTestpropertyOptions Read FPO Write FPO;
+    // Various options for the generated code
+    Property CodeOptions : TTestCodeOptions Read FCO Write FCO;
+    // Destination unit name. If empty, name will be taken from input file.
+    Property DestUnitName : string Read FDestUnitName Write FDestUnitName;
+    // Name for the global unit test case. If not set, it is 'Test'+the input unit name
+    Property UnitTestClassName: String Read FUTC Write FUTC;
+    // Prefix for names of all tests
+    Property TestNamePrefix : String Read FTP Write FTP;
+    // Name of parent of all test classes
+    Property TestClassParent : String Read FTCP Write FTCP;
+    // Text to put in Fail() statement.
+    Property FailMessage : String Read FFailMessage Write SetFailMessage;
+  end;
+
+Const
+  DefaultVisibilities    = [visDefault,visPublished,visPublic];
+  DefaultPropertyOptions = [tDefault];
+  DefaultCodeOptions     = [coCreateDeclaration,coImplementation,coDefaultFail,coCreateUnit,
+                            coSetup,coTearDown, coFunctions, coClasses,
+                            coRegisterTests];
+  DefaultMembers         = [tmtMethods,tmtFields,tmtProperties];
+  DefaultTestClassParent = 'TTestCase';
+
+Resourcestring
+  DefaultFailmessage     = 'This test is not yet implemented';
+
+Procedure CreateUnitTests(Const InputFile,OutputFile : String; ACodeOptions : TTestCodeOptions = [] );
+
+implementation
+
+Type
+  { TTestContainer }
+
+  TTestContainer = Class(TPasTreeContainer)
+  Public
+    function CreateElement(AClass: TPTreeElement; const AName: String;
+      AParent: TPasElement; AVisibility: TPasMemberVisibility;
+      const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;overload;
+      override;
+    function FindElement(const AName: String): TPasElement; override;
+  end;
+
+procedure CreateUnitTests(const InputFile, OutputFile: String; ACodeOptions : TTestCodeOptions = [] );
+begin
+  with TFPTestCodeCreator.Create(Nil) do
+    try
+      if ACodeOptions<>[] then
+        CodeOptions:=ACodeOptions;
+      Execute(inputfile,outputfile);
+    finally
+      free;
+    end;
+end;
+
+{ TFPTestCodeCreator }
+
+procedure TFPTestCodeCreator.SetLimits(AValue: TStrings);
+begin
+  if FLimits=AValue then Exit;
+  FLimits.Assign(AValue);
+end;
+
+function TFPTestCodeCreator.GetTestClassName(CT: TPasClassType): String;
+begin
+  Result:=CT.Name;
+  if Not (coSingleClass in CodeOptions) then
+    begin
+    if Upcase(Result[1])='T' then
+      Delete(Result,1,1);
+    Result:='TTest'+Result;
+    end;
+end;
+
+procedure TFPTestCodeCreator.EndTestClassDecl(C: TStrings; AClassName: String);
+begin
+  C.Add('  end;');
+  C.Add('');
+  C.Add('');
+end;
+
+procedure TFPTestCodeCreator.AddTest(const ATestClass, ATestName: String);
+
+Var
+  CN,TN : String;
+
+begin
+  TN:=ATestName;
+  if ATestClass='' then
+    CN:=UnitTestClassName
+  else
+    CN:=ATestClass;
+  if (coSingleClass in CodeOptions) then
+    begin
+    TN:=ATestClass+TN;
+    CN:=UnitTestClassName;
+    end;
+  FTests.Add(CN+'.'+TestNamePrefix+TN);
+end;
+
+procedure TFPTestCodeCreator.DoCreateTests(const TCN: String;
+  CT: TPasClasstype; P: TPasOverloadedProc);
+begin
+  AddTest(TCN,P.Name);
+end;
+
+procedure TFPTestCodeCreator.DoCreateTests(P : TPasProcedure);
+
+begin
+  AddTest('',P.Name);
+end;
+
+procedure TFPTestCodeCreator.DoCreateTests(P: TPasOverloadedProc);
+begin
+  AddTest('',P.Name);
+end;
+
+procedure TFPTestCodeCreator.DoCreateTests(Const TCN: String; CT : TPasClasstype; P : TPasprocedure);
+
+begin
+  AddTest(TCN,P.Name);
+end;
+
+Function TFPTestCodeCreator.IsStringType(T : TPasType) : Boolean;
+
+Var
+  tn : string;
+begin
+  While t is TPasAliasType do
+    T:=TPasAliasType(t).DestType;
+  tn:=lowercase(t.name);
+  Result:=(T is TPasStringType) or (tn='string') or (tn='ansistring') or (tn='widestring') or (tn='unicodestring') or (tn='shortstring');
+end;
+
+procedure TFPTestCodeCreator.DoCreateTests(Const TCN: String; CT : TPasClasstype; P : TPasVariable);
+
+begin
+  if (tDefault in PropertyOptions) then
+    AddTest(TCN,P.Name);
+  if (tRequired in PropertyOptions) then
+    AddTest(TCN,P.Name+'Required');
+  if (tGetBounds in PropertyOptions) then
+    AddTest(TCN,P.Name+'GetBounds');
+  If (tmaxLen in PropertyOptions) then
+    if Assigned(P.VarType) and IsStringType(P.VarType) then
+      AddTest(TCN,P.Name+'MaxLen');
+end;
+
+procedure TFPTestCodeCreator.DoCreateTests(const TCN: String;
+  CT: TPasClasstype; P: TPasProperty);
+begin
+  if (tDefault in PropertyOptions) then
+    AddTest(TCN,P.Name);
+  if (tRequired in PropertyOptions) then
+    AddTest(TCN,P.Name+'Required');
+  if (tGetBounds in PropertyOptions) then
+    AddTest(TCN,P.Name+'GetBounds');
+  if (tNotify in PropertyOptions) then
+    AddTest(TCN,P.Name+'Notify');
+  If (tmaxLen in PropertyOptions) then
+    if Assigned(P.VarType) and IsStringType(P.VarType) then
+      AddTest(TCN,P.Name+'MaxLen');
+end;
+
+procedure TFPTestCodeCreator.DoCreateTests(CT : TPasClasstype);
+
+Var
+  E : TPasElement;
+  I : Integer;
+  TCN : String;
+
+begin
+  TCN:=GetTestClassName(CT);
+  For I:=0 to DefaultClassTests.Count-1 do
+    AddTest(TCN,DefaultClassTests[i]);
+  if (tmtMethods in Membertypes) then
+    For I:=0 to CT.Members.Count-1 do
+      begin
+      E:=TPasElement(CT.Members[i]);
+      if (E is TPasProcedure) and (E.Visibility in Visibilities) then
+        DoCreateTests(TCN,CT,TPasProcedure(E))
+      else if (E is TPasoverloadedProc) and (E.Visibility in Visibilities) then
+        DoCreateTests(TCN,CT,TPasoverloadedProc(E));
+      end;
+  if (tmtFields in Membertypes) then
+    For I:=0 to CT.Members.Count-1 do
+      begin
+      E:=TPasElement(CT.Members[i]);
+      if (E is TPasVariable) and (Not(E is TPasProperty)) and (E.Visibility in Visibilities) then
+        DoCreateTests(TCN,CT,TPasVariable(E));
+      end;
+  if (tmtProperties in Membertypes) then
+    For I:=0 to CT.Members.Count-1 do
+      begin
+      E:=TPasElement(CT.Members[i]);
+      if (E is TPasProperty) and (E.Visibility in Visibilities) then
+        DoCreateTests(TCN,CT,TPasProperty(E));
+      end;
+end;
+
+function TFPTestCodeCreator.AllowIdentifier(S: TPasElement) : boolean;
+
+begin
+  Result:=(LimitIdentifiers.Count=0) or (LimitIdentifiers.IndexOf(S.Name)<>-1);
+end;
+
+procedure TFPTestCodeCreator.DoCreateTests(S: TPasSection);
+
+Var
+  I : integer;
+  CT : TPasClasstype;
+  FT : TPasProcedure;
+  O : TPasOverloadedProc;
+
+begin
+  if coClasses in CodeOptions then
+    For I:=0 to S.Classes.Count-1 do
+      begin
+      CT:=TPasClassType(S.Classes[i]);
+      If Not CT.IsForward then
+        if AllowIdentifier(CT) then
+          DoCreateTests(CT);
+      end;
+  if coFunctions in CodeOptions then
+    For I:=0 to S.Functions.Count-1 do
+      begin
+      if TPasElement(S.Functions[i]) is TPasProcedure then
+        begin
+        FT:=TPasElement(S.Functions[i]) as TPasProcedure;
+        If Not FT.IsForward then
+          if AllowIdentifier(FT) then
+            DoCreateTests(FT);
+        end
+      else if TPasElement(S.Functions[i]) is TPasOverloadedProc then
+        begin
+        O:=TPasElement(S.Functions[i]) as TPasOverloadedProc;
+        if AllowIdentifier(O) then
+          DoCreateTests(O);
+        end;
+      end;
+end;
+
+procedure TFPTestCodeCreator.DoCreateTests(M: TPasModule);
+
+begin
+  If UnitTestClassName='' then
+    UnitTestClassName:='Test'+M.Name;
+  DoCreateTests(M.InterfaceSection);
+end;
+
+procedure TFPTestCodeCreator.SetDCT(AValue: TStrings);
+begin
+  if FDCT=AValue then Exit;
+  FDCT.Assign(AValue);
+end;
+
+procedure TFPTestCodeCreator.SetFailMessage(Const AValue: String);
+begin
+  if FFailMessage=AValue then Exit;
+  FFailMessage:=AValue;
+  FM:=StringReplace(FailMessage,'''','''''',[rfReplaceAll]);
+end;
+
+constructor TFPTestCodeCreator.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  FLimits:=TStringList.Create;
+  TStringList(FLimits).Sorted:=True;
+  FDCT:=TstringList.Create;
+  FDCT.Add('Empty');
+  FDCT.Add('IsValid');
+  TestNamePrefix:='Test';
+  Visibilities:=DefaultVisibilities;
+  CodeOptions:=DefaultCodeOptions;
+  PropertyOptions:=DefaultPropertyOptions;
+  MemberTypes:=DefaultMembers;
+  TestClassParent:=DefaultTestClassParent;
+  FailMessage:=DefaultFailmessage;
+end;
+
+destructor TFPTestCodeCreator.Destroy;
+begin
+  FreeAndNil(FDCT);
+  FreeAndNil(FLimits);
+  inherited Destroy;
+end;
+
+procedure TFPTestCodeCreator.Execute(const ASourceFileName,
+  ADestFileName: String);
+
+Var
+  Fi,Fo : TFileStream;
+
+begin
+  Fi:=TFileStream.Create(ASourceFileName,fmOpenRead);
+  try
+    Fo:=TFileStream.Create(ADestFileName,fmCreate);
+    try
+      if (DestunitName='') then
+        DestUnitName:=ChangeFileExt(ExtractFileName(ADestFileName),'');
+      Execute(Fi,Fo);
+    finally
+      FO.free;
+    end;
+  finally
+    Fi.Free;
+  end;
+end;
+
+procedure TFPTestCodeCreator.StartTestClassDecl(C : TStrings; AClassName : String);
+
+begin
+  C.Add('  { '+AClassName+' }');
+  C.Add('');
+  C.Add(Format('  %s = Class(%s)',[ACLassName,TestClassParent]));
+  If (([coSetup,coTearDown] * CodeOptions)<>[]) then
+    begin
+    C.Add('  Protected');
+    if coSetup in CodeOptions then
+      C.Add('    procedure Setup; override;');
+    if coSetup in CodeOptions then
+      C.Add('    procedure TearDown; override;');
+    end;
+end;
+
+
+procedure TFPTestCodeCreator.AddDefaultMethodDecl(C : TStrings; const AClassName : String);
+
+begin
+//
+end;
+
+Procedure TFPTestCodeCreator.ExtractClassMethod(S : string; Out CN,MN : String);
+
+Var
+  P : Integer;
+begin
+  P:=Pos('.',S);
+  Cn:=Copy(S,1,P-1);
+  MN:=S;
+  Delete(MN,1,P);
+end;
+
+procedure TFPTestCodeCreator.CreateInterfaceCode(C : TStrings);
+
+Var
+  CCN,CN,MN : String;
+  I : Integer;
+
+begin
+  CCN:='';
+  For I:=0 to FTests.Count-1 do
+    begin
+    ExtractClassMethod(FTests[i],Cn,MN);
+    If (CN<>CCN) then
+      begin
+      if (CCN<>'') then
+        EndTestClassDecl(C,CN);
+      StartTestClassDecl(C,CN);
+      C.Add('  Published');
+      AddDefaultMethodDecl(C,CN);
+      CCN:=CN;
+      end;
+    C.Add('    Procedure '+MN+';');
+    end;
+  if (CCN<>'') then
+    EndTestClassDecl(C,CN);
+end;
+
+procedure TFPTestCodeCreator.AddMethodImpl(C : TStrings; Const AClassName,AMethodName : String; AddFail : Boolean; AddInherited : Boolean = false);
+
+begin
+  C.Add('');
+  C.Add(Format('Procedure %s.%s;',[AClassName,AMethodName]));
+  C.Add('');
+  C.Add('begin');
+  if AddFail then
+    C.Add(Format('  Fail(''%s'');',[FM]));
+  if AddInherited then
+    C.Add('  Inherited;');  
+  C.Add('end;');
+  C.Add('');
+end;
+
+procedure TFPTestCodeCreator.StartTestClassImpl(C : TStrings; Const AClassName : String);
+
+begin
+  C.Add('');
+  C.Add('  { '+AClassName+' }');
+  C.Add('');
+  if coSetup in CodeOptions then
+    AddMethodImpl(C,AClassName,'Setup',False,True);
+  if coTearDown in CodeOptions then
+    AddMethodImpl(C,AClassName,'TearDown',False,True);
+end;
+
+procedure TFPTestCodeCreator.EndTestClassImpl(C : TStrings; Const AClassName : String);
+
+begin
+end;
+
+procedure TFPTestCodeCreator.CreateImplementationCode(C : TStrings);
+
+Var
+  CCN,CN,MN : String;
+  I : Integer;
+  F : Boolean;
+
+begin
+  CCN:='';
+  F:=coDefaultFail in CodeOptions;
+  For I:=0 to FTests.Count-1 do
+    begin
+    ExtractClassMethod(FTests[i],Cn,MN);
+    If (CN<>CCN) then
+      begin
+      if (CCN<>'') then
+        EndTestClassImpl(C,CN);
+      StartTestClassImpl(C,CN);
+      CCN:=CN;
+      end;
+    AddMethodImpl(C,CN,MN,F);
+    end;
+  if (CCN<>'') then
+    EndTestClassImpl(C,CN);
+end;
+
+procedure TFPTestCodeCreator.CreateTestCode(Dest : TStream; Const InputUnitName : string);
+
+  Function GetTestClassNames : String;
+
+  Var
+    L : TStringList;
+    i : Integer;
+    CN,MN : String;
+
+  begin
+    L:=TStringList.Create;
+    try
+      L.Sorted:=True;
+      L.Duplicates:=dupIgnore;
+      For I:=0 to Tests.Count-1 do
+        begin
+        Self.ExtractClassMethod(Tests[i],CN,MN);
+        L.Add(CN);
+        end;
+      Result:=L.CommaText;
+    finally
+      L.free;
+    end;
+  end;
+
+Var
+  C : TStrings;
+  S : String;
+
+begin
+  C:=TStringList.Create;
+  try
+    If (coCreateUnit in CodeOptions) then
+      begin
+      C.Add(Format('unit %s;',[DestUnitName]));
+      C.Add('');
+      C.Add('interface');
+      C.Add('');
+      C.Add(Format('Uses Classes, SysUtils, fpcunit, testutils, testregistry, %s;',[InputUnitName]));
+      C.Add('');
+      C.Add('Type');
+      end;
+    If (coCreateDeclaration in CodeOptions) then
+      CreateInterfaceCode(C);
+    if (coImplementation in CodeOptions) then
+      begin
+      If (coCreateUnit in CodeOptions) then
+        begin
+        C.Add('');
+        C.Add('implementation');
+        C.Add('');
+        end;
+      CreateImplementationCode(C);
+      If (coCreateUnit in CodeOptions) then
+        begin
+        C.Add('');
+        if coRegisterTests in CodeOptions then
+          begin
+          S:=GetTestClassNames;
+          C.Add('Initialization');
+          C.Add(Format('  RegisterTests([%s]);',[S]));
+          end;
+        C.Add('end.');
+        end;
+      end;
+    C.SaveToStream(Dest);
+  finally
+    C.Free;
+  end;
+end;
+
+procedure TFPTestCodeCreator.CreateTests(M: TPasModule; Dest: TStream);
+
+begin
+  FTests:=TStringList.Create;
+  try
+    DoCreateTests(M);
+    CreateTestCode(Dest,M.Name);
+  finally
+    FTests.Free;
+  end;
+end;
+
+Function TFPTestCodeCreator.ParseSource(const ASourceStream : TStream) : TPasModule;
+
+Var
+  R : TStreamResolver;
+  S : TPascalScanner;
+  P : TPasParser;
+  M : TPasModule;
+  C : TTestContainer;
+
+begin
+  R:=TStreamResolver.Create;
+  try
+    R.AddStream('file.pp',ASourceStream);
+    S:=TPascalScanner.Create(R);
+    try
+      S.OpenFile('file.pp');
+      C:=TTestContainer.Create;
+      try
+        C.InterfaceOnly:=True;
+        P:=TPasParser.Create(S,R,C);
+        try
+          P.ParseMain(Result);
+        finally
+          P.Free;
+        end;
+      finally
+        C.Free;
+      end;
+    finally
+      S.Free;
+    end;
+  finally
+    R.Free;
+  end;
+end;
+
+procedure TFPTestCodeCreator.Execute(const ASourceStream, ADestStream: TStream);
+
+Var
+  M : TPasModule;
+
+begin
+  M:=ParseSource(ASourceStream);
+  try
+    if Assigned(M) then
+      CreateTests(M,ADestStream);
+  finally
+    M.Free;
+  end;
+end;
+
+procedure TFPTestCodeCreator.Execute(const ASourceCode, ADestCode: TStrings);
+
+Var
+  MIn,Mout : TStringStream;
+
+begin
+  Min:=TStringStream.Create(ASourceCode.Text);
+  try
+    Mout:=TStringstream.Create('');
+    try
+      Min.Position:=0;
+      Execute(Min,Mout);
+      Mout.Position:=0;
+      ADestCode.Text:=Mout.DataString;
+    finally
+      Mout.free;
+    end;
+  finally
+    Min.Free;
+  end;
+end;
+
+{ TTestContainer }
+
+function TTestContainer.CreateElement(AClass: TPTreeElement;
+  const AName: String; AParent: TPasElement; AVisibility: TPasMemberVisibility;
+  const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;
+begin
+  Result:=AClass.Create(AName,AParent);
+  Result.Visibility:=AVisibility;
+  Result.SourceFilename:=ASourceFileName;
+  Result.SourceLinenumber:=ASourceLineNumber;
+end;
+
+function TTestContainer.FindElement(const AName: String): TPasElement;
+begin
+  Result:=Nil;
+end;
+
+end.
+

+ 369 - 74
packages/fcl-passrc/src/pastree.pp

@@ -50,6 +50,8 @@ resourcestring
   SPasTreeInterfaceType = 'interface';
   SPasTreeInterfaceType = 'interface';
   SPasTreeGenericType = 'generic class';
   SPasTreeGenericType = 'generic class';
   SPasTreeSpecializedType = 'specialized class type';
   SPasTreeSpecializedType = 'specialized class type';
+  SPasClassHelperType = 'Class helper type';
+  SPasRecordHelperType = 'Record helper type';
   SPasTreeArgument = 'argument';
   SPasTreeArgument = 'argument';
   SPasTreeProcedureType = 'procedure type';
   SPasTreeProcedureType = 'procedure type';
   SPasTreeResultElement = 'function result';
   SPasTreeResultElement = 'function result';
@@ -192,6 +194,7 @@ type
   { TInheritedExpr }
   { TInheritedExpr }
 
 
   TInheritedExpr = class(TPasExpr)
   TInheritedExpr = class(TPasExpr)
+  Public
     constructor Create(AParent : TPasElement); overload;
     constructor Create(AParent : TPasElement); overload;
     function GetDeclaration(full : Boolean) : string; override;
     function GetDeclaration(full : Boolean) : string; override;
   end;
   end;
@@ -437,9 +440,9 @@ type
   public
   public
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
   public
   public
-//    IsValueUsed: Boolean;
-//    Value: Integer;
-    AssignedValue : string;
+    Value: TPasExpr;
+    Destructor Destroy; override;
+    Function AssignedValue : string;
   end;
   end;
 
 
   { TPasEnumType }
   { TPasEnumType }
@@ -475,7 +478,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
-    Values: TStringList;
+    Values: TFPList;
     Members: TPasRecordType;
     Members: TPasRecordType;
   end;
   end;
 
 
@@ -498,7 +501,8 @@ type
   end;
   end;
 
 
   TPasGenericTemplateType = Class(TPasElement);
   TPasGenericTemplateType = Class(TPasElement);
-  TPasObjKind = (okObject, okClass, okInterface, okGeneric, okSpecialize);
+  TPasObjKind = (okObject, okClass, okInterface, okGeneric, okSpecialize,
+                 okClassHelper,okRecordHelper);
 
 
   { TPasClassType }
   { TPasClassType }
 
 
@@ -511,16 +515,19 @@ type
     PackMode : TPackMode;
     PackMode : TPackMode;
     ObjKind: TPasObjKind;
     ObjKind: TPasObjKind;
     AncestorType: TPasType;     // TPasClassType or TPasUnresolvedTypeRef
     AncestorType: TPasType;     // TPasClassType or TPasUnresolvedTypeRef
+    HelperForType: TPasType;     // TPasClassType or TPasUnresolvedTypeRef
     IsForward : Boolean;
     IsForward : Boolean;
     IsShortDefinition: Boolean;//class(anchestor); without end
     IsShortDefinition: Boolean;//class(anchestor); without end
+    GUIDExpr : TPasExpr;
     Members: TFPList;     // array of TPasElement objects
     Members: TFPList;     // array of TPasElement objects
-    InterfaceGUID : string; // 15/06/07 - Inoussa
-
     ClassVars: TFPList;   // class vars
     ClassVars: TFPList;   // class vars
     Modifiers: TStringList;
     Modifiers: TStringList;
     Interfaces : TFPList;
     Interfaces : TFPList;
     GenericTemplateTypes : TFPList;
     GenericTemplateTypes : TFPList;
+    Function FindMember(MemberClass : TPTreeElement; Const MemberName : String) : TPasElement;
+    Function FindMemberInAncestors(MemberClass : TPTreeElement; Const MemberName : String) : TPasElement;
     Function IsPacked : Boolean;
     Function IsPacked : Boolean;
+    Function InterfaceGUID : string;
   end;
   end;
 
 
 
 
@@ -616,7 +623,7 @@ type
   end;
   end;
 
 
   { TPasVariable }
   { TPasVariable }
-  TVariableModifier = (vmCVar, vmExternal, vmPublic, vmExport);
+  TVariableModifier = (vmCVar, vmExternal, vmPublic, vmExport, vmClass);
   TVariableModifiers = set of TVariableModifier;
   TVariableModifiers = set of TVariableModifier;
 
 
   TPasVariable = class(TPasElement)
   TPasVariable = class(TPasElement)
@@ -626,12 +633,12 @@ type
     function GetDeclaration(full : boolean) : string; override;
     function GetDeclaration(full : boolean) : string; override;
   public
   public
     VarType: TPasType;
     VarType: TPasType;
-    Value: string;
     VarModifiers : TVariableModifiers;
     VarModifiers : TVariableModifiers;
     LibraryName,ExportName : string;
     LibraryName,ExportName : string;
     Modifiers : string;
     Modifiers : string;
     AbsoluteLocation : String;
     AbsoluteLocation : String;
     Expr: TPasExpr;
     Expr: TPasExpr;
+    Function Value : String;
   end;
   end;
 
 
   { TPasExportSymbol }
   { TPasExportSymbol }
@@ -655,16 +662,23 @@ type
   { TPasProperty }
   { TPasProperty }
 
 
   TPasProperty = class(TPasVariable)
   TPasProperty = class(TPasVariable)
+  Public
+    FResolvedType : TPasType;
   public
   public
     constructor Create(const AName: string; AParent: TPasElement); override;
     constructor Create(const AName: string; AParent: TPasElement); override;
     destructor Destroy; override;
     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
+    IndexExpr,
+    DefaultExpr : TPasExpr;
     Args: TFPList;        // List of TPasArgument objects
     Args: TFPList;        // List of TPasArgument objects
-    IndexValue, ReadAccessorName, WriteAccessorName,ImplementsName,
-      StoredAccessorName, DefaultValue: string;
+    ReadAccessorName, WriteAccessorName,ImplementsName,
+      StoredAccessorName: string;
     IsDefault, IsNodefault: Boolean;
     IsDefault, IsNodefault: Boolean;
+    Function ResolvedType : TPasType;
+    Function IndexValue : String;
+    Function DefaultValue : string;
   end;
   end;
 
 
   { TPasProcedureBase }
   { TPasProcedureBase }
@@ -687,11 +701,11 @@ type
   end;
   end;
 
 
   TProcedureModifier = (pmVirtual, pmDynamic, pmAbstract, pmOverride,
   TProcedureModifier = (pmVirtual, pmDynamic, pmAbstract, pmOverride,
-                        pmExported, pmOverload, pmMessage, pmReintroduce,
-                        pmStatic,pmInline,pmAssembler,pmVarargs,
+                        pmExport, pmOverload, pmMessage, pmReintroduce,
+                        pmStatic,pmInline,pmAssembler,pmVarargs, pmPublic,
                         pmCompilerProc,pmExternal,pmForward);
                         pmCompilerProc,pmExternal,pmForward);
   TProcedureModifiers = Set of TProcedureModifier;
   TProcedureModifiers = Set of TProcedureModifier;
-  TProcedureMessageType = (pmtInteger,pmtString);
+  TProcedureMessageType = (pmtNone,pmtInteger,pmtString);
                         
                         
   TProcedureBody = class;
   TProcedureBody = class;
 
 
@@ -711,6 +725,9 @@ type
   public
   public
     ProcType : TPasProcedureType;
     ProcType : TPasProcedureType;
     Body : TProcedureBody;
     Body : TProcedureBody;
+    PublicName,
+    LibrarySymbolName,
+    LibraryExpr : TPasExpr;
     Procedure AddModifier(AModifier : TProcedureModifier);
     Procedure AddModifier(AModifier : TProcedureModifier);
     Function IsVirtual : Boolean;
     Function IsVirtual : Boolean;
     Function IsDynamic : Boolean;
     Function IsDynamic : Boolean;
@@ -730,10 +747,13 @@ type
   end;
   end;
 
 
   TPasFunction = class(TPasProcedure)
   TPasFunction = class(TPasProcedure)
+  private
+    function GetFT: TPasFunctionType;
   public
   public
     function ElementTypeName: string; override;
     function ElementTypeName: string; override;
     function TypeName: string; override;
     function TypeName: string; override;
     function GetDeclaration (full : boolean) : string; override;
     function GetDeclaration (full : boolean) : string; override;
+    Property FuncType : TPasFunctionType Read GetFT;
   end;
   end;
 
 
   { TPasOperator }
   { TPasOperator }
@@ -877,16 +897,16 @@ type
     function AddCommands: TPasImplCommands; // used by mkxmlrpc, not by pparser
     function AddCommands: TPasImplCommands; // used by mkxmlrpc, not by pparser
     function AddBeginBlock: TPasImplBeginBlock;
     function AddBeginBlock: TPasImplBeginBlock;
     function AddRepeatUntil: TPasImplRepeatUntil;
     function AddRepeatUntil: TPasImplRepeatUntil;
-    function AddIfElse(const ACondition: string): TPasImplIfElse;
-    function AddWhileDo(const ACondition: string): TPasImplWhileDo;
-    function AddWithDo(const Expression: string): TPasImplWithDo;
-    function AddCaseOf(const Expression: string): TPasImplCaseOf;
+    function AddIfElse(const ACondition: TPasExpr): TPasImplIfElse;
+    function AddWhileDo(const ACondition: TPasExpr): TPasImplWhileDo;
+    function AddWithDo(const Expression: TPasExpr): TPasImplWithDo;
+    function AddCaseOf(const Expression: TPasExpr): TPasImplCaseOf;
     function AddForLoop(AVar: TPasVariable;
     function AddForLoop(AVar: TPasVariable;
-      const AStartValue, AEndValue: string): TPasImplForLoop;
-    function AddForLoop(const AVarName, AStartValue, AEndValue: string;
+      const AStartValue, AEndValue: TPasExpr): TPasImplForLoop;
+    function AddForLoop(const AVarName : String; AStartValue, AEndValue: TPasExpr;
       ADownTo: Boolean = false): TPasImplForLoop;
       ADownTo: Boolean = false): TPasImplForLoop;
     function AddTry: TPasImplTry;
     function AddTry: TPasImplTry;
-    function AddExceptOn(const VarName, TypeName: string): TPasImplExceptOn;
+    function AddExceptOn(const VarName, TypeName: TPasExpr): TPasImplExceptOn;
     function AddRaise: TPasImplRaise;
     function AddRaise: TPasImplRaise;
     function AddLabelMark(const Id: string): TPasImplLabelMark;
     function AddLabelMark(const Id: string): TPasImplLabelMark;
     function AddAssign(left, right: TPasExpr): TPasImplAssign;
     function AddAssign(left, right: TPasExpr): TPasImplAssign;
@@ -922,7 +942,9 @@ type
 
 
   TPasImplRepeatUntil = class(TPasImplBlock)
   TPasImplRepeatUntil = class(TPasImplBlock)
   public
   public
-    Condition: string;
+    ConditionExpr : TPasExpr;
+    destructor Destroy; override;
+    Function Condition: string;
   end;
   end;
 
 
   { TPasImplIfElse }
   { TPasImplIfElse }
@@ -933,9 +955,10 @@ type
     procedure AddElement(Element: TPasImplElement); override;
     procedure AddElement(Element: TPasImplElement); override;
     function CloseOnSemicolon: boolean; override;
     function CloseOnSemicolon: boolean; override;
   public
   public
-    Condition: string;
+    ConditionExpr : TPasExpr;
     IfBranch: TPasImplElement;
     IfBranch: TPasImplElement;
     ElseBranch: TPasImplElement; // can be nil
     ElseBranch: TPasImplElement; // can be nil
+    Function Condition: string;
   end;
   end;
 
 
   { TPasImplWhileDo }
   { TPasImplWhileDo }
@@ -945,8 +968,9 @@ type
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddElement(Element: TPasImplElement); override;
     procedure AddElement(Element: TPasImplElement); override;
   public
   public
-    Condition: string;
+    ConditionExpr : TPasExpr;
     Body: TPasImplElement;
     Body: TPasImplElement;
+    function Condition: string;
   end;
   end;
 
 
   { TPasImplWithDo }
   { TPasImplWithDo }
@@ -956,9 +980,9 @@ type
     constructor Create(const AName: string; AParent: TPasElement); override;
     constructor Create(const AName: string; AParent: TPasElement); override;
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddElement(Element: TPasImplElement); override;
     procedure AddElement(Element: TPasImplElement); override;
-    procedure AddExpression(const Expression: string);
+    procedure AddExpression(const Expression: TPasExpr);
   public
   public
-    Expressions: TStrings;
+    Expressions: TFPList;
     Body: TPasImplElement;
     Body: TPasImplElement;
   end;
   end;
 
 
@@ -971,11 +995,12 @@ type
   public
   public
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddElement(Element: TPasImplElement); override;
     procedure AddElement(Element: TPasImplElement); override;
-    function AddCase(const Expression: string): TPasImplCaseStatement;
+    function AddCase(const Expression: TPasExpr): TPasImplCaseStatement;
     function AddElse: TPasImplCaseElse;
     function AddElse: TPasImplCaseElse;
   public
   public
-    Expression: string;
+    CaseExpr : TPasExpr;
     ElseBranch: TPasImplCaseElse;
     ElseBranch: TPasImplCaseElse;
+    function Expression: string;
   end;
   end;
 
 
   { TPasImplCaseStatement }
   { TPasImplCaseStatement }
@@ -985,9 +1010,9 @@ type
     constructor Create(const AName: string; AParent: TPasElement); override;
     constructor Create(const AName: string; AParent: TPasElement); override;
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddElement(Element: TPasImplElement); override;
     procedure AddElement(Element: TPasImplElement); override;
-    procedure AddExpression(const Expr: string);
+    procedure AddExpression(const Expr: TPasExpr);
   public
   public
-    Expressions: TStrings;
+    Expressions: TFPList;
     Body: TPasImplElement;
     Body: TPasImplElement;
   end;
   end;
 
 
@@ -997,24 +1022,30 @@ type
   end;
   end;
 
 
   { TPasImplForLoop }
   { TPasImplForLoop }
-
+  TLoopType = (ltNormal,ltDown,ltIn);
   TPasImplForLoop = class(TPasImplStatement)
   TPasImplForLoop = class(TPasImplStatement)
   public
   public
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddElement(Element: TPasImplElement); override;
     procedure AddElement(Element: TPasImplElement); override;
   public
   public
     Variable: TPasVariable;
     Variable: TPasVariable;
-    VariableName, StartValue, EndValue: string;
-    Down: boolean; // downto
+    StartExpr : TPasExpr;
+    EndExpr : TPasExpr;
+    VariableName : String;
+    LoopType : TLoopType;
     Body: TPasImplElement;
     Body: TPasImplElement;
+    Function Down: boolean; // downto, backward compatibility
+    Function StartValue : String;
+    Function EndValue: string;
   end;
   end;
 
 
   { TPasImplAssign }
   { TPasImplAssign }
-
+  TAssignKind = (akDefault,akAdd,akMinus,akMul,akDivision);
   TPasImplAssign = class (TPasImplStatement)
   TPasImplAssign = class (TPasImplStatement)
   public
   public
     left  : TPasExpr;
     left  : TPasExpr;
     right : TPasExpr;
     right : TPasExpr;
+    Kind : TAssignKind;
     Destructor Destroy; override;
     Destructor Destroy; override;
   end;
   end;
 
 
@@ -1069,13 +1100,20 @@ type
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddElement(Element: TPasImplElement); override;
     procedure AddElement(Element: TPasImplElement); override;
   public
   public
-    VariableName, TypeName: string;
+    VarExpr,TypeExpr : TPasExpr;
     Body: TPasImplElement;
     Body: TPasImplElement;
+    Function VariableName : String;
+    Function TypeName: string;
   end;
   end;
 
 
   { TPasImplRaise }
   { TPasImplRaise }
 
 
   TPasImplRaise = class(TPasImplStatement)
   TPasImplRaise = class(TPasImplStatement)
+  public
+    destructor Destroy; override;
+  Public
+    ExceptObject,
+    ExceptAddr : TPasExpr;
   end;
   end;
 
 
   { TPassTreeVisitor }
   { TPassTreeVisitor }
@@ -1099,7 +1137,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','class','class');
+    'object', 'class', 'interface','class','class','class helper','record helper');
   
   
   OpcodeStrings : Array[TExprOpCode] of string = 
   OpcodeStrings : Array[TExprOpCode] of string = 
        ('','+','-','*','/','div','mod','**',
        ('','+','-','*','/','div','mod','**',
@@ -1116,10 +1154,41 @@ const
   cCallingConventions : array[TCallingConvention] of string =
   cCallingConventions : array[TCallingConvention] of string =
       ( '', 'Register','Pascal','CDecl','StdCall','OldFPCCall','SafeCall');
       ( '', 'Register','Pascal','CDecl','StdCall','OldFPCCall','SafeCall');
 
 
+  ModifierNames : Array[TProcedureModifier] of string
+                = ('virtual', 'dynamic','abstract', 'override',
+                   'export', 'overload', 'message', 'reintroduce',
+                   'static','inline','assembler','varargs', 'public',
+                   'compilerproc','external','forward');
+
 implementation
 implementation
 
 
 uses SysUtils;
 uses SysUtils;
 
 
+{ TPasImplRaise }
+
+destructor TPasImplRaise.Destroy;
+begin
+  FreeAndNil(ExceptObject);
+  FreeAndNil(ExceptAddr);
+  Inherited;
+end;
+
+{ TPasImplRepeatUntil }
+
+destructor TPasImplRepeatUntil.Destroy;
+begin
+  FreeAndNil(ConditionExpr);
+  inherited Destroy;
+end;
+
+function TPasImplRepeatUntil.Condition: string;
+begin
+  If Assigned(ConditionExpr) then
+    Result:=ConditionExpr.GetDeclaration(True)
+  else
+    Result:='';
+end;
+
 { TPasImplSimple }
 { TPasImplSimple }
 
 
 destructor TPasImplSimple.Destroy;
 destructor TPasImplSimple.Destroy;
@@ -1158,7 +1227,6 @@ begin
     Result:=Result+' name '+ExportName.GetDeclaration(Full)
     Result:=Result+' name '+ExportName.GetDeclaration(Full)
   else if (ExportIndex<>Nil) then
   else if (ExportIndex<>Nil) then
     Result:=Result+' index '+ExportIndex.GetDeclaration(Full);
     Result:=Result+' index '+ExportIndex.GetDeclaration(Full);
-
 end;
 end;
 
 
 { TPasUnresolvedUnitRef }
 { TPasUnresolvedUnitRef }
@@ -1242,6 +1310,21 @@ function TPasRangeType.ElementTypeName: string; begin Result := SPasTreeRangeTyp
 function TPasArrayType.ElementTypeName: string; begin Result := SPasTreeArrayType end;
 function TPasArrayType.ElementTypeName: string; begin Result := SPasTreeArrayType end;
 function TPasFileType.ElementTypeName: string; begin Result := SPasTreeFileType end;
 function TPasFileType.ElementTypeName: string; begin Result := SPasTreeFileType end;
 function TPasEnumValue.ElementTypeName: string; begin Result := SPasTreeEnumValue end;
 function TPasEnumValue.ElementTypeName: string; begin Result := SPasTreeEnumValue end;
+
+destructor TPasEnumValue.Destroy;
+begin
+  FreeAndNil(Value);
+  inherited Destroy;
+end;
+
+function TPasEnumValue.AssignedValue: string;
+begin
+  If Assigned(Value) then
+    Result:=Value.GetDeclaration(True)
+  else
+    Result:='';
+end;
+
 function TPasEnumType.ElementTypeName: string; begin Result := SPasTreeEnumType end;
 function TPasEnumType.ElementTypeName: string; begin Result := SPasTreeEnumType end;
 function TPasSetType.ElementTypeName: string; begin Result := SPasTreeSetType end;
 function TPasSetType.ElementTypeName: string; begin Result := SPasTreeSetType end;
 function TPasRecordType.ElementTypeName: string; begin Result := SPasTreeRecordType end;
 function TPasRecordType.ElementTypeName: string; begin Result := SPasTreeRecordType end;
@@ -1255,6 +1338,12 @@ function TPasConst.ElementTypeName: string; begin Result := SPasTreeConst end;
 function TPasProperty.ElementTypeName: string; begin Result := SPasTreeProperty end;
 function TPasProperty.ElementTypeName: string; begin Result := SPasTreeProperty end;
 function TPasOverloadedProc.ElementTypeName: string; begin Result := SPasTreeOverloadedProcedure end;
 function TPasOverloadedProc.ElementTypeName: string; begin Result := SPasTreeOverloadedProcedure end;
 function TPasProcedure.ElementTypeName: string; begin Result := SPasTreeProcedure end;
 function TPasProcedure.ElementTypeName: string; begin Result := SPasTreeProcedure end;
+
+function TPasFunction.GetFT: TPasFunctionType;
+begin
+  Result:=ProcType as TPasFunctionType;
+end;
+
 function TPasFunction.ElementTypeName: string; begin Result := SPasTreeFunction end;
 function TPasFunction.ElementTypeName: string; begin Result := SPasTreeFunction end;
 function TPasClassProcedure.ElementTypeName: string; begin Result := SPasTreeClassProcedure; end;
 function TPasClassProcedure.ElementTypeName: string; begin Result := SPasTreeClassProcedure; end;
 function TPasClassFunction.ElementTypeName: string; begin Result := SPasTreeClassFunction; end;
 function TPasClassFunction.ElementTypeName: string; begin Result := SPasTreeClassFunction; end;
@@ -1274,9 +1363,62 @@ begin
     okInterface: Result := SPasTreeInterfaceType;
     okInterface: Result := SPasTreeInterfaceType;
     okGeneric : Result := SPasTreeGenericType;
     okGeneric : Result := SPasTreeGenericType;
     okSpecialize : Result := SPasTreeSpecializedType;
     okSpecialize : Result := SPasTreeSpecializedType;
+    okClassHelper : Result:=SPasClassHelperType;
+    okRecordHelper : Result:=SPasRecordHelperType;
   end;
   end;
 end;
 end;
 
 
+function TPasClassType.FindMember(MemberClass: TPTreeElement; const MemberName: String): TPasElement;
+
+Var
+  I : Integer;
+
+begin
+//  Writeln('Looking for ',MemberName,'(',MemberClass.ClassName,') in ',Name);
+  Result:=Nil;
+  I:=0;
+  While (Result=Nil) and (I<Members.Count) do
+    begin
+    Result:=TPasElement(Members[i]);
+    if (Result.ClassType<>MemberClass) or (CompareText(Result.Name,MemberName)<>0) then
+      Result:=Nil;
+    Inc(I);
+    end;
+end;
+
+function TPasClassType.FindMemberInAncestors(MemberClass: TPTreeElement;
+  const MemberName: String): TPasElement;
+
+  Function A (C : TPasClassType) : TPasClassType;
+
+  begin
+    if C.AncestorType is TPasClassType then
+      result:=TPasClassType(C.AncestorType)
+    else
+      result:=Nil;
+  end;
+
+Var
+  C : TPasClassType;
+
+begin
+  Result:=Nil;
+  C:=A(Self);
+  While (Result=Nil) and (C<>Nil) do
+    begin
+    Result:=C.FindMember(MemberClass,MemberName);
+    C:=A(C);
+    end;
+end;
+
+function TPasClassType.InterfaceGUID: string;
+begin
+  If Assigned(GUIDExpr) then
+    Result:=GUIDExpr.GetDeclaration(True)
+  else
+    Result:=''
+end;
+
 function TPasClassType.IsPacked: Boolean;
 function TPasClassType.IsPacked: Boolean;
 begin
 begin
   Result:=PackMode<>pmNone;
   Result:=PackMode<>pmNone;
@@ -1288,7 +1430,6 @@ end;
 
 
 procedure TPasElement.ProcessHints(const ASemiColonPrefix: boolean; var AResult: string);
 procedure TPasElement.ProcessHints(const ASemiColonPrefix: boolean; var AResult: string);
 var
 var
-  h: TPasMemberHint;
   S : String;
   S : String;
 begin
 begin
   if Hints <> [] then
   if Hints <> [] then
@@ -1379,9 +1520,17 @@ begin
     Result := nil
     Result := nil
   else
   else
   begin
   begin
-    Result := TPasModule(Self);
-    while Assigned(Result) and not (Result is TPasModule) do
-      Result := TPasModule(Result.Parent);
+    if self is TPasModule then
+      begin
+        Result := TPasModule(Self);
+        while Assigned(Result) and not (Result is TPasModule) do
+        Result := TPasModule(Result.Parent);
+      end
+    else
+     begin
+       // typical case that this happens: symbol was loaded from .XCT
+       result:=nil;
+     end;
   end;
   end;
 end;
 end;
 
 
@@ -1538,11 +1687,17 @@ end;
 constructor TPasVariant.Create(const AName: string; AParent: TPasElement);
 constructor TPasVariant.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Values := TStringList.Create;
+  Values := TFPList.Create;
 end;
 end;
 
 
 destructor TPasVariant.Destroy;
 destructor TPasVariant.Destroy;
+
+Var
+  I : Integer;
+
 begin
 begin
+  For I:=0 to Values.Count-1 do
+    TObject(Values[i]).Free;
   Values.Free;
   Values.Free;
   if Assigned(Members) then
   if Assigned(Members) then
     Members.Release;
     Members.Release;
@@ -1597,9 +1752,14 @@ var
 begin
 begin
   for i := 0 to Members.Count - 1 do
   for i := 0 to Members.Count - 1 do
     TPasElement(Members[i]).Release;
     TPasElement(Members[i]).Release;
+  for i := 0 to Interfaces.Count - 1 do
+    TPasElement(Interfaces[i]).Release;
   Members.Free;
   Members.Free;
   if Assigned(AncestorType) then
   if Assigned(AncestorType) then
     AncestorType.Release;
     AncestorType.Release;
+  if Assigned(HelperForType) then
+    HelperForType.Release;
+  FreeAndNil(GUIDExpr);
   Modifiers.Free;
   Modifiers.Free;
   ClassVars.Free;
   ClassVars.Free;
   Interfaces.Free;
   Interfaces.Free;
@@ -1679,6 +1839,7 @@ end;
 
 
 destructor TPasVariable.Destroy;
 destructor TPasVariable.Destroy;
 begin
 begin
+//  FreeAndNil(Expr);
   { Attention, in derived classes, VarType isn't necessarily set!
   { Attention, in derived classes, VarType isn't necessarily set!
     (e.g. in Constants) }
     (e.g. in Constants) }
   if Assigned(VarType) then
   if Assigned(VarType) then
@@ -1702,6 +1863,8 @@ begin
   for i := 0 to Args.Count - 1 do
   for i := 0 to Args.Count - 1 do
     TPasArgument(Args[i]).Release;
     TPasArgument(Args[i]).Release;
   Args.Free;
   Args.Free;
+  FreeAndNil(DefaultExpr);
+  FreeAndNil(IndexExpr);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
@@ -1749,6 +1912,9 @@ begin
     ProcType.Release;
     ProcType.Release;
   if Assigned(Body) then
   if Assigned(Body) then
     Body.Release;
     Body.Release;
+  FreeAndNil(PublicName);
+  FreeAndNil(LibraryExpr);
+  FreeAndNil(LibrarySymbolName);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
@@ -1812,6 +1978,7 @@ end;
 
 
 destructor TPasImplIfElse.Destroy;
 destructor TPasImplIfElse.Destroy;
 begin
 begin
+  FreeAndNil(ConditionExpr);
   if Assigned(IfBranch) then
   if Assigned(IfBranch) then
     IfBranch.Release;
     IfBranch.Release;
   if Assigned(ElseBranch) then
   if Assigned(ElseBranch) then
@@ -1841,8 +2008,16 @@ begin
   Result:=ElseBranch<>nil;
   Result:=ElseBranch<>nil;
 end;
 end;
 
 
+function TPasImplIfElse.Condition: string;
+begin
+  If Assigned(ConditionExpr) then
+    Result:=ConditionExpr.GetDeclaration(True);
+end;
+
 destructor TPasImplForLoop.Destroy;
 destructor TPasImplForLoop.Destroy;
 begin
 begin
+  FreeAndNil(StartExpr);
+  FreeAndNil(EndExpr);
   if Assigned(Variable) then
   if Assigned(Variable) then
     Variable.Release;
     Variable.Release;
   if Assigned(Body) then
   if Assigned(Body) then
@@ -1862,6 +2037,27 @@ begin
     raise Exception.Create('TPasImplForLoop.AddElement body already set - please report this bug');
     raise Exception.Create('TPasImplForLoop.AddElement body already set - please report this bug');
 end;
 end;
 
 
+function TPasImplForLoop.Down: boolean;
+begin
+  Result:=(LoopType=ltDown);
+end;
+
+function TPasImplForLoop.StartValue: String;
+begin
+  If Assigned(StartExpr) then
+    Result:=StartExpr.GetDeclaration(true)
+  else
+    Result:='';
+end;
+
+function TPasImplForLoop.EndValue: string;
+begin
+  If Assigned(EndExpr) then
+    Result:=EndExpr.GetDeclaration(true)
+  else
+    Result:='';
+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);
@@ -1908,52 +2104,53 @@ begin
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
-function TPasImplBlock.AddIfElse(const ACondition: string): TPasImplIfElse;
+function TPasImplBlock.AddIfElse(const ACondition: TPasExpr): TPasImplIfElse;
 begin
 begin
   Result := TPasImplIfElse.Create('', Self);
   Result := TPasImplIfElse.Create('', Self);
-  Result.Condition := ACondition;
+  Result.ConditionExpr := ACondition;
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
-function TPasImplBlock.AddWhileDo(const ACondition: string): TPasImplWhileDo;
+function TPasImplBlock.AddWhileDo(const ACondition: TPasExpr): TPasImplWhileDo;
 begin
 begin
   Result := TPasImplWhileDo.Create('', Self);
   Result := TPasImplWhileDo.Create('', Self);
-  Result.Condition := ACondition;
+  Result.ConditionExpr := ACondition;
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
-function TPasImplBlock.AddWithDo(const Expression: string): TPasImplWithDo;
+function TPasImplBlock.AddWithDo(const Expression: TPasExpr): TPasImplWithDo;
 begin
 begin
   Result := TPasImplWithDo.Create('', Self);
   Result := TPasImplWithDo.Create('', Self);
   Result.AddExpression(Expression);
   Result.AddExpression(Expression);
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
-function TPasImplBlock.AddCaseOf(const Expression: string): TPasImplCaseOf;
+function TPasImplBlock.AddCaseOf(const Expression: TPasExpr): TPasImplCaseOf;
 begin
 begin
   Result := TPasImplCaseOf.Create('', Self);
   Result := TPasImplCaseOf.Create('', Self);
-  Result.Expression := Expression;
+  Result.CaseExpr:= Expression;
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
 function TPasImplBlock.AddForLoop(AVar: TPasVariable; const AStartValue,
 function TPasImplBlock.AddForLoop(AVar: TPasVariable; const AStartValue,
-  AEndValue: string): TPasImplForLoop;
+  AEndValue: TPasExpr): TPasImplForLoop;
 begin
 begin
   Result := TPasImplForLoop.Create('', Self);
   Result := TPasImplForLoop.Create('', Self);
   Result.Variable := AVar;
   Result.Variable := AVar;
-  Result.StartValue := AStartValue;
-  Result.EndValue := AEndValue;
+  Result.StartExpr := AStartValue;
+  Result.EndExpr:= AEndValue;
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
-function TPasImplBlock.AddForLoop(const AVarName, AStartValue,
-  AEndValue: string; ADownTo: Boolean): TPasImplForLoop;
+function TPasImplBlock.AddForLoop(const AVarName: String; AStartValue,
+  AEndValue: TPasExpr; ADownTo: Boolean): TPasImplForLoop;
 begin
 begin
   Result := TPasImplForLoop.Create('', Self);
   Result := TPasImplForLoop.Create('', Self);
   Result.VariableName := AVarName;
   Result.VariableName := AVarName;
-  Result.StartValue := AStartValue;
-  Result.EndValue := AEndValue;
-  Result.Down := ADownTo;
+  Result.StartExpr := AStartValue;
+  Result.EndExpr := AEndValue;
+  if ADownto then
+    Result.Looptype := ltDown;
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
@@ -1963,12 +2160,12 @@ begin
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
-function TPasImplBlock.AddExceptOn(const VarName, TypeName: string
+function TPasImplBlock.AddExceptOn(const VarName, TypeName: TPasExpr
   ): TPasImplExceptOn;
   ): TPasImplExceptOn;
 begin
 begin
   Result:=TPasImplExceptOn.Create('',Self);
   Result:=TPasImplExceptOn.Create('',Self);
-  Result.VariableName:=VarName;
-  Result.TypeName:=TypeName;
+  Result.VarExpr:=VarName;
+  Result.TypeExpr:=TypeName;
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
@@ -2350,12 +2547,7 @@ 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
-    Value := Expr.GetDeclaration(full);
   If Assigned(VarType) then
   If Assigned(VarType) then
     begin
     begin
     If VarType.Name='' then
     If VarType.Name='' then
@@ -2375,6 +2567,14 @@ begin
     end;
     end;
 end;
 end;
 
 
+
+
+function TPasVariable.Value: String;
+begin
+  If Assigned(Expr) then
+    Result:=Expr.GetDeclaration(True)
+end;
+
 function TPasProperty.GetDeclaration (full : boolean) : string;
 function TPasProperty.GetDeclaration (full : boolean) : string;
 
 
 Var
 Var
@@ -2389,8 +2589,8 @@ begin
     else
     else
       Result:=VarType.Name;
       Result:=VarType.Name;
     end
     end
-  else
-    Result:=Value;
+  else if Assigned(Expr) then
+    Result:=Expr.GetDeclaration(True);
   S:='';
   S:='';
   If Assigned(Args) and (Args.Count>0) then
   If Assigned(Args) and (Args.Count>0) then
     begin
     begin
@@ -2416,6 +2616,56 @@ begin
   ProcessHints(True, Result);
   ProcessHints(True, Result);
 end;
 end;
 
 
+function TPasProperty.ResolvedType: TPasType;
+
+  Function GC(P : TPasProperty) : TPasClassType;
+
+  begin
+    if Assigned(P) and Assigned(P.Parent) and (P.Parent is TPasClassType) then
+      Result:=P.Parent as TPasClassType
+    else
+      Result:=Nil;
+  end;
+
+
+Var
+  P : TPasProperty;
+  C : TPasClassType;
+
+begin
+  Result:=FResolvedType;
+  if Result=Nil then
+    Result:=VarType;
+  P:=Self;
+  While (Result=Nil) and (P<>Nil) do
+    begin
+    C:=GC(P);
+//    Writeln('Looking for ',Name,' in ancestor ',C.Name);
+    P:=TPasProperty(C.FindMemberInAncestors(TPasProperty,Name));
+    if Assigned(P) then
+      begin
+//      Writeln('Found ',Name,' in ancestor : ',P.Name);
+      Result:=P.ResolvedType;
+      end
+    end;
+end;
+
+function TPasProperty.IndexValue: String;
+begin
+  If Assigned(IndexExpr) then
+    Result:=IndexExpr.GetDeclaration(true)
+  else
+    Result:='';
+end;
+
+function TPasProperty.DefaultValue: string;
+begin
+  If Assigned(DefaultExpr) then
+    Result:=DefaultExpr.GetDeclaration(true)
+  else
+    Result:='';
+end;
+
 Procedure TPasProcedure.GetModifiers(List : TStrings);
 Procedure TPasProcedure.GetModifiers(List : TStrings);
 
 
   Procedure DoAdd(B : Boolean; S : string);
   Procedure DoAdd(B : Boolean; S : string);
@@ -2464,7 +2714,7 @@ end;
 
 
 Function TPasProcedure.IsExported : Boolean;
 Function TPasProcedure.IsExported : Boolean;
 begin
 begin
-  Result:=pmExported in FModifiers;
+  Result:=pmExport in FModifiers;
 end;
 end;
 
 
 function TPasProcedure.IsExternal: Boolean;
 function TPasProcedure.IsExternal: Boolean;
@@ -2681,6 +2931,7 @@ end;
 
 
 destructor TPasImplWhileDo.Destroy;
 destructor TPasImplWhileDo.Destroy;
 begin
 begin
+  FreeAndNil(ConditionExpr);
   if Assigned(Body) then
   if Assigned(Body) then
     Body.Release;
     Body.Release;
   inherited Destroy;
   inherited Destroy;
@@ -2698,10 +2949,17 @@ begin
     raise Exception.Create('TPasImplWhileDo.AddElement body already set - please report this bug');
     raise Exception.Create('TPasImplWhileDo.AddElement body already set - please report this bug');
 end;
 end;
 
 
+function TPasImplWhileDo.Condition: string;
+begin
+  If Assigned(ConditionExpr) then
+    Result:=ConditionExpr.GetDeclaration(True);
+end;
+
 { TPasImplCaseOf }
 { TPasImplCaseOf }
 
 
 destructor TPasImplCaseOf.Destroy;
 destructor TPasImplCaseOf.Destroy;
 begin
 begin
+  FreeAndNil(CaseExpr);
   if Assigned(ElseBranch) then
   if Assigned(ElseBranch) then
     ElseBranch.Release;
     ElseBranch.Release;
   inherited Destroy;
   inherited Destroy;
@@ -2714,7 +2972,7 @@ begin
   inherited AddElement(Element);
   inherited AddElement(Element);
 end;
 end;
 
 
-function TPasImplCaseOf.AddCase(const Expression: string
+function TPasImplCaseOf.AddCase(const Expression: TPasExpr
   ): TPasImplCaseStatement;
   ): TPasImplCaseStatement;
 begin
 begin
   Result:=TPasImplCaseStatement.Create('',Self);
   Result:=TPasImplCaseStatement.Create('',Self);
@@ -2729,17 +2987,31 @@ begin
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
+function TPasImplCaseOf.Expression: string;
+begin
+  if Assigned(CaseExpr) then
+    Result:=CaseExpr.GetDeclaration(True)
+  else
+    Result:='';
+end;
+
 { TPasImplCaseStatement }
 { TPasImplCaseStatement }
 
 
 constructor TPasImplCaseStatement.Create(const AName: string;
 constructor TPasImplCaseStatement.Create(const AName: string;
   AParent: TPasElement);
   AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Expressions:=TStringList.Create;
+  Expressions:=TFPList.Create;
 end;
 end;
 
 
 destructor TPasImplCaseStatement.Destroy;
 destructor TPasImplCaseStatement.Destroy;
+
+Var
+  I : integer;
+
 begin
 begin
+  For I:=0 to Expressions.Count-1 do
+    TPasExpr(Expressions[i]).Free;
   FreeAndNil(Expressions);
   FreeAndNil(Expressions);
   if Assigned(Body) then
   if Assigned(Body) then
     Body.Release;
     Body.Release;
@@ -2756,7 +3028,7 @@ begin
     end
     end
 end;
 end;
 
 
-procedure TPasImplCaseStatement.AddExpression(const Expr: string);
+procedure TPasImplCaseStatement.AddExpression(const Expr: TPasExpr);
 begin
 begin
   Expressions.Add(Expr);
   Expressions.Add(Expr);
 end;
 end;
@@ -2766,13 +3038,17 @@ end;
 constructor TPasImplWithDo.Create(const AName: string; AParent: TPasElement);
 constructor TPasImplWithDo.Create(const AName: string; AParent: TPasElement);
 begin
 begin
   inherited Create(AName, AParent);
   inherited Create(AName, AParent);
-  Expressions:=TStringList.Create;
+  Expressions:=TFPList.Create;
 end;
 end;
 
 
 destructor TPasImplWithDo.Destroy;
 destructor TPasImplWithDo.Destroy;
+Var
+  I : Integer;
 begin
 begin
   if Assigned(Body) then
   if Assigned(Body) then
     Body.Release;
     Body.Release;
+  For I:=0 to Expressions.Count-1 do
+    TObject(Expressions[i]).Free;
   FreeAndNil(Expressions);
   FreeAndNil(Expressions);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
@@ -2787,7 +3063,7 @@ begin
     end;
     end;
 end;
 end;
 
 
-procedure TPasImplWithDo.AddExpression(const Expression: string);
+procedure TPasImplWithDo.AddExpression(const Expression: TPasExpr);
 begin
 begin
   Expressions.Add(Expression);
   Expressions.Add(Expression);
 end;
 end;
@@ -2825,6 +3101,8 @@ end;
 
 
 destructor TPasImplExceptOn.Destroy;
 destructor TPasImplExceptOn.Destroy;
 begin
 begin
+  FreeAndNil(VarExpr);
+  FreeAndNil(TypeExpr);
   if Assigned(Body) then
   if Assigned(Body) then
     Body.Release;
     Body.Release;
   inherited Destroy;
   inherited Destroy;
@@ -2840,6 +3118,22 @@ begin
     end;
     end;
 end;
 end;
 
 
+function TPasImplExceptOn.VariableName: String;
+begin
+  If assigned(VarExpr) then
+    Result:=VarExpr.GetDeclaration(True)
+  else
+    Result:='';
+end;
+
+function TPasImplExceptOn.TypeName: string;
+begin
+  If assigned(TypeExpr) then
+    Result:=TypeExpr.GetDeclaration(True)
+  else
+    Result:='';
+end;
+
 { TPasImplStatement }
 { TPasImplStatement }
 
 
 function TPasImplStatement.CloseOnSemicolon: boolean;
 function TPasImplStatement.CloseOnSemicolon: boolean;
@@ -3068,7 +3362,7 @@ end;
 
 
 { TInheritedExpr }
 { TInheritedExpr }
 
 
-Function TInheritedExpr.GetDeclaration(Full :Boolean):AnsiString;
+function TInheritedExpr.GetDeclaration(full: Boolean): string;
 begin
 begin
   Result:='Inherited';
   Result:='Inherited';
 end;
 end;
@@ -3134,6 +3428,7 @@ begin
   inherited Create(AParent,pekInherited, eopNone);
   inherited Create(AParent,pekInherited, eopNone);
 end;
 end;
 
 
+
 { TSelfExpr }
 { TSelfExpr }
 
 
 constructor TSelfExpr.Create(AParent : TPasElement);
 constructor TSelfExpr.Create(AParent : TPasElement);

+ 3 - 3
packages/fcl-passrc/src/paswrite.pp

@@ -127,11 +127,11 @@ end;
 
 
 procedure TPasWriter.WriteElement(AElement: TPasElement);
 procedure TPasWriter.WriteElement(AElement: TPasElement);
 begin
 begin
-  if AElement.ClassType = TPasModule then
+  if AElement.InheritsFrom(TPasModule) then
     WriteModule(TPasModule(AElement))
     WriteModule(TPasModule(AElement))
-  else if AElement.ClassType = TPasSection then
+  else if AElement.InheritsFrom(TPasSection) then
     WriteSection(TPasSection(AElement))
     WriteSection(TPasSection(AElement))
-  else if AElement.ClassType = TPasVariable then
+  else if AElement.InheritsFrom(TPasVariable) then
     WriteVariable(TPasVariable(AElement))
     WriteVariable(TPasVariable(AElement))
   else if AElement.InheritsFrom(TPasType) then
   else if AElement.InheritsFrom(TPasType) then
     WriteType(TPasType(AElement))
     WriteType(TPasType(AElement))

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


+ 62 - 12
packages/fcl-passrc/src/pscanner.pp

@@ -76,6 +76,10 @@ type
     tkGreaterEqualThan,      // '>='
     tkGreaterEqualThan,      // '>='
     tkPower,                 // '**'
     tkPower,                 // '**'
     tkSymmetricalDifference, // '><'
     tkSymmetricalDifference, // '><'
+    tkAssignPlus,            // +=
+    tkAssignMinus,           // -=
+    tkAssignMul,             // *=
+    tkAssignDivision,        // /=
     // Reserved words
     // Reserved words
     tkabsolute,
     tkabsolute,
     tkand,
     tkand,
@@ -105,6 +109,7 @@ type
     tkfunction,
     tkfunction,
     tkgeneric,
     tkgeneric,
     tkgoto,
     tkgoto,
+    tkHelper,
     tkif,
     tkif,
     tkimplementation,
     tkimplementation,
     tkin,
     tkin,
@@ -185,6 +190,7 @@ type
   private
   private
     FTextFile: Text;
     FTextFile: Text;
     FileOpened: Boolean;
     FileOpened: Boolean;
+    FBuffer : Array[0..4096-1] of byte;
   public
   public
     constructor Create(const AFilename: string); override;
     constructor Create(const AFilename: string); override;
     destructor Destroy; override;
     destructor Destroy; override;
@@ -215,7 +221,7 @@ type
 
 
   TStringStreamLineReader = class(TStreamLineReader)
   TStringStreamLineReader = class(TStreamLineReader)
   Public
   Public
-    constructor Create(const AFilename: string; Const ASource: String);
+    constructor Create( const AFilename: string; Const ASource: String);
   end;
   end;
 
 
   { TMacroReader }
   { TMacroReader }
@@ -288,7 +294,7 @@ type
 
 
   TPascalScannerPPSkipMode = (ppSkipNone, ppSkipIfBranch, ppSkipElseBranch, ppSkipAll);
   TPascalScannerPPSkipMode = (ppSkipNone, ppSkipIfBranch, ppSkipElseBranch, ppSkipAll);
 
 
-  TPOption = (po_delphi);
+  TPOption = (po_delphi,po_cassignments);
   TPOptions = set of TPOption;
   TPOptions = set of TPOption;
 
 
   { TPascalScanner }
   { TPascalScanner }
@@ -402,6 +408,10 @@ const
     '>=',
     '>=',
     '**',
     '**',
     '><',
     '><',
+    '+=',
+    '-=',
+    '*=',
+    '/=',
     // Reserved words
     // Reserved words
     'absolute',
     'absolute',
     'and',
     'and',
@@ -431,6 +441,7 @@ const
     'function',
     'function',
     'generic',
     'generic',
     'goto',
     'goto',
+    'helper',
     'if',
     'if',
     'implementation',
     'implementation',
     'in',
     'in',
@@ -483,7 +494,7 @@ const
 function FilenameIsAbsolute(const TheFilename: string):boolean;
 function FilenameIsAbsolute(const TheFilename: string):boolean;
 function FilenameIsWinAbsolute(const TheFilename: string): boolean;
 function FilenameIsWinAbsolute(const TheFilename: string): boolean;
 function FilenameIsUnixAbsolute(const TheFilename: string): boolean;
 function FilenameIsUnixAbsolute(const TheFilename: string): boolean;
-function IsNamedToken(Const AToken : String; Var T : TToken) : Boolean;
+function IsNamedToken(Const AToken : String; Out T : TToken) : Boolean;
 
 
 implementation
 implementation
 
 
@@ -551,7 +562,7 @@ begin
   Result:=-1;
   Result:=-1;
 end;
 end;
 
 
-function IsNamedToken(Const AToken : String; Var T : TToken) : Boolean;
+function IsNamedToken(Const AToken : String; Out T : TToken) : Boolean;
 
 
 Var
 Var
   I : Integer;
   I : Integer;
@@ -787,10 +798,12 @@ end;
   ---------------------------------------------------------------------}
   ---------------------------------------------------------------------}
 
 
 constructor TFileLineReader.Create(const AFilename: string);
 constructor TFileLineReader.Create(const AFilename: string);
+
 begin
 begin
   inherited Create(AFileName);
   inherited Create(AFileName);
   Assign(FTextFile, AFilename);
   Assign(FTextFile, AFilename);
   Reset(FTextFile);
   Reset(FTextFile);
+  SetTextBuf(FTextFile,FBuffer,SizeOf(FBuffer));
   FileOpened := true;
   FileOpened := true;
 end;
 end;
 
 
@@ -895,7 +908,10 @@ end;
 
 
 procedure TBaseFileResolver.AddIncludePath(const APath: string);
 procedure TBaseFileResolver.AddIncludePath(const APath: string);
 begin
 begin
-  FIncludePaths.Add(IncludeTrailingPathDelimiter(ExpandFileName(APath)));
+  if (APath='') then
+    FIncludePaths.Add('./')
+  else
+    FIncludePaths.Add(IncludeTrailingPathDelimiter(ExpandFileName(APath)));
 end;
 end;
 
 
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
@@ -1249,7 +1265,7 @@ var
   TokenStart, CurPos: PChar;
   TokenStart, CurPos: PChar;
   i: TToken;
   i: TToken;
   OldLength, SectionLength, NestingLevel, Index: Integer;
   OldLength, SectionLength, NestingLevel, Index: Integer;
-  Directive, Param, MN, MV: string;
+  Directive, Param : string;
 begin
 begin
   if TokenStr = nil then
   if TokenStr = nil then
     if not FetchLine then
     if not FetchLine then
@@ -1368,13 +1384,30 @@ begin
         begin
         begin
           Inc(TokenStr);
           Inc(TokenStr);
           Result := tkPower;
           Result := tkPower;
-        end else
-          Result := tkMul;
+        end else if not (po_cassignments in options) then
+          Result := tkMul
+        else
+          begin
+          if TokenStr[0]='=' then
+            begin
+            Inc(TokenStr);
+            Result:=tkAssignMul;
+            end;
+          end
       end;
       end;
     '+':
     '+':
       begin
       begin
         Inc(TokenStr);
         Inc(TokenStr);
-        Result := tkPlus;
+        if not (po_cassignments in options) then
+          Result := tkPlus
+        else
+          begin
+          if TokenStr[0]='=' then
+            begin
+            Inc(TokenStr);
+            Result:=tkAssignPlus;
+            end;
+          end
       end;
       end;
     ',':
     ',':
       begin
       begin
@@ -1384,7 +1417,16 @@ begin
     '-':
     '-':
       begin
       begin
         Inc(TokenStr);
         Inc(TokenStr);
-        Result := tkMinus;
+        if not (po_cassignments in options) then
+          Result := tkMinus
+        else
+          begin
+          if TokenStr[0]='=' then
+            begin
+            Inc(TokenStr);
+            Result:=tkAssignMinus;
+            end;
+          end
       end;
       end;
     '.':
     '.':
       begin
       begin
@@ -1412,8 +1454,16 @@ begin
             Move(TokenStart^, FCurTokenString[1], SectionLength);
             Move(TokenStart^, FCurTokenString[1], SectionLength);
           Result := tkComment;
           Result := tkComment;
           //WriteLn('Einzeiliger Kommentar: "', CurTokenString, '"');
           //WriteLn('Einzeiliger Kommentar: "', CurTokenString, '"');
-        end else
-          Result := tkDivision;
+        end else if not (po_cassignments in options) then
+          Result := tkDivision
+        else
+          begin
+          if TokenStr[0]='=' then
+            begin
+            Inc(TokenStr);
+            Result:=tkAssignDivision;
+            end;
+          end
       end;
       end;
     '0'..'9':
     '0'..'9':
       begin
       begin

+ 496 - 0
packages/fcl-passrc/tests/tcbaseparser.pas

@@ -0,0 +1,496 @@
+unit tcbaseparser;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit, pastree, pscanner, pparser, testregistry;
+
+Type
+  { TTestEngine }
+
+  TTestEngine = Class(TPasTreeContainer)
+  Private
+    FList : TFPList;
+  public
+    Destructor Destroy; override;
+    function CreateElement(AClass: TPTreeElement; const AName: String;
+      AParent: TPasElement; AVisibility: TPasMemberVisibility;
+      const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;
+      override;
+    function FindElement(const AName: String): TPasElement; override;
+  end;
+  TTestPasParser = Class(TPasParser);
+
+  { TTestParser }
+
+  TTestParser= class(TTestCase)
+  Private
+    FDeclarations: TPasDeclarations;
+    FDefinition: TPasElement;
+    FEngine : TTestEngine;
+    FModule: TPasModule;
+    FParseResult: TPasElement;
+    FScanner : TPascalScanner;
+    FResolver : TStreamResolver;
+    FParser : TTestPasParser;
+    FSource: TStrings;
+    FFileName : string;
+    FIsUnit : Boolean;
+    FImplementation : Boolean;
+    FEndSource: Boolean;
+    FUseImplementation: Boolean;
+    function GetPL: TPasLibrary;
+    function GetPP: TPasProgram;
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+    Procedure StartUnit(AUnitName : String);
+    Procedure StartProgram(AFileName : String; AIn : String = ''; AOut : String = '');
+    Procedure StartLibrary(AFileName : String);
+    Procedure UsesClause(Units : Array of string);
+    Procedure StartImplementation;
+    Procedure EndSource;
+    Procedure Add(Const ALine : String);
+    Procedure StartParsing;
+    Procedure ParseDeclarations;
+    Procedure ParseModule;
+    Procedure CheckHint(AHint : TPasMemberHint);
+    Function AssertExpression(Const Msg: String; AExpr : TPasExpr; aKind : TPasExprKind; AClass : TClass) : TPasExpr;
+    Function AssertExpression(Const Msg: String; AExpr : TPasExpr; aKind : TPasExprKind; AValue : String) : TPrimitiveExpr;
+    Procedure AssertExportSymbol(Const Msg: String; AIndex : Integer; AName,AExportName : String; AExportIndex : Integer = -1);
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TPasExprKind); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TLoopType); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TPasObjKind); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TexprOpcode); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TPasMemberHint); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TCallingConvention); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TArgumentAccess); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TVariableModifier); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TVariableModifiers); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TPasMemberVisibility); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TProcedureModifier); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TProcedureModifiers); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TAssignKind); overload;
+    Procedure AssertEquals(Const Msg : String; AExpected, AActual: TProcedureMessageType); overload;
+    Procedure HaveHint(AHint : TPasMemberHint; AHints : TPasMemberHints);
+    Property Resolver : TStreamResolver Read FResolver;
+    Property Scanner : TPascalScanner Read FScanner;
+    Property Parser : TTestPasParser read FParser ;
+    Property Source : TStrings Read FSource;
+    Property Module : TPasModule Read FModule;
+    Property PasProgram : TPasProgram Read GetPP;
+    Property PasLibrary : TPasLibrary Read GetPL;
+    Property Declarations : TPasDeclarations read FDeclarations Write FDeclarations;
+    Property Definition : TPasElement Read FDefinition Write FDefinition;
+    // If set, Will be freed in teardown
+    Property ParseResult : TPasElement Read FParseResult Write FParseResult;
+    Property UseImplementation : Boolean Read FUseImplementation Write FUseImplementation;
+  end;
+
+implementation
+
+uses typinfo;
+{ TTestEngine }
+
+destructor TTestEngine.Destroy;
+begin
+  FreeAndNil(FList);
+  inherited Destroy;
+end;
+
+function TTestEngine.CreateElement(AClass: TPTreeElement; const AName: String;
+  AParent: TPasElement; AVisibility: TPasMemberVisibility;
+  const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement;
+begin
+  Result := AClass.Create(AName, AParent);
+  Result.Visibility := AVisibility;
+  Result.SourceFilename := ASourceFilename;
+  Result.SourceLinenumber := ASourceLinenumber;
+  If not Assigned(FList) then
+    FList:=TFPList.Create;
+  FList.Add(Result);
+end;
+
+function TTestEngine.FindElement(const AName: String): TPasElement;
+
+Var
+  I : Integer;
+
+begin
+  Result:=Nil;
+  if Assigned(FList) then
+    begin
+    I:=FList.Count-1;
+    While (Result=Nil) and (I>=0) do
+      begin
+      if CompareText(TPasElement(FList[I]).Name,AName)=0 then
+        Result:=TPasElement(Flist[i]);
+      Dec(i);
+      end;
+    end;
+end;
+
+function TTestParser.GetPP: TPasProgram;
+begin
+  Result:=Module as TPasProgram;
+end;
+
+function TTestParser.GetPL: TPasLibrary;
+begin
+  Result:=Module as TPasLibrary;
+end;
+
+procedure TTestParser.SetUp;
+begin
+  FResolver:=TStreamResolver.Create;
+  FResolver.OwnsStreams:=True;
+  FScanner:=TPascalScanner.Create(FResolver);
+  FEngine:=TTestEngine.Create;
+  FParser:=TTestPasParser.Create(FScanner,FResolver,FEngine);
+  FSource:=TStringList.Create;
+  FModule:=Nil;
+  FDeclarations:=Nil;
+  FEndSource:=False;
+  FImplementation:=False;
+  FIsUnit:=False;
+end;
+
+procedure TTestParser.TearDown;
+begin
+  if Not Assigned(FModule) then
+    FreeAndNil(FDeclarations)
+  else
+    FDeclarations:=Nil;
+  FImplementation:=False;
+  FEndSource:=False;
+  FIsUnit:=False;
+  FreeAndNil(FModule);
+  FreeAndNil(FSource);
+  FreeAndNil(FParseResult);
+  FreeAndNil(FParser);
+  FreeAndNil(FEngine);
+  FreeAndNil(FScanner);
+  FreeAndNil(FResolver);
+end;
+
+procedure TTestParser.StartUnit(AUnitName: String);
+begin
+  FIsUnit:=True;
+  If (AUnitName='') then
+    AUnitName:='afile';
+  Add('unit '+aUnitName+';');
+  Add('');
+  Add('interface');
+  Add('');
+  FFileName:=AUnitName+'.pp';
+end;
+
+procedure TTestParser.StartProgram(AFileName : String; AIn : String = ''; AOut : String = '');
+begin
+  FIsUnit:=False;
+  If (AFileName='') then
+    AFileName:='proga';
+  FFileName:=AFileName+'.pp';
+  If (AIn<>'') then
+    begin
+    AFileName:=AFileName+'('+AIn;
+    if (AOut<>'') then
+      AFileName:=AFIleName+','+AOut;
+    AFileName:=AFileName+')';
+    end;
+  Add('program '+AFileName+';');
+  FImplementation:=True;
+end;
+
+procedure TTestParser.StartLibrary(AFileName: String);
+begin
+  FIsUnit:=False;
+  If (AFileName='') then
+    AFileName:='liba';
+  FFileName:=AFileName+'.pp';
+  Add('library '+AFileName+';');
+  FImplementation:=True;
+end;
+
+procedure TTestParser.UsesClause(Units: array of string);
+
+Var
+  S : String;
+  I : integer;
+
+begin
+  S:='';
+  For I:=Low(units) to High(units) do
+    begin
+    If (S<>'') then
+        S:=S+', ';
+    S:=S+Units[i];
+    end;
+  Add('uses '+S+';');
+  Add('');
+end;
+
+procedure TTestParser.StartImplementation;
+begin
+  if Not FImplementation then
+    begin
+    if UseImplementation then
+      begin
+      FSource.Insert(0,'');
+      FSource.Insert(0,'Implementation');
+      FSource.Insert(0,'');
+      end
+    else
+      begin
+      Add('');
+      Add('Implementation');
+      Add('');
+      end;
+    FImplementation:=True;
+    end;
+end;
+
+procedure TTestParser.EndSource;
+begin
+  if Not FEndSource then
+    begin
+    Add('end.');
+    FEndSource:=True;
+    end;
+end;
+
+procedure TTestParser.Add(const ALine: String);
+begin
+  FSource.Add(ALine);
+end;
+
+procedure TTestParser.StartParsing;
+
+begin
+  If FIsUnit then
+    StartImplementation;
+  EndSource;
+  If (FFileName='') then
+    FFileName:='afile.pp';
+  FResolver.AddStream(FFileName,TStringStream.Create(FSource.text));
+  FScanner.OpenFile(FFileName);
+  Writeln('// Test : ',Self.TestName);
+  Writeln(FSource.Text);
+end;
+
+procedure TTestParser.ParseDeclarations;
+begin
+  if UseImplementation then
+    StartImplementation;
+  FSource.Insert(0,'');
+  FSource.Insert(0,'interface');
+  FSource.Insert(0,'');
+  FSource.Insert(0,'unit afile;');
+  if Not UseImplementation then
+    StartImplementation;
+  EndSource;
+  ParseModule;
+  if UseImplementation then
+    FDeclarations:=Module.ImplementationSection
+  else
+    FDeclarations:=Module.InterfaceSection;
+end;
+
+procedure TTestParser.ParseModule;
+begin
+  StartParsing;
+  FParser.ParseMain(FModule);
+  AssertNotNull('Module resulted in Module',FModule);
+  AssertEquals('modulename',ChangeFileExt(FFileName,''),Module.Name);
+end;
+
+procedure TTestParser.CheckHint(AHint: TPasMemberHint);
+begin
+  HaveHint(AHint,Definition.Hints);
+end;
+
+function TTestParser.AssertExpression(const Msg: String; AExpr: TPasExpr;
+  aKind: TPasExprKind; AClass: TClass): TPasExpr;
+begin
+  AssertEquals(Msg+': Correct expression kind',aKind,AExpr.Kind);
+  AssertEquals(Msg+': Correct expression class',AClass,AExpr.ClassType);
+  Result:=AExpr;
+end;
+
+function TTestParser.AssertExpression(const Msg: String; AExpr: TPasExpr;
+  aKind: TPasExprKind; AValue: String): TPrimitiveExpr;
+begin
+  Result:=AssertExpression(Msg,AExpr,aKind,TPrimitiveExpr) as TPrimitiveExpr;
+  AssertEquals(Msg+': Primitive expression value',AValue,TPrimitiveExpr(AExpr).Value);
+end;
+
+procedure TTestParser.AssertExportSymbol(const Msg: String; AIndex: Integer;
+  AName, AExportName: String; AExportIndex: Integer);
+
+Var
+  E: TPasExportSymbol;
+
+begin
+  AssertNotNull(Msg+'Have export symbols list',PasLibrary.LibrarySection.ExportSymbols);
+  if AIndex>=PasLibrary.LibrarySection.ExportSymbols.Count then
+    Fail(Format(Msg+'%d not a valid export list symbol',[AIndex]));
+  AssertNotNull(Msg+'Have export symbol',PasLibrary.LibrarySection.ExportSymbols[Aindex]);
+  AssertEquals(Msg+'Correct export symbol class',TPasExportSymbol,TObject(PasLibrary.LibrarySection.ExportSymbols[Aindex]).ClassType);
+  E:=TPasExportSymbol(PasLibrary.LibrarySection.ExportSymbols[Aindex]);
+  AssertEquals(Msg+'Correct export symbol name',AName,E.Name);
+  if (AExportName='') then
+    AssertNull(Msg+'No export name',E.ExportName)
+  else
+    begin
+    AssertNotNull(Msg+'Export name symbol',E.ExportName);
+    AssertEquals(Msg+'TPrimitiveExpr',TPrimitiveExpr,E.ExportName.CLassType);
+    AssertEquals(Msg+'Correct export symbol export name ',''''+AExportName+'''',TPrimitiveExpr(E.ExportName).Value);
+    end;
+  If AExportIndex=-1 then
+    AssertNull(Msg+'No export name',E.ExportIndex)
+  else
+    begin
+    AssertNotNull(Msg+'Export name symbol',E.ExportIndex);
+    AssertEquals(Msg+'TPrimitiveExpr',TPrimitiveExpr,E.ExportIndex.CLassType);
+    AssertEquals(Msg+'Correct export symbol export index',IntToStr(AExportindex),TPrimitiveExpr(E.ExportIndex).Value);
+    end;
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TPasExprKind);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TPasExprKind),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TPasExprKind),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TLoopType);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TLoopType),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TLoopType),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TPasObjKind);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TexprOpcode),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TexprOpcode),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TexprOpcode);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TexprOpcode),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TexprOpcode),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TPasMemberHint);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TPasMemberHint),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TPasMemberHint),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TCallingConvention);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TCallingConvention),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TCallingConvention),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TArgumentAccess);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TArgumentAccess),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TArgumentAccess),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TVariableModifier);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TVariableModifier),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TVariableModifier),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TVariableModifiers);
+
+ Function sn (S : TVariableModifiers) : string;
+
+ Var
+   M : TVariableModifier;
+
+ begin
+   Result:='';
+   For M:=Low(TVariableModifier) to High(TVariableModifier) do
+     if M in S then
+       begin
+       if (Result<>'') then
+         Result:=Result+',';
+       end;
+   Result:='['+Result+']';
+ end;
+
+begin
+  AssertEquals(Msg,Sn(AExpected),Sn(AActual));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TPasMemberVisibility);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TPasMemberVisibility),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TPasMemberVisibility),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TProcedureModifier);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TProcedureModifier),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TProcedureModifier),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TProcedureModifiers);
+
+  Function Sn (S : TProcedureModifiers) : String;
+
+  Var
+    m : TProcedureModifier;
+  begin
+    Result:='';
+    For M:=Low(TProcedureModifier) to High(TProcedureModifier) do
+      If (m in S) then
+        begin
+        If (Result<>'') then
+           Result:=Result+',';
+        Result:=Result+GetEnumName(TypeInfo(TProcedureModifier),Ord(m))
+        end;
+  end;
+begin
+  AssertEquals(Msg,Sn(AExpected),SN(AActual));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TAssignKind);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TAssignKind),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TAssignKind),Ord(AActual)));
+end;
+
+procedure TTestParser.AssertEquals(const Msg: String; AExpected,
+  AActual: TProcedureMessageType);
+begin
+  AssertEquals(Msg,GetEnumName(TypeInfo(TProcedureMessageType),Ord(AExpected)),
+                   GetEnumName(TypeInfo(TProcedureMessageType),Ord(AActual)));
+end;
+
+procedure TTestParser.HaveHint(AHint: TPasMemberHint; AHints: TPasMemberHints);
+begin
+  If not (AHint in AHints) then
+    Fail(GetEnumName(TypeInfo(TPasMemberHint),Ord(AHint))+'hint expected.');
+end;
+
+end.
+

+ 1432 - 0
packages/fcl-passrc/tests/tcclasstype.pas

@@ -0,0 +1,1432 @@
+unit tcclasstype;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit, pparser, pastree, testregistry, tctypeparser;
+
+type
+
+  { TTestClassType }
+
+  TTestClassType = Class(TBaseTestTypeParser)
+  Private
+    FDecl : TStrings;
+    FClass : TPasClassType;
+    FMember1: TPasElement;
+    FParent : String;
+    FEnded,
+    FStarted: Boolean;
+    function GetC(AIndex: Integer): TPasConst;
+    function GetF1: TPasVariable;
+    function GetM(AIndex : Integer): TPasElement;
+    function GetMM(AIndex : Integer): TPasProcedure;
+    function GetMF1: TPasFunction;
+    function GetP1: TPasProperty;
+    function GetP2: TPasProperty;
+    function GetT(AIndex : Integer) : TPasType;
+  protected
+    Procedure StartClass (AParent : String = 'TObject'; InterfaceList : String = '');
+    Procedure StartClassHelper (ForType : String = 'TOriginal'; AParent : String = 'TObject');
+    Procedure StartInterface (AParent : String = 'IInterface'; UUID : String = '');
+    Procedure StartRecordHelper (ForType : String = 'TOriginal'; AParent : String = 'TObject');
+    Procedure StartVisibility(A : TPasMemberVisibility);
+    Procedure EndClass(AEnd : String = 'end');
+    Procedure AddMember(S : String);
+    Procedure ParseClass;
+    procedure SetUp; override;
+    procedure TearDown; override;
+    procedure DefaultMethod;
+    Procedure AssertParserError(Const Msg : String);
+    Procedure AssertVisibility(V : TPasMemberVisibility = visDefault; Member : TPasElement = Nil);
+    procedure AssertMemberType(AType : TClass; Member : TPaselement = Nil);
+    procedure AssertMemberName(AName : string; Member : TPaselement = Nil);
+    Procedure AssertProperty(P : TPasProperty; AVisibility : TPasMemberVisibility;AName,ARead,AWrite,AStored,AImplements : String; AArgCount : Integer; ADefault,ANodefault : Boolean);
+    Property TheClass : TPasClassType Read FClass;
+    Property Members[AIndex : Integer] : TPasElement Read GetM;
+    Property Member1 : TPasElement Read FMember1;
+    Property Field1 : TPasVariable Read GetF1;
+    Property Method1 : TPasProcedure Index 0 Read GetMM;
+    Property Method2 : TPasProcedure Index 1 Read GetMM;
+    Property Method3 : TPasProcedure index 2 Read GetMM;
+    Property FunctionMethod1 : TPasFunction Read GetMF1;
+    Property Property1 : TPasProperty Read GetP1;
+    Property Property2 : TPasProperty Read GetP2;
+    Property Type1 : TPasType Index 0 Read GetT;
+    Property Type2 : TPasType Index 1 Read GetT;
+    Property Const1 : TPasConst Index 0 Read GetC;
+    Property Const2 : TPasConst Index 1 Read GetC;
+  published
+    procedure TestEmpty;
+    procedure TestEmptyDeprecated;
+    procedure TestEmptyEnd;
+    procedure TestEmptyEndNoParent;
+    Procedure TestOneInterface;
+    Procedure TestTwoInterfaces;
+    Procedure TestOneField;
+    Procedure TestOneVarField;
+    Procedure TestOneClassField;
+    Procedure TestOneFieldVisibility;
+    Procedure TestOneFieldDeprecated;
+    Procedure TestTwoFields;
+    Procedure TestTwoFieldsB;
+    Procedure TestTwoVarFieldsB;
+    Procedure TestTwoFieldsVisibility;
+    procedure TestHintFieldDeprecated;
+    procedure TestHintFieldPlatform;
+    procedure TestHintFieldExperimental;
+    procedure TestHintFieldLibraryError;
+    procedure TestHintFieldUninmplemented;
+    Procedure TestMethodSimple;
+    Procedure TestClassMethodSimple;
+    Procedure TestFunctionMethodSimple;
+    Procedure TestClassFunctionMethodSimple;
+    Procedure TestMethodOneArg;
+    Procedure TestMethodVirtual;
+    Procedure TestMethodVirtualSemicolon;
+    Procedure TestMethodVirtualAbstract;
+    Procedure TestMethodOverride;
+    procedure TestMethodDynamic;
+    procedure TestMethodReintroduce;
+    procedure TestMethodInline;
+    Procedure TestMethodVisibility;
+    Procedure TestMethodSVisibility;
+    Procedure TestMethodOverloadVisibility;
+    Procedure TestMethodHint;
+    Procedure TestMethodVirtualHint;
+    Procedure TestIntegerMessageMethod;
+    Procedure TestStringMessageMethod;
+    Procedure Test2Methods;
+    Procedure Test2MethodsDifferentVisibility;
+    Procedure TestPropertyRedeclare;
+    Procedure TestPropertyReadOnly;
+    Procedure TestPropertyReadWrite;
+    Procedure TestPropertyWriteOnly;
+    Procedure TestPropertyDefault;
+    Procedure TestPropertyNoDefault;
+    Procedure TestPropertyIndex;
+    Procedure TestPropertyStored;
+    Procedure TestPropertyStoredFalse;
+    Procedure TestPropertyFullyQualifiedType;
+    Procedure TestPropertyArrayReadOnly;
+    Procedure TestPropertyArrayReadWrite;
+    Procedure TestPropertyArrayReadOnlyDefault;
+    Procedure TestPropertyArrayReadWriteDefault;
+    Procedure TestPropertyArrayMultiDimReadOnly;
+    Procedure TestPropertyImplements;
+    Procedure TestPropertyImplementsFullyQualifiedName;
+    Procedure TestPropertyReadFromRecordField;
+    procedure TestPropertyReadWriteFromRecordField;
+    Procedure TestLocalSimpleType;
+    Procedure TestLocalSimpleTypes;
+    Procedure TestLocalSimpleConst;
+    Procedure TestLocalSimpleConsts;
+    procedure TestClassHelperEmpty;
+    procedure TestClassHelperParentedEmpty;
+    procedure TestClassHelperOneMethod;
+    procedure TestInterfaceEmpty;
+    procedure TestInterfaceParentedEmpty;
+    procedure TestInterfaceOneMethod;
+    procedure TestInterfaceNoConstructor;
+    procedure TestInterfaceNoDestructor;
+    procedure TestInterfaceNoFields;
+    procedure TestInterfaceUUID;
+    procedure TestInterfaceUUIDParentedEmpty;
+    procedure TestInterfaceUUIDOneMethod;
+    procedure TestRecordHelperEmpty;
+    procedure TestRecordHelperParentedEmpty;
+    procedure TestRecordHelperOneMethod;
+  end;
+
+implementation
+
+{ TTestClassType }
+
+function TTestClassType.GetM(AIndex : Integer): TPasElement;
+begin
+  AssertNotNull('Have class',TheClass);
+  if (AIndex>=TheClass.Members.Count) then
+    Fail('No member '+IntToStr(AIndex));
+  AssertNotNull('Have member'+IntToStr(AIndex),TheClass.Members[AIndex]);
+  If Not (TObject(TheClass.Members[AIndex]) is TPasElement) then
+    Fail('Member '+IntTostr(AIndex)+' is not a Tpaselement');
+  Result:=TPasElement(TheClass.Members[AIndex])
+end;
+
+function TTestClassType.GetMM(AIndex : integer): TPasProcedure;
+begin
+  AssertNotNull('Have member '+IntToStr(AIndex),Members[AIndex]);
+  AssertEquals('Member is method '+IntToStr(AIndex),TPasProcedure,Members[Aindex].ClassType);
+  Result:=TPasProcedure(Members[Aindex]);
+end;
+
+function TTestClassType.GetMF1: TPasFunction;
+begin
+  AssertNotNull('Have 1 member',Member1);
+  AssertEquals('Member 1 is function method',TPasFunction,Member1.ClassType);
+  Result:=TPasFunction(Member1);
+end;
+
+function TTestClassType.GetP1: TPasProperty;
+begin
+  AssertNotNull('Have 1 member',Member1);
+  AssertEquals('Member 1 is property',TPasProperty,Member1.ClassType);
+  Result:=TPasProperty(Member1);
+end;
+
+function TTestClassType.GetP2: TPasProperty;
+begin
+  AssertNotNull('Have 2 members',Members[1]);
+  AssertEquals('Member 1 is property',TPasProperty,Members[1].ClassType);
+  Result:=TPasProperty(Members[1]);
+end;
+
+function TTestClassType.GetT(Aindex :integer): TPasType;
+begin
+  AssertNotNull('Have member '+IntToStr(AIndex),Members[AIndex]);
+  if not (Members[AIndex] is TPasType) then
+    Fail('Member '+IntToStr(AIndex)+' is not a type');
+  Result:=TPasType(Members[AIndex]);
+end;
+
+function TTestClassType.GetF1: TPasVariable;
+begin
+  AssertNotNull('Have 1 member',Member1);
+  AssertEquals('Member 1 is field',TPasVariable,Member1.ClassType);
+  Result:=TPasVariable(Member1);
+end;
+
+function TTestClassType.GetC(AIndex: Integer): TPasConst;
+begin
+  AssertNotNull('Have member '+IntToStr(AIndex),Members[AIndex]);
+  if not (Members[AIndex] is TPasConst) then
+    Fail('Member '+IntToStr(AIndex)+' is not a const');
+  Result:=TPasConst(Members[AIndex]);
+end;
+
+procedure TTestClassType.StartClass(AParent: String = 'TObject'; InterfaceList: String = '');
+
+Var
+  S : String;
+begin
+  FStarted:=True;
+  S:='TMyClass = Class';
+  if (AParent<>'') then
+    begin
+    S:=S+'('+AParent;
+    if (InterfaceList<>'') then
+      S:=S+','+InterfaceList;
+    S:=S+')';
+    end;
+  FDecl.Add(S);
+  FParent:=AParent;
+end;
+
+procedure TTestClassType.StartClassHelper(ForType: String; AParent: String);
+Var
+  S : String;
+begin
+  FStarted:=True;
+  S:='TMyClass = Class Helper';
+  if (AParent<>'') then
+    begin
+    S:=S+'('+AParent;
+    S:=S+')';
+    end;
+  S:=S+' for '+ForType;
+  FDecl.Add(S);
+  FParent:=AParent;
+end;
+
+procedure TTestClassType.StartInterface(AParent: String; UUID: String);
+Var
+  S : String;
+begin
+  FStarted:=True;
+  S:='TMyClass = Interface';
+  if (AParent<>'') then
+    S:=S+' ('+AParent+')';
+  if (UUID<>'') then
+    S:=S+' ['''+UUID+''']';
+  FDecl.Add(S);
+  FParent:=AParent;
+end;
+
+procedure TTestClassType.StartRecordHelper(ForType: String; AParent: String);
+Var
+  S : String;
+begin
+  FStarted:=True;
+  S:='TMyClass = Record Helper';
+  if (AParent<>'') then
+    begin
+    S:=S+'('+AParent;
+    S:=S+')';
+    end;
+  S:=S+' for '+ForType;
+  FDecl.Add(S);
+  FParent:=AParent;
+end;
+
+procedure TTestClassType.StartVisibility(A: TPasMemberVisibility);
+begin
+  if not FStarted then
+    StartClass;
+  FDecl.Add('  '+VisibilityNames[A]);
+end;
+
+procedure TTestClassType.EndClass(AEnd: String);
+begin
+  if FEnded then exit;
+  if not FStarted then
+    StartClass;
+  FEnded:=True;
+  if (AEnd<>'') then
+    FDecl.Add('  '+AEnd);
+end;
+
+procedure TTestClassType.AddMember(S: String);
+begin
+  if Not FStarted then
+    StartClass;
+  FDecl.Add('    '+S+';');
+end;
+
+procedure TTestClassType.ParseClass;
+begin
+  EndClass;
+  Add('Type');
+  Add('  '+TrimRight(FDecl.Text)+';');
+  ParseDeclarations;
+  AssertEquals('One class type definition',1,Declarations.Classes.Count);
+  AssertEquals('First declaration is type definition.',TPasClassType,TObject(Declarations.Classes[0]).ClassType);
+  FClass:=TObject(Declarations.Classes[0]) as TPasClassType;
+  if (FParent<>'') then
+     begin
+     AssertNotNull('Have parent class',TheClass.AncestorType);
+     AssertEquals('Parent class',TPasUnresolvedTypeRef,TheClass.AncestorType.ClassType);
+     AssertEquals('Parent class name',FParent,TPasUnresolvedTypeRef(TheClass.AncestorType).Name);
+     end;
+  if (TheClass.ObjKind<>okInterface) then
+    AssertNull('No interface, No GUID',TheClass.GUIDExpr);
+  if (Not (TheClass.ObjKind in [okClassHelper,okRecordHelper])) then
+    AssertNull('No helperfortype if not helper',TheClass.HelperForType);
+  if TheClass.Members.Count>0 then
+    FMember1:=TObject(TheClass.Members[0]) as TPaselement;
+end;
+
+procedure TTestClassType.SetUp;
+begin
+  inherited SetUp;
+  FDecl:=TstringList.Create;
+  FClass:=Nil;
+  FParent:='';
+  FStarted:=False;
+end;
+
+procedure TTestClassType.TearDown;
+begin
+  FClass:=Nil;
+  FreeAndNil(FDecl);
+  inherited TearDown;
+end;
+
+procedure TTestClassType.AssertVisibility(V: TPasMemberVisibility;
+  Member: TPasElement);
+begin
+  If Member=Nil then
+    Member:=Member1;
+  AssertNotNull('Cannot get visibility of null member',Member);
+  AssertEquals('Visibility of '+Member.Name,V,Member.Visibility);
+end;
+
+procedure TTestClassType.AssertMemberType(AType: TClass; Member: TPaselement);
+begin
+  If Member=Nil then
+    Member:=Member1;
+  AssertEquals('Member '+Member.Name+' type',AType,Member.ClassType);
+end;
+
+procedure TTestClassType.AssertMemberName(AName: string; Member: TPaselement);
+begin
+  If Member=Nil then
+    Member:=Member1;
+  AssertEquals('Member name ',AName,Member.Name)
+end;
+
+procedure TTestClassType.AssertProperty(P: TPasProperty; AVisibility : TPasMemberVisibility;AName, ARead, AWrite,
+  AStored,AImplements: String; AArgCount: Integer; ADefault, ANodefault: Boolean);
+begin
+  AssertEquals(P.Name+': Visibility',AVisibility,P.Visibility);
+  Assertequals(P.Name+': No args',AArgCount,P.Args.Count);
+  Assertequals(P.Name+': Read accessor',ARead,P.ReadAccessorName);
+  Assertequals(P.Name+': Write accessor',AWrite,P.WriteAccessorName);
+  Assertequals(P.Name+': implements name',AImplements,P.ImplementsName);
+  Assertequals(P.Name+': stored accessor name',AStored,P.StoredAccessorName);
+  Assertequals(P.Name+': default',ADefault,P.IsDefault);
+  Assertequals(P.Name+': nodefault',ANodefault,P.IsNoDefault);
+end;
+
+procedure TTestClassType.TestEmpty;
+begin
+  EndClass('');
+  ParseClass;
+  AssertEquals('No members',0,TheClass.Members.Count);
+end;
+
+procedure TTestClassType.TestEmptyDeprecated;
+begin
+  EndClass('end deprecated');
+  ParseClass;
+  AssertEquals('No members',0,TheClass.Members.Count);
+  HaveHint(hDeprecated,Theclass.Hints);
+end;
+
+procedure TTestClassType.TestEmptyEnd;
+begin
+  ParseClass;
+  AssertEquals('No members',0,TheClass.Members.Count);
+end;
+
+procedure TTestClassType.TestEmptyEndNoParent;
+begin
+  StartClass('','');
+  ParseClass;
+  AssertEquals('No members',0,TheClass.Members.Count);
+end;
+
+procedure TTestClassType.TestOneInterface;
+begin
+  StartClass('TObject','ISomething');
+  ParseClass;
+  AssertEquals('Have 1 interface',1,TheClass.Interfaces.Count);
+  AssertNotNull('Correct class',TheClass.Interfaces[0]);
+  AssertEquals('Correct class',TPasUnresolvedTypeRef,TObject(TheClass.Interfaces[0]).ClassType);
+  AssertEquals('Interface name','ISomething',TPasUnresolvedTypeRef(TheClass.Interfaces[0]).Name);
+end;
+
+procedure TTestClassType.TestTwoInterfaces;
+begin
+  StartClass('TObject','ISomething, ISomethingElse');
+  ParseClass;
+  AssertEquals('Have 2 interface',2,TheClass.Interfaces.Count);
+  AssertNotNull('Correct class',TheClass.Interfaces[0]);
+  AssertEquals('Correct class',TPasUnresolvedTypeRef,TObject(TheClass.Interfaces[0]).ClassType);
+  AssertEquals('Interface name','ISomething',TPasUnresolvedTypeRef(TheClass.Interfaces[0]).Name);
+  AssertNotNull('Correct class',TheClass.Interfaces[1]);
+  AssertEquals('Correct class',TPasUnresolvedTypeRef,TObject(TheClass.Interfaces[1]).ClassType);
+  AssertEquals('Interface name','ISomethingElse',TPasUnresolvedTypeRef(TheClass.Interfaces[1]).Name);
+end;
+
+procedure TTestClassType.TestOneField;
+begin
+  AddMember('a : integer');
+  ParseClass;
+  AssertNotNull('Have 1 field',Field1);
+  AssertMemberName('a');
+  AssertVisibility;
+end;
+
+procedure TTestClassType.TestOneVarField;
+begin
+  StartVisibility(visPublished);
+  FDecl.Add('var');
+  AddMember('a : integer');
+  ParseClass;
+  AssertNotNull('Have 1 field',Field1);
+  AssertMemberName('a');
+  AssertVisibility(visPublished);
+end;
+
+procedure TTestClassType.TestOneClassField;
+begin
+  StartVisibility(visPublished);
+  FDecl.Add('class var');
+  AddMember('a : integer');
+  ParseClass;
+  AssertNotNull('Have 1 field',Field1);
+  AssertMemberName('a');
+  AssertVisibility(visPublished);
+  if not (vmClass in Field1.VarModifiers) then
+     Fail('Field is not a class field');
+end;
+
+procedure TTestClassType.TestOneFieldVisibility;
+begin
+  StartVisibility(visPublished);
+  AddMember('a : integer');
+  ParseClass;
+  AssertNotNull('Have 1 field',Field1);
+  AssertMemberName('a');
+  AssertVisibility(visPublished);
+end;
+
+procedure TTestClassType.TestOneFieldDeprecated;
+begin
+  AddMember('a : integer deprecated');
+  ParseClass;
+  AssertNotNull('Have 1 field',Field1);
+  AssertMemberName('a');
+  HaveHint(hDeprecated,Member1.Hints);
+  AssertVisibility;
+end;
+
+procedure TTestClassType.TestTwoFields;
+begin
+  AddMember('a : integer');
+  AddMember('b : integer');
+  ParseClass;
+  AssertEquals('2 members',2,TheClass.members.Count);
+  AssertNotNull('Have field',Field1);
+  AssertMemberName('a');
+  AssertVisibility;
+  AssertNotNull('Have field',Members[1]);
+  AssertMemberName('b',Members[1]);
+  AssertMemberType(TPasVariable,Members[1]);
+  AssertVisibility(visDefault,Members[1]);
+end;
+
+procedure TTestClassType.TestTwoFieldsB;
+begin
+  AddMember('a,b : integer');
+  ParseClass;
+  AssertEquals('2 members',2,TheClass.members.Count);
+  AssertNotNull('Have field',Field1);
+  AssertMemberName('a');
+  AssertVisibility;
+  AssertNotNull('Have field',Members[1]);
+  AssertMemberName('b',Members[1]);
+  AssertMemberType(TPasVariable,Members[1]);
+  AssertVisibility(visDefault,Members[1]);
+end;
+
+procedure TTestClassType.TestTwoVarFieldsB;
+begin
+  StartVisibility(visPublic);
+  FDecl.Add('var');
+  AddMember('a,b : integer');
+  ParseClass;
+  AssertEquals('2 members',2,TheClass.members.Count);
+  AssertNotNull('Have field',Field1);
+  AssertMemberName('a');
+  AssertVisibility(vispublic);
+  AssertNotNull('Have field',Members[1]);
+  AssertMemberName('b',Members[1]);
+  AssertMemberType(TPasVariable,Members[1]);
+  AssertVisibility(visPublic,Members[1]);
+end;
+
+procedure TTestClassType.TestTwoFieldsVisibility;
+begin
+  StartVisibility(visPublic);
+  AddMember('a,b : integer');
+  ParseClass;
+  AssertEquals('2 members',2,TheClass.members.Count);
+  AssertNotNull('Have field',Field1);
+  AssertMemberName('a');
+  AssertVisibility(vispublic);
+  AssertNotNull('Have field',Members[1]);
+  AssertMemberName('b',Members[1]);
+  AssertMemberType(TPasVariable,Members[1]);
+  AssertVisibility(visPublic,Members[1]);
+end;
+
+procedure TTestClassType.TestHintFieldDeprecated;
+begin
+  AddMember('deprecated : integer');
+  ParseClass;
+  AssertEquals('1 members',1,TheClass.members.Count);
+  AssertNotNull('Have field',Field1);
+  AssertMemberName('deprecated');
+end;
+
+procedure TTestClassType.TestHintFieldPlatform;
+begin
+  AddMember('platform : integer');
+  ParseClass;
+  AssertEquals('1 members',1,TheClass.members.Count);
+  AssertNotNull('Have field',Field1);
+  AssertMemberName('platform');
+end;
+
+procedure TTestClassType.TestHintFieldLibraryError;
+begin
+  AddMember('library: integer');
+  AssertException(EParserError,@ParseClass);
+end;
+
+procedure TTestClassType.TestHintFieldExperimental;
+begin
+  AddMember('experimental: integer');
+  ParseClass;
+  AssertEquals('1 members',1,TheClass.members.Count);
+  AssertNotNull('Have field',Field1);
+  AssertMemberName('experimental');
+end;
+
+procedure TTestClassType.TestHintFieldUninmplemented;
+begin
+  AddMember('unimplemented: integer');
+  ParseClass;
+  AssertEquals('1 members',1,TheClass.members.Count);
+  AssertNotNull('Have field',Field1);
+  AssertMemberName('unimplemented');
+end;
+
+procedure TTestClassType.TestMethodSimple;
+begin
+  AddMember('Procedure DoSomething');
+  ParseClass;
+  AssertEquals('1 members',1,TheClass.members.Count);
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertNotNull('Have method',Method1);
+  AssertMemberName('DoSomething');
+  AssertEquals('No modifiers',[],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+  AssertNotNull('Method proc type',Method1.ProcType);
+  AssertEquals('No arguments',0,Method1.ProcType.Args.Count)
+end;
+
+procedure TTestClassType.TestClassMethodSimple;
+begin
+  AddMember('Class Procedure DoSomething');
+  ParseClass;
+  AssertEquals('1 members',1,TheClass.members.Count);
+  AssertEquals('1 class procedure',TPasClassProcedure,members[0].ClassType);
+  AssertEquals('Default visibility',visDefault,Members[0].Visibility);
+  AssertMemberName('DoSomething');
+  AssertEquals('No modifiers',[],TPasClassProcedure(Members[0]).Modifiers);
+  AssertEquals('Default calling convention',ccDefault, TPasClassProcedure(Members[0]).ProcType.CallingConvention);
+  AssertNotNull('Method proc type',TPasClassProcedure(Members[0]).ProcType);
+  AssertEquals('No arguments',0,TPasClassProcedure(Members[0]).ProcType.Args.Count)
+end;
+
+procedure TTestClassType.TestFunctionMethodSimple;
+begin
+  AddMember('Function DoSomething : integer');
+  ParseClass;
+  AssertEquals('1 members',1,TheClass.members.Count);
+  AssertEquals('Default visibility',visDefault,FunctionMethod1.Visibility);
+  AssertNotNull('Have method',Member1);
+  AssertMemberName('DoSomething');
+  AssertEquals('No modifiers',[],functionMethod1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, functionMethod1.ProcType.CallingConvention);
+  AssertNotNull('Method proc type',functionMethod1.ProcType);
+  AssertEquals('No arguments',0,functionMethod1.ProcType.Args.Count)
+end;
+
+procedure TTestClassType.TestClassFunctionMethodSimple;
+begin
+  AddMember('Class Function DoSomething : integer');
+  ParseClass;
+  AssertEquals('1 members',1,TheClass.members.Count);
+  AssertEquals('1 class procedure',TPasClassFunction,members[0].ClassType);
+  AssertEquals('Default visibility',visDefault,Members[0].Visibility);
+  AssertMemberName('DoSomething');
+  AssertEquals('No modifiers',[],TPasClassFunction(members[0]).Modifiers);
+  AssertEquals('Default calling convention',ccDefault, TPasClassFunction(members[0]).ProcType.CallingConvention);
+  AssertNotNull('Method proc type',TPasClassFunction(members[0]).ProcType);
+  AssertEquals('No arguments',0,TPasClassFunction(members[0]).ProcType.Args.Count)
+end;
+
+procedure TTestClassType.DefaultMethod;
+
+begin
+  if TheClass.members.Count<1 then
+    Fail('No members for method');
+  AssertNotNull('Have method',Method1);
+  AssertNotNull('Method proc type',Method1.ProcType);
+    AssertMemberName('DoSomething');
+  AssertEquals('1 argument',1,Method1.ProcType.Args.Count) ;
+  AssertEquals('Argument name','A',TPasVariable(Method1.ProcType.Args[0]).Name);
+end;
+
+procedure TTestClassType.AssertParserError(Const Msg : String);
+begin
+  AssertException(Msg,EParserError,@ParseClass)
+end;
+
+procedure TTestClassType.TestMethodOneArg;
+begin
+  AddMember('Procedure DoSomething(A : Integer)');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('No modifiers',[],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestMethodVirtual;
+begin
+  AddMember('Procedure DoSomething(A : Integer) virtual');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('Virtual modifiers',[pmVirtual],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestMethodVirtualSemicolon;
+begin
+  AddMember('Procedure DoSomething(A : Integer); virtual');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('Virtual modifiers',[pmVirtual],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestMethodVirtualAbstract;
+begin
+  AddMember('Procedure DoSomething(A : Integer) virtual abstract');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('Virtual, abstract modifiers',[pmVirtual,pmAbstract],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+
+procedure TTestClassType.TestMethodOverride;
+begin
+  AddMember('Procedure DoSomething(A : Integer) override');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('Override modifiers',[pmoverride],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestMethodReintroduce;
+begin
+  AddMember('Procedure DoSomething(A : Integer) ReIntroduce');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('Reintroduce modifiers',[pmReintroduce],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestMethodDynamic;
+begin
+  AddMember('Procedure DoSomething(A : Integer) dynamic');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('Dynamic modifiers',[pmDynamic],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestMethodInline;
+begin
+  AddMember('Procedure DoSomething(A : Integer) inline');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('Inline modifiers',[pmInline],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestMethodVisibility;
+begin
+  StartVisibility(visPublic);
+  AddMember('Procedure DoSomething(A : Integer)');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Public visibility',visPublic,Method1.Visibility);
+  AssertEquals('No modifiers',[],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestMethodSVisibility;
+begin
+  AddMember('Procedure DoSomething(A : Integer)');
+  StartVisibility(visPublic);
+  AddMember('Procedure DoSomethingB(A : Integer)');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('First Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('No modifiers',[],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+  AssertNotNull('Have method 2',Method2);
+  AssertEquals('Second Default visibility',visPublic,Method2.Visibility);
+  AssertNotNull('Method proc type',Method2.ProcType);
+  AssertMemberName('DoSomethingB',Method2);
+  AssertEquals('1 argument',1,Method2.ProcType.Args.Count) ;
+  AssertEquals('Argument name','A',TPasVariable(Method2.ProcType.Args[0]).Name);
+end;
+
+procedure TTestClassType.TestMethodOverloadVisibility;
+begin
+  AddMember('Procedure DoSomething(A : Integer)');
+  StartVisibility(visPublic);
+  AddMember('Procedure DoSomething(A : String)');
+  ParseClass;
+  AssertNotNull('Have member 1',Member1);
+  AssertEquals('Overload',TPasOverloadedProc,Member1.ClassType);
+  AssertEquals('Default visibility',visDefault,Member1.Visibility);
+end;
+
+procedure TTestClassType.TestMethodHint;
+begin
+  AddMember('Procedure DoSomething(A : Integer) deprecated');
+  ParseClass;
+  DefaultMethod;
+  HaveHint(hDeprecated,Member1.Hints);
+  HaveHint(hDeprecated,Method1.ProcType.Hints);
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('No modifiers',[],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestMethodVirtualHint;
+begin
+  AddMember('Procedure DoSomething(A : Integer) virtual; deprecated');
+  ParseClass;
+  DefaultMethod;
+  HaveHint(hDeprecated,Member1.Hints);
+  HaveHint(hDeprecated,Method1.ProcType.Hints);
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('virtual modifiers',[pmVirtual],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestIntegerMessageMethod;
+begin
+  AddMember('Procedure DoSomething(A : Integer) message 123');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('No modifiers',[pmMessage],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+  AssertEquals('Message name','123',Method1.MessageName);
+end;
+
+procedure TTestClassType.TestStringMessageMethod;
+begin
+  AddMember('Procedure DoSomething(A : Integer) message ''aha''');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('No modifiers',[pmMessage],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+  AssertEquals('Message name','''aha''',Method1.MessageName);
+end;
+
+procedure TTestClassType.Test2Methods;
+begin
+  AddMember('Procedure DoSomething(A : Integer) virtual');
+  AddMember('Procedure DoSomethingElse');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('Virtual modifiers',[pmVirtual],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+  AssertEquals('Default visibility',visDefault,Members[1].Visibility);
+  AssertEquals('Default visibility',TPasProcedure,Members[1].ClassType);
+  AssertEquals('Virtual modifiers',[],TPasProcedure(Members[1]).Modifiers);
+  AssertEquals('Default calling convention',ccDefault, TPasProcedure(Members[1]).ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.Test2MethodsDifferentVisibility;
+begin
+  AddMember('Procedure DoSomething(A : Integer) virtual');
+  StartVisibility(visPublic);
+  AddMember('Procedure DoSomethingElse');
+  ParseClass;
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('Virtual modifiers',[pmVirtual],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+  AssertEquals('2 Public visibility',visPublic,Members[1].Visibility);
+  AssertEquals('2 Default visibility',TPasProcedure,Members[1].ClassType);
+  AssertEquals('2 No modifiers',[],TPasProcedure(Members[1]).Modifiers);
+  AssertEquals('2 Default calling convention',ccDefault, TPasProcedure(Members[1]).ProcType.CallingConvention);
+
+end;
+
+procedure TTestClassType.TestPropertyRedeclare;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','','','','',0,False,False);
+  AssertNull('No type',Property1.VarType);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyReadOnly;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : integer Read FSomething');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','FSomething','','','',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyReadWrite;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : integer Read FSomething Write FSomething');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','FSomething','FSomething','','',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyWriteOnly;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : integer Write FSomething');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','','FSomething','','',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyDefault;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : integer Read FSomething Write FSomething default 1');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','FSomething','FSomething','','',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertExpression('Default expression',Property1.DefaultExpr,pekNumber,'1');
+  Assertequals('Default value','1',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyNoDefault;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : integer Read FSomething Write FSomething nodefault');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','FSomething','FSomething','','',0,False,True);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No Default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyIndex;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : integer Index 2 Read GetF Write SetF');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','GetF','SetF','','',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  AssertExpression('Index expression',Property1.IndexExpr,pekNumber,'2');
+  Assertequals('index','2',Property1.IndexValue);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No Default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyStored;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : integer Read GetF Write SetF Stored CheckStored');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','GetF','SetF','CheckStored','',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No Default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyStoredFalse;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : integer Read GetF Write SetF Stored False');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','GetF','SetF','False','',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No Default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyFullyQualifiedType;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : unita.typeb Read FSomething');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','FSomething','','','',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','unita.typeb',Property1.vartype.name);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyArrayReadOnly;
+Var
+  A : TPasArgument;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Somethings[AIndex : Integer] : integer Read GetF');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Somethings','GetF','','','',1,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  AssertEquals('Argument class',TPasArgument,TObject(Property1.Args[0]).ClassType);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No Default value','',Property1.DefaultValue);
+  // Argument
+  A:=TPasArgument(Property1.Args[0]);
+  AssertEquals('Argument name','AIndex',A.Name);
+  AssertNotNull('Argument class', A.ArgType);
+  AssertEquals('Argument class type',TPasUnresolvedTypeRef,A.ArgType.ClassType);
+  AssertEquals('Argument class type name','Integer',A.ArgType.Name);
+end;
+
+procedure TTestClassType.TestPropertyArrayReadWrite;
+Var
+  A : TPasArgument;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Somethings[AIndex : Integer] : integer Read GetF Write SetF');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Somethings','GetF','SetF','','',1,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No Default value','',Property1.DefaultValue);
+  // Argument
+  AssertEquals('Argument class',TPasArgument,TObject(Property1.Args[0]).ClassType);
+  A:=TPasArgument(Property1.Args[0]);
+  AssertEquals('Argument name','AIndex',A.Name);
+  AssertNotNull('Argument class', A.ArgType);
+  AssertEquals('Argument class type',TPasUnresolvedTypeRef,A.ArgType.ClassType);
+  AssertEquals('Argument class type name','Integer',A.ArgType.Name);
+end;
+
+procedure TTestClassType.TestPropertyArrayReadOnlyDefault;
+
+Var
+  A : TPasArgument;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Somethings[AIndex : Integer] : integer Read GetF; default');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Somethings','GetF','','','',1,True,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No Default value','',Property1.DefaultValue);
+  // Argument
+  AssertEquals('Argument class',TPasArgument,TObject(Property1.Args[0]).ClassType);
+  A:=TPasArgument(Property1.Args[0]);
+  AssertEquals('Argument name','AIndex',A.Name);
+  AssertNotNull('Argument class', A.ArgType);
+  AssertEquals('Argument class type',TPasUnresolvedTypeRef,A.ArgType.ClassType);
+  AssertEquals('Argument class type name','Integer',A.ArgType.Name);
+end;
+
+procedure TTestClassType.TestPropertyArrayReadWriteDefault;
+Var
+  A : TPasArgument;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Somethings[AIndex : Integer] : integer Read GetF Write SetF; default');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Somethings','GetF','SetF','','',1,True,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No Default value','',Property1.DefaultValue);
+  // Argument
+  AssertEquals('Argument class',TPasArgument,TObject(Property1.Args[0]).ClassType);
+  A:=TPasArgument(Property1.Args[0]);
+  AssertEquals('Argument name','AIndex',A.Name);
+  AssertNotNull('Argument class', A.ArgType);
+  AssertEquals('Argument class type',TPasUnresolvedTypeRef,A.ArgType.ClassType);
+  AssertEquals('Argument class type name','Integer',A.ArgType.Name);
+end;
+
+procedure TTestClassType.TestPropertyArrayMultiDimReadOnly;
+Var
+  A : TPasArgument;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Somethings[ACol : Integer,ARow : Integer] : integer Read GetF; default');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Somethings','GetF','','','',2,True,False);
+  AssertEquals('Published property',vispublished,Property1.Visibility);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Default expression',Property1.DefaultExpr);
+  Assertequals('No Default value','',Property1.DefaultValue);
+  // Argument 1
+  AssertEquals('Argument 1 class',TPasArgument,TObject(Property1.Args[0]).ClassType);
+  A:=TPasArgument(Property1.Args[0]);
+  AssertEquals('Argument 1name','ACol',A.Name);
+  AssertNotNull('Argument  1class', A.ArgType);
+  AssertEquals('Argument 1 class type',TPasUnresolvedTypeRef,A.ArgType.ClassType);
+  AssertEquals('Argument 1 class type name','Integer',A.ArgType.Name);
+  // Argument 2
+  AssertEquals('Argument 2 class',TPasArgument,TObject(Property1.Args[1]).ClassType);
+  A:=TPasArgument(Property1.Args[1]);
+  AssertEquals('Argument 2 name','ARow',A.Name);
+  AssertNotNull('Argument 2 class', A.ArgType);
+  AssertEquals('Argument 2 class type',TPasUnresolvedTypeRef,A.ArgType.ClassType);
+  AssertEquals('Argument 2 class type name','Integer',A.ArgType.Name);
+end;
+
+procedure TTestClassType.TestPropertyImplements;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : AInterface Read FSomething Implements ISomeInterface');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','FSomething','','','ISomeInterface',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','AInterface',Property1.vartype.name);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertNull('No default expression',Property1.DefaultExpr);
+  Assertequals('Default value','',Property1.DefaultValue);
+
+end;
+
+procedure TTestClassType.TestPropertyImplementsFullyQualifiedName;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : AInterface Read FSomething Implements UnitB.ISomeInterface');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','FSomething','','','UnitB.ISomeInterface',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','AInterface',Property1.vartype.name);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertNull('No default expression',Property1.DefaultExpr);
+  Assertequals('Default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyReadFromRecordField;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : Integer Read FPoint.X');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','FPoint.X','','','',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertNull('No default expression',Property1.DefaultExpr);
+  Assertequals('Default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestPropertyReadWriteFromRecordField;
+begin
+  StartVisibility(visPublished);
+  AddMember('Property Something : Integer Read FPoint.X Write FPoint.X');
+  ParseClass;
+  AssertProperty(Property1,visPublished,'Something','FPoint.X','FPoint.X','','',0,False,False);
+  AssertNotNull('Have type',Property1.VarType);
+  AssertEquals('Property type class type',TPasUnresolvedTypeRef,Property1.vartype.ClassType);
+  AssertEquals('Property type name','Integer',Property1.vartype.name);
+  Assertequals('No index','',Property1.IndexValue);
+  AssertNull('No Index expression',Property1.IndexExpr);
+  AssertNull('No default expression',Property1.DefaultExpr);
+  Assertequals('Default value','',Property1.DefaultValue);
+end;
+
+procedure TTestClassType.TestLocalSimpleType;
+begin
+  StartVisibility(visPublic);
+  FDecl.add('Type');
+  AddMember('TDirection = (left,right)');
+  AddMember('Procedure Something');
+  ParseClass;
+  AssertEquals('Local Enumeration type',TPasEnumType, Type1.ClassType);
+  AssertEquals('Visibility is correct',VisPublic, Type1.Visibility);
+  AssertEquals('Type name','TDirection', Type1.Name);
+  AssertSame('Type parent is class',TheClass, Type1.Parent);
+  AssertNotNull('Member 2 is procedure',Method2);
+  AssertEquals('method name','Something', Method2.Name);
+end;
+
+procedure TTestClassType.TestLocalSimpleTypes;
+begin
+  StartVisibility(visPublic);
+  FDecl.add('Type');
+  AddMember('TDirection = (left,right)');
+  AddMember('TVerticalDirection = (up,down)');
+  AddMember('Procedure Something');
+  ParseClass;
+  AssertEquals('Local Enumeration type',TPasEnumType, Type1.ClassType);
+  AssertEquals('Visibility is correct',VisPublic, Type1.Visibility);
+  AssertEquals('Type name','TDirection', Type1.Name);
+  AssertSame('Type parent is class',TheClass, Type1.Parent);
+  AssertEquals('Local Enumeration type',TPasEnumType, Type2.ClassType);
+  AssertEquals('Visibility is correct',VisPublic, Type2.Visibility);
+  AssertEquals('Type name','TVerticalDirection', Type2.Name);
+  AssertSame('Type parent is class',TheClass, Type2.Parent);
+  AssertNotNull('Member 2 is procedure',Method3);
+  AssertEquals('method name','Something', Method3.Name);
+end;
+
+procedure TTestClassType.TestLocalSimpleConst;
+begin
+  StartVisibility(visPublic);
+  FDecl.add('Const');
+  AddMember(' A = 23');
+  AddMember('Procedure Something');
+  ParseClass;
+  AssertEquals('Local const value',TPasConst, Const1.ClassType);
+  AssertEquals('Visibility is correct',VisPublic, Const1.Visibility);
+  AssertEquals('Const name','A', Const1.Name);
+  AssertExpression('Const value',Const1.Expr,pekNUmber,'23');
+  AssertSame('Const parent is class',TheClass, Const1.Parent);
+  AssertNotNull('Member 2 is procedure',Method2);
+  AssertEquals('method name','Something', Method2.Name);
+end;
+
+procedure TTestClassType.TestLocalSimpleConsts;
+begin
+  StartVisibility(visPublic);
+  FDecl.add('Const');
+  AddMember(' A = 23');
+  AddMember(' B = 45');
+  AddMember('Procedure Something');
+  ParseClass;
+  // Const A
+  AssertEquals('Local const value',TPasConst, Const1.ClassType);
+  AssertEquals('Visibility is correct',VisPublic, Const1.Visibility);
+  AssertEquals('Const name','A', Const1.Name);
+  AssertExpression('Const value',Const1.Expr,pekNUmber,'23');
+  AssertSame('Type parent is class',TheClass, Const1.Parent);
+  // Const B
+  AssertEquals('Local const value',TPasConst, Const2.ClassType);
+  AssertEquals('Visibility is correct',VisPublic, Const2.Visibility);
+  AssertEquals('Const name','B', Const2.Name);
+  AssertExpression('Const value',Const2.Expr,pekNUmber,'45');
+  AssertSame('Type parent is class',TheClass, Const2.Parent);
+  AssertNotNull('Member 3 is procedure',Method3);
+  AssertEquals('method name','Something', Method3.Name);
+end;
+
+procedure TTestClassType.TestClassHelperEmpty;
+begin
+  StartClassHelper('TOriginal','');
+  EndClass();
+  ParseClass;
+  AssertEquals('Is class helper',okClassHelper,TheClass.ObjKind);
+  AssertNotNull('Have helper original',TheClass.HelperForType);
+  AssertEquals('Have helper original alias',TPasUnresolvedTypeRef,TheClass.HelperForType.CLassType);
+  AssertEquals('Helper original alias name','TOriginal',TheClass.HelperForType.Name);
+  AssertEquals('No members',0,TheClass.Members.Count);
+end;
+
+procedure TTestClassType.TestClassHelperParentedEmpty;
+begin
+  StartClassHelper('TOriginal','TOtherHelper');
+  EndClass();
+  ParseClass;
+  AssertEquals('Is class helper',okClassHelper,TheClass.ObjKind);
+  AssertNotNull('Have helper original',TheClass.HelperForType);
+  AssertEquals('Have helper original alias',TPasUnresolvedTypeRef,TheClass.HelperForType.CLassType);
+  AssertEquals('Helper original alias name','TOriginal',TheClass.HelperForType.Name);
+  AssertEquals('No members',0,TheClass.Members.Count);
+end;
+
+procedure TTestClassType.TestClassHelperOneMethod;
+begin
+  StartClassHelper('TOriginal','');
+  AddMember('Procedure DoSomething(A : Integer)');
+  ParseClass;
+  AssertEquals('Is class helper',okClassHelper,TheClass.ObjKind);
+  AssertNotNull('Have helper original',TheClass.HelperForType);
+  AssertEquals('Have helper original alias',TPasUnresolvedTypeRef,TheClass.HelperForType.CLassType);
+  AssertEquals('Helper original alias name','TOriginal',TheClass.HelperForType.Name);
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('No modifiers',[],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+procedure TTestClassType.TestInterfaceEmpty;
+begin
+  StartInterface('','');
+  EndClass();
+  ParseClass;
+  AssertEquals('Is interface',okInterface,TheClass.ObjKind);
+  AssertEquals('No members',0,TheClass.Members.Count);
+  AssertNull('No UUID',TheClass.GUIDExpr);
+end;
+
+procedure TTestClassType.TestInterfaceParentedEmpty;
+begin
+  StartInterface('IInterface','');
+  EndClass();
+  ParseClass;
+  AssertEquals('Is interface',okInterface,TheClass.ObjKind);
+  AssertEquals('No members',0,TheClass.Members.Count);
+  AssertNull('No UUID',TheClass.GUIDExpr);
+end;
+
+procedure TTestClassType.TestInterfaceOneMethod;
+begin
+  StartInterface('IInterface','');
+  AddMember('Procedure DoSomething(A : Integer)');
+  EndClass();
+  ParseClass;
+  AssertEquals('Is interface',okInterface,TheClass.ObjKind);
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('No modifiers',[],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+  AssertNull('No UUID',TheClass.GUIDExpr);
+end;
+
+procedure TTestClassType.TestInterfaceNoConstructor;
+begin
+  StartInterface('','');
+  AddMember('Constructor DoSomething(A : Integer)');
+  AssertParserError('No constructor in interface');
+end;
+
+procedure TTestClassType.TestInterfaceNoDestructor;
+begin
+  StartInterface('','');
+  AddMember('Destructor DoSomething(A : Integer)');
+  AssertParserError('No destructor in interface');
+end;
+
+procedure TTestClassType.TestInterfaceNoFields;
+begin
+  StartInterface('','');
+  AddMember('AField : Integer');
+  AssertParserError('No fields in interface');
+end;
+
+procedure TTestClassType.TestInterfaceUUID;
+begin
+  StartInterface('','123');
+  EndClass();
+  ParseClass;
+  AssertEquals('Is interface',okInterface,TheClass.ObjKind);
+  AssertEquals('No members',0,TheClass.Members.Count);
+  AssertExpression('UUID',TheClass.GUIDExpr,pekString,'''123''');
+end;
+
+procedure TTestClassType.TestInterfaceUUIDParentedEmpty;
+begin
+  StartInterface('IInterface','123');
+  EndClass();
+  ParseClass;
+  AssertEquals('Is interface',okInterface,TheClass.ObjKind);
+  AssertEquals('No members',0,TheClass.Members.Count);
+  AssertExpression('UUID',TheClass.GUIDExpr,pekString,'''123''');
+end;
+
+procedure TTestClassType.TestInterfaceUUIDOneMethod;
+begin
+  StartInterface('IInterface','123');
+  AddMember('Procedure DoSomething(A : Integer)');
+  EndClass();
+  ParseClass;
+  AssertEquals('Is interface',okInterface,TheClass.ObjKind);
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('No modifiers',[],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+  AssertExpression('UUID',TheClass.GUIDExpr,pekString,'''123''');
+end;
+
+procedure TTestClassType.TestRecordHelperEmpty;
+begin
+  StartRecordHelper('TOriginal','');
+  ParseClass;
+  AssertEquals('Is Record helper',okRecordHelper,TheClass.ObjKind);
+  AssertNotNull('Have helper original',TheClass.HelperForType);
+  AssertEquals('Have helper original alias',TPasUnresolvedTypeRef,TheClass.HelperForType.ClassType);
+  AssertEquals('Helper original alias name','TOriginal',TheClass.HelperForType.Name);
+  AssertEquals('No members',0,TheClass.Members.Count);
+end;
+
+procedure TTestClassType.TestRecordHelperParentedEmpty;
+begin
+  StartRecordHelper('TOriginal','TOtherHelper');
+  ParseClass;
+  AssertEquals('Is Record helper',okRecordHelper,TheClass.ObjKind);
+  AssertNotNull('Have helper original',TheClass.HelperForType);
+  AssertEquals('Have helper original alias',TPasUnresolvedTypeRef,TheClass.HelperForType.ClassType);
+  AssertEquals('Helper original alias name','TOriginal',TheClass.HelperForType.Name);
+  AssertEquals('No members',0,TheClass.Members.Count);
+end;
+
+procedure TTestClassType.TestRecordHelperOneMethod;
+begin
+  StartRecordHelper('TOriginal','');
+  AddMember('Procedure DoSomething(A : Integer)');
+  ParseClass;
+  AssertEquals('Is Record helper',okRecordHelper,TheClass.ObjKind);
+  AssertNotNull('Have helper original',TheClass.HelperForType);
+  AssertEquals('Have helper original alias',TPasUnresolvedTypeRef,TheClass.HelperForType.ClassType);
+  AssertEquals('Helper original alias name','TOriginal',TheClass.HelperForType.Name);
+  DefaultMethod;
+  AssertEquals('Default visibility',visDefault,Method1.Visibility);
+  AssertEquals('No modifiers',[],Method1.Modifiers);
+  AssertEquals('Default calling convention',ccDefault, Method1.ProcType.CallingConvention);
+end;
+
+initialization
+
+  RegisterTest(TTestClassType);
+end.
+

+ 910 - 0
packages/fcl-passrc/tests/tcexprparser.pas

@@ -0,0 +1,910 @@
+unit tcexprparser;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit,  testregistry, tcbaseparser, pastree;
+
+type
+
+  { TTestExpressions }
+
+  TTestExpressions= class(TTestParser)
+  private
+    FLeft: TPAsExpr;
+    FRight: TPAsExpr;
+    FTheExpr: TPasExpr;
+    FVariables : TStringList;
+    procedure AssertLeftPrecedence(AInnerLeft: Integer; AInnerOp: TExprOpCode;
+      AInnerRight: Integer; AOuterOp: TexprOpCode; AOuterRight: Integer);
+    procedure AssertRightPrecedence(AOuterLeft: Integer; AOuterOp: TExprOpCode;
+      AInnerLeft: Integer; AInnerOp: TexprOpCode; AInnerRight: Integer);
+    procedure DeclareVar(const AVarType: String; const AVarName: String = 'a');
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+    Procedure SetExpression(Const AExpression : String);
+    Procedure ParseExpression;
+    Procedure ParseExpression(Const AExpression : String);
+    Function AssertBinaryExpr(Const Msg : String; Op : TExprOpCode; Out ALeft,ARight : TPasExpr) : TBinaryExpr;
+    Function AssertBinaryExpr(Const Msg : String; AExpr : TPasExpr; Op : TExprOpCode; Out ALeft,ARight : TPasExpr) : TBinaryExpr;
+    Function AssertUnaryExpr(Const Msg : String; Op : TExprOpCode; Out AOperand : TPasExpr) : TUnaryExpr;
+    Function AssertUnaryExpr(Const Msg : String; AExpr: TPasExpr; Op : TExprOpCode; Out AOperand : TPasExpr) : TUnaryExpr;
+    Property TheExpr : TPasExpr read FTheExpr;
+    Property Theleft : TPAsExpr Read FLeft;
+    Property TheRight : TPAsExpr Read FRight;
+  published
+    {
+      TPasExprKind = (pekRange,
+       pekListOfExp, );
+    }
+    procedure TestPrimitiveInteger;
+    procedure TestPrimitiveIntegerHex;
+    procedure TestPrimitiveIntegerOctal;
+    procedure TestPrimitiveIntegerBinary;
+    procedure TestPrimitiveDouble;
+    procedure TestPrimitiveString;
+    procedure TestPrimitiveIdent;
+    procedure TestPrimitiveBooleanFalse;
+    procedure TestPrimitiveBooleanTrue;
+    procedure TestPrimitiveNil;
+    procedure TestPrimitiveSet;
+    procedure TestPrimitiveChar;
+    procedure TestPrimitiveControlChar;
+    procedure TestPrimitiveSetEmpty;
+    procedure TestPrimitiveSelf;
+    Procedure TestInherited;
+    Procedure TestInheritedFunction;
+    Procedure TestUnaryMinus;
+    Procedure TestUnaryMinusWhiteSpace;
+    Procedure TestUnaryAddress;
+    Procedure TestUnaryNot;
+    Procedure TestUnaryDeref;
+    Procedure TestBinaryAdd;
+    Procedure TestBinarySubtract;
+    Procedure TestBinaryMultiply;
+    Procedure TestBinaryDivision;
+    Procedure TestBinaryPower;
+    Procedure TestBinaryMod;
+    Procedure TestBinaryDiv;
+    procedure TestBinaryShl;
+    procedure TestBinaryShr;
+    Procedure TestBinarySymmetricalDifference;
+    Procedure TestBinaryAnd;
+    Procedure TestBinaryOr;
+    Procedure TestBinaryXOr;
+    Procedure TestBinaryIn;
+    Procedure TestBinaryIs;
+    Procedure TestBinaryAs;
+    Procedure TestBinaryEquals;
+    Procedure TestBinaryDiffers;
+    Procedure TestBinaryLessThan;
+    Procedure TestBinaryLessThanEqual;
+    Procedure TestBinaryLargerThan;
+    Procedure TestBinaryLargerThanEqual;
+    procedure TestBinaryFullIdent;
+    Procedure TestArrayElement;
+    Procedure TestArrayElement2Dims;
+    Procedure TestFunctionCall;
+    Procedure TestFunctionCall2args;
+    Procedure TestFunctionCallNoArgs;
+    Procedure TestRange;
+    Procedure TestBracketsTotal;
+    Procedure TestBracketsLeft;
+    Procedure TestBracketsRight;
+    Procedure TestPrecedenceLeftToRight;
+    Procedure TestPrecedenceLeftToRightMinus;
+    Procedure TestPrecedenceLeftToRightMultiply;
+    Procedure TestPrecedenceLeftToRightDivision;
+    Procedure TestPrecedenceLeftToRightPlusMinus;
+    Procedure TestPrecedenceLeftToRightMinusPlus;
+    Procedure TestPrecedenceLeftToRightMultiplyDivision;
+    Procedure TestPrecedenceLeftToRightDivisionMultiply;
+    Procedure TestPrecedencePlusMultiply;
+    Procedure TestPrecedencePlusDivide;
+    Procedure TestPrecedenceMinusMultiply;
+    Procedure TestPrecedenceMinusDivide;
+    Procedure TestPrecedencePlusOr;
+    Procedure TestPrecedenceAndOr;
+    Procedure TestPrecedenceAndNot;
+    Procedure TestPrecedencePlusAnd;
+    Procedure TestPrecedenceMinusOr;
+    Procedure TestPrecedenceMinusAnd;
+    Procedure TestPrecedenceMultiplyOr;
+    Procedure TestPrecedenceMultiplyAnd;
+    Procedure TestPrecedencePlusDiv;
+    Procedure TestPrecedencePlusMod;
+    Procedure TestPrecedenceMultiplyDiv;
+    Procedure TestPrecedenceDivMultiply;
+    Procedure TestTypeCast;
+    Procedure TestCreate;
+  end;
+
+implementation
+
+procedure TTestExpressions.DeclareVar(const AVarType: String;
+const AVarName: String = 'a');
+begin
+  FVariables.Add(AVarName+' : '+AVarType+';');
+end;
+
+procedure TTestExpressions.TestPrimitiveInteger;
+begin
+  ParseExpression('1');
+  AssertExpression('Simple integer',theExpr,pekNumber,'1');
+end;
+
+procedure TTestExpressions.TestPrimitiveIntegerHex;
+begin
+  ParseExpression('$FF');
+  AssertExpression('Simple integer',theExpr,pekNumber,'$FF');
+end;
+
+procedure TTestExpressions.TestPrimitiveIntegerOctal;
+begin
+  ParseExpression('&777');
+  AssertExpression('Simple integer',theExpr,pekNumber,'&777');
+end;
+
+procedure TTestExpressions.TestPrimitiveIntegerBinary;
+begin
+  ParseExpression('%10101010');
+  AssertExpression('Simple integer',theExpr,pekNumber,'%10101010');
+end;
+
+procedure TTestExpressions.TestPrimitiveDouble;
+begin
+  ParseExpression('1.2');
+  AssertExpression('Simple double',theExpr,pekNumber,'1.2');
+end;
+
+procedure TTestExpressions.TestPrimitiveString;
+begin
+  DeclareVar('string');
+  ParseExpression('''123''');
+  AssertExpression('Simple string',theExpr,pekString,'''123''');
+end;
+
+procedure TTestExpressions.TestPrimitiveIdent;
+begin
+  DeclareVar('integer','a');
+  DeclareVar('integer','b');
+  ParseExpression('b');
+  AssertExpression('Simple identifier',theExpr,pekIdent,'b');
+end;
+
+procedure TTestExpressions.TestBinaryFullIdent;
+begin
+  DeclareVar('integer','a');
+  DeclareVar('record x,y : integer; end','b');
+  ParseExpression('b.x');
+  AssertBinaryExpr('sub identifier',eopSubIdent,Fleft,FRight);
+  AssertExpression('Simple identifier',Theleft,pekIdent,'b');
+  AssertExpression('Simple identifier',Theright,pekIdent,'x');
+end;
+
+procedure TTestExpressions.TestArrayElement;
+
+Var
+  P : TParamsExpr;
+
+begin
+  DeclareVar('integer','a');
+  DeclareVar('array[1..2] of integer','b');
+  ParseExpression('b[1]');
+  P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekArrayParams,TParamsExpr));
+  AssertExpression('Name of array',P.Value,pekIdent,'b');
+  AssertEquals('One dimension',1,Length(p.params));
+  AssertExpression('Simple identifier',p.params[0],pekNumber,'1');
+end;
+
+procedure TTestExpressions.TestArrayElement2Dims;
+Var
+  P : TParamsExpr;
+
+begin
+  DeclareVar('integer','a');
+  DeclareVar('array[1..2,1..2] of integer','b');
+  ParseExpression('b[1,2]');
+  P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekArrayParams,TParamsExpr));
+  AssertExpression('Name of array',P.Value,pekIdent,'b');
+  AssertEquals('Two dimensions',2,Length(p.params));
+  AssertExpression('Simple identifier',p.params[0],pekNumber,'1');
+  AssertExpression('Simple identifier',p.params[1],pekNumber,'2');
+end;
+
+procedure TTestExpressions.TestFunctionCall;
+Var
+  P : TParamsExpr;
+
+begin
+  DeclareVar('integer','a');
+  ParseExpression('Random(10)');
+  P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekFuncParams,TParamsExpr));
+  AssertExpression('Name of function',P.Value,pekIdent,'Random');
+  AssertEquals('1 argument',1,Length(p.params));
+  AssertExpression('Simple identifier',p.params[0],pekNumber,'10');
+end;
+
+procedure TTestExpressions.TestFunctionCall2args;
+Var
+  P : TParamsExpr;
+
+begin
+  DeclareVar('integer','a');
+  ParseExpression('Random(10,12)');
+  P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekFuncParams,TParamsExpr));
+  AssertExpression('Name of function',P.Value,pekIdent,'Random');
+  AssertEquals('2 argument',2,Length(p.params));
+  AssertExpression('Simple identifier 1',p.params[0],pekNumber,'10');
+  AssertExpression('Simple identifier 2',p.params[1],pekNumber,'12');
+end;
+
+procedure TTestExpressions.TestFunctionCallNoArgs;
+
+Var
+  P : TParamsExpr;
+
+begin
+  DeclareVar('integer','a');
+  ParseExpression('Random()');
+  P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekFuncParams,TParamsExpr));
+  AssertExpression('Name of function',P.Value,pekIdent,'Random');
+  AssertEquals('0 arguments',0,Length(p.params));
+end;
+
+procedure TTestExpressions.TestRange;
+
+Var
+  B : TBinaryExpr;
+
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('byte','b');
+  ParseExpression('b in 0..10');
+  AssertBinaryExpr('Simple binary In',eopIn,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekIdent,'b');
+  B:=TBinaryExpr(AssertExpression('Right is range',TheRight,pekRange,TBinaryExpr));
+  AssertExpression('Left is 0',B.Left,pekNumber,'0');
+  AssertExpression('Right is 10',B.Right,pekNumber,'10');
+end;
+
+procedure TTestExpressions.TestBracketsTotal;
+begin
+  DeclareVar('integer','a');
+  ParseExpression('(3+4)');
+  AssertBinaryExpr('simple binary add',eopAdd,FLeft,FRight);
+  AssertExpression('Inner Left is 3',TheLeft,pekNumber,'3');
+  AssertExpression('Inner Right is 4',TheRight,pekNumber,'4');
+end;
+
+procedure TTestExpressions.TestBracketsLeft;
+begin
+  DeclareVar('integer','a');
+  ParseExpression('2*(3+4)');
+  AssertRightPrecedence(2,eopMultiply,3,eopAdd,4);
+end;
+
+procedure TTestExpressions.TestBracketsRight;
+begin
+  DeclareVar('integer','a');
+  ParseExpression('(2*3)+4');
+  AssertLeftPrecedence(2,eopMultiply,3,eopAdd,4);
+end;
+
+procedure TTestExpressions.TestPrecedenceLeftToRight;
+begin
+  ParseExpression('1+2+3');
+  AssertLeftPrecedence(1,eopAdd,2,eopAdd,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceLeftToRightMinus;
+begin
+  ParseExpression('1-2-3');
+  AssertLeftPrecedence(1,eopSubtract,2,eopSubtract,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceLeftToRightMultiply;
+begin
+  ParseExpression('1*2*3');
+  AssertLeftPrecedence(1,eopMultiply,2,eopMultiply,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceLeftToRightDivision;
+begin
+  ParseExpression('1/2/3');
+  AssertLeftPrecedence(1,eopDivide,2,eopDivide,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceLeftToRightPlusMinus;
+begin
+  ParseExpression('1+2-3');
+  AssertLeftPrecedence(1,eopAdd,2,eopSubtract,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceLeftToRightMinusPlus;
+begin
+  ParseExpression('1-2+3');
+  AssertLeftPrecedence(1,eopSubtract,2,eopAdd,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceLeftToRightMultiplyDivision;
+begin
+  ParseExpression('1*2/3');
+  AssertLeftPrecedence(1,eopMultiply,2,eopDivide,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceLeftToRightDivisionMultiply;
+begin
+  ParseExpression('1/2*3');
+  AssertLeftPrecedence(1,eopDivide,2,eopMultiply,3);
+end;
+
+procedure TTestExpressions.TestPrecedencePlusMultiply;
+begin
+  ParseExpression('1+2*3');
+  AssertRightPrecedence(1,eopAdd,2,eopMultiply,3);
+end;
+
+procedure TTestExpressions.TestPrecedencePlusDivide;
+begin
+  ParseExpression('1+2/3');
+  AssertRightPrecedence(1,eopAdd,2,eopDivide,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceMinusMultiply;
+begin
+  ParseExpression('1-2*3');
+  AssertRightPrecedence(1,eopsubtract,2,eopMultiply,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceMinusDivide;
+begin
+  ParseExpression('1-2/3');
+  AssertRightPrecedence(1,eopsubtract,2,eopDivide,3);
+end;
+
+procedure TTestExpressions.TestPrecedencePlusOr;
+begin
+  ParseExpression('1 or 2 + 3');
+  AssertLeftPrecedence(1,eopor,2,eopAdd,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceAndOr;
+begin
+  ParseExpression('1 or 2 and 3');
+  AssertRightPrecedence(1,eopor,2,eopAnd,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceAndNot;
+begin
+  ParseExpression('Not 1 and 3');
+  AssertBinaryExpr('Simple binary and',eopAnd,FLeft,FRight);
+  AssertExpression('Outer right is 3',TheRight,pekNumber,'3');
+  AssertUnaryExpr('Left is Unary not ',TheLeft,eopNot,FRight);
+  AssertExpression('Inner Right is 1',TheRight,pekNumber,'1');
+end;
+
+procedure TTestExpressions.TestPrecedencePlusAnd;
+begin
+  ParseExpression('1 + 2 and 3');
+  AssertRightPrecedence(1,eopAdd,2,eopAnd,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceMinusOr;
+begin
+  ParseExpression('1 or 2 - 3');
+  AssertLeftPrecedence(1,eopOr,2,eopSubtract,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceMinusAnd;
+begin
+  ParseExpression('1 - 2 and 3');
+  AssertRightPrecedence(1,eopSubtract,2,eopand,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceMultiplyOr;
+begin
+  ParseExpression('1 or 2 * 3');
+  AssertRightPrecedence(1,eopOr,2,eopMultiply,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceMultiplyAnd;
+begin
+  ParseExpression('1 * 2 and 3');
+  AssertLeftPrecedence(1,eopMultiply,2,eopAnd,3);
+end;
+
+procedure TTestExpressions.TestPrecedencePlusDiv;
+begin
+  ParseExpression('1+2 div 3');
+  AssertRightPrecedence(1,eopAdd,2,eopDiv,3);
+end;
+
+procedure TTestExpressions.TestPrecedencePlusMod;
+begin
+  ParseExpression('1+2 mod 3');
+  AssertRightPrecedence(1,eopAdd,2,eopMod,3);
+end;
+
+procedure TTestExpressions.AssertLeftPrecedence(AInnerLeft : Integer; AInnerOp : TExprOpCode; AInnerRight : Integer; AOuterOp : TexprOpCode; AOuterRight: Integer);
+
+begin
+  AssertBinaryExpr('Outer expression',AOuterOp,FLeft,FRight);
+  AssertExpression('Outer right constant',TheRight,pekNumber,intToStr(AOuterRight));
+  AssertBinaryExpr('Inner (left) expression',TheLeft,AInnerOp,FLeft,FRight);
+  AssertExpression('Inner Left constant',TheLeft,pekNumber,IntToStr(AInnerLeft));
+  AssertExpression('Inner Right constant',TheRight,pekNumber,IntToStr(AInnerRight));
+end;
+
+
+procedure TTestExpressions.AssertRightPrecedence(AOuterLeft : Integer; AOuterOp : TExprOpCode; AInnerLeft : Integer; AInnerOp : TexprOpCode; AInnerRight: Integer);
+
+begin
+  AssertBinaryExpr('Outer expression',AOuterOp,FLeft,FRight);
+  AssertExpression('Outer left constant',TheLeft,pekNumber,intToStr(AOuterLeft));
+  AssertBinaryExpr('Inner (right) expression',TheRight,AInnerOp,FLeft,FRight);
+  AssertExpression('Inner Left constant',TheLeft,pekNumber,IntToStr(AInnerLeft));
+  AssertExpression('Inner Right constant',TheRight,pekNumber,IntToStr(AInnerRight));
+end;
+
+procedure TTestExpressions.TestPrecedenceMultiplyDiv;
+begin
+  ParseExpression('1 * 2 div 3');
+  AssertLeftPrecedence(1,eopMultiply,2,eopDiv,3);
+end;
+
+procedure TTestExpressions.TestPrecedenceDivMultiply;
+begin
+  ParseExpression('1 div 2 * 3');
+  AssertLeftPrecedence(1,eopDiv,2,eopMultiply,3);
+end;
+
+procedure TTestExpressions.TestTypeCast;
+begin
+  DeclareVar('TSDOBaseDataObjectClass');
+  ParseExpression('TSDOBaseDataObjectClass(Self.ClassType).Create');
+end;
+
+procedure TTestExpressions.TestCreate;
+begin
+  DeclareVar('ESDOSerializationException');
+  ParseExpression('ESDOSerializationException.CreateFmt(SERR_InvalidDataTypeInContext,[IntToStr(Ord(AOwner^.DataType))])');
+end;
+
+
+procedure TTestExpressions.TestUnaryMinus;
+begin
+  DeclareVar('integer','a');
+  DeclareVar('integer','b');
+  ParseExpression('-b');
+  AssertUnaryExpr('Simple minus unary',eopSubtract,FLeft);
+  AssertExpression('Simple identifier',theLeft,pekIdent,'b');
+end;
+
+procedure TTestExpressions.TestUnaryMinusWhiteSpace;
+begin
+  DeclareVar('integer','a');
+  DeclareVar('integer','b');
+  ParseExpression('- b');
+  AssertUnaryExpr('Simple minus unary',eopSubtract,FLeft);
+  AssertExpression('Simple identifier',theLeft,pekIdent,'b');
+end;
+
+procedure TTestExpressions.TestUnaryAddress;
+begin
+  DeclareVar('integer','a');
+  DeclareVar('integer','b');
+  ParseExpression('@b');
+  AssertUnaryExpr('Simple address unary',eopAddress,FLeft);
+  AssertExpression('Simple identifier',theLeft,pekIdent,'b');
+end;
+
+procedure TTestExpressions.TestUnaryNot;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('boolean','b');
+  ParseExpression('not b');
+  AssertUnaryExpr('Simple address unary',eopNot,FLeft);
+  AssertExpression('Simple identifier',theLeft,pekIdent,'b');
+end;
+
+procedure TTestExpressions.TestUnaryDeref;
+begin
+  DeclareVar('integer','a');
+  DeclareVar('pinteger','b');
+  ParseExpression('b^');
+  AssertUnaryExpr('Simple address unary',eopDeref,FLeft);
+  AssertExpression('Simple identifier',theLeft,pekIdent,'b');
+end;
+
+procedure TTestExpressions.TestBinaryAdd;
+begin
+  ParseExpression('1+2');
+  AssertBinaryExpr('Simple binary add',eopAdd,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekNumber,'1');
+  AssertExpression('Right is 2',TheRight,pekNumber,'2');
+end;
+
+procedure TTestExpressions.TestBinarySubtract;
+begin
+  ParseExpression('1-2');
+  AssertBinaryExpr('Simple binary subtract',eopSubtract,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekNumber,'1');
+  AssertExpression('Right is 2',TheRight,pekNumber,'2');
+end;
+
+procedure TTestExpressions.TestBinaryMultiply;
+begin
+  ParseExpression('1*2');
+  AssertBinaryExpr('Simple binary multiply',eopMultiply,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekNumber,'1');
+  AssertExpression('Right is 2',TheRight,pekNumber,'2');
+end;
+
+procedure TTestExpressions.TestBinaryDivision;
+begin
+  DeclareVar('double');
+  ParseExpression('1/2');
+  AssertBinaryExpr('Simple binary division',eopDivide,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekNumber,'1');
+  AssertExpression('Right is 2',TheRight,pekNumber,'2');
+end;
+
+procedure TTestExpressions.TestBinaryPower;
+begin
+  DeclareVar('double');
+  ParseExpression('1**2');
+  AssertBinaryExpr('Simple binary power',eopPower,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekNumber,'1');
+  AssertExpression('Right is 2',TheRight,pekNumber,'2');
+end;
+
+procedure TTestExpressions.TestBinaryMod;
+begin
+  ParseExpression('1 mod 2');
+  AssertBinaryExpr('Simple binary mod',eopMod,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekNumber,'1');
+  AssertExpression('Right is 2',TheRight,pekNumber,'2');
+end;
+
+procedure TTestExpressions.TestBinaryDiv;
+begin
+  ParseExpression('1 div 2');
+  AssertBinaryExpr('Simple binary div',eopDiv,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekNumber,'1');
+  AssertExpression('Right is 2',TheRight,pekNumber,'2');
+end;
+
+procedure TTestExpressions.TestBinaryShl;
+begin
+  ParseExpression('1 shl 2');
+  AssertBinaryExpr('Simple binary shl',eopShl,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekNumber,'1');
+  AssertExpression('Right is 2',TheRight,pekNumber,'2');
+end;
+
+procedure TTestExpressions.TestBinaryShr;
+begin
+  ParseExpression('1 shr 2');
+  AssertBinaryExpr('Simple binary shr',eopShr,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekNumber,'1');
+  AssertExpression('Right is 2',TheRight,pekNumber,'2');
+end;
+
+procedure TTestExpressions.TestBinarySymmetricalDifference;
+begin
+  DeclareVar('Set of Byte','a');
+  DeclareVar('Set of Byte','b');
+  DeclareVar('Set of Byte','c');
+  ParseExpression('b >< c');
+  AssertBinaryExpr('Simple binary smmetrical difference',eopSymmetricalDifference,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekident,'b');
+  AssertExpression('Right is c',TheRight,pekIdent,'c');
+end;
+
+procedure TTestExpressions.TestBinaryAnd;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('boolean','b');
+  DeclareVar('boolean','b');
+  ParseExpression('b and c');
+  AssertBinaryExpr('Simple binary and',eopAnd,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekIdent,'b');
+  AssertExpression('Right is c',TheRight,pekIdent,'c');
+end;
+
+procedure TTestExpressions.TestBinaryOr;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('boolean','b');
+  DeclareVar('boolean','b');
+  ParseExpression('b or c');
+  AssertBinaryExpr('Simple binary or',eopOr,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekIdent,'b');
+  AssertExpression('Right is c',TheRight,pekIdent,'c');
+end;
+
+procedure TTestExpressions.TestBinaryXOr;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('boolean','b');
+  DeclareVar('boolean','b');
+  ParseExpression('b xor c');
+  AssertBinaryExpr('Simple binary xor',eopxOr,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekIdent,'b');
+  AssertExpression('Right is c',TheRight,pekIdent,'c');
+end;
+
+procedure TTestExpressions.TestBinaryIn;
+begin
+  DeclareVar('boolean','a');
+  ParseExpression('1 in [1,2,3]');
+  AssertBinaryExpr('Simple binary In',eopIn,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekNumber,'1');
+  AssertExpression('Right is array set',TheRight,pekSet,TParamsExpr);
+end;
+
+procedure TTestExpressions.TestBinaryIs;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('TObject','b');
+  ParseExpression('b is TObject');
+  AssertBinaryExpr('Simple binary Is',eopIs,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekident,'b');
+  AssertExpression('Right is TObject',TheRight,pekIdent,'TObject');
+end;
+
+procedure TTestExpressions.TestBinaryAs;
+begin
+  DeclareVar('TObject','a');
+  DeclareVar('TObject','b');
+  ParseExpression('b as TObject');
+  AssertBinaryExpr('Simple binary As',eopAs,FLeft,FRight);
+  AssertExpression('Left is 1',TheLeft,pekident,'b');
+  AssertExpression('Right is TObject',TheRight,pekIdent,'TObject');
+end;
+
+procedure TTestExpressions.TestBinaryEquals;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('integer','b');
+  DeclareVar('integer','c');
+  ParseExpression('b=c');
+  AssertBinaryExpr('Simple binary equals',eopEqual,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekident,'b');
+  AssertExpression('Right is c',TheRight,pekIdent,'c');
+end;
+
+procedure TTestExpressions.TestBinaryDiffers;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('integer','b');
+  DeclareVar('integer','c');
+  ParseExpression('b<>c');
+  AssertBinaryExpr('Simple binary differs',eopNotEqual,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekident,'b');
+  AssertExpression('Right is c',TheRight,pekIdent,'c');
+end;
+
+procedure TTestExpressions.TestBinaryLessThan;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('integer','b');
+  DeclareVar('integer','c');
+  ParseExpression('b<c');
+  AssertBinaryExpr('Simple binary less than',eopLessThan,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekident,'b');
+  AssertExpression('Right is c',TheRight,pekIdent,'c');
+end;
+
+procedure TTestExpressions.TestBinaryLessThanEqual;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('integer','b');
+  DeclareVar('integer','c');
+  ParseExpression('b<=c');
+  AssertBinaryExpr('Simple binary less than or equal',eopLessThanEqual,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekident,'b');
+  AssertExpression('Right is c',TheRight,pekIdent,'c');
+end;
+
+procedure TTestExpressions.TestBinaryLargerThan;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('integer','b');
+  DeclareVar('integer','c');
+  ParseExpression('b>c');
+  AssertBinaryExpr('Simple binary larger than ',eopGreaterThan,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekident,'b');
+  AssertExpression('Right is c',TheRight,pekIdent,'c');
+end;
+
+procedure TTestExpressions.TestBinaryLargerThanEqual;
+begin
+  DeclareVar('boolean','a');
+  DeclareVar('integer','b');
+  DeclareVar('integer','c');
+  ParseExpression('b>=c');
+  AssertBinaryExpr('Simple binary larger than or equal',eopGreaterThanEqual,FLeft,FRight);
+  AssertExpression('Left is b',TheLeft,pekident,'b');
+  AssertExpression('Right is c',TheRight,pekIdent,'c');
+end;
+
+procedure TTestExpressions.TestPrimitiveBooleanFalse;
+begin
+  DeclareVar('boolean','a');
+  ParseExpression('False');
+  AssertExpression('Simple boolean',theExpr,pekBoolConst,TBoolConstExpr);
+  AssertEquals('Boolean false',False,TBoolConstExpr(TheExpr).Value);
+end;
+
+procedure TTestExpressions.TestPrimitiveBooleanTrue;
+begin
+  DeclareVar('boolean','a');
+  ParseExpression('True');
+  AssertExpression('Simple boolean',theExpr,pekBoolConst,TBoolConstExpr);
+  AssertEquals('Boolean true',True,TBoolConstExpr(TheExpr).Value);
+end;
+
+procedure TTestExpressions.TestPrimitiveNil;
+begin
+  DeclareVar('pointer','a');
+  ParseExpression('Nil');
+  AssertExpression('Nil expr',theExpr,pekNil,TNilExpr);
+end;
+
+procedure TTestExpressions.TestPrimitiveSet;
+
+Var
+  P : TParamsExpr;
+begin
+  DeclareVar('set of byte','a');
+  ParseExpression('[1,2,3]');
+  P:=TParamsExpr(AssertExpression('Set expr',theExpr,pekSet,TParamsExpr));
+  AssertEquals('Element count',3,Length(P.Params));
+  AssertExpression('Element 1 in set',P.Params[0],pekNumber,'1');
+  AssertExpression('Element 2 in set',P.Params[1],pekNumber,'2');
+  AssertExpression('Element 3 in set',P.Params[2],pekNumber,'3');
+end;
+
+procedure TTestExpressions.TestPrimitiveChar;
+begin
+  DeclareVar('char');
+  ParseExpression('#32');
+  AssertExpression('Simple string',theExpr,pekString,'#32');
+end;
+
+procedure TTestExpressions.TestPrimitiveControlChar;
+begin
+  DeclareVar('char');
+  ParseExpression('^M');
+  AssertExpression('Simple string',theExpr,pekString,'^M');
+end;
+
+procedure TTestExpressions.TestPrimitiveSetEmpty;
+
+Var
+  P : TParamsExpr;
+begin
+  DeclareVar('set of byte','a');
+  ParseExpression('[]');
+  P:=TParamsExpr(AssertExpression('Set expr',theExpr,pekSet,TParamsExpr));
+  AssertEquals('Element count',0,Length(P.Params));
+end;
+
+procedure TTestExpressions.TestPrimitiveSelf;
+
+begin
+  DeclareVar('pointer','a');
+  ParseExpression('Self');
+  AssertExpression('Inherited expr',theExpr,pekSelf,TSelfExpr);
+end;
+
+procedure TTestExpressions.TestInherited;
+
+begin
+  DeclareVar('pointer','a');
+  ParseExpression('inherited');
+  AssertExpression('Inherited expr',theExpr,pekInherited,TInheritedExpr);
+end;
+
+procedure TTestExpressions.TestInheritedFunction;
+
+begin
+  DeclareVar('pointer','a');
+  ParseExpression('inherited myfunction');
+  AssertBinaryExpr('Inherited expr',eopNone,Fleft,FRight);
+  AssertExpression('Inherited expr',theleft,pekInherited,TInheritedExpr);
+  AssertExpression('Inherited expr',theright,pekIdent,'myfunction');
+end;
+
+procedure TTestExpressions.SetUp;
+begin
+  Inherited;
+  FVariables:=TStringList.Create;
+end;
+
+procedure TTestExpressions.TearDown;
+
+begin
+  FreeAndNil(FVariables);
+  Inherited;
+end;
+
+procedure TTestExpressions.SetExpression(const AExpression: String);
+
+Var
+  I : Integer;
+
+begin
+  StartProgram('afile');
+  if FVariables.Count=0 then
+    DeclareVar('integer');
+  Add('Var');
+  For I:=0 to FVariables.Count-1 do
+    Add('  '+Fvariables[I]);
+  Add('begin');
+  Add('  a:='+AExpression+';');
+end;
+
+procedure TTestExpressions.ParseExpression;
+begin
+  ParseModule;
+  AssertEquals('Have program',TPasProgram,Module.ClassType);
+  AssertNotNull('Have program section',PasProgram.ProgramSection);
+  AssertNotNull('Have initialization section',PasProgram.InitializationSection);
+  AssertEquals('Have initialization statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertNotNull('Have initialization statement',PasProgram.InitializationSection.Elements[0]);
+  AssertEquals('Assignment statement',TPasImplAssign,TObject(PasProgram.InitializationSection.Elements[0]).ClassType);
+  FTheExpr:=TPasImplAssign(PasProgram.InitializationSection.Elements[0]).right;
+  AssertNotNull('Have assignment expression',FTheExpr);
+end;
+
+procedure TTestExpressions.ParseExpression(const AExpression: String);
+begin
+  SetExpression(AExpression);
+  ParseExpression;
+end;
+
+function TTestExpressions.AssertBinaryExpr(const Msg: String; Op: TExprOpCode;
+  out ALeft, ARight: TPasExpr): TBinaryExpr;
+begin
+  Result:=AssertBinaryExpr(Msg,TheExpr,Op,ALeft,ARight);
+end;
+
+function TTestExpressions.AssertBinaryExpr(const Msg: String; AExpr: TPasExpr;
+  Op: TExprOpCode; out ALeft, ARight: TPasExpr): TBinaryExpr;
+begin
+  AssertExpression(Msg+' is binary',AExpr,pekBinary,TBinaryExpr);
+  Result:=AExpr as TBinaryExpr;
+  AssertEquals(Msg+' opcode OK',Op,Result.OpCode);
+  ALeft:=Result.Left;
+  ARight:=Result.Right;
+  AssertNotNull('Have left',ALeft);
+  AssertNotNull('Have right',ARight);
+end;
+
+function TTestExpressions.AssertUnaryExpr(const Msg: String; Op: TExprOpCode;
+  out AOperand : TPasExpr): TUnaryExpr;
+begin
+  Result:=AssertUnaryExpr(Msg,TheExpr,OP,AOperand);
+end;
+
+function TTestExpressions.AssertUnaryExpr(const Msg: String; AExpr: TPasExpr;
+  Op: TExprOpCode; out AOperand: TPasExpr): TUnaryExpr;
+begin
+  AssertExpression(Msg+' is unary',AExpr,pekUnary,TUnaryExpr);
+  Result:=AExpr as TUnaryExpr;
+  AssertEquals(Msg+' opcode OK',Op,Result.OpCode);
+  AOperand:=Result.Operand;
+  AssertNotNull('Have left',AOperand);
+end;
+
+initialization
+
+  RegisterTest(TTestExpressions);
+end.
+

+ 377 - 0
packages/fcl-passrc/tests/tcmoduleparser.pas

@@ -0,0 +1,377 @@
+unit tcmoduleparser;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit, pastree, pscanner, pparser,
+  tcbaseparser, testregistry;
+
+Type
+  { TTestModuleParser }
+
+  TTestModuleParser = class(TTestParser)
+  private
+    function GetIf: TInterfaceSection;
+    function GetIm: TImplementationSection;
+    function CheckUnit(AIndex: Integer; const AName: String; AList: TFPList): TPasUnresolvedUnitRef;
+  Protected
+    Procedure ParseUnit;
+    Procedure ParseProgram;
+    Procedure ParseLibrary;
+    Procedure AssertProgramError;
+    Property ImplSection : TImplementationSection Read GetIm;
+    Property IntfSection : TInterfaceSection Read GetIf;
+  Published
+    Procedure TestEmptyUnit;
+    Procedure TestUnitOneUses;
+    Procedure TestUnitTwoUses;
+    Procedure TestUnitOneImplUses;
+    Procedure TestUnitTwoImplUses;
+    Procedure TestEmptyUnitInitialization;
+    Procedure TestEmptyUnitFinalization;
+    Procedure TestEmptyUnitInitializationFinalization;
+    Procedure TestEmptyUnitBegin;
+    Procedure TestEmptyProgram;
+    Procedure TestEmptyProgramInputOUtput;
+    Procedure TestEmptyProgramNoInitialization;
+    Procedure TestEmptyProgramNoFinalization;
+    Procedure TestEmptyProgramMissingBegin;
+    Procedure TestEmptyProgramNoheader;
+    Procedure TestEmptyProgramUses;
+    Procedure TestEmptyProgramUsesTwoUnits;
+    Procedure TestEmptyProgramUsesUnitIn;
+    Procedure TestEmptyLibrary;
+    Procedure TestEmptyLibraryUses;
+    Procedure TestEmptyLibraryExports;
+    Procedure TestEmptyLibraryExportsAlias;
+    Procedure TestEmptyLibraryExportsIndex;
+    Procedure TestEmptyLibraryExportsTwo;
+    Procedure TestEmptyLibraryExportsTwoAlias;
+    Procedure TestEmptyLibraryExportsTwoIndex;
+  end;
+
+implementation
+{ TTestModuleParser }
+
+function TTestModuleParser.GetIf: TInterfaceSection;
+begin
+  Result:=Module.InterfaceSection;
+end;
+
+function TTestModuleParser.GetIm: TImplementationSection;
+begin
+  Result:=Module.ImplementationSection;
+end;
+
+procedure TTestModuleParser.ParseUnit;
+begin
+  EndSource;
+  ParseModule;
+  AssertNotNull('Have interface',Module.InterfaceSection);
+  Declarations:=Module.InterfaceSection;
+  AssertEquals('Interface section',TInterfaceSection,Declarations.ClassType);
+  AssertNotNull('Have implmeentation',Module.ImplementationSection);
+  AssertEquals('implementation section',TImplementationSection,Module.ImplementationSection.ClassType);
+  AssertNotNull('Have interface units',IntfSection.UsesList);
+  AssertNotNull('Have implementation units',ImplSection.UsesList);
+end;
+
+procedure TTestModuleParser.ParseProgram;
+begin
+  EndSource;
+  ParseModule;
+  AssertEquals('Is program',TPasProgram,Module.ClassType);
+end;
+
+procedure TTestModuleParser.ParseLibrary;
+begin
+  EndSource;
+  ParseModule;
+  AssertEquals('Is library',TPasLibrary,Module.ClassType);
+end;
+
+procedure TTestModuleParser.AssertProgramError;
+begin
+  AssertException(EParserError,@ParseProgram)
+end;
+
+function TTestModuleParser.CheckUnit(AIndex: Integer; const AName: String;
+  AList: TFPList) : TPasUnresolvedUnitRef;
+
+Var
+  C : string;
+
+begin
+  C:='Unit '+IntTostr(AIndex)+' ';
+  if (AIndex>=AList.Count) then
+    Fail(Format('Index %d larger than unit list count %d',[AIndex,AList.Count ]));
+  AssertNotNull('Have pascal element',AList[AIndex]);
+  AssertEquals(C+'Correct class',TPasUnresolvedUnitRef,TObject(AList[AIndex]).CLassType);
+  Result:=TPasUnresolvedUnitRef(AList[AIndex]);
+  AssertEquals(C+'Unit name correct',AName,Result.Name);
+end;
+
+procedure TTestModuleParser.TestEmptyUnit;
+begin
+  StartUnit('unit1');
+  StartImplementation;
+  ParseUnit;
+  AssertEquals('No interface units',0,IntfSection.UsesList.Count);
+  AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
+end;
+
+procedure TTestModuleParser.TestUnitOneUses;
+begin
+  StartUnit('unit1');
+  UsesClause(['a']);
+  StartImplementation;
+  ParseUnit;
+  AssertEquals('Two interface units',2,IntfSection.UsesList.Count);
+  CheckUnit(0,'System',IntfSection.UsesList);
+  CheckUnit(1,'a',IntfSection.UsesList);
+  AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
+end;
+
+procedure TTestModuleParser.TestUnitTwoUses;
+begin
+  StartUnit('unit1');
+  UsesClause(['a','b']);
+  StartImplementation;
+  ParseUnit;
+  AssertEquals('Two interface units',3,IntfSection.UsesList.Count);
+  CheckUnit(0,'System',IntfSection.UsesList);
+  CheckUnit(1,'a',IntfSection.UsesList);
+  CheckUnit(2,'b',IntfSection.UsesList);
+  AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
+end;
+
+procedure TTestModuleParser.TestUnitOneImplUses;
+begin
+  StartUnit('unit1');
+  StartImplementation;
+  UsesClause(['a']);
+  ParseUnit;
+  AssertEquals('One implementation units',1,ImplSection.UsesList.Count);
+  CheckUnit(0,'a',ImplSection.UsesList);
+  AssertEquals('No interface units',0,IntfSection.UsesList.Count);
+end;
+
+procedure TTestModuleParser.TestUnitTwoImplUses;
+begin
+  StartUnit('unit1');
+  StartImplementation;
+  UsesClause(['a','b']);
+  ParseUnit;
+  AssertEquals('Two implementation units',2,ImplSection.UsesList.Count);
+  CheckUnit(0,'a',ImplSection.UsesList);
+  CheckUnit(1,'b',ImplSection.UsesList);
+  AssertEquals('No interface units',0,IntfSection.UsesList.Count);
+end;
+
+procedure TTestModuleParser.TestEmptyUnitInitialization;
+begin
+  StartUnit('unit1');
+  StartImplementation;
+  Add('initialization');
+  ParseUnit;
+  AssertNotNull('Have initialization section',Module.InitializationSection);
+  AssertNull('Have no finalization section',Module.FinalizationSection)
+end;
+
+procedure TTestModuleParser.TestEmptyUnitFinalization;
+begin
+  StartUnit('unit1');
+  StartImplementation;
+  Add('finalization');
+  ParseUnit;
+  AssertNull('Have no initalization section',Module.InitializationSection);
+  AssertNotNull('Have finalization section',Module.FinalizationSection)
+end;
+
+procedure TTestModuleParser.TestEmptyUnitInitializationFinalization;
+begin
+  StartUnit('unit1');
+  StartImplementation;
+  Add('initialization');
+  Add('finalization');
+  ParseUnit;
+  AssertNotNull('Have finalization section',Module.InitializationSection);
+  AssertNotNull('Have finalization section',Module.FinalizationSection);
+end;
+
+procedure TTestModuleParser.TestEmptyUnitBegin;
+begin
+  StartUnit('unit1');
+  StartImplementation;
+  Add('begin');
+  ParseUnit;
+  AssertNotNull('Have initialization section',Module.InitializationSection);
+  AssertNull('Have no finalization section',Module.FinalizationSection)
+end;
+
+procedure TTestModuleParser.TestEmptyProgram;
+begin
+  StartProgram('something');
+  Add('begin');
+  ParseProgram;
+end;
+
+procedure TTestModuleParser.TestEmptyProgramInputOUtput;
+begin
+  StartProgram('something','input','output');
+  Add('begin');
+  ParseProgram;
+end;
+
+procedure TTestModuleParser.TestEmptyProgramNoInitialization;
+begin
+  StartProgram('something','input','output');
+  Add('initialization');
+  AssertProgramError;
+end;
+
+procedure TTestModuleParser.TestEmptyProgramNoFinalization;
+begin
+  StartProgram('something','input','output');
+  Add('finalization');
+  AssertProgramError;
+end;
+
+procedure TTestModuleParser.TestEmptyProgramMissingBegin;
+begin
+  StartProgram('something','input','output');
+  AssertProgramError;
+end;
+
+procedure TTestModuleParser.TestEmptyProgramNoheader;
+begin
+  Add('begin');
+  ParseProgram;
+end;
+
+procedure TTestModuleParser.TestEmptyProgramUses;
+begin
+  UsesClause(['a']);
+  Add('begin');
+  ParseProgram;
+  AssertEquals('Two interface units',2, PasProgram.ProgramSection.UsesList.Count);
+  CheckUnit(0,'System',PasProgram.ProgramSection.UsesList);
+  CheckUnit(1,'a',PasProgram.ProgramSection.UsesList);
+end;
+
+procedure TTestModuleParser.TestEmptyProgramUsesTwoUnits;
+begin
+  UsesClause(['a','b']);
+  Add('begin');
+  ParseProgram;
+  AssertEquals('Three interface units',3, PasProgram.ProgramSection.UsesList.Count);
+  CheckUnit(0,'System',PasProgram.ProgramSection.UsesList);
+  CheckUnit(1,'a',PasProgram.ProgramSection.UsesList);
+  CheckUnit(2,'b',PasProgram.ProgramSection.UsesList);
+end;
+
+procedure TTestModuleParser.TestEmptyProgramUsesUnitIn;
+
+Var
+  U : TPasUnresolvedUnitRef;
+
+begin
+  UsesClause(['a in ''../a.pas''','b']);
+  Add('begin');
+  ParseProgram;
+  AssertEquals('One interface unit',3, PasProgram.ProgramSection.UsesList.Count);
+  CheckUnit(0,'System',PasProgram.ProgramSection.UsesList);
+  U:=CheckUnit(1,'a',PasProgram.ProgramSection.UsesList);
+  AssertEquals('Filename','''../a.pas''',U.FileName);
+  CheckUnit(2,'b',PasProgram.ProgramSection.UsesList);
+end;
+
+procedure TTestModuleParser.TestEmptyLibrary;
+begin
+  StartLibrary('');
+  ParseLibrary;
+  AssertEquals('Correct class',TPasLibrary,Module.ClassType);
+end;
+
+procedure TTestModuleParser.TestEmptyLibraryUses;
+begin
+  StartLibrary('');
+  UsesClause(['a']);
+  ParseLibrary;
+  AssertEquals('Correct class',TPasLibrary,Module.ClassType);
+  AssertEquals('Two interface units',2, PasLibrary.LibrarySection.UsesList.Count);
+  CheckUnit(0,'System',PasLibrary.LibrarySection.UsesList);
+  CheckUnit(1,'a',PasLibrary.LibrarySection.UsesList);
+end;
+
+procedure TTestModuleParser.TestEmptyLibraryExports;
+begin
+  StartLibrary('');
+  UsesClause(['b']);
+  Add('exports A;');
+  ParseLibrary;
+  AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
+  AssertExportSymbol('Export symbol a',0,'A','',-1);
+end;
+
+procedure TTestModuleParser.TestEmptyLibraryExportsAlias;
+begin
+  StartLibrary('');
+  UsesClause(['b']);
+  Add('exports A name ''c'';');
+  ParseLibrary;
+  AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
+  AssertExportSymbol('Export symbol a',0,'A','c',-1);
+end;
+
+procedure TTestModuleParser.TestEmptyLibraryExportsIndex;
+begin
+  StartLibrary('');
+  UsesClause(['b']);
+  Add('exports A index 23;');
+  ParseLibrary;
+  AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
+  AssertExportSymbol('Export symbol a',0,'A','',23);
+end;
+
+procedure TTestModuleParser.TestEmptyLibraryExportsTwo;
+begin
+  StartLibrary('');
+  UsesClause(['b']);
+  Add('exports A , C;');
+  ParseLibrary;
+  AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
+  AssertExportSymbol('Export symbol a',0,'A','',-1);
+  AssertExportSymbol('Export symbol C',1,'C','',-1);
+end;
+
+procedure TTestModuleParser.TestEmptyLibraryExportsTwoAlias;
+begin
+  StartLibrary('');
+  UsesClause(['b']);
+  Add('exports A name ''de'', C;');
+  ParseLibrary;
+  AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
+  AssertExportSymbol('Export symbol a',0,'A','de',-1);
+  AssertExportSymbol('Export symbol C',1,'C','',-1);
+
+end;
+
+procedure TTestModuleParser.TestEmptyLibraryExportsTwoIndex;
+begin
+  StartLibrary('');
+  UsesClause(['b']);
+  Add('exports A index 23, C;');
+  ParseLibrary;
+  AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
+  AssertExportSymbol('Export symbol a',0,'A','',23);
+  AssertExportSymbol('Export symbol C',1,'C','',-1);
+end;
+
+initialization
+  RegisterTests([TTestModuleParser]);
+
+end.
+

+ 631 - 0
packages/fcl-passrc/tests/tconstparser.pas

@@ -0,0 +1,631 @@
+unit tconstparser;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit, pastree, pscanner, tcbaseparser, testregistry;
+
+Type
+    { TTestConstParser }
+
+  TTestConstParser = Class(TTestParser)
+  private
+    FConst: TPasConst;
+    FExpr: TPasExpr;
+    FHint : string;
+    FTyped: String;
+  Protected
+    Function ParseConst(ASource : String) : TPasConst;
+    Procedure CheckExprNameKindClass(AKind : TPasExprKind; AClass : TClass);
+    Property TheConst : TPasConst Read FConst;
+    Property TheExpr : TPasExpr Read FExpr;
+    Property Hint : string Read FHint Write FHint;
+    Property Typed : String Read FTyped Write FTyped;
+    procedure SetUp; override;
+  Public
+    Procedure DoTestSimpleIntConst;
+    Procedure DoTestSimpleFloatConst;
+    Procedure DoTestSimpleStringConst;
+    Procedure DoTestSimpleNilConst;
+    Procedure DoTestSimpleBoolConst;
+    Procedure DoTestSimpleIdentifierConst;
+    Procedure DoTestSimpleSetConst;
+    Procedure DoTestSimpleExprConst;
+  Published
+    Procedure TestSimpleIntConst;
+    Procedure TestSimpleFloatConst;
+    Procedure TestSimpleStringConst;
+    Procedure TestSimpleNilConst;
+    Procedure TestSimpleBoolConst;
+    Procedure TestSimpleIdentifierConst;
+    Procedure TestSimpleSetConst;
+    Procedure TestSimpleExprConst;
+    Procedure TestSimpleIntConstDeprecatedMsg;
+    Procedure TestSimpleIntConstDeprecated;
+    Procedure TestSimpleFloatConstDeprecated;
+    Procedure TestSimpleStringConstDeprecated;
+    Procedure TestSimpleNilConstDeprecated;
+    Procedure TestSimpleBoolConstDeprecated;
+    Procedure TestSimpleIdentifierConstDeprecated;
+    Procedure TestSimpleSetConstDeprecated;
+    Procedure TestSimpleExprConstDeprecated;
+    Procedure TestSimpleIntConstPlatform;
+    Procedure TestSimpleFloatConstPlatform;
+    Procedure TestSimpleStringConstPlatform;
+    Procedure TestSimpleNilConstPlatform;
+    Procedure TestSimpleBoolConstPlatform;
+    Procedure TestSimpleIdentifierConstPlatform;
+    Procedure TestSimpleSetConstPlatform;
+    Procedure TestSimpleExprConstPlatform;
+    Procedure TestSimpleIntConstExperimental;
+    Procedure TestSimpleFloatConstExperimental;
+    Procedure TestSimpleStringConstExperimental;
+    Procedure TestSimpleNilConstExperimental;
+    Procedure TestSimpleBoolConstExperimental;
+    Procedure TestSimpleIdentifierConstExperimental;
+    Procedure TestSimpleSetConstExperimental;
+    Procedure TestSimpleExprConstExperimental;
+    Procedure TestTypedIntConst;
+    Procedure TestTypedFloatConst;
+    Procedure TestTypedStringConst;
+    Procedure TestTypedNilConst;
+    Procedure TestTypedBoolConst;
+    Procedure TestTypedIdentifierConst;
+    Procedure TestTypedSetConst;
+    Procedure TestTypedExprConst;
+    Procedure TestRecordConst;
+    Procedure TestArrayConst;
+  end;
+
+  { TTestResourcestringParser }
+
+  TTestResourcestringParser = Class(TTestParser)
+  private
+    FExpr: TPasExpr;
+    FHint : string;
+    FTheStr: TPasResString;
+  Protected
+    Function ParseResourcestring(ASource : String) : TPasResString;
+    Procedure CheckExprNameKindClass(AKind : TPasExprKind; AClass : TClass);
+    Property Hint : string Read FHint Write FHint;
+    Property TheStr : TPasResString Read FTheStr;
+    Property TheExpr : TPasExpr Read FExpr;
+  Public
+    Procedure DoTestSimple;
+    Procedure DoTestSum;
+    Procedure DoTestSum2;
+  Published
+    Procedure TestSimple;
+    Procedure TestSimpleDeprecated;
+    Procedure TestSimplePlatform;
+    Procedure TestSum1;
+    Procedure TestSum1Deprecated;
+    Procedure TestSum1Platform;
+    Procedure TestSum2;
+    Procedure TestSum2Deprecated;
+    Procedure TestSum2Platform;
+  end;
+
+
+implementation
+{ TTestConstParser }
+
+function TTestConstParser.ParseConst(ASource: String): TPasConst;
+
+Var
+  D : String;
+begin
+  Add('Const');
+  D:=' A ';
+  If (Typed<>'') then
+    D:=D+' : '+Typed+' ';
+  D:=D+' = '+ASource;
+  If Hint<>'' then
+    D:=D+' '+Hint;
+  Add('  '+D+';');
+  ParseDeclarations;
+  AssertEquals('One constant definition',1,Declarations.Consts.Count);
+  AssertEquals('First declaration is constant definition.',TPasConst,TObject(Declarations.Consts[0]).ClassType);
+  Result:=TPasConst(Declarations.Consts[0]);
+  AssertNotNull(Result.Expr);
+  FExpr:=Result.Expr;
+  FConst:=Result;
+  Definition:=Result;
+end;
+
+
+procedure TTestConstParser.CheckExprNameKindClass(
+  AKind: TPasExprKind; AClass : TClass);
+begin
+  AssertEquals('Correct name','A',TheConst.Name);
+  AssertExpression('Const', TheExpr,aKind,AClass);
+end;
+
+procedure TTestConstParser.SetUp;
+begin
+  inherited SetUp;
+  Hint:='';
+end;
+
+procedure TTestConstParser.DoTestSimpleIntConst;
+
+begin
+  ParseConst('1');
+  AssertExpression('Integer Const',TheExpr,pekNumber,'1');
+end;
+
+procedure TTestConstParser.DoTestSimpleFloatConst;
+begin
+  ParseConst('1.2');
+  AssertExpression('Float const', TheExpr,pekNumber,'1.2');
+end;
+
+procedure TTestConstParser.DoTestSimpleStringConst;
+begin
+  ParseConst('''test''');
+  AssertExpression('String const', TheExpr,pekString,'''test''');
+end;
+
+procedure TTestConstParser.DoTestSimpleNilConst;
+begin
+  ParseConst('Nil');
+  CheckExprNameKindClass(pekNil,TNilExpr);
+end;
+
+procedure TTestConstParser.DoTestSimpleBoolConst;
+begin
+  ParseConst('True');
+  CheckExprNameKindClass(pekBoolConst,TBoolconstExpr);
+  AssertEquals('Correct expression value',True,TBoolconstExpr(TheExpr).Value);
+end;
+
+procedure TTestConstParser.DoTestSimpleIdentifierConst;
+begin
+  ParseConst('taCenter');
+  AssertExpression('Enumeration const', theExpr,pekIdent,'taCenter');
+end;
+
+procedure TTestConstParser.DoTestSimpleSetConst;
+begin
+  ParseConst('[taLeftJustify,taRightJustify]');
+  CheckExprNameKindClass(pekSet,TParamsExpr);
+  AssertEquals('Correct set count',2,Length(TParamsExpr(TheExpr).Params));
+  AssertExpression('Set element 1',TParamsExpr(TheExpr).Params[0],pekIdent,'taLeftJustify');
+  AssertExpression('Set element 2',TParamsExpr(TheExpr).Params[1],pekIdent,'taRightJustify');
+end;
+
+procedure TTestConstParser.DoTestSimpleExprConst;
+
+Var
+  B : TBinaryExpr;
+
+begin
+  ParseConst('1 + 2');
+  CheckExprNameKindClass(pekBinary,TBinaryExpr);
+  B:=TBinaryExpr(TheExpr);
+  AssertExpression('Left expression',B.Left,pekNumber,'1');
+  AssertExpression('Right expression',B.Right,pekNumber,'2');
+end;
+
+procedure TTestConstParser.TestSimpleIntConst;
+begin
+  DoTestSimpleIntConst
+end;
+
+procedure TTestConstParser.TestSimpleFloatConst;
+begin
+  DoTestSimpleFloatConst
+end;
+
+procedure TTestConstParser.TestSimpleStringConst;
+begin
+  DoTestSimpleStringConst
+end;
+
+procedure TTestConstParser.TestSimpleNilConst;
+begin
+  DoTestSimpleNilConst
+end;
+
+procedure TTestConstParser.TestSimpleBoolConst;
+begin
+  DoTestSimpleBoolConst
+end;
+
+procedure TTestConstParser.TestSimpleIdentifierConst;
+begin
+  DoTestSimpleIdentifierConst
+end;
+
+procedure TTestConstParser.TestSimpleSetConst;
+begin
+  DoTestSimpleSetConst
+end;
+
+procedure TTestConstParser.TestSimpleExprConst;
+begin
+  DoTestSimpleExprConst;
+end;
+
+procedure TTestConstParser.TestSimpleIntConstDeprecatedMsg;
+begin
+  Hint:='deprecated ''this is old''' ;
+  DoTestSimpleIntConst;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestConstParser.TestSimpleIntConstDeprecated;
+begin
+  Hint:='deprecated';
+  DoTestSimpleIntConst;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestConstParser.TestSimpleFloatConstDeprecated;
+begin
+  Hint:='deprecated';
+  DoTestSimpleIntConst;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestConstParser.TestSimpleStringConstDeprecated;
+begin
+  Hint:='deprecated';
+  DoTestSimpleStringConst;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestConstParser.TestSimpleNilConstDeprecated;
+begin
+  Hint:='deprecated';
+  DoTestSimpleNilConst;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestConstParser.TestSimpleBoolConstDeprecated;
+begin
+  Hint:='deprecated';
+  DoTestSimpleBoolConst;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestConstParser.TestSimpleIdentifierConstDeprecated;
+begin
+  Hint:='deprecated';
+  DoTestSimpleIdentifierConst;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestConstParser.TestSimpleSetConstDeprecated;
+begin
+  Hint:='deprecated';
+  DoTestSimpleSetConst;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestConstParser.TestSimpleExprConstDeprecated;
+begin
+  Hint:='deprecated';
+  DoTestSimpleExprConst;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestConstParser.TestSimpleIntConstPlatform;
+begin
+  Hint:='Platform';
+  DoTestSimpleIntConst;
+  CheckHint(hPlatform);
+end;
+
+procedure TTestConstParser.TestSimpleFloatConstPlatform;
+begin
+  Hint:='Platform';
+  DoTestSimpleIntConst;
+  CheckHint(hPlatform);
+end;
+
+procedure TTestConstParser.TestSimpleStringConstPlatform;
+begin
+  Hint:='Platform';
+  DoTestSimpleStringConst;
+  CheckHint(hPlatform);
+end;
+
+procedure TTestConstParser.TestSimpleNilConstPlatform;
+begin
+  Hint:='Platform';
+  DoTestSimpleNilConst;
+  CheckHint(hPlatform);
+end;
+
+procedure TTestConstParser.TestSimpleBoolConstPlatform;
+begin
+  Hint:='Platform';
+  DoTestSimpleBoolConst;
+  CheckHint(hPlatform);
+end;
+
+procedure TTestConstParser.TestSimpleIdentifierConstPlatform;
+begin
+  Hint:='Platform';
+  DoTestSimpleIdentifierConst;
+  CheckHint(hPlatform);
+end;
+
+procedure TTestConstParser.TestSimpleExprConstPlatform;
+begin
+  Hint:='Platform';
+  DoTestSimpleExprConst;
+  CheckHint(hPlatform);
+end;
+
+procedure TTestConstParser.TestSimpleSetConstPlatform;
+begin
+  Hint:='Platform';
+  DoTestSimpleSetConst;
+  CheckHint(hPlatform);
+end;
+
+procedure TTestConstParser.TestSimpleIntConstExperimental;
+begin
+  Hint:='Experimental';
+  DoTestSimpleIntConst;
+  CheckHint(hExperimental);
+end;
+
+procedure TTestConstParser.TestSimpleFloatConstExperimental;
+begin
+  Hint:='Experimental';
+  DoTestSimpleIntConst;
+  CheckHint(hExperimental);
+end;
+
+procedure TTestConstParser.TestSimpleStringConstExperimental;
+begin
+  Hint:='Experimental';
+  DoTestSimpleStringConst;
+  CheckHint(hExperimental);
+end;
+
+procedure TTestConstParser.TestSimpleNilConstExperimental;
+begin
+  Hint:='Experimental';
+  DoTestSimpleNilConst;
+  CheckHint(hExperimental);
+end;
+
+procedure TTestConstParser.TestSimpleBoolConstExperimental;
+begin
+  Hint:='Experimental';
+  DoTestSimpleBoolConst;
+  CheckHint(hExperimental);
+end;
+
+procedure TTestConstParser.TestSimpleIdentifierConstExperimental;
+begin
+  Hint:='Experimental';
+  DoTestSimpleIdentifierConst;
+  CheckHint(hExperimental);
+end;
+
+procedure TTestConstParser.TestSimpleSetConstExperimental;
+begin
+  Hint:='Experimental';
+  DoTestSimpleSetConst;
+  CheckHint(hExperimental);
+end;
+
+procedure TTestConstParser.TestSimpleExprConstExperimental;
+begin
+  Hint:='Experimental';
+  DoTestSimpleExprConst;
+  CheckHint(hExperimental);
+end;
+
+procedure TTestConstParser.TestTypedIntConst;
+begin
+  Typed:='Integer';
+  DoTestSimpleIntConst
+end;
+
+procedure TTestConstParser.TestTypedFloatConst;
+begin
+  Typed:='Double';
+  DoTestSimpleFloatConst
+end;
+
+procedure TTestConstParser.TestTypedStringConst;
+begin
+  Typed:='shortstring';
+  DoTestSimpleStringConst
+end;
+
+procedure TTestConstParser.TestTypedNilConst;
+begin
+  Typed:='PChar';
+  DoTestSimpleNilConst
+end;
+
+procedure TTestConstParser.TestTypedBoolConst;
+begin
+  Typed:='Boolean';
+  DoTestSimpleBoolConst
+end;
+
+procedure TTestConstParser.TestTypedIdentifierConst;
+begin
+  Typed:='TAlign';
+  DoTestSimpleIdentifierConst
+end;
+
+procedure TTestConstParser.TestTypedSetConst;
+begin
+  Typed:='TAligns';
+  DoTestSimpleSetConst
+end;
+
+procedure TTestConstParser.TestTypedExprConst;
+begin
+  Typed:='ShortInt';
+  DoTestSimpleExprConst;
+end;
+
+procedure TTestConstParser.TestRecordConst;
+Var
+  R : TRecordValues;
+  Fi : TRecordValuesItem;
+begin
+  Typed := 'TPoint';
+  ParseConst('(x:1;y: 2)');
+  AssertEquals('Record Values',TRecordValues,TheExpr.ClassType);
+  R:=TheExpr as TRecordValues;
+  AssertEquals('Expression list of ',pekListOfExp,TheExpr.Kind);
+  AssertEquals('2 elements',2,Length(R.Fields));
+  FI:=R.Fields[0];
+  AssertEquals('Name field 1','x',Fi.Name);
+  AssertExpression('Field 1 value',Fi.ValueExp,pekNumber,'1');
+  FI:=R.Fields[1];
+  AssertEquals('Name field 2','y',Fi.Name);
+  AssertExpression('Field 2 value',Fi.ValueExp,pekNumber,'2');
+end;
+
+procedure TTestConstParser.TestArrayConst;
+
+Var
+  R : TArrayValues;
+begin
+  Typed := 'TMyArray';
+  ParseConst('(1 , 2)');
+  AssertEquals('Array Values',TArrayValues,TheExpr.ClassType);
+  R:=TheExpr as TArrayValues;
+  AssertEquals('Expression list of ',pekListOfExp,TheExpr.Kind);
+  AssertEquals('2 elements',2,Length(R.Values));
+  AssertExpression('Element 1 value',R.Values[0],pekNumber,'1');
+  AssertExpression('Element 2 value',R.Values[1],pekNumber,'2');
+end;
+
+{ TTestResourcestringParser }
+
+function TTestResourcestringParser.ParseResourcestring(ASource: String
+  ): TPasResString;
+
+Var
+  D : String;
+begin
+  Add('Resourcestring');
+  D:=' A = '+ASource;
+  If Hint<>'' then
+    D:=D+' '+Hint;
+  Add('  '+D+';');
+  Add('end.');
+  //Writeln(source.text);
+  ParseDeclarations;
+  AssertEquals('One resourcestring definition',1,Declarations.ResStrings.Count);
+  AssertEquals('First declaration is constant definition.',TPasResString,TObject(Declarations.ResStrings[0]).ClassType);
+  Result:=TPasResString(Declarations.ResStrings[0]);
+  FTheStr:=Result;
+  FExpr:=Result.Expr;
+  Definition:=Result;
+end;
+
+procedure TTestResourcestringParser.CheckExprNameKindClass(AKind: TPasExprKind;
+  AClass: TClass);
+begin
+  AssertEquals('Correct name','A',TheStr.Name);
+  AssertEquals('Correct expression kind',aKind,TheExpr.Kind);
+  AssertEquals('Correct expression class',AClass,TheExpr.ClassType);
+  // Writeln('Delcaration : ',TheStr.GetDeclaration(True));
+end;
+
+procedure TTestResourcestringParser.DoTestSimple;
+begin
+  ParseResourcestring('''Something''');
+  CheckExprNameKindClass(pekString,TPrimitiveExpr);
+  AssertEquals('Correct expression value','''Something''',TPrimitiveExpr(TheExpr).Value);
+end;
+
+procedure TTestResourcestringParser.DoTestSum;
+begin
+  ParseResourcestring('''Something''+'' else''');
+  CheckExprNameKindClass(pekBinary,TBinaryExpr);
+  AssertEquals('Correct left',TPrimitiveExpr,TBinaryExpr(TheExpr).Left.ClassType);
+  AssertEquals('Correct right',TPrimitiveExpr,TBinaryExpr(TheExpr).Right.ClassType);
+  AssertEquals('Correct left expression value','''Something''',TPrimitiveExpr(TBinaryExpr(TheExpr).Left).Value);
+  AssertEquals('Correct right expression value',''' else''',TPrimitiveExpr(TBinaryExpr(TheExpr).Right).Value);
+end;
+
+procedure TTestResourcestringParser.DoTestSum2;
+begin
+  ParseResourcestring('''Something''+different');
+  CheckExprNameKindClass(pekBinary,TBinaryExpr);
+  AssertEquals('Correct left',TPrimitiveExpr,TBinaryExpr(TheExpr).Left.ClassType);
+  AssertEquals('Correct right',TPrimitiveExpr,TBinaryExpr(TheExpr).Right.ClassType);
+  AssertEquals('Correct left expression value','''Something''',TPrimitiveExpr(TBinaryExpr(TheExpr).Left).Value);
+  AssertEquals('Correct right expression value','different',TPrimitiveExpr(TBinaryExpr(TheExpr).Right).Value);
+
+end;
+
+procedure TTestResourcestringParser.TestSimple;
+begin
+  DoTestSimple;
+end;
+
+procedure TTestResourcestringParser.TestSimpleDeprecated;
+begin
+  Hint:='deprecated';
+  DoTestSimple;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestResourcestringParser.TestSimplePlatform;
+begin
+  Hint:='platform';
+  DoTestSimple;
+  CheckHint(hPlatform);
+end;
+
+procedure TTestResourcestringParser.TestSum2;
+begin
+  DoTestSum2;
+end;
+
+procedure TTestResourcestringParser.TestSum2Deprecated;
+begin
+  Hint:='deprecated';
+  DoTestSum2;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestResourcestringParser.TestSum2Platform;
+begin
+  Hint:='platform';
+  DoTestSum2;
+  CheckHint(hplatform);
+end;
+procedure TTestResourcestringParser.TestSum1;
+begin
+  DoTestSum;
+end;
+
+procedure TTestResourcestringParser.TestSum1Deprecated;
+begin
+  Hint:='deprecated';
+  DoTestSum;
+  CheckHint(hDeprecated);
+end;
+
+procedure TTestResourcestringParser.TestSum1Platform;
+begin
+  Hint:='platform';
+  DoTestSum;
+  CheckHint(hplatform);
+end;
+
+initialization
+  RegisterTests([TTestConstParser,TTestResourcestringParser]);
+
+
+end.
+

+ 422 - 0
packages/fcl-passrc/tests/tcpassrcutil.pas

@@ -0,0 +1,422 @@
+unit tcpassrcutil;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit, testutils,passrcutil, testregistry;
+
+type
+
+  { TPasSrcUtilTest }
+
+  TPasSrcUtilTest= class(TTestCase)
+  Protected
+    FAnalyser : TPasSrcAnalysis;
+    FSrc : TStrings;
+    FList : TStrings;
+    FStream: TmemoryStream;
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+    Procedure AddLine(Const ALine : String);
+    Procedure AddUses(Const AUsesList : String);
+    Procedure StartUnit;
+    Procedure StartImplementation;
+    Procedure EndSource;
+    Procedure AssertList(Msg : String; Els : Array of string);
+    Property Analyser : TPasSrcAnalysis Read FAnalyser;
+    Property List : TStrings Read FList;
+  published
+    procedure TestGetInterfaceUses;
+    procedure TestGetInterfaceUsesEmpty;
+    procedure TestGetImplementationUses;
+    procedure TestGetImplementationUsesEmpty;
+    procedure TestGetAllUses;
+    procedure TestGetInterfaceIdentifiers;
+    procedure TestGetInterfaceVarIdentifiers;
+    procedure TestGetInterface2VarIdentifiers;
+    procedure TestGetInterfaceConstIdentifiers;
+    procedure TestGetInterface2ConstsIdentifiers;
+    procedure TestGetInterfaceTypeIdentifiers;
+    procedure TestGetInterface2TypeIdentifiers;
+    procedure TestGetInterfaceProcIdentifiers;
+    procedure TestGetInterfaceResourcestringIdentifiers;
+    procedure TestGetInterfaceEnumTypeIdentifiersNoRecurse;
+    procedure TestGetInterfaceEnumTypeIdentifiersRecurse;
+    procedure TestGetInterfaceRecordTypeIdentifiersNoRecurse;
+    procedure TestGetInterfaceRecordTypeIdentifiersRecurse;
+    procedure TestGetInterfaceRecordTypeIdentifiersRecurseVariant;
+    procedure TestGetInterfaceClassTypeIdentifiersNoRecurse;
+    procedure TestGetInterfaceClassTypeIdentifiersRecurse;
+    procedure TestGetImplementationVarIdentifiers;
+    procedure TestInterfaceHasResourceStrings;
+    procedure TestInterfaceHasResourceStringsFalse;
+    procedure TestImplementationHasResourceStrings;
+    procedure TestHasResourceStrings;
+    procedure TestHasResourceStrings2;
+    procedure TestHasResourceStrings3;
+    procedure TestHasResourceStrings4;
+  end;
+
+implementation
+
+procedure TPasSrcUtilTest.TestGetInterfaceUses;
+begin
+  StartUnit;
+  AddUses('a,b,c');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceUnits(List);
+  AssertList('4 interface units',['System','a','b','c']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceUsesEmpty;
+begin
+  StartUnit;
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceUnits(List);
+  AssertList('0 interface units',[]);
+end;
+
+procedure TPasSrcUtilTest.TestGetImplementationUses;
+begin
+  StartUnit;
+  StartImplementation;
+  AddUses('d,a,b,c');
+  EndSource;
+  Analyser.GetImplementationUnits(List);
+  AssertList('4 implementation units',['d','a','b','c']);
+end;
+
+procedure TPasSrcUtilTest.TestGetImplementationUsesEmpty;
+begin
+  StartUnit;
+  StartImplementation;
+  EndSource;
+  Analyser.GetImplementationUnits(List);
+  AssertList('0 implementation units',[]);
+end;
+
+procedure TPasSrcUtilTest.TestGetAllUses;
+begin
+  StartUnit;
+  AddUses('a,b,c');
+  StartImplementation;
+  AddUses('d,e');
+  EndSource;
+  Analyser.GetUsedUnits(List);
+  AssertList('6 units',['System','a','b','c','d','e']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceIdentifiers;
+begin
+  StartUnit;
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List);
+  AssertList('0 identifiers',[]);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceVarIdentifiers;
+begin
+  StartUnit;
+  AddLine('Var a : integer;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List);
+  AssertList('1 identifiers',['a']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterface2VarIdentifiers;
+begin
+  StartUnit;
+  AddLine('Var a,b : integer;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List);
+  AssertList('2 identifiers',['a','b']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceConstIdentifiers;
+begin
+  StartUnit;
+  AddLine('Const a = 123;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List);
+  AssertList('1 identifiers',['a']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterface2ConstsIdentifiers;
+begin
+  StartUnit;
+  AddLine('Const a = 123;');
+  AddLine(' b = 123;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List);
+  AssertList('2 identifiers',['a','b']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceTypeIdentifiers;
+begin
+  StartUnit;
+  AddLine('Type a = Integer;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List);
+  AssertList('1 identifiers',['a']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterface2TypeIdentifiers;
+begin
+  StartUnit;
+  AddLine('Type a = Integer;');
+  AddLine(' b = Word;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List);
+  AssertList('2 identifiers',['a','b']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceProcIdentifiers;
+begin
+  StartUnit;
+  AddLine('Procedure a (b : Integer);');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List);
+  AssertList('1 identifiers',['a']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceResourcestringIdentifiers;
+begin
+  StartUnit;
+  AddLine('Resourcestring astring = ''Something'';');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List);
+  AssertList('1 identifiers',['astring']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceEnumTypeIdentifiersNoRecurse;
+begin
+  StartUnit;
+  AddLine('Type aenum = (one,two,three);');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List);
+  AssertList('1 identifiers',['aenum']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceEnumTypeIdentifiersRecurse;
+begin
+  StartUnit;
+  AddLine('Type aenum = (one,two,three);');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List,True);
+  AssertList('4 identifiers',['aenum','aenum.one','aenum.two','aenum.three']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceRecordTypeIdentifiersNoRecurse;
+begin
+  StartUnit;
+  AddLine('Type arec = record one,two,three : integer; end;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List,False);
+  AssertList('1 identifier',['arec']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceRecordTypeIdentifiersRecurse;
+begin
+  StartUnit;
+  AddLine('Type arec = record one,two,three : integer; end;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List,True);
+  AssertList('4 identifiers',['arec','arec.one','arec.two','arec.three']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceRecordTypeIdentifiersRecurseVariant;
+begin
+  StartUnit;
+  AddLine('Type arec = record one,two,three : integer; case integer of 1: (x : integer;); end;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List,True);
+  AssertList('4 identifiers',['arec','arec.one','arec.two','arec.three','arec.x']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceClassTypeIdentifiersNoRecurse;
+begin
+  StartUnit;
+  AddLine('Type TMyClass = Class');
+  AddLine('   one,two,three : integer;');
+  AddLine('end;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List,False);
+  AssertList('4 identifiers',['TMyClass']);
+end;
+
+procedure TPasSrcUtilTest.TestGetInterfaceClassTypeIdentifiersRecurse;
+begin
+  StartUnit;
+  AddLine('Type TMyClass = Class');
+  AddLine('   one,two,three : integer;');
+  AddLine('end;');
+  StartImplementation;
+  EndSource;
+  Analyser.GetInterfaceIdentifiers(List,True);
+  AssertList('4 identifiers',['TMyClass','TMyClass.one','TMyClass.two','TMyClass.three']);
+end;
+
+procedure TPasSrcUtilTest.TestGetImplementationVarIdentifiers;
+begin
+  StartUnit;
+  StartImplementation;
+  AddLine('Var a : integer;');
+  EndSource;
+  Analyser.GetImplementationIdentifiers(List);
+  AssertList('1 identifiers',['a']);
+end;
+
+procedure TPasSrcUtilTest.TestInterfaceHasResourceStrings;
+begin
+  StartUnit;
+  AddLine('Resourcestring astring = ''Something'';');
+  StartImplementation;
+  EndSource;
+  AssertEquals('Have res. strings',True,Analyser.InterfaceHasResourcestrings)
+end;
+
+procedure TPasSrcUtilTest.TestInterfaceHasResourceStringsFalse;
+begin
+  StartUnit;
+  StartImplementation;
+  AddLine('Resourcestring astring = ''Something'';');
+  EndSource;
+  AssertEquals('Have no res. strings',False,Analyser.InterfaceHasResourcestrings)
+end;
+
+procedure TPasSrcUtilTest.TestImplementationHasResourceStrings;
+begin
+  StartUnit;
+  StartImplementation;
+  AddLine('Resourcestring astring = ''Something'';');
+  EndSource;
+  AssertEquals('Have res. strings',True,Analyser.ImplementationHasResourcestrings)
+end;
+
+procedure TPasSrcUtilTest.TestHasResourceStrings;
+begin
+  StartUnit;
+  StartImplementation;
+  EndSource;
+  AssertEquals('No res. strings',False,Analyser.ImplementationHasResourcestrings)
+end;
+
+procedure TPasSrcUtilTest.TestHasResourceStrings2;
+begin
+  StartUnit;
+  AddLine('Resourcestring astring = ''Something'';');
+  StartImplementation;
+  EndSource;
+  AssertEquals('Have  res. strings',True,Analyser.HasResourcestrings)
+end;
+
+procedure TPasSrcUtilTest.TestHasResourceStrings3;
+begin
+  StartUnit;
+  AddLine('Resourcestring astring = ''Something'';');
+  StartImplementation;
+  EndSource;
+  AssertEquals('Have  res. strings',True,Analyser.HasResourcestrings)
+end;
+
+procedure TPasSrcUtilTest.TestHasResourceStrings4;
+begin
+  StartUnit;
+  AddLine('Resourcestring astring = ''Something'';');
+  StartImplementation;
+  AddLine('Resourcestring astring2 = ''Something'';');
+  EndSource;
+  AssertEquals('Have  res. strings',True,Analyser.HasResourcestrings)
+end;
+
+procedure TPasSrcUtilTest.SetUp;
+begin
+  FAnalyser:=TPasSrcAnalysis.Create(Nil);
+  FSrc:=TStringList.Create;
+  FList:=TStringList.Create;
+  FStream:=TMemoryStream.Create;
+  FAnalyser.FileName:='atest.pp';
+  FAnalyser.Stream:=FStream;
+end;
+
+procedure TPasSrcUtilTest.TearDown;
+begin
+  FreeAndNil(FAnalyser);
+  FreeAndNil(FStream);
+  FreeAndNil(FSrc);
+  FreeAndNil(FList);
+end;
+
+procedure TPasSrcUtilTest.AddLine(const ALine: String);
+begin
+  FSrc.Add(ALine);
+end;
+
+procedure TPasSrcUtilTest.AddUses(const AUsesList: String);
+begin
+  AddLine('uses '+AUseslist+';');
+  AddLine('');
+end;
+
+procedure TPasSrcUtilTest.StartUnit;
+begin
+  AddLine('unit atest;');
+  AddLine('');
+  AddLine('Interface');
+  AddLine('');
+end;
+
+procedure TPasSrcUtilTest.StartImplementation;
+begin
+  AddLine('');
+  AddLine('Implementation');
+  AddLine('');
+end;
+
+procedure TPasSrcUtilTest.EndSource;
+begin
+  AddLine('');
+  AddLine('end.');
+  FSrc.SaveToStream(FStream);
+  FStream.Position:=0;
+  Writeln('// Test name : ',Self.TestName);
+  Writeln(FSrc.Text);
+end;
+
+procedure TPasSrcUtilTest.AssertList(Msg: String; Els: array of string);
+
+Var
+  I : Integer;
+
+begin
+  AssertEquals(Msg+': number of elements',Length(Els),List.Count);
+  For I:=Low(Els) to High(Els) do
+    AssertEquals(Msg+': list element '+IntToStr(i)+' matches : ',Els[i],List[i]);
+end;
+
+
+initialization
+
+  RegisterTest(TPasSrcUtilTest);
+end.
+

+ 1121 - 0
packages/fcl-passrc/tests/tcprocfunc.pas

@@ -0,0 +1,1121 @@
+unit tcprocfunc;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, typinfo, fpcunit, pastree, pscanner, pparser, tcbaseparser,testregistry;
+
+type
+
+  { TTestProcedureFunction }
+
+  TTestProcedureFunction= class(TTestParser)
+  private
+    FFunc: TPasFunction;
+    FHint: String;
+    FProc: TPasProcedure;
+    procedure AddDeclaration(const ASource: string; const AHint: String='');
+    procedure AssertArg(ProcType: TPasProcedureType; AIndex: Integer;
+      AName: String; AAccess: TArgumentAccess; const TypeName: String;
+      AValue: String='');
+    procedure AssertArrayArg(ProcType: TPasProcedureType; AIndex: Integer;
+      AName: String; AAccess: TArgumentAccess; const ElementTypeName: String);
+    procedure AssertFunc(Mods: TProcedureModifiers; CC: TCallingConvention; ArgCount: Integer; P: TPasFunction=nil);
+    procedure AssertProc(Mods: TProcedureModifiers; CC: TCallingConvention; ArgCount: Integer; P: TPasProcedure=nil);
+    function BaseAssertArg(ProcType: TPasProcedureType; AIndex: Integer;
+      AName: String; AAccess: TArgumentAccess; AValue: String=''): TPasArgument;
+    function GetFT: TPasFunctionType;
+    function GetPT: TPasProcedureType;
+    Procedure ParseProcedure;
+    function ParseProcedure(const ASource: string; const AHint: String=''): TPasProcedure;
+    Procedure ParseFunction;
+    function ParseFunction(const ASource : String; AResult: string = ''; const AHint: String=''; CC : TCallingConvention = ccDefault): TPasProcedure;
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+    Property Hint : String Read FHint Write FHint;
+    Property Proc : TPasProcedure Read FProc;
+    Property ProcType : TPasProcedureType Read GetPT;
+    Property Func : TPasFunction Read FFunc;
+    Property FuncType : TPasFunctionType Read GetFT;
+  published
+    procedure TestEmptyProcedure;
+    Procedure TestEmptyFunction;
+    procedure TestEmptyProcedureDeprecated;
+    Procedure TestEmptyFunctionDeprecated;
+    procedure TestEmptyProcedurePlatform;
+    Procedure TestEmptyFunctionPlatform;
+    procedure TestEmptyProcedureExperimental;
+    Procedure TestEmptyFunctionExperimental;
+    procedure TestEmptyProcedureUnimplemented;
+    Procedure TestEmptyFunctionUnimplemented;
+    procedure TestProcedureOneArg;
+    Procedure TestFunctionOneArg;
+    procedure TestProcedureOneVarArg;
+    Procedure TestFunctionOneVarArg;
+    procedure TestProcedureOneConstArg;
+    Procedure TestFunctionOneConstArg;
+    procedure TestProcedureOneOutArg;
+    Procedure TestFunctionOneOutArg;
+    procedure TestProcedureOneConstRefArg;
+    Procedure TestFunctionOneConstRefArg;
+    procedure TestProcedureTwoArgs;
+    Procedure TestFunctionTwoArgs;
+    procedure TestProcedureTwoArgsSeparate;
+    Procedure TestFunctionTwoArgsSeparate;
+    procedure TestProcedureOneArgDefault;
+    Procedure TestFunctionOneArgDefault;
+    procedure TestProcedureOneArgDefaultSet;
+    Procedure TestFunctionOneArgDefaultSet;
+    procedure TestProcedureOneArgDefaultExpr;
+    Procedure TestFunctionOneArgDefaultExpr;
+    procedure TestProcedureTwoArgsDefault;
+    Procedure TestFunctionTwoArgsDefault;
+    procedure TestProcedureOneUntypedVarArg;
+    Procedure TestFunctionOneUntypedVarArg;
+    procedure TestProcedureTwoUntypedVarArgs;
+    Procedure TestFunctionTwoUntypedVarArgs;
+    procedure TestProcedureOneUntypedConstArg;
+    Procedure TestFunctionOneUntypedConstArg;
+    procedure TestProcedureTwoUntypedConstArgs;
+    Procedure TestFunctionTwoUntypedConstArgs;
+    procedure TestProcedureOpenArrayArg;
+    Procedure TestFunctionOpenArrayArg;
+    procedure TestProcedureTwoOpenArrayArgs;
+    Procedure TestFunctionTwoOpenArrayArgs;
+    procedure TestProcedureConstOpenArrayArg;
+    Procedure TestFunctionConstOpenArrayArg;
+    procedure TestProcedureVarOpenArrayArg;
+    Procedure TestFunctionVarOpenArrayArg;
+    procedure TestProcedureArrayOfConstArg;
+    Procedure TestFunctionArrayOfConstArg;
+    procedure TestProcedureConstArrayOfConstArg;
+    Procedure TestFunctionConstArrayOfConstArg;
+    Procedure TestProcedureCdecl;
+    Procedure TestFunctionCdecl;
+    Procedure TestProcedureCdeclDeprecated;
+    Procedure TestFunctionCdeclDeprecated;
+    Procedure TestProcedureSafeCall;
+    Procedure TestFunctionSafeCall;
+    //ccDefault,ccRegister,ccPascal,ccCDecl,ccStdCall,ccOldFPCCall,ccSafeCall);
+    Procedure TestProcedurePascal;
+    Procedure TestFunctionPascal;
+    Procedure TestProcedureStdCall;
+    Procedure TestFunctionStdCall;
+    Procedure TestProcedureOldFPCCall;
+    Procedure TestFunctionOldFPCCall;
+    Procedure TestProcedurePublic;
+    Procedure TestProcedurePublicIdent;
+    Procedure TestFunctionPublic;
+    Procedure TestProcedureCdeclPublic;
+    Procedure TestFunctionCdeclPublic;
+    Procedure TestProcedureOverload;
+    Procedure TestFunctionOverload;
+    Procedure TestProcedureVarargs;
+    Procedure TestFunctionVarArgs;
+    Procedure TestProcedureCDeclVarargs;
+    Procedure TestFunctionCDeclVarArgs;
+    Procedure TestProcedureForwardInterface;
+    Procedure TestFunctionForwardInterface;
+    Procedure TestProcedureForward;
+    Procedure TestFunctionForward;
+    Procedure TestProcedureCdeclForward;
+    Procedure TestFunctionCDeclForward;
+    Procedure TestProcedureCompilerProc;
+    Procedure TestFunctionCompilerProc;
+    Procedure TestProcedureCDeclCompilerProc;
+    Procedure TestFunctionCDeclCompilerProc;
+    Procedure TestProcedureAssembler;
+    Procedure TestFunctionAssembler;
+    Procedure TestProcedureCDeclAssembler;
+    Procedure TestFunctionCDeclAssembler;
+    Procedure TestProcedureExport;
+    Procedure TestFunctionExport;
+    Procedure TestProcedureCDeclExport;
+    Procedure TestFunctionCDeclExport;
+    Procedure TestProcedureExternal;
+    Procedure TestFunctionExternal;
+    Procedure TestProcedureExternalLibName;
+    Procedure TestFunctionExternalLibName;
+    Procedure TestProcedureExternalLibNameName;
+    Procedure TestFunctionExternalLibNameName;
+    Procedure TestProcedureExternalName;
+    Procedure TestFunctionExternalName;
+    Procedure TestProcedureCdeclExternal;
+    Procedure TestFunctionCdeclExternal;
+    Procedure TestProcedureCdeclExternalLibName;
+    Procedure TestFunctionCdeclExternalLibName;
+    Procedure TestProcedureCdeclExternalLibNameName;
+    Procedure TestFunctionCdeclExternalLibNameName;
+    Procedure TestProcedureCdeclExternalName;
+    Procedure TestFunctionCdeclExternalName;
+  end;
+
+implementation
+
+
+procedure TTestProcedureFunction.AddDeclaration(Const ASource : string; Const AHint : String = '');
+
+Var
+  D : String;
+begin
+  Hint:=AHint;
+  D:=ASource;
+  If Hint<>'' then
+    D:=D+' '+Hint;
+  if (D[Length(D)]<>';') then
+    D:=D+';';
+  Add(D);
+end;
+
+function TTestProcedureFunction.GetPT: TPasProcedureType;
+begin
+  AssertNotNull('have procedure to get type from',Proc);
+  Result:=Proc.ProcType;
+end;
+
+Function TTestProcedureFunction.ParseProcedure(Const ASource : string; Const AHint : String = '') : TPasProcedure;
+
+
+begin
+  AddDeclaration('procedure A '+ASource,AHint);
+  Self.ParseProcedure;
+  Result:=Fproc;
+end;
+
+procedure TTestProcedureFunction.ParseProcedure;
+
+begin
+  //  Writeln(source.text);
+  ParseDeclarations;
+  AssertEquals('One variable definition',1,Declarations.Functions.Count);
+  AssertEquals('First declaration is procedure declaration.',TPasProcedure,TObject(Declarations.Functions[0]).ClassType);
+  FProc:=TPasProcedure(Declarations.Functions[0]);
+  Definition:=FProc;
+  AssertEquals('First declaration has correct name.','A',FProc.Name);
+  if (Hint<>'') then
+    CheckHint(TPasMemberHint(Getenumvalue(typeinfo(TPasMemberHint),'h'+Hint)));
+end;
+
+function TTestProcedureFunction.ParseFunction(const ASource : String;AResult: string = ''; const AHint: String = ''; CC : TCallingConvention = ccDefault): TPasProcedure;
+Var
+  D :String;
+begin
+  if (AResult='') then
+    AResult:='Integer';
+  D:='Function A '+ASource+' : '+AResult;
+  If (cc<>ccDefault) then
+    D:=D+'; '+cCallingConventions[cc]+';';
+  AddDeclaration(D,AHint);
+  Self.ParseFunction;
+  Result:=FFunc;
+  AssertNotNull('Have function result element',FuncType.ResultEl);
+  AssertNotNull('Have function result type element',FuncType.ResultEl.ResultType);
+  AssertEquals('Correct function result type name',AResult,FuncType.ResultEl.ResultType.Name);
+end;
+
+procedure TTestProcedureFunction.ParseFunction;
+begin
+  //  Writeln(source.text);
+  ParseDeclarations;
+  AssertEquals('One variable definition',1,Declarations.Functions.Count);
+  AssertEquals('First declaration is function declaration.',TPasFunction,TObject(Declarations.Functions[0]).ClassType);
+  FFunc:=TPasFunction(Declarations.Functions[0]);
+  Definition:=FFunc;
+  AssertEquals('First declaration has correct name.','A',FFunc.Name);
+  if (Hint<>'') then
+    CheckHint(TPasMemberHint(Getenumvalue(typeinfo(TPasMemberHint),'h'+Hint)));
+end;
+
+procedure TTestProcedureFunction.AssertProc(Mods : TProcedureModifiers; CC : TCallingConvention; ArgCount : Integer; P : TPasProcedure = Nil);
+
+begin
+  If P=Nil then
+    P:=Proc;
+  AssertNotNull('No proc to assert',P);
+  AssertEquals('Procedure modifiers',Mods,P.Modifiers);
+  AssertEquals('Procedue calling convention',CC,P.CallingConvention);
+  AssertEquals('No message name','',p.MessageName);
+  AssertEquals('No message type',pmtNone,P.MessageType);
+  AssertNotNull('Have procedure type to assert',P.ProcType);
+  AssertEquals('Correct number of arguments',ArgCount,P.ProcType.Args.Count);
+  AssertEquals('Not of object',False,P.ProcType.IsOfObject);
+  AssertEquals('Not is nested',False,P.ProcType.IsNested);
+end;
+
+procedure TTestProcedureFunction.AssertFunc(Mods : TProcedureModifiers; CC : TCallingConvention; ArgCount : Integer; P : TPasFunction = Nil);
+
+begin
+  If P=Nil then
+    P:=Func;
+  AssertNotNull('No func to assert',P);
+  AssertEquals('Procedure modifiers',Mods,P.Modifiers);
+  AssertEquals('Procedue calling convention',CC,P.CallingConvention);
+  AssertEquals('No message name','',p.MessageName);
+  AssertEquals('No message type',pmtNone,P.MessageType);
+  AssertNotNull('Have procedure type to assert',P.ProcType);
+  AssertEquals('Correct number of arguments',ArgCount,P.ProcType.Args.Count);
+  AssertEquals('Not of object',False,P.ProcType.IsOfObject);
+  AssertEquals('Not is nested',False,P.ProcType.IsNested);
+end;
+
+Function TTestProcedureFunction.BaseAssertArg(ProcType : TPasProcedureType; AIndex : Integer; AName : String; AAccess : TArgumentAccess; AValue : String='') : TPasArgument;
+
+Var
+  A : TPasArgument;
+  N : String;
+
+begin
+  AssertNotNull('Have proctype to test argument',ProcType);
+  if AIndex>=Proctype.Args.Count then
+    Fail(Format('Cannot test argument: index %d is larger than the number of arguments (%d).',[AIndex,Proctype.Args.Count]));
+  AssertNotNull('Have argument at position '+IntToStr(AIndex),Proctype.Args[AIndex]);
+  AssertEquals('Have argument type at position '+IntToStr(AIndex),TPasArgument,TObject(Proctype.Args[AIndex]).ClassType);
+  N:='Argument '+IntToStr(AIndex+1)+' : ';
+  A:=TPasArgument(Proctype.Args[AIndex]);
+  AssertEquals(N+'Argument name',AName,A.Name);
+  AssertEquals(N+'Argument access',AAccess,A.Access);
+  if (AValue='') then
+    AssertNull(N+' no default value',A.ValueExpr)
+  else
+    begin
+    AssertNotNull(N+' Have default value',A.ValueExpr);
+    AssertEquals(N+' Default value',AValue,A.Value);
+    end;
+  Result:=A;
+end;
+
+procedure TTestProcedureFunction.AssertArg(ProcType : TPasProcedureType; AIndex : Integer; AName : String; AAccess : TArgumentAccess; Const TypeName : String; AValue : String='');
+
+Var
+  A : TPasArgument;
+  N : String;
+
+begin
+  A:=BaseAssertArg(ProcType,AIndex,ANAme,AAccess,AValue);
+  N:='Argument '+IntToStr(AIndex+1)+' : ';
+  if (TypeName='') then
+    AssertNull(N+' No argument type',A.ArgType)
+  else
+    begin
+    AssertNotNull(N+' Have argument type',A.ArgType);
+    AssertEquals(N+' Correct argument type name',TypeName,A.ArgType.Name);
+    end;
+end;
+
+procedure TTestProcedureFunction.AssertArrayArg(ProcType: TPasProcedureType;
+  AIndex: Integer; AName: String; AAccess: TArgumentAccess;
+  const ElementTypeName: String);
+Var
+  A : TPasArgument;
+  AT : TPasArrayType;
+  N : String;
+
+begin
+  A:=BaseAssertArg(ProcType,AIndex,ANAme,AAccess,'');
+  N:='Argument '+IntToStr(AIndex+1)+' : ';
+  AssertNotNull(N+' Have argument type',A.ArgType);
+  AssertEquals(N+' is arrayType',TPasArrayType,A.ArgType.ClassType);
+  AT:=TPasArrayType(A.ArgType);
+  if (ElementTypeName='') then
+    AssertNull(N+' No array element type',AT.ElType)
+  else
+    begin
+    AssertNotNull(N+' Have array element type',AT.ElType);
+    AssertEquals(N+' Correct array element type name',ElementTypeName,AT.ElType.Name);
+    end;
+end;
+
+function TTestProcedureFunction.GetFT: TPasFunctionType;
+begin
+  AssertNotNull('have function to get type from',Func);
+  AssertEquals('Function type is correct type',TPasFunctionType,Func.ProcType.ClassType);
+  Result:=Func.FuncType;
+end;
+
+//TProcedureMessageType
+
+procedure TTestProcedureFunction.TestEmptyProcedure;
+begin
+  ParseProcedure('');
+  AssertProc([],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestEmptyFunction;
+begin
+  ParseFunction('');
+  AssertFunc([],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestEmptyProcedureDeprecated;
+begin
+  ParseProcedure('','deprecated');
+  AssertProc([],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestEmptyFunctionDeprecated;
+begin
+  ParseFunction('','deprecated');
+  AssertFunc([],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestEmptyProcedurePlatform;
+begin
+  ParseProcedure('','platform');
+  AssertProc([],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestEmptyFunctionPlatform;
+begin
+  ParseFunction('','platform');
+  AssertFunc([],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestEmptyProcedureExperimental;
+begin
+  ParseProcedure('','experimental');
+  AssertProc([],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestEmptyFunctionExperimental;
+begin
+  ParseFunction('','experimental');
+  AssertFunc([],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestEmptyProcedureUnimplemented;
+begin
+  ParseProcedure('','unimplemented');
+  AssertProc([],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestEmptyFunctionUnimplemented;
+begin
+  ParseFunction('','unimplemented');
+  AssertFunc([],ccDefault,0);
+
+end;
+
+
+
+procedure TTestProcedureFunction.TestProcedureOneArg;
+begin
+  ParseProcedure('(B : Integer)');
+  AssertProc([],ccDefault,1);
+  AssertArg(ProcType,0,'B',argDefault,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOneArg;
+begin
+  ParseFunction('(B : Integer)');
+  AssertFunc([],ccDefault,1);
+  AssertArg(FuncType,0,'B',argDefault,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOneVarArg;
+begin
+  ParseProcedure('(Var B : Integer)');
+  AssertProc([],ccDefault,1);
+  AssertArg(ProcType,0,'B',argVar,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOneVarArg;
+begin
+  ParseFunction('(Var B : Integer)');
+  AssertFunc([],ccDefault,1);
+  AssertArg(FuncType,0,'B',argVar,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOneConstArg;
+begin
+  ParseProcedure('(Const B : Integer)');
+  AssertProc([],ccDefault,1);
+  AssertArg(ProcType,0,'B',argConst,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOneConstArg;
+begin
+  ParseFunction('(Const B : Integer)');
+  AssertFunc([],ccDefault,1);
+  AssertArg(FuncType,0,'B',argConst,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOneOutArg;
+begin
+  ParseProcedure('(Out B : Integer)');
+  AssertProc([],ccDefault,1);
+  AssertArg(ProcType,0,'B',argOut,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOneOutArg;
+begin
+  ParseFunction('(Out B : Integer)');
+  AssertFunc([],ccDefault,1);
+  AssertArg(FuncType,0,'B',argOut,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOneConstRefArg;
+begin
+  ParseProcedure('(Constref B : Integer)');
+  AssertProc([],ccDefault,1);
+  AssertArg(ProcType,0,'B',argConstRef,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOneConstRefArg;
+begin
+  ParseFunction('(ConstRef B : Integer)');
+  AssertFunc([],ccDefault,1);
+  AssertArg(FuncType,0,'B',argConstref,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureTwoArgs;
+begin
+  ParseProcedure('(B,C : Integer)');
+  AssertProc([],ccDefault,2);
+  AssertArg(ProcType,0,'B',argDefault,'Integer','');
+  AssertArg(ProcType,1,'C',argDefault,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionTwoArgs;
+begin
+  ParseFunction('(B,C : Integer)');
+  AssertFunc([],ccDefault,2);
+  AssertArg(FuncType,0,'B',argDefault,'Integer','');
+  AssertArg(FuncType,1,'C',argDefault,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureTwoArgsSeparate;
+begin
+  ParseProcedure('(B : Integer; C : Integer)');
+  AssertProc([],ccDefault,2);
+  AssertArg(ProcType,0,'B',argDefault,'Integer','');
+  AssertArg(ProcType,1,'C',argDefault,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionTwoArgsSeparate;
+begin
+  ParseFunction('(B : Integer;C : Integer)');
+  AssertFunc([],ccDefault,2);
+  AssertArg(FuncType,0,'B',argDefault,'Integer','');
+  AssertArg(FuncType,1,'C',argDefault,'Integer','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOneArgDefault;
+begin
+  ParseProcedure('(B : Integer = 1)');
+  AssertProc([],ccDefault,1);
+  AssertArg(ProcType,0,'B',argDefault,'Integer','1');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOneArgDefault;
+begin
+  ParseFunction('(B : Integer = 1)');
+  AssertFunc([],ccDefault,1);
+  AssertArg(FuncType,0,'B',argDefault,'Integer','1');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOneArgDefaultSet;
+begin
+  ParseProcedure('(B : MySet = [1,2])');
+  AssertProc([],ccDefault,1);
+  AssertArg(ProcType,0,'B',argDefault,'MySet','[1, 2]');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOneArgDefaultSet;
+begin
+  ParseFunction('(B : MySet = [1,2])');
+  AssertFunc([],ccDefault,1);
+  AssertArg(FuncType,0,'B',argDefault,'MySet','[1, 2]');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOneArgDefaultExpr;
+begin
+  ParseProcedure('(B : Integer = 1 + 2)');
+  AssertProc([],ccDefault,1);
+  AssertArg(ProcType,0,'B',argDefault,'Integer','1 + 2');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOneArgDefaultExpr;
+begin
+  ParseFunction('(B : Integer = 1 + 2)');
+  AssertFunc([],ccDefault,1);
+  AssertArg(FuncType,0,'B',argDefault,'Integer','1 + 2');
+end;
+
+procedure TTestProcedureFunction.TestProcedureTwoArgsDefault;
+begin
+  ParseProcedure('(B : Integer = 1; C : Integer = 2)');
+  AssertProc([],ccDefault,2);
+  AssertArg(ProcType,0,'B',argDefault,'Integer','1');
+  AssertArg(ProcType,1,'C',argDefault,'Integer','2');
+end;
+
+procedure TTestProcedureFunction.TestFunctionTwoArgsDefault;
+begin
+  ParseFunction('(B : Integer = 1; C : Integer = 2)');
+  AssertFunc([],ccDefault,2);
+  AssertArg(FuncType,0,'B',argDefault,'Integer','1');
+  AssertArg(FuncType,1,'C',argDefault,'Integer','2');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOneUntypedVarArg;
+begin
+  ParseProcedure('(Var B)');
+  AssertProc([],ccDefault,1);
+  AssertArg(ProcType,0,'B',argVar,'','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOneUntypedVarArg;
+begin
+  ParseFunction('(Var B)');
+  AssertFunc([],ccDefault,1);
+  AssertArg(FuncType,0,'B',argVar,'','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureTwoUntypedVarArgs;
+begin
+  ParseProcedure('(Var B; Var C)');
+  AssertProc([],ccDefault,2);
+  AssertArg(ProcType,0,'B',argVar,'','');
+  AssertArg(ProcType,1,'C',argVar,'','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionTwoUntypedVarArgs;
+begin
+  ParseFunction('(Var B; Var C)');
+  AssertFunc([],ccDefault,2);
+  AssertArg(FuncType,0,'B',argVar,'','');
+  AssertArg(FuncType,1,'C',argVar,'','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOneUntypedConstArg;
+begin
+  ParseProcedure('(Const B)');
+  AssertProc([],ccDefault,1);
+  AssertArg(ProcType,0,'B',argConst,'','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOneUntypedConstArg;
+begin
+  ParseFunction('(Const B)');
+  AssertFunc([],ccDefault,1);
+  AssertArg(FuncType,0,'B',argConst,'','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureTwoUntypedConstArgs;
+begin
+  ParseProcedure('(Const B; Const C)');
+  AssertProc([],ccDefault,2);
+  AssertArg(ProcType,0,'B',argConst,'','');
+  AssertArg(ProcType,1,'C',argConst,'','');
+end;
+
+procedure TTestProcedureFunction.TestFunctionTwoUntypedConstArgs;
+begin
+  ParseFunction('(Const B; Const C)');
+  AssertFunc([],ccDefault,2);
+  AssertArg(FuncType,0,'B',argConst,'','');
+  AssertArg(FuncType,1,'C',argConst,'','');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOpenArrayArg;
+begin
+  ParseProcedure('(B : Array of Integer)');
+  AssertProc([],ccDefault,1);
+  AssertArrayArg(ProcType,0,'B',argDefault,'Integer');
+end;
+
+procedure TTestProcedureFunction.TestFunctionOpenArrayArg;
+begin
+  ParseFunction('(B : Array of Integer)');
+  AssertFunc([],ccDefault,1);
+  AssertArrayArg(FuncType,0,'B',argDefault,'Integer');
+end;
+
+procedure TTestProcedureFunction.TestProcedureTwoOpenArrayArgs;
+begin
+  ParseProcedure('(B : Array of Integer;C : Array of Integer)');
+  AssertProc([],ccDefault,2);
+  AssertArrayArg(ProcType,0,'B',argDefault,'Integer');
+  AssertArrayArg(ProcType,1,'C',argDefault,'Integer');
+end;
+
+procedure TTestProcedureFunction.TestFunctionTwoOpenArrayArgs;
+begin
+  ParseFunction('(B : Array of Integer;C : Array of Integer)');
+  AssertFunc([],ccDefault,2);
+  AssertArrayArg(FuncType,0,'B',argDefault,'Integer');
+  AssertArrayArg(FuncType,1,'C',argDefault,'Integer');
+end;
+
+procedure TTestProcedureFunction.TestProcedureConstOpenArrayArg;
+begin
+  ParseProcedure('(Const B : Array of Integer)');
+  AssertProc([],ccDefault,1);
+  AssertArrayArg(ProcType,0,'B',argConst,'Integer');
+end;
+
+procedure TTestProcedureFunction.TestFunctionConstOpenArrayArg;
+begin
+  ParseFunction('(Const B : Array of Integer)');
+  AssertFunc([],ccDefault,1);
+  AssertArrayArg(FuncType,0,'B',argConst,'Integer');
+end;
+
+procedure TTestProcedureFunction.TestProcedureVarOpenArrayArg;
+begin
+  ParseProcedure('(Var B : Array of Integer)');
+  AssertProc([],ccDefault,1);
+  AssertArrayArg(ProcType,0,'B',argVar,'Integer');
+end;
+
+procedure TTestProcedureFunction.TestFunctionVarOpenArrayArg;
+begin
+  ParseFunction('(Var B : Array of Integer)');
+  AssertFunc([],ccDefault,1);
+  AssertArrayArg(FuncType,0,'B',argVar,'Integer');
+end;
+
+procedure TTestProcedureFunction.TestProcedureArrayOfConstArg;
+begin
+  ParseProcedure('(B : Array of Const)');
+  AssertProc([],ccDefault,1);
+  AssertArrayArg(ProcType,0,'B',argDefault,'');
+end;
+
+procedure TTestProcedureFunction.TestFunctionArrayOfConstArg;
+begin
+  ParseFunction('(B : Array of Const)');
+  AssertFunc([],ccDefault,1);
+  AssertArrayArg(FuncType,0,'B',argDefault,'');
+end;
+
+procedure TTestProcedureFunction.TestProcedureConstArrayOfConstArg;
+begin
+  ParseProcedure('(Const B : Array of Const)');
+  AssertProc([],ccDefault,1);
+  AssertArrayArg(ProcType,0,'B',argConst,'');
+end;
+
+procedure TTestProcedureFunction.TestFunctionConstArrayOfConstArg;
+begin
+  ParseFunction('(Const B : Array of Const)');
+  AssertFunc([],ccDefault,1);
+  AssertArrayArg(FuncType,0,'B',argConst,'');
+end;
+
+procedure TTestProcedureFunction.TestProcedureCdecl;
+begin
+  ParseProcedure('; cdecl');
+  AssertProc([],ccCdecl,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionCdecl;
+begin
+  ParseFunction('','','',ccCdecl);
+  AssertFunc([],ccCdecl,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureCdeclDeprecated;
+begin
+  ParseProcedure('; cdecl;','deprecated');
+  AssertProc([],ccCdecl,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionCdeclDeprecated;
+begin
+  ParseFunction('','','deprecated',ccCdecl);
+  AssertFunc([],ccCdecl,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureSafeCall;
+begin
+  ParseProcedure('; safecall;','');
+  AssertProc([],ccSafeCall,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionSafeCall;
+begin
+  ParseFunction('','','',ccSafecall);
+  AssertFunc([],ccSafecall,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedurePascal;
+begin
+  ParseProcedure('; pascal;','');
+  AssertProc([],ccPascal,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionPascal;
+begin
+  ParseFunction('','','',ccPascal);
+  AssertFunc([],ccPascal,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureStdCall;
+begin
+  ParseProcedure('; stdcall;','');
+  AssertProc([],ccstdcall,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionStdCall;
+begin
+  ParseFunction('','','',ccStdCall);
+  AssertFunc([],ccStdCall,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureOldFPCCall;
+begin
+  ParseProcedure('; oldfpccall;','');
+  AssertProc([],ccoldfpccall,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionOldFPCCall;
+begin
+  ParseFunction('','','',ccOldFPCCall);
+  AssertFunc([],ccOldFPCCall,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedurePublic;
+begin
+  ParseProcedure('; public name ''myfunc'';','');
+  AssertProc([pmPublic],ccDefault,0);
+  AssertExpression('Public name',Proc.PublicName,pekString,'''myfunc''');
+end;
+
+procedure TTestProcedureFunction.TestProcedurePublicIdent;
+begin
+  ParseProcedure('; public name exportname;','');
+  AssertProc([pmPublic],ccDefault,0);
+  AssertExpression('Public name',Proc.PublicName,pekIdent,'exportname');
+end;
+
+procedure TTestProcedureFunction.TestFunctionPublic;
+begin
+  AddDeclaration('function A : Integer; public name exportname');
+  ParseFunction;
+  AssertFunc([pmPublic],ccDefault,0);
+  AssertExpression('Public name',Func.PublicName,pekIdent,'exportname');
+end;
+
+procedure TTestProcedureFunction.TestProcedureCdeclPublic;
+begin
+  ParseProcedure('; cdecl; public name exportname;','');
+  AssertProc([pmPublic],ccCDecl,0);
+  AssertExpression('Public name',Proc.PublicName,pekIdent,'exportname');
+end;
+
+procedure TTestProcedureFunction.TestFunctionCdeclPublic;
+begin
+  AddDeclaration('function A : Integer; cdecl; public name exportname');
+  ParseFunction;
+  AssertFunc([pmPublic],ccCDecl,0);
+  AssertExpression('Public name',Func.PublicName,pekIdent,'exportname');
+end;
+
+procedure TTestProcedureFunction.TestProcedureOverload;
+begin
+  ParseProcedure('; overload;','');
+  AssertProc([pmOverload],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionOverload;
+begin
+  AddDeclaration('function A : Integer; overload');
+  ParseFunction;
+  AssertFunc([pmOverload],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureVarargs;
+begin
+  ParseProcedure('; varargs;','');
+  AssertProc([pmVarArgs],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionVarArgs;
+begin
+  AddDeclaration('function A : Integer; varargs');
+  ParseFunction;
+  AssertFunc([pmVarArgs],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureCDeclVarargs;
+begin
+  ParseProcedure(';cdecl; varargs;','');
+  AssertProc([pmVarArgs],ccCDecl,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionCDeclVarArgs;
+begin
+  AddDeclaration('function A : Integer; cdecl; varargs');
+  ParseFunction;
+  AssertFunc([pmVarArgs],ccCdecl,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureForwardInterface;
+begin
+  AddDeclaration('procedure A; forward;');
+  AssertException(EParserError,@ParseProcedure);
+end;
+
+procedure TTestProcedureFunction.TestFunctionForwardInterface;
+begin
+  AddDeclaration('function A : integer; forward;');
+  AssertException(EParserError,@ParseFunction);
+end;
+
+procedure TTestProcedureFunction.TestProcedureForward;
+begin
+  UseImplementation:=True;
+  AddDeclaration('procedure A; forward;');
+  ParseProcedure;
+  AssertProc([pmforward],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionForward;
+begin
+  UseImplementation:=True;
+  AddDeclaration('function A : integer; forward;');
+  ParseFunction;
+  AssertFunc([pmforward],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureCdeclForward;
+begin
+  UseImplementation:=True;
+  AddDeclaration('procedure A; cdecl; forward;');
+  ParseProcedure;
+  AssertProc([pmforward],ccCDecl,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionCDeclForward;
+begin
+  UseImplementation:=True;
+  AddDeclaration('function A : integer; cdecl; forward;');
+  ParseFunction;
+  AssertFunc([pmforward],ccCDecl,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureCompilerProc;
+begin
+  ParseProcedure(';compilerproc;','');
+  AssertProc([pmCompilerProc],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionCompilerProc;
+begin
+  AddDeclaration('function A : Integer; compilerproc');
+  ParseFunction;
+  AssertFunc([pmCompilerProc],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureCDeclCompilerProc;
+begin
+  ParseProcedure(';cdecl;compilerproc;','');
+  AssertProc([pmCompilerProc],ccCDecl,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionCDeclCompilerProc;
+begin
+  AddDeclaration('function A : Integer; cdecl; compilerproc');
+  ParseFunction;
+  AssertFunc([pmCompilerProc],ccCDecl,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureAssembler;
+begin
+  ParseProcedure(';assembler;','');
+  AssertProc([pmAssembler],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionAssembler;
+begin
+  AddDeclaration('function A : Integer; assembler');
+  ParseFunction;
+  AssertFunc([pmAssembler],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureCDeclAssembler;
+begin
+  ParseProcedure(';cdecl;assembler;','');
+  AssertProc([pmAssembler],ccCDecl,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionCDeclAssembler;
+begin
+  AddDeclaration('function A : Integer; cdecl; assembler');
+  ParseFunction;
+  AssertFunc([pmAssembler],ccCDecl,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureExport;
+begin
+  ParseProcedure(';export;','');
+  AssertProc([pmExport],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionExport;
+begin
+  AddDeclaration('function A : Integer; export');
+  ParseFunction;
+  AssertFunc([pmExport],ccDefault,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureCDeclExport;
+begin
+  ParseProcedure('cdecl;export;','');
+  AssertProc([pmExport],ccCDecl,0);
+end;
+
+procedure TTestProcedureFunction.TestFunctionCDeclExport;
+begin
+  AddDeclaration('function A : Integer; cdecl; export');
+  ParseFunction;
+  AssertFunc([pmExport],ccCDecl,0);
+end;
+
+procedure TTestProcedureFunction.TestProcedureExternal;
+begin
+  ParseProcedure(';external','');
+  AssertProc([pmExternal],ccDefault,0);
+  AssertNull('No Library name expression',Proc.LibraryExpr);
+end;
+
+procedure TTestProcedureFunction.TestFunctionExternal;
+begin
+  AddDeclaration('function A : Integer; external');
+  ParseFunction;
+  AssertFunc([pmExternal],ccDefault,0);
+  AssertNull('No Library name expression',Func.LibraryExpr);
+end;
+
+procedure TTestProcedureFunction.TestProcedureExternalLibName;
+begin
+  ParseProcedure(';external ''libname''','');
+  AssertProc([pmExternal],ccDefault,0);
+  AssertExpression('Library name expression',Proc.LibraryExpr,pekString,'''libname''');
+end;
+
+procedure TTestProcedureFunction.TestFunctionExternalLibName;
+begin
+  AddDeclaration('function A : Integer; external ''libname''');
+  ParseFunction;
+  AssertFunc([pmExternal],ccDefault,0);
+  AssertExpression('Library name expression',Func.LibraryExpr,pekString,'''libname''');
+end;
+
+procedure TTestProcedureFunction.TestProcedureExternalLibNameName;
+begin
+  ParseProcedure(';external ''libname'' name ''symbolname''','');
+  AssertProc([pmExternal],ccDefault,0);
+  AssertExpression('Library name expression',Proc.LibraryExpr,pekString,'''libname''');
+  AssertExpression('Library symbol expression',Proc.LibrarySymbolName,pekString,'''symbolname''');
+end;
+
+procedure TTestProcedureFunction.TestFunctionExternalLibNameName;
+begin
+  AddDeclaration('function A : Integer; external ''libname'' name ''symbolname''');
+  ParseFunction;
+  AssertFunc([pmExternal],ccDefault,0);
+  AssertExpression('Library name expression',Func.LibraryExpr,pekString,'''libname''');
+  AssertExpression('Library symbol expression',Func.LibrarySymbolName,pekString,'''symbolname''');
+end;
+
+procedure TTestProcedureFunction.TestProcedureExternalName;
+begin
+  ParseProcedure(';external name ''symbolname''','');
+  AssertProc([pmExternal],ccDefault,0);
+  AssertNull('No Library name expression',Proc.LibraryExpr);
+  AssertExpression('Library symbol expression',Proc.LibrarySymbolName,pekString,'''symbolname''');
+end;
+
+procedure TTestProcedureFunction.TestFunctionExternalName;
+begin
+  AddDeclaration('function A : Integer; external name ''symbolname''');
+  ParseFunction;
+  AssertFunc([pmExternal],ccDefault,0);
+  AssertNull('No Library name expression',Func.LibraryExpr);
+  AssertExpression('Library symbol expression',Func.LibrarySymbolName,pekString,'''symbolname''');
+end;
+
+procedure TTestProcedureFunction.TestProcedureCdeclExternal;
+begin
+  ParseProcedure('; cdecl; external','');
+  AssertProc([pmExternal],ccCdecl,0);
+  AssertNull('No Library name expression',Proc.LibraryExpr);
+end;
+
+procedure TTestProcedureFunction.TestFunctionCdeclExternal;
+begin
+  AddDeclaration('function A : Integer; cdecl; external');
+  ParseFunction;
+  AssertFunc([pmExternal],ccCdecl,0);
+  AssertNull('No Library name expression',Func.LibraryExpr);
+end;
+
+procedure TTestProcedureFunction.TestProcedureCdeclExternalLibName;
+begin
+  ParseProcedure('; cdecl; external ''libname''','');
+  AssertProc([pmExternal],ccCdecl,0);
+  AssertExpression('Library name expression',Proc.LibraryExpr,pekString,'''libname''');
+end;
+
+procedure TTestProcedureFunction.TestFunctionCdeclExternalLibName;
+begin
+  AddDeclaration('function A : Integer; cdecl; external ''libname''');
+  ParseFunction;
+  AssertFunc([pmExternal],ccCdecl,0);
+  AssertExpression('Library name expression',Func.LibraryExpr,pekString,'''libname''');
+end;
+
+procedure TTestProcedureFunction.TestProcedureCdeclExternalLibNameName;
+begin
+  ParseProcedure('; cdecl; external ''libname'' name ''symbolname''','');
+  AssertProc([pmExternal],ccCdecl,0);
+  AssertExpression('Library name expression',Proc.LibraryExpr,pekString,'''libname''');
+  AssertExpression('Library symbol expression',Proc.LibrarySymbolName,pekString,'''symbolname''');
+end;
+
+procedure TTestProcedureFunction.TestFunctionCdeclExternalLibNameName;
+begin
+  AddDeclaration('function A : Integer; cdecl; external ''libname'' name ''symbolname''');
+  ParseFunction;
+  AssertFunc([pmExternal],ccCdecl,0);
+  AssertExpression('Library name expression',Func.LibraryExpr,pekString,'''libname''');
+  AssertExpression('Library symbol expression',Func.LibrarySymbolName,pekString,'''symbolname''');
+end;
+
+procedure TTestProcedureFunction.TestProcedureCdeclExternalName;
+begin
+  ParseProcedure('; cdecl; external name ''symbolname''','');
+  AssertProc([pmExternal],ccCdecl,0);
+  AssertNull('No Library name expression',Proc.LibraryExpr);
+  AssertExpression('Library symbol expression',Proc.LibrarySymbolName,pekString,'''symbolname''');
+end;
+
+procedure TTestProcedureFunction.TestFunctionCdeclExternalName;
+begin
+  AddDeclaration('function A : Integer; cdecl; external name ''symbolname''');
+  ParseFunction;
+  AssertFunc([pmExternal],ccCdecl,0);
+  AssertNull('No Library name expression',Func.LibraryExpr);
+  AssertExpression('Library symbol expression',Func.LibrarySymbolName,pekString,'''symbolname''');
+end;
+
+procedure TTestProcedureFunction.SetUp;
+begin
+   Inherited;
+end;
+
+procedure TTestProcedureFunction.TearDown;
+begin
+   Inherited;
+end;
+
+initialization
+
+  RegisterTest(TTestProcedureFunction);
+end.
+

+ 39 - 1
packages/fcl-passrc/tests/tcscanner.pas

@@ -5,7 +5,7 @@ unit tcscanner;
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, typinfo, fpcunit, testutils, testregistry, pscanner, pparser;
+  Classes, SysUtils, typinfo, fpcunit, testregistry, pscanner;
 
 
 type
 type
 
 
@@ -99,6 +99,10 @@ type
     procedure TestBackslash;
     procedure TestBackslash;
     procedure TestDotDot;
     procedure TestDotDot;
     procedure TestAssign;
     procedure TestAssign;
+    procedure TestAssignPlus;
+    procedure TestAssignMinus;
+    procedure TestAssignMul;
+    procedure TestAssignDivision;
     procedure TestNotEqual;
     procedure TestNotEqual;
     procedure TestLessEqualThan;
     procedure TestLessEqualThan;
     procedure TestGreaterEqualThan;
     procedure TestGreaterEqualThan;
@@ -131,6 +135,7 @@ type
     procedure TestFunction;
     procedure TestFunction;
     procedure TestGeneric;
     procedure TestGeneric;
     procedure TestGoto;
     procedure TestGoto;
+    Procedure TestHelper;
     procedure TestIf;
     procedure TestIf;
     procedure TestImplementation;
     procedure TestImplementation;
     procedure TestIn;
     procedure TestIn;
@@ -636,6 +641,34 @@ begin
   TestToken(tkAssign,':=');
   TestToken(tkAssign,':=');
 end;
 end;
 
 
+procedure TTestScanner.TestAssignPlus;
+begin
+  TestTokens([tkPlus,tkEqual],'+=');
+  FScanner.Options:=[po_cassignments];
+  TestToken(tkAssignPlus,'+=');
+end;
+
+procedure TTestScanner.TestAssignMinus;
+begin
+  TestTokens([tkMinus,tkEqual],'-=');
+  FScanner.Options:=[po_cassignments];
+  TestToken(tkAssignMinus,'-=');
+end;
+
+procedure TTestScanner.TestAssignMul;
+begin
+  TestTokens([tkMul,tkEqual],'*=');
+  FScanner.Options:=[po_cassignments];
+  TestToken(tkAssignMul,'*=');
+end;
+
+procedure TTestScanner.TestAssignDivision;
+begin
+  TestTokens([tkDivision,tkEqual],'/=');
+  FScanner.Options:=[po_cassignments];
+  TestToken(tkAssignDivision,'/=');
+end;
+
 
 
 procedure TTestScanner.TestNotEqual;
 procedure TTestScanner.TestNotEqual;
 
 
@@ -860,6 +893,11 @@ begin
   TestToken(tkgoto,'goto');
   TestToken(tkgoto,'goto');
 end;
 end;
 
 
+procedure TTestScanner.TestHelper;
+begin
+  TestToken(tkHelper,'helper');
+end;
+
 
 
 procedure TTestScanner.TestIf;
 procedure TTestScanner.TestIf;
 
 

+ 1402 - 0
packages/fcl-passrc/tests/tcstatements.pas

@@ -0,0 +1,1402 @@
+unit tcstatements;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit, pastree, pscanner, pparser,
+  tcbaseparser, testregistry;
+
+Type
+  { TTestStatementParser }
+
+  TTestStatementParser = Class(TTestParser)
+  private
+    FStatement: TPasImplBlock;
+    FVariables : TStrings;
+  Protected
+    Procedure SetUp; override;
+    Procedure TearDown; override;
+    procedure AddStatements(ASource : Array of string);
+    Procedure DeclareVar(Const AVarType : String; Const AVarName : String = 'A');
+    function TestStatement(ASource : string) : TPasImplElement;
+    function TestStatement(ASource : Array of string) : TPasImplElement;
+    Procedure ExpectParserError(Const Msg : string);
+    Procedure ExpectParserError(Const Msg : string; ASource : Array of string);
+    Function AssertStatement(Msg : String; AClass : TClass;AIndex : Integer = 0) : TPasImplBlock;
+    Property Statement: TPasImplBlock Read FStatement;
+  Published
+    Procedure TestEmpty;
+    Procedure TestEmptyStatement;
+    Procedure TestEmptyStatements;
+    Procedure TestBlock;
+    Procedure TestAssignment;
+    Procedure TestAssignmentAdd;
+    Procedure TestAssignmentMinus;
+    Procedure TestAssignmentMul;
+    Procedure TestAssignmentDivision;
+    Procedure TestCall;
+    Procedure TestCallQualified;
+    Procedure TestCallQualified2;
+    Procedure TestCallNoArgs;
+    Procedure TestCallOneArg;
+    Procedure TestIf;
+    Procedure TestIfBlock;
+    Procedure TestIfAssignment;
+    Procedure TestIfElse;
+    Procedure TestIfElseBlock;
+    Procedure TestIfSemiColonElseError;
+    Procedure TestNestedIf;
+    Procedure TestNestedIfElse;
+    Procedure TestWhile;
+    Procedure TestWhileBlock;
+    Procedure TestWhileNested;
+    Procedure TestRepeat;
+    Procedure TestRepeatBlock;
+    procedure TestRepeatBlockNosemicolon;
+    Procedure TestRepeatNested;
+    Procedure TestFor;
+    Procedure TestForIn;
+    Procedure TestForExpr;
+    Procedure TestForBlock;
+    procedure TestDowntoBlock;
+    Procedure TestForNested;
+    Procedure TestWith;
+    Procedure TestWithMultiple;
+    Procedure TestCaseEmpty;
+    Procedure TestCaseOneInteger;
+    Procedure TestCaseTwoIntegers;
+    Procedure TestCaseRange;
+    Procedure TestCaseRangeSeparate;
+    Procedure TestCase2Cases;
+    Procedure TestCaseBlock;
+    Procedure TestCaseElseBlockEmpty;
+    Procedure TestCaseElseBlockAssignment;
+    Procedure TestCaseElseBlock2Assignments;
+    Procedure TestCaseIfCaseElse;
+    Procedure TestCaseIfElse;
+    Procedure TestRaise;
+    Procedure TestRaiseEmpty;
+    Procedure TestRaiseAt;
+    Procedure TestTryFinally;
+    Procedure TestTryFinallyEmpty;
+    Procedure TestTryFinallyNested;
+    procedure TestTryExcept;
+    procedure TestTryExceptNested;
+    procedure TestTryExceptEmpty;
+    Procedure TestTryExceptOn;
+    Procedure TestTryExceptOn2;
+    Procedure TestTryExceptOnElse;
+    Procedure TestTryExceptOnIfElse;
+  end;
+
+implementation
+
+{ TTestStatementParser }
+
+procedure TTestStatementParser.SetUp;
+begin
+  inherited SetUp;
+  FVariables:=TStringList.Create;
+end;
+
+procedure TTestStatementParser.TearDown;
+begin
+  FreeAndNil(FVariables);
+  inherited TearDown;
+end;
+
+procedure TTestStatementParser.AddStatements(ASource: array of string);
+
+Var
+  I :Integer;
+begin
+  StartProgram('afile');
+  if FVariables.Count>0 then
+    begin
+    Add('Var');
+    For I:=0 to FVariables.Count-1 do
+      Add('  '+Fvariables[I]);
+    end;
+  Add('begin');
+  For I:=Low(ASource) to High(ASource) do
+    Add('  '+ASource[i]);
+end;
+
+procedure TTestStatementParser.DeclareVar(const AVarType: String;
+  const AVarName: String);
+begin
+  FVariables.Add(AVarName+' : '+AVarType+';');
+end;
+
+function TTestStatementParser.TestStatement(ASource: string): TPasImplElement;
+begin
+  Result:=TestStatement([ASource]);
+end;
+
+function TTestStatementParser.TestStatement(ASource: array of string): TPasImplElement;
+
+
+begin
+  Result:=Nil;
+  FStatement:=Nil;
+  AddStatements(ASource);
+  ParseModule;
+  AssertEquals('Have program',TPasProgram,Module.ClassType);
+  AssertNotNull('Have program section',PasProgram.ProgramSection);
+  AssertNotNull('Have initialization section',PasProgram.InitializationSection);
+  if (PasProgram.InitializationSection.Elements.Count>0) then
+    if TObject(PasProgram.InitializationSection.Elements[0]) is TPasImplBlock then
+      FStatement:=TPasImplBlock(PasProgram.InitializationSection.Elements[0]);
+  Result:=FStatement;
+end;
+
+procedure TTestStatementParser.ExpectParserError(Const Msg : string);
+begin
+  AssertException(Msg,EParserError,@ParseModule);
+end;
+
+procedure TTestStatementParser.ExpectParserError(const Msg: string;
+  ASource: array of string);
+begin
+  AddStatements(ASource);
+  ExpectParserError(Msg);
+end;
+
+function TTestStatementParser.AssertStatement(Msg: String; AClass: TClass;
+  AIndex: Integer): TPasImplBlock;
+begin
+  if not (AIndex<PasProgram.InitializationSection.Elements.Count) then
+    Fail(Msg+': No such statement : '+intTostr(AIndex));
+  AssertNotNull(Msg+' Have statement',PasProgram.InitializationSection.Elements[AIndex]);
+  AssertEquals(Msg+' statement class',AClass,TObject(PasProgram.InitializationSection.Elements[AIndex]).ClassType);
+  Result:=TObject(PasProgram.InitializationSection.Elements[AIndex]) as TPasImplBlock;
+end;
+
+procedure TTestStatementParser.TestEmpty;
+begin
+  //TestStatement(';');
+  TestStatement('');
+  AssertEquals('No statements',0,PasProgram.InitializationSection.Elements.Count);
+end;
+
+procedure TTestStatementParser.TestEmptyStatement;
+begin
+  TestStatement(';');
+  AssertEquals('0 statement',0,PasProgram.InitializationSection.Elements.Count);
+end;
+
+procedure TTestStatementParser.TestEmptyStatements;
+begin
+  TestStatement(';;');
+  AssertEquals('0 statement',0,PasProgram.InitializationSection.Elements.Count);
+end;
+
+procedure TTestStatementParser.TestBlock;
+
+Var
+  B : TPasImplBeginBlock;
+
+begin
+  TestStatement(['begin','end']);
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertNotNull('Statement assigned',PasProgram.InitializationSection.Elements[0]);
+  AssertEquals('Block statement',TPasImplBeginBlock,Statement.ClassType);
+  B:= Statement as TPasImplBeginBlock;
+  AssertEquals('Empty block',0,B.Elements.Count);
+end;
+
+procedure TTestStatementParser.TestAssignment;
+
+Var
+  A : TPasImplAssign;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['a:=1;']);
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertEquals('Assignment statement',TPasImplAssign,Statement.ClassType);
+  A:=Statement as TPasImplAssign;
+  AssertEquals('Normal assignment',akDefault,A.Kind);
+  AssertExpression('Right side is constant',A.Right,pekNumber,'1');
+  AssertExpression('Left side is variable',A.Left,pekIdent,'a');
+end;
+
+procedure TTestStatementParser.TestAssignmentAdd;
+
+Var
+  A : TPasImplAssign;
+
+begin
+  Parser.Scanner.Options:=[po_cassignments];
+  DeclareVar('integer');
+  TestStatement(['a+=1;']);
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertEquals('Assignment statement',TPasImplAssign,Statement.ClassType);
+  A:=Statement as TPasImplAssign;
+  AssertEquals('Add assignment',akAdd,A.Kind);
+  AssertExpression('Right side is constant',A.Right,pekNumber,'1');
+  AssertExpression('Left side is variable',A.Left,pekIdent,'a');
+end;
+
+procedure TTestStatementParser.TestAssignmentMinus;
+Var
+  A : TPasImplAssign;
+
+begin
+  Parser.Scanner.Options:=[po_cassignments];
+  DeclareVar('integer');
+  TestStatement(['a-=1;']);
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertEquals('Assignment statement',TPasImplAssign,Statement.ClassType);
+  A:=Statement as TPasImplAssign;
+  AssertEquals('Minus assignment',akMinus,A.Kind);
+  AssertExpression('Right side is constant',A.Right,pekNumber,'1');
+  AssertExpression('Left side is variable',A.Left,pekIdent,'a');
+end;
+
+procedure TTestStatementParser.TestAssignmentMul;
+Var
+  A : TPasImplAssign;
+
+begin
+  Parser.Scanner.Options:=[po_cassignments];
+  DeclareVar('integer');
+  TestStatement(['a*=1;']);
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertEquals('Assignment statement',TPasImplAssign,Statement.ClassType);
+  A:=Statement as TPasImplAssign;
+  AssertEquals('Mul assignment',akMul,A.Kind);
+  AssertExpression('Right side is constant',A.Right,pekNumber,'1');
+  AssertExpression('Left side is variable',A.Left,pekIdent,'a');
+end;
+
+procedure TTestStatementParser.TestAssignmentDivision;
+Var
+  A : TPasImplAssign;
+
+begin
+  Parser.Scanner.Options:=[po_cassignments];
+  DeclareVar('integer');
+  TestStatement(['a/=1;']);
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertEquals('Assignment statement',TPasImplAssign,Statement.ClassType);
+  A:=Statement as TPasImplAssign;
+  AssertEquals('Division assignment',akDivision,A.Kind);
+  AssertExpression('Right side is constant',A.Right,pekNumber,'1');
+  AssertExpression('Left side is variable',A.Left,pekIdent,'a');
+end;
+
+procedure TTestStatementParser.TestCall;
+
+Var
+  S : TPasImplSimple;
+
+begin
+  TestStatement('Doit;');
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
+  S:=Statement as TPasImplSimple;
+  AssertExpression('Doit call',S.Expr,pekIdent,'Doit');
+end;
+
+procedure TTestStatementParser.TestCallQualified;
+
+Var
+  S : TPasImplSimple;
+  B : TBinaryExpr;
+
+begin
+  TestStatement('Unita.Doit;');
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
+  S:=Statement as TPasImplSimple;
+  AssertExpression('Doit call',S.Expr,pekBinary,TBinaryExpr);
+  B:=S.Expr as TBinaryExpr;
+  AssertExpression('Unit name',B.Left,pekIdent,'Unita');
+  AssertExpression('Doit call',B.Right,pekIdent,'Doit');
+
+end;
+
+procedure TTestStatementParser.TestCallQualified2;
+Var
+  S : TPasImplSimple;
+  B : TBinaryExpr;
+
+begin
+  TestStatement('Unita.ClassB.Doit;');
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
+  S:=Statement as TPasImplSimple;
+  AssertExpression('Doit call',S.Expr,pekBinary,TBinaryExpr);
+  B:=S.Expr as TBinaryExpr;
+  AssertExpression('Unit name',B.Left,pekIdent,'Unita');
+  AssertExpression('Doit call',B.Right,pekBinary,TBinaryExpr);
+  B:=B.Right  as TBinaryExpr;
+  AssertExpression('Unit name',B.Left,pekIdent,'ClassB');
+  AssertExpression('Doit call',B.Right,pekIdent,'Doit');
+end;
+
+procedure TTestStatementParser.TestCallNoArgs;
+
+Var
+  S : TPasImplSimple;
+  P : TParamsExpr;
+
+begin
+  TestStatement('Doit();');
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
+  S:=Statement as TPasImplSimple;
+  AssertExpression('Doit call',S.Expr,pekFuncParams,TParamsExpr);
+  P:=S.Expr as TParamsExpr;
+  AssertExpression('Correct function call name',P.Value,pekIdent,'Doit');
+  AssertEquals('No params',0,Length(P.Params));
+end;
+
+procedure TTestStatementParser.TestCallOneArg;
+Var
+  S : TPasImplSimple;
+  P : TParamsExpr;
+
+begin
+  TestStatement('Doit(1);');
+  AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,Statement.ClassType);
+  S:=Statement as TPasImplSimple;
+  AssertExpression('Doit call',S.Expr,pekFuncParams,TParamsExpr);
+  P:=S.Expr as TParamsExpr;
+  AssertExpression('Correct function call name',P.Value,pekIdent,'Doit');
+  AssertEquals('One param',1,Length(P.Params));
+  AssertExpression('Parameter is constant',P.Params[0],pekNumber,'1');
+end;
+
+procedure TTestStatementParser.TestIf;
+
+Var
+  I : TPasImplIfElse;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['if a then',';']);
+  I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
+  AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
+  AssertNull('No else',i.ElseBranch);
+  AssertNull('No if branch',I.IfBranch);
+end;
+
+procedure TTestStatementParser.TestIfBlock;
+
+Var
+  I : TPasImplIfElse;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['if a then','  begin','  end']);
+  I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
+  AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
+  AssertNull('No else',i.ElseBranch);
+  AssertNotNull('if branch',I.IfBranch);
+  AssertEquals('begin end block',TPasImplBeginBlock,I.ifBranch.ClassType);
+end;
+
+procedure TTestStatementParser.TestIfAssignment;
+
+Var
+  I : TPasImplIfElse;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['if a then','  a:=False;']);
+  I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
+  AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
+  AssertNull('No else',i.ElseBranch);
+  AssertNotNull('if branch',I.IfBranch);
+  AssertEquals('assignment statement',TPasImplAssign,I.ifBranch.ClassType);
+end;
+
+procedure TTestStatementParser.TestIfElse;
+
+Var
+  I : TPasImplIfElse;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['if a then','  begin','  end','else',';']);
+  I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
+  AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
+  AssertNull('No else',i.ElseBranch);
+  AssertNotNull('if branch',I.IfBranch);
+  AssertEquals('begin end block',TPasImplBeginBlock,I.ifBranch.ClassType);
+end;
+
+procedure TTestStatementParser.TestIfElseBlock;
+Var
+  I : TPasImplIfElse;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['if a then','  begin','  end','else','  begin','  end']);
+  I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
+  AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
+  AssertNotNull('if branch',I.IfBranch);
+  AssertEquals('begin end block',TPasImplBeginBlock,I.ifBranch.ClassType);
+  AssertNotNull('Else branch',i.ElseBranch);
+  AssertEquals('begin end block',TPasImplBeginBlock,I.ElseBranch.ClassType);
+end;
+
+procedure TTestStatementParser.TestIfSemiColonElseError;
+
+begin
+  DeclareVar('boolean');
+  ExpectParserError('No semicolon before else',['if a then','  begin','  end;','else','  begin','  end']);
+end;
+
+procedure TTestStatementParser.TestNestedIf;
+Var
+  I : TPasImplIfElse;
+begin
+  DeclareVar('boolean');
+  DeclareVar('boolean','b');
+  TestStatement(['if a then','  if b then','    begin','    end','else','  begin','  end']);
+  I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
+  AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
+  AssertNotNull('if branch',I.IfBranch);
+  AssertNull('Else branch',i.ElseBranch);
+  AssertEquals('if in if branch',TPasImplIfElse,I.ifBranch.ClassType);
+  I:=I.Ifbranch as TPasImplIfElse;
+  AssertEquals('begin end block',TPasImplBeginBlock,I.ElseBranch.ClassType);
+
+end;
+
+procedure TTestStatementParser.TestNestedIfElse;
+
+Var
+  I : TPasImplIfElse;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['if a then','  if b then','    begin','    end','  else','    begin','    end','else','  begin','end']);
+  I:=AssertStatement('If statement',TPasImplIfElse) as TPasImplIfElse;
+  AssertExpression('IF condition',I.ConditionExpr,pekIdent,'a');
+  AssertNotNull('if branch',I.IfBranch);
+  AssertNotNull('Else branch',i.ElseBranch);
+  AssertEquals('begin end block',TPasImplBeginBlock,I.ElseBranch.ClassType);
+  AssertEquals('if in if branch',TPasImplIfElse,I.ifBranch.ClassType);
+  I:=I.Ifbranch as TPasImplIfElse;
+  AssertEquals('begin end block',TPasImplBeginBlock,I.ElseBranch.ClassType);
+end;
+
+procedure TTestStatementParser.TestWhile;
+
+Var
+  W : TPasImplWhileDo;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['While a do ;']);
+  W:=AssertStatement('While statement',TPasImplWhileDo) as TPasImplWhileDo;
+  AssertExpression('While condition',W.ConditionExpr,pekIdent,'a');
+  AssertNull('Empty body',W.Body);
+end;
+
+procedure TTestStatementParser.TestWhileBlock;
+Var
+  W : TPasImplWhileDo;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['While a do','  begin','  end']);
+  W:=AssertStatement('While statement',TPasImplWhileDo) as TPasImplWhileDo;
+  AssertExpression('While condition',W.ConditionExpr,pekIdent,'a');
+  AssertNotNull('Have while body',W.Body);
+  AssertEquals('begin end block',TPasImplBeginBlock,W.Body.ClassType);
+  AssertEquals('Empty block',0,TPasImplBeginBlock(W.Body).ELements.Count);
+end;
+
+procedure TTestStatementParser.TestWhileNested;
+
+Var
+  W : TPasImplWhileDo;
+
+begin
+  DeclareVar('boolean');
+  DeclareVar('boolean','b');
+  TestStatement(['While a do','  while b do','    begin','    end']);
+  W:=AssertStatement('While statement',TPasImplWhileDo) as TPasImplWhileDo;
+  AssertExpression('While condition',W.ConditionExpr,pekIdent,'a');
+  AssertNotNull('Have while body',W.Body);
+  AssertEquals('Nested while',TPasImplWhileDo,W.Body.ClassType);
+  W:=W.Body as TPasImplWhileDo;
+  AssertExpression('While condition',W.ConditionExpr,pekIdent,'b');
+  AssertNotNull('Have nested while body',W.Body);
+  AssertEquals('Nested begin end block',TPasImplBeginBlock,W.Body.ClassType);
+  AssertEquals('Empty nested block',0,TPasImplBeginBlock(W.Body).ELements.Count);
+end;
+
+procedure TTestStatementParser.TestRepeat;
+
+Var
+  R : TPasImplRepeatUntil;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['Repeat','Until a;']);
+  R:=AssertStatement('Repeat statement',TPasImplRepeatUntil) as TPasImplRepeatUntil;
+  AssertExpression('repeat condition',R.ConditionExpr,pekIdent,'a');
+  AssertEquals('Empty body',0,R.Elements.Count);
+end;
+
+procedure TTestStatementParser.TestRepeatBlock;
+
+Var
+  R : TPasImplRepeatUntil;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['Repeat','begin','end;','Until a;']);
+  R:=AssertStatement('repeat statement',TPasImplRepeatUntil) as TPasImplRepeatUntil;
+  AssertExpression('repeat condition',R.ConditionExpr,pekIdent,'a');
+  AssertEquals('Have statement',1,R.Elements.Count);
+  AssertEquals('begin end block',TPasImplBeginBlock,TObject(R.Elements[0]).ClassType);
+  AssertEquals('Empty block',0,TPasImplBeginBlock(R.Elements[0]).ELements.Count);
+end;
+
+procedure TTestStatementParser.TestRepeatBlockNosemicolon;
+
+Var
+  R : TPasImplRepeatUntil;
+
+begin
+  DeclareVar('boolean');
+  TestStatement(['Repeat','begin','end','Until a;']);
+  R:=AssertStatement('repeat statement',TPasImplRepeatUntil) as TPasImplRepeatUntil;
+  AssertExpression('repeat condition',R.ConditionExpr,pekIdent,'a');
+  AssertEquals('Have statement',1,R.Elements.Count);
+  AssertEquals('begin end block',TPasImplBeginBlock,TObject(R.Elements[0]).ClassType);
+  AssertEquals('Empty block',0,TPasImplBeginBlock(R.Elements[0]).ELements.Count);
+end;
+
+procedure TTestStatementParser.TestRepeatNested;
+
+Var
+  R : TPasImplRepeatUntil;
+
+begin
+  DeclareVar('boolean');
+  DeclareVar('boolean','b');
+  TestStatement(['Repeat','repeat','begin','end','until b','Until a;']);
+  R:=AssertStatement('repeat statement',TPasImplRepeatUntil) as TPasImplRepeatUntil;
+  AssertExpression('repeat condition',R.ConditionExpr,pekIdent,'a');
+  AssertEquals('Have statement',1,R.Elements.Count);
+  AssertEquals('Nested repeat',TPasImplRepeatUntil,TObject(R.Elements[0]).ClassType);
+  R:=TPasImplRepeatUntil(R.Elements[0]);
+  AssertExpression('repeat condition',R.ConditionExpr,pekIdent,'b');
+  AssertEquals('Have statement',1,R.Elements.Count);
+  AssertEquals('begin end block',TPasImplBeginBlock,TObject(R.Elements[0]).ClassType);
+  AssertEquals('Empty block',0,TPasImplBeginBlock(R.Elements[0]).ELements.Count);
+end;
+
+procedure TTestStatementParser.TestFor;
+
+Var
+  F : TPasImplForLoop;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['For a:=1 to 10 do',';']);
+  F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
+  AssertEquals('Loop variable name','a',F.VariableName);
+  AssertEquals('Loop type',ltNormal,F.Looptype);
+  AssertEquals('Up loop',False,F.Down);
+  AssertExpression('Start value',F.StartExpr,pekNumber,'1');
+  AssertExpression('End value',F.EndExpr,pekNumber,'10');
+  AssertNull('Empty body',F.Body);
+end;
+
+procedure TTestStatementParser.TestForIn;
+
+Var
+  F : TPasImplForLoop;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['For a in SomeSet Do',';']);
+  F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
+  AssertEquals('Loop variable name','a',F.VariableName);
+  AssertEquals('Loop type',ltIn,F.Looptype);
+  AssertEquals('In loop',False,F.Down);
+  AssertExpression('Start value',F.StartExpr,pekIdent,'SomeSet');
+  AssertNull('Loop type',F.EndExpr);
+  AssertNull('Empty body',F.Body);
+end;
+
+procedure TTestStatementParser.TestForExpr;
+Var
+  F : TPasImplForLoop;
+  B : TBinaryExpr;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['For a:=1+1 to 5+5 do',';']);
+  F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
+  AssertEquals('Loop variable name','a',F.VariableName);
+  AssertEquals('Up loop',False,F.Down);
+  AssertExpression('Start expression',F.StartExpr,pekBinary,TBinaryExpr);
+  B:=F.StartExpr as TBinaryExpr;
+  AssertExpression('Start value left',B.left,pekNumber,'1');
+  AssertExpression('Start value right',B.right,pekNumber,'1');
+  AssertExpression('Start expression',F.StartExpr,pekBinary,TBinaryExpr);
+  B:=F.EndExpr as TBinaryExpr;
+  AssertExpression('End value left',B.left,pekNumber,'5');
+  AssertExpression('End value right',B.right,pekNumber,'5');
+  AssertNull('Empty body',F.Body);
+end;
+
+procedure TTestStatementParser.TestForBlock;
+
+Var
+  F : TPasImplForLoop;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['For a:=1 to 10 do','begin','end']);
+  F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
+  AssertEquals('Loop variable name','a',F.VariableName);
+  AssertEquals('Up loop',False,F.Down);
+  AssertExpression('Start value',F.StartExpr,pekNumber,'1');
+  AssertExpression('End value',F.EndExpr,pekNumber,'10');
+  AssertNotNull('Have for body',F.Body);
+  AssertEquals('begin end block',TPasImplBeginBlock,F.Body.ClassType);
+  AssertEquals('Empty block',0,TPasImplBeginBlock(F.Body).ELements.Count);
+end;
+
+procedure TTestStatementParser.TestDowntoBlock;
+
+Var
+  F : TPasImplForLoop;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['For a:=10 downto 1 do','begin','end']);
+  F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
+  AssertEquals('Loop variable name','a',F.VariableName);
+  AssertEquals('Down loop',True,F.Down);
+  AssertExpression('Start value',F.StartExpr,pekNumber,'10');
+  AssertExpression('End value',F.EndExpr,pekNumber,'1');
+  AssertNotNull('Have for body',F.Body);
+  AssertEquals('begin end block',TPasImplBeginBlock,F.Body.ClassType);
+  AssertEquals('Empty block',0,TPasImplBeginBlock(F.Body).ELements.Count);
+end;
+
+procedure TTestStatementParser.TestForNested;
+Var
+  F : TPasImplForLoop;
+
+begin
+  DeclareVar('integer');
+  DeclareVar('integer','b');
+  TestStatement(['For a:=1 to 10 do','For b:=11 to 20 do','begin','end']);
+  F:=AssertStatement('For statement',TPasImplForLoop) as TPasImplForLoop;
+  AssertEquals('Loop variable name','a',F.VariableName);
+  AssertEquals('Up loop',False,F.Down);
+  AssertExpression('Start value',F.StartExpr,pekNumber,'1');
+  AssertExpression('End value',F.EndExpr,pekNumber,'10');
+  AssertNotNull('Have while body',F.Body);
+  AssertEquals('begin end block',TPasImplForLoop,F.Body.ClassType);
+  F:=F.Body as TPasImplForLoop;
+  AssertEquals('Loop variable name','b',F.VariableName);
+  AssertEquals('Up loop',False,F.Down);
+  AssertExpression('Start value',F.StartExpr,pekNumber,'11');
+  AssertExpression('End value',F.EndExpr,pekNumber,'20');
+  AssertNotNull('Have for body',F.Body);
+  AssertEquals('begin end block',TPasImplBeginBlock,F.Body.ClassType);
+  AssertEquals('Empty block',0,TPasImplBeginBlock(F.Body).ELements.Count);
+end;
+
+procedure TTestStatementParser.TestWith;
+
+Var
+  W : TpasImplWithDo;
+
+begin
+  DeclareVar('record X,Y : Integer; end');
+  TestStatement(['With a do','begin','end']);
+  W:=AssertStatement('For statement',TpasImplWithDo) as TpasImplWithDo;
+  AssertEquals('1 expression',1,W.Expressions.Count);
+  AssertExpression('With identifier',TPasExpr(W.Expressions[0]),pekIdent,'a');
+  AssertNotNull('Have with body',W.Body);
+  AssertEquals('begin end block',TPasImplBeginBlock,W.Body.ClassType);
+  AssertEquals('Empty block',0,TPasImplBeginBlock(W.Body).ELements.Count);
+end;
+
+procedure TTestStatementParser.TestWithMultiple;
+Var
+  W : TpasImplWithDo;
+
+begin
+  DeclareVar('record X,Y : Integer; end');
+  DeclareVar('record W,Z : Integer; end','b');
+  TestStatement(['With a,b do','begin','end']);
+  W:=AssertStatement('For statement',TpasImplWithDo) as TpasImplWithDo;
+  AssertEquals('2 expressions',2,W.Expressions.Count);
+  AssertExpression('With identifier 1',TPasExpr(W.Expressions[0]),pekIdent,'a');
+  AssertExpression('With identifier 2',TPasExpr(W.Expressions[1]),pekIdent,'b');
+  AssertNotNull('Have with body',W.Body);
+  AssertEquals('begin end block',TPasImplBeginBlock,W.Body.ClassType);
+  AssertEquals('Empty block',0,TPasImplBeginBlock(W.Body).ELements.Count);
+end;
+
+procedure TTestStatementParser.TestCaseEmpty;
+begin
+  DeclareVar('integer');
+  AddStatements(['case a of','end;']);
+  ExpectParserError('Empty case not allowed');
+end;
+
+procedure TTestStatementParser.TestCaseOneInteger;
+
+Var
+  C : TPasImplCaseOf;
+  S : TPasImplCaseStatement;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['case a of','1 : ;','end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertNull('No else branch',C.ElseBranch);
+  AssertEquals('One case label',1,C.Elements.Count);
+  AssertEquals('Correct case for case label',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
+  S:=TPasImplCaseStatement(C.Elements[0]);
+  AssertEquals('1 expression for case',1,S.Expressions.Count);
+  AssertExpression('With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
+  AssertEquals('Empty case label statement',0,S.Elements.Count);
+  AssertNull('Empty case label statement',S.Body);
+end;
+
+procedure TTestStatementParser.TestCaseTwoIntegers;
+
+Var
+  C : TPasImplCaseOf;
+  S : TPasImplCaseStatement;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['case a of','1,2 : ;','end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertNull('No else branch',C.ElseBranch);
+  AssertEquals('One case label',1,C.Elements.Count);
+  AssertEquals('Correct case for case label',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
+  S:=TPasImplCaseStatement(C.Elements[0]);
+  AssertEquals('2 expressions for case',2,S.Expressions.Count);
+  AssertExpression('With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
+  AssertExpression('With identifier 2',TPasExpr(S.Expressions[1]),pekNumber,'2');
+  AssertEquals('Empty case label statement',0,S.Elements.Count);
+  AssertNull('Empty case label statement',S.Body);
+end;
+
+procedure TTestStatementParser.TestCaseRange;
+Var
+  C : TPasImplCaseOf;
+  S : TPasImplCaseStatement;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['case a of','1..3 : ;','end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertNull('No else branch',C.ElseBranch);
+  AssertEquals('One case label',1,C.Elements.Count);
+  AssertEquals('Correct case for case label',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
+  S:=TPasImplCaseStatement(C.Elements[0]);
+  AssertEquals('1 expression for case',1,S.Expressions.Count);
+  AssertExpression('With identifier 1',TPasExpr(S.Expressions[0]),pekRange,TBinaryExpr);
+  AssertEquals('Empty case label statement',0,S.Elements.Count);
+  AssertNull('Empty case label statement',S.Body);
+end;
+
+procedure TTestStatementParser.TestCaseRangeSeparate;
+Var
+  C : TPasImplCaseOf;
+  S : TPasImplCaseStatement;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['case a of','1..3,5 : ;','end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertNull('No else branch',C.ElseBranch);
+  AssertEquals('One case label',1,C.Elements.Count);
+  AssertEquals('Correct case for case label',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
+  S:=TPasImplCaseStatement(C.Elements[0]);
+  AssertEquals('2 expressions for case',2,S.Expressions.Count);
+  AssertExpression('With identifier 1',TPasExpr(S.Expressions[0]),pekRange,TBinaryExpr);
+  AssertExpression('With identifier 2',TPasExpr(S.Expressions[1]),pekNumber,'5');
+  AssertEquals('Empty case label statement',0,S.Elements.Count);
+  AssertNull('Empty case label statement',S.Body);
+end;
+
+procedure TTestStatementParser.TestCase2Cases;
+Var
+  C : TPasImplCaseOf;
+  S : TPasImplCaseStatement;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['case a of','1 : ;','2 : ;','end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertNull('No else branch',C.ElseBranch);
+  AssertEquals('Two case labels',2,C.Elements.Count);
+  AssertEquals('Correct case for case label 1',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
+  S:=TPasImplCaseStatement(C.Elements[0]);
+  AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
+  AssertExpression('Case 1 With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
+  AssertEquals('Empty case label statement 1',0,S.Elements.Count);
+  AssertNull('Empty case label statement 1',S.Body);
+  // Two
+  AssertEquals('Correct case for case label 2',TPasImplCaseStatement,TPasElement(C.Elements[1]).ClassType);
+  S:=TPasImplCaseStatement(C.Elements[1]);
+  AssertEquals('2 expressions for case 2',1,S.Expressions.Count);
+  AssertExpression('Case 2 With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'2');
+  AssertEquals('Empty case label statement 2',0,S.Elements.Count);
+  AssertNull('Empty case label statement 2',S.Body);
+end;
+
+procedure TTestStatementParser.TestCaseBlock;
+
+Var
+  C : TPasImplCaseOf;
+  S : TPasImplCaseStatement;
+  B : TPasImplbeginBlock;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['case a of','1 : begin end;','end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertNull('No else branch',C.ElseBranch);
+  AssertEquals('Two case labels',1,C.Elements.Count);
+  AssertEquals('Correct case for case label 1',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
+  S:=TPasImplCaseStatement(C.Elements[0]);
+  AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
+  AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
+  AssertEquals('1 case label statement',1,S.Elements.Count);
+  AssertEquals('Correct case for case label 1',TPasImplbeginBlock,TPasElement(S.Elements[0]).ClassType);
+  B:=TPasImplbeginBlock(S.Elements[0]);
+  AssertEquals('0 statements in block',0,B.Elements.Count);
+
+end;
+
+procedure TTestStatementParser.TestCaseElseBlockEmpty;
+
+Var
+  C : TPasImplCaseOf;
+  S : TPasImplCaseStatement;
+  B : TPasImplbeginBlock;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['case a of','1 : begin end;','else',' end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertEquals('Two case labels',2,C.Elements.Count);
+  AssertEquals('Correct case for case label 1',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
+  S:=TPasImplCaseStatement(C.Elements[0]);
+  AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
+  AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
+  AssertEquals('1 case label statement',1,S.Elements.Count);
+  AssertEquals('Correct case for case label 1',TPasImplbeginBlock,TPasElement(S.Elements[0]).ClassType);
+  B:=TPasImplbeginBlock(S.Elements[0]);
+  AssertEquals('0 statements in block',0,B.Elements.Count);
+  AssertNotNull('Have else branch',C.ElseBranch);
+  AssertEquals('Correct else branch class',TPasImplCaseElse,C.ElseBranch.ClassType);
+  AssertEquals('Zero statements ',0,TPasImplCaseElse(C.ElseBranch).Elements.Count);
+end;
+
+procedure TTestStatementParser.TestCaseElseBlockAssignment;
+Var
+  C : TPasImplCaseOf;
+  S : TPasImplCaseStatement;
+  B : TPasImplbeginBlock;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['case a of','1 : begin end;','else','a:=1',' end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertEquals('Two case labels',2,C.Elements.Count);
+  AssertEquals('Correct case for case label 1',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
+  S:=TPasImplCaseStatement(C.Elements[0]);
+  AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
+  AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
+  AssertEquals('1 case label statement',1,S.Elements.Count);
+  AssertEquals('Correct case for case label 1',TPasImplbeginBlock,TPasElement(S.Elements[0]).ClassType);
+  B:=TPasImplbeginBlock(S.Elements[0]);
+  AssertEquals('0 statements in block',0,B.Elements.Count);
+  AssertNotNull('Have else branch',C.ElseBranch);
+  AssertEquals('Correct else branch class',TPasImplCaseElse,C.ElseBranch.ClassType);
+  AssertEquals('1 statement in else branch ',1,TPasImplCaseElse(C.ElseBranch).Elements.Count);
+end;
+
+procedure TTestStatementParser.TestCaseElseBlock2Assignments;
+
+Var
+  C : TPasImplCaseOf;
+  S : TPasImplCaseStatement;
+  B : TPasImplbeginBlock;
+
+begin
+  DeclareVar('integer');
+  TestStatement(['case a of','1 : begin end;','else','a:=1;','a:=32;',' end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertEquals('Two case labels',2,C.Elements.Count);
+  AssertEquals('Correct case for case label 1',TPasImplCaseStatement,TPasElement(C.Elements[0]).ClassType);
+  S:=TPasImplCaseStatement(C.Elements[0]);
+  AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
+  AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
+  AssertEquals('1 case label statement',1,S.Elements.Count);
+  AssertEquals('Correct case for case label 1',TPasImplbeginBlock,TPasElement(S.Elements[0]).ClassType);
+  B:=TPasImplbeginBlock(S.Elements[0]);
+  AssertEquals('0 statements in block',0,B.Elements.Count);
+  AssertNotNull('Have else branch',C.ElseBranch);
+  AssertEquals('Correct else branch class',TPasImplCaseElse,C.ElseBranch.ClassType);
+  AssertEquals('2 statements in else branch ',2,TPasImplCaseElse(C.ElseBranch).Elements.Count);
+end;
+
+procedure TTestStatementParser.TestCaseIfCaseElse;
+
+Var
+  C : TPasImplCaseOf;
+
+begin
+  DeclareVar('integer');
+  DeclareVar('boolean','b');
+  TestStatement(['case a of','1 : if b then',' begin end;','else',' end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertEquals('Two case labels',2,C.Elements.Count);
+  AssertNotNull('Have else branch',C.ElseBranch);
+  AssertEquals('Correct else branch class',TPasImplCaseElse,C.ElseBranch.ClassType);
+  AssertEquals('0 statement in else branch ',0,TPasImplCaseElse(C.ElseBranch).Elements.Count);
+end;
+
+procedure TTestStatementParser.TestCaseIfElse;
+Var
+  C : TPasImplCaseOf;
+  S : TPasImplCaseStatement;
+
+begin
+  DeclareVar('integer');
+  DeclareVar('boolean','b');
+  TestStatement(['case a of','1 : if b then',' begin end','else','begin','end',' end;']);
+  C:=AssertStatement('Case statement',TpasImplCaseOf) as TpasImplCaseOf;
+  AssertNotNull('Have case expression',C.CaseExpr);
+  AssertExpression('Case expression',C.CaseExpr,pekIdent,'a');
+  AssertEquals('Two case labels',1,C.Elements.Count);
+  AssertNull('Have no else branch',C.ElseBranch);
+  S:=TPasImplCaseStatement(C.Elements[0]);
+  AssertEquals('2 expressions for case 1',1,S.Expressions.Count);
+  AssertExpression('Case With identifier 1',TPasExpr(S.Expressions[0]),pekNumber,'1');
+  AssertEquals('1 case label statement',1,S.Elements.Count);
+  AssertEquals('If statement in case label 1',TPasImplIfElse,TPasElement(S.Elements[0]).ClassType);
+  AssertNotNull('If statement has else block',TPasImplIfElse(S.Elements[0]).ElseBranch);
+end;
+
+procedure TTestStatementParser.TestRaise;
+
+Var
+  R : TPasImplRaise;
+
+begin
+  DeclareVar('Exception');
+  TestStatement('Raise A;');
+  R:=AssertStatement('Raise statement',TPasImplRaise) as TPasImplRaise;
+  AssertEquals(0,R.Elements.Count);
+  AssertNotNull(R.ExceptObject);
+  AssertNull(R.ExceptAddr);
+  AssertExpression('Expression object',R.ExceptObject,pekIdent,'A');
+end;
+
+procedure TTestStatementParser.TestRaiseEmpty;
+Var
+  R : TPasImplRaise;
+
+begin
+  TestStatement('Raise;');
+  R:=AssertStatement('Raise statement',TPasImplRaise) as TPasImplRaise;
+  AssertEquals(0,R.Elements.Count);
+  AssertNull(R.ExceptObject);
+  AssertNull(R.ExceptAddr);
+end;
+
+procedure TTestStatementParser.TestRaiseAt;
+
+Var
+  R : TPasImplRaise;
+
+begin
+  DeclareVar('Exception');
+  DeclareVar('Pointer','B');
+  TestStatement('Raise A at B;');
+  R:=AssertStatement('Raise statement',TPasImplRaise) as TPasImplRaise;
+  AssertEquals(0,R.Elements.Count);
+  AssertNotNull(R.ExceptObject);
+  AssertNotNull(R.ExceptAddr);
+  AssertExpression('Expression object',R.ExceptAddr,pekIdent,'B');
+end;
+
+procedure TTestStatementParser.TestTryFinally;
+
+Var
+  T : TPasImplTry;
+  S : TPasImplSimple;
+  F : TPasImplTryFinally;
+
+begin
+  TestStatement(['Try','  DoSomething;','finally','  DoSomethingElse','end']);
+  T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
+  AssertEquals(1,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNull(T.ElseBranch);
+  AssertNotNull(T.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  S:=TPasImplSimple(T.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  AssertEquals('Finally statement',TPasImplTryFinally,T.FinallyExcept.ClassType);
+  F:=TPasImplTryFinally(T.FinallyExcept);
+  AssertEquals(1,F.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(F.Elements[0]).ClassType);
+  S:=TPasImplSimple(F.Elements[0]);
+  AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
+end;
+
+procedure TTestStatementParser.TestTryFinallyEmpty;
+Var
+  T : TPasImplTry;
+  F : TPasImplTryFinally;
+
+begin
+  TestStatement(['Try','finally','end;']);
+  T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
+  AssertEquals(0,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNull(T.ElseBranch);
+  AssertEquals('Finally statement',TPasImplTryFinally,T.FinallyExcept.ClassType);
+  F:=TPasImplTryFinally(T.FinallyExcept);
+  AssertEquals(0,F.Elements.Count);
+end;
+
+procedure TTestStatementParser.TestTryFinallyNested;
+Var
+  T : TPasImplTry;
+  S : TPasImplSimple;
+  F : TPasImplTryFinally;
+
+begin
+  TestStatement(['Try','  DoSomething1;','  Try','    DoSomething2;','  finally','    DoSomethingElse2','  end;','Finally','  DoSomethingElse1','end']);
+  T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
+  AssertEquals(2,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNull(T.ElseBranch);
+  AssertNotNull(T.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  S:=TPasImplSimple(T.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething1');
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  AssertEquals('Finally statement',TPasImplTryFinally,T.FinallyExcept.ClassType);
+  F:=TPasImplTryFinally(T.FinallyExcept);
+  AssertEquals(1,F.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(F.Elements[0]).ClassType);
+  S:=TPasImplSimple(F.Elements[0]);
+  AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse1');
+  // inner statement
+  AssertNotNull(T.Elements[1]);
+  AssertEquals('Nested try statement',TPasImplTry,TPasElement(T.Elements[1]).ClassType);
+  T:=TPasImplTry(T.Elements[1]);
+  AssertEquals(1,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNull(T.ElseBranch);
+  AssertNotNull(T.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  S:=TPasImplSimple(T.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething2');
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  AssertEquals('Finally statement',TPasImplTryFinally,T.FinallyExcept.ClassType);
+  F:=TPasImplTryFinally(T.FinallyExcept);
+  AssertEquals(1,F.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(F.Elements[0]).ClassType);
+  S:=TPasImplSimple(F.Elements[0]);
+  AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse2');
+end;
+
+procedure TTestStatementParser.TestTryExcept;
+
+Var
+  T : TPasImplTry;
+  S : TPasImplSimple;
+  E : TPasImplTryExcept;
+
+begin
+  TestStatement(['Try','  DoSomething;','except','  DoSomethingElse','end']);
+  T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
+  AssertEquals(1,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNull(T.ElseBranch);
+  AssertNotNull(T.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  S:=TPasImplSimple(T.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
+  E:=TPasImplTryExcept(T.FinallyExcept);
+  AssertEquals(1,E.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(E.Elements[0]).ClassType);
+  S:=TPasImplSimple(E.Elements[0]);
+  AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
+end;
+
+procedure TTestStatementParser.TestTryExceptNested;
+Var
+  T : TPasImplTry;
+  S : TPasImplSimple;
+  E : TPasImplTryExcept;
+
+begin
+  TestStatement(['Try','  DoSomething1;','  try','    DoSomething2;','  except','    DoSomethingElse2','  end','except','  DoSomethingElse1','end']);
+  T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
+  AssertEquals(2,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNull(T.ElseBranch);
+  AssertNotNull(T.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  S:=TPasImplSimple(T.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething1');
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
+  E:=TPasImplTryExcept(T.FinallyExcept);
+  AssertEquals(1,E.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(E.Elements[0]).ClassType);
+  S:=TPasImplSimple(E.Elements[0]);
+  AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse1');
+  AssertNotNull(T.Elements[1]);
+  AssertEquals('Simple statement',TPasImplTry,TPasElement(T.Elements[1]).ClassType);
+  T:=TPasImplTry(T.Elements[1]);
+  AssertEquals(1,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNull(T.ElseBranch);
+  AssertNotNull(T.Elements[0]);
+  AssertEquals('Simple statement 2',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  S:=TPasImplSimple(T.Elements[0]);
+  AssertExpression('DoSomething2 call ',S.Expr,pekIdent,'DoSomething2');
+  AssertEquals('Simple statement2',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  AssertEquals('Except statement2',TPasImplTryExcept,T.FinallyExcept.ClassType);
+  E:=TPasImplTryExcept(T.FinallyExcept);
+  AssertEquals(1,E.Elements.Count);
+  AssertEquals('Simple statement2',TPasImplSimple,TPasElement(E.Elements[0]).ClassType);
+  S:=TPasImplSimple(E.Elements[0]);
+  AssertExpression('DoSomethingElse2 call',S.Expr,pekIdent,'DoSomethingElse2');
+end;
+
+procedure TTestStatementParser.TestTryExceptEmpty;
+
+Var
+  T : TPasImplTry;
+  E : TPasImplTryExcept;
+
+begin
+  TestStatement(['Try','except','end;']);
+  T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
+  AssertEquals(0,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNull(T.ElseBranch);
+  AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
+  E:=TPasImplTryExcept(T.FinallyExcept);
+  AssertEquals(0,E.Elements.Count);
+end;
+
+procedure TTestStatementParser.TestTryExceptOn;
+
+Var
+  T : TPasImplTry;
+  S : TPasImplSimple;
+  E : TPasImplTryExcept;
+  O : TPasImplExceptOn;
+
+begin
+  TestStatement(['Try','  DoSomething;','except','On E : Exception do','DoSomethingElse;','end']);
+  T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
+  AssertEquals(1,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNull(T.ElseBranch);
+  AssertNotNull(T.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  S:=TPasImplSimple(T.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
+  E:=TPasImplTryExcept(T.FinallyExcept);
+  AssertEquals(1,E.Elements.Count);
+  AssertEquals('Except on handler',TPasImplExceptOn,TPasElement(E.Elements[0]).ClassType);
+  O:=TPasImplExceptOn(E.Elements[0]);
+  AssertEquals(1,O.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(O.Elements[0]).ClassType);
+  AssertExpression('Exception Variable name',O.VarExpr,pekIdent,'E');
+  AssertExpression('Exception Type name',O.TypeExpr,pekIdent,'Exception');
+  S:=TPasImplSimple(O.Elements[0]);
+  AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
+//  AssertEquals('Variable name',
+
+end;
+
+procedure TTestStatementParser.TestTryExceptOn2;
+
+Var
+  T : TPasImplTry;
+  S : TPasImplSimple;
+  E : TPasImplTryExcept;
+  O : TPasImplExceptOn;
+
+begin
+  TestStatement(['Try','  DoSomething;','except',
+                 'On E : Exception do','DoSomethingElse;',
+                 'On Y : Exception2 do','DoSomethingElse2;',
+                 'end']);
+  T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
+  AssertEquals(1,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNull(T.ElseBranch);
+  AssertNotNull(T.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  S:=TPasImplSimple(T.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
+  E:=TPasImplTryExcept(T.FinallyExcept);
+  AssertEquals(2,E.Elements.Count);
+  // Exception handler 1
+  AssertEquals('Except on handler',TPasImplExceptOn,TPasElement(E.Elements[0]).ClassType);
+  O:=TPasImplExceptOn(E.Elements[0]);
+  AssertEquals(1,O.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(O.Elements[0]).ClassType);
+  AssertExpression('Exception Variable name',O.VarExpr,pekIdent,'E');
+  AssertExpression('Exception Type name',O.TypeExpr,pekIdent,'Exception');
+  S:=TPasImplSimple(O.Elements[0]);
+  AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
+  // Exception handler 2
+  AssertEquals('Except on handler',TPasImplExceptOn,TPasElement(E.Elements[1]).ClassType);
+  O:=TPasImplExceptOn(E.Elements[1]);
+  AssertEquals(1,O.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(O.Elements[0]).ClassType);
+  AssertExpression('Exception Variable name',O.VarExpr,pekIdent,'Y');
+  AssertExpression('Exception Type name',O.TypeExpr,pekIdent,'Exception2');
+  S:=TPasImplSimple(O.Elements[0]);
+  AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse2');
+end;
+
+procedure TTestStatementParser.TestTryExceptOnElse;
+Var
+  T : TPasImplTry;
+  S : TPasImplSimple;
+  E : TPasImplTryExcept;
+  O : TPasImplExceptOn;
+  EE : TPasImplTryExceptElse;
+  I : TPasImplIfElse;
+
+begin
+  DeclareVar('Boolean','b');
+  // Check that Else belongs to Except, not to IF
+
+  TestStatement(['Try','  DoSomething;','except','On E : Exception do','if b then','DoSomethingElse;','else','DoSomethingMore;','end']);
+  T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
+  AssertEquals(1,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNotNull(T.ElseBranch);
+  AssertNotNull(T.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  S:=TPasImplSimple(T.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
+  E:=TPasImplTryExcept(T.FinallyExcept);
+  AssertEquals(1,E.Elements.Count);
+  AssertEquals('Except on handler',TPasImplExceptOn,TPasElement(E.Elements[0]).ClassType);
+  O:=TPasImplExceptOn(E.Elements[0]);
+  AssertExpression('Exception Variable name',O.VarExpr,pekIdent,'E');
+  AssertExpression('Exception Type name',O.TypeExpr,pekIdent,'Exception');
+  AssertEquals(1,O.Elements.Count);
+  AssertEquals('Simple statement',TPasImplIfElse,TPasElement(O.Elements[0]).ClassType);
+  I:=TPasImplIfElse(O.Elements[0]);
+  AssertEquals(1,I.Elements.Count);
+  AssertNull('No else barcnh for if',I.ElseBranch);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(I.Elements[0]).ClassType);
+  S:=TPasImplSimple(I.Elements[0]);
+  AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
+  AssertEquals('Except Else statement',TPasImplTryExceptElse,T.ElseBranch.ClassType);
+  EE:=TPasImplTryExceptElse(T.ElseBranch);
+  AssertEquals(1,EE.Elements.Count);
+  AssertNotNull(EE.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(EE.Elements[0]).ClassType);
+  S:=TPasImplSimple(EE.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomethingMore');
+end;
+
+procedure TTestStatementParser.TestTryExceptOnIfElse;
+Var
+  T : TPasImplTry;
+  S : TPasImplSimple;
+  E : TPasImplTryExcept;
+  O : TPasImplExceptOn;
+  EE : TPasImplTryExceptElse;
+
+begin
+  TestStatement(['Try','  DoSomething;','except','On E : Exception do','DoSomethingElse;','else','DoSomethingMore;','end']);
+  T:=AssertStatement('Try statement',TPasImplTry) as TPasImplTry;
+  AssertEquals(1,T.Elements.Count);
+  AssertNotNull(T.FinallyExcept);
+  AssertNotNull(T.ElseBranch);
+  AssertNotNull(T.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  S:=TPasImplSimple(T.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomething');
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(T.Elements[0]).ClassType);
+  AssertEquals('Except statement',TPasImplTryExcept,T.FinallyExcept.ClassType);
+  E:=TPasImplTryExcept(T.FinallyExcept);
+  AssertEquals(1,E.Elements.Count);
+  AssertEquals('Except on handler',TPasImplExceptOn,TPasElement(E.Elements[0]).ClassType);
+  O:=TPasImplExceptOn(E.Elements[0]);
+  AssertExpression('Exception Variable name',O.VarExpr,pekIdent,'E');
+  AssertExpression('Exception Type name',O.TypeExpr,pekIdent,'Exception');
+  AssertEquals(1,O.Elements.Count);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(O.Elements[0]).ClassType);
+  S:=TPasImplSimple(O.Elements[0]);
+  AssertExpression('DoSomethingElse call',S.Expr,pekIdent,'DoSomethingElse');
+  AssertEquals('Except Else statement',TPasImplTryExceptElse,T.ElseBranch.ClassType);
+  EE:=TPasImplTryExceptElse(T.ElseBranch);
+  AssertEquals(1,EE.Elements.Count);
+  AssertNotNull(EE.Elements[0]);
+  AssertEquals('Simple statement',TPasImplSimple,TPasElement(EE.Elements[0]).ClassType);
+  S:=TPasImplSimple(EE.Elements[0]);
+  AssertExpression('DoSomething call',S.Expr,pekIdent,'DoSomethingMore');
+end;
+
+initialization
+  RegisterTests([TTestStatementParser]);
+
+end.
+

+ 2839 - 0
packages/fcl-passrc/tests/tctypeparser.pas

@@ -0,0 +1,2839 @@
+unit tctypeparser;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit, pastree, pscanner, pparser,
+  tcbaseparser, testregistry;
+
+type
+  { TBaseTestTypeParser }
+
+  TBaseTestTypeParser= Class(TTestParser)
+  private
+    FType : TPasType;
+    FHint : string;
+    FErrorSource : String;
+  Protected
+    Function ParseType(ASource : String; ATypeClass : TClass;Const AHint : String = '') : TPasType; virtual; overload;
+    Procedure AssertParseTypeError(ASource : String);
+    Property TheType : TPasType Read FType;
+    Property Hint : string Read FHint Write FHint;
+    procedure SetUp; override;
+    Procedure TearDown; override;
+  end;
+
+  { TTestTypeParser }
+
+  TTestTypeParser = Class(TBaseTestTypeParser)
+  private
+  Protected
+    Procedure DoTestAliasType(Const AnAliasType : String; Const AHint : String);
+    procedure DoTestStringType(const AnAliasType: String; const AHint: String);
+    procedure DoTypeError(Const AMsg,ASource : string);
+    Procedure DoParseError;
+    Procedure DoParsePointer(Const ASource : String; Const AHint : String; ADestType : TClass = Nil);
+    Procedure DoParseArray(Const ASource : String; Const AHint : String; ADestType : TClass = Nil);
+    Procedure DoParseEnumerated(Const ASource : String; Const AHint : String; ACount : integer);
+    Procedure DoTestFileType(Const AType : String; Const AHint : String; ADestType : TClass = Nil);
+    Procedure DoTestRangeType(Const AStart,AStop,AHint : String);
+    Procedure DoParseSimpleSet(Const ASource : String; Const AHint : String);
+    Procedure DoParseComplexSet(Const ASource : String; Const AHint : String);
+    procedure DoParseRangeSet(const ASource: String; const AHint: String);
+    Procedure DoTestComplexSet;
+    Procedure DoTestClassOf(Const AHint : string);
+  Published
+    Procedure TestAliasType;
+    Procedure TestCrossUnitAliasType;
+    Procedure TestAliasTypeDeprecated;
+    Procedure TestAliasTypePlatform;
+    Procedure TestSimpleTypeByte;
+    Procedure TestSimpleTypeByteDeprecated;
+    Procedure TestSimpleTypeBytePlatform;
+    Procedure TestSimpleTypeBoolean;
+    Procedure TestSimpleTypeBooleanDeprecated;
+    Procedure TestSimpleTypeBooleanPlatform;
+    Procedure TestSimpleTypeChar;
+    Procedure TestSimpleTypeCharDeprecated;
+    Procedure TestSimpleTypeCharPlatform;
+    Procedure TestSimpleTypeInteger;
+    Procedure TestSimpleTypeIntegerDeprecated;
+    Procedure TestSimpleTypeIntegerPlatform;
+    Procedure TestSimpleTypeInt64;
+    Procedure TestSimpleTypeInt64Deprecated;
+    Procedure TestSimpleTypeInt64Platform;
+    Procedure TestSimpleTypeLongInt;
+    Procedure TestSimpleTypeLongIntDeprecated;
+    Procedure TestSimpleTypeLongIntPlatform;
+    Procedure TestSimpleTypeLongWord;
+    Procedure TestSimpleTypeLongWordDeprecated;
+    Procedure TestSimpleTypeLongWordPlatform;
+    Procedure TestSimpleTypeDouble;
+    Procedure TestSimpleTypeDoubleDeprecated;
+    Procedure TestSimpleTypeDoublePlatform;
+    Procedure TestSimpleTypeShortInt;
+    Procedure TestSimpleTypeShortIntDeprecated;
+    Procedure TestSimpleTypeShortIntPlatform;
+    Procedure TestSimpleTypeSmallInt;
+    Procedure TestSimpleTypeSmallIntDeprecated;
+    Procedure TestSimpleTypeSmallIntPlatform;
+    Procedure TestSimpleTypeString;
+    Procedure TestSimpleTypeStringDeprecated;
+    Procedure TestSimpleTypeStringPlatform;
+    Procedure TestSimpleTypeStringSize;
+    Procedure TestSimpleTypeStringSizeIncomplete;
+    Procedure TestSimpleTypeStringSizeWrong;
+    Procedure TestSimpleTypeStringSizeDeprecated;
+    Procedure TestSimpleTypeStringSizePlatform;
+    Procedure TestSimpleTypeWord;
+    Procedure TestSimpleTypeWordDeprecated;
+    Procedure TestSimpleTypeWordPlatform;
+    Procedure TestSimpleTypeQWord;
+    Procedure TestSimpleTypeQWordDeprecated;
+    Procedure TestSimpleTypeQWordPlatform;
+    Procedure TestSimpleTypeCardinal;
+    Procedure TestSimpleTypeCardinalDeprecated;
+    Procedure TestSimpleTypeCardinalPlatform;
+    Procedure TestSimpleTypeWideChar;
+    Procedure TestSimpleTypeWideCharDeprecated;
+    Procedure TestSimpleTypeWideCharPlatform;
+    Procedure TestPointerSimple;
+    procedure TestPointerSimpleDeprecated;
+    procedure TestPointerSimplePlatform;
+    Procedure TestStaticArray;
+    procedure TestStaticArrayDeprecated;
+    procedure TestStaticArrayPlatform;
+    Procedure TestStaticArrayPacked;
+    Procedure TestStaticArrayTypedIndex;
+    Procedure TestDynamicArray;
+    Procedure TestSimpleEnumerated;
+    Procedure TestSimpleEnumeratedDeprecated;
+    Procedure TestSimpleEnumeratedPlatform;
+    Procedure TestAssignedEnumerated;
+    Procedure TestAssignedEnumeratedDeprecated;
+    Procedure TestAssignedEnumeratedPlatform;
+    Procedure TestFileType;
+    Procedure TestFileTypeDeprecated;
+    Procedure TestFileTypePlatform;
+    Procedure TestRangeType;
+    Procedure TestRangeTypeDeprecated;
+    Procedure TestRangeTypePlatform;
+    Procedure TestIdentifierRangeType;
+    Procedure TestIdentifierRangeTypeDeprecated;
+    Procedure TestIdentifierRangeTypePlatform;
+    Procedure TestNegativeIdentifierRangeType;
+    Procedure TestSimpleSet;
+    Procedure TestSimpleSetDeprecated;
+    Procedure TestSimpleSetPlatform;
+    Procedure TestComplexSet;
+    Procedure TestComplexSetDeprecated;
+    Procedure TestComplexSetPlatform;
+    Procedure TestRangeSet;
+    Procedure TestRangeSetDeprecated;
+    Procedure TestRangeSetPlatform;
+    Procedure TestClassOf;
+    Procedure TestClassOfDeprecated;
+    Procedure TestClassOfPlatform;
+    Procedure TestReferenceAlias;
+    Procedure TestReferenceSet;
+    Procedure TestReferenceClassOf;
+    Procedure TestReferenceFile;
+    Procedure TestReferenceArray;
+    Procedure TestReferencePointer;
+  end;
+
+  { TTestRecordTypeParser }
+
+  TTestRecordTypeParser= Class(TBaseTestTypeParser)
+  private
+    Function GetField(AIndex : Integer; R : TPasRecordType) : TPasVariable;
+    Function GetField(AIndex : Integer; R : TPasVariant) : TPasVariable;
+    function GetF(AIndex: Integer): TPasVariable;
+    function GetR: TPasRecordType;
+    Function GetVariant(AIndex : Integer; R : TPasRecordType) : TPasVariant;
+    function GetV(AIndex: Integer): TPasVariant;
+  Protected
+    Procedure TestFields(Const Fields : Array of string; AHint : String; HaveVariant : Boolean = False);
+    procedure AssertVariantSelector(AName, AType: string);
+    procedure AssertField1(Hints: TPasMemberHints);
+    procedure AssertField2(Hints: TPasMemberHints);
+    procedure AssertVariant1(Hints: TPasMemberHints);
+    procedure AssertVariant1(Hints: TPasMemberHints; VariantLabels : Array of string);
+    procedure AssertVariant2(Hints: TPasMemberHints);
+    procedure AssertVariant2(Hints: TPasMemberHints; VariantLabels : Array of string);
+    procedure AssertOneIntegerField(Hints: TPasMemberHints);
+    procedure AssertTwoIntegerFields(Hints1, Hints2: TPasMemberHints);
+    procedure AssertRecordField(AIndex: Integer;Hints: TPasMemberHints);
+    procedure AssertRecordVariant(AIndex: Integer;Hints: TPasMemberHints; VariantLabels : Array of string);
+    Procedure AssertRecordVariantVariant(AIndex: Integer;Const AFieldName,ATypeName: string;Hints: TPasMemberHints; VariantLabels : Array of string);
+    Procedure DoTestEmpty(Const AHint : String);
+    procedure DoTestDeprecatedVariantNoStorage(Const AHint : string);
+    procedure DoTestDeprecatedVariantStorage(Const AHint : string);
+    procedure DoTestVariantNoStorage(Const AHint : string);
+    procedure DoTestVariantStorage(Const AHint : string);
+    procedure DoTestTwoVariantsNoStorage(Const AHint : string);
+    procedure DoTestTwoVariantsStorage(Const AHint : string);
+    procedure DoTestTwoVariantsFirstDeprecatedStorage(Const AHint : string);
+    procedure DoTestTwoVariantsSecondDeprecatedStorage(Const AHint : string);
+    Procedure DoTestVariantTwoLabels(Const AHint : string);
+    Procedure DoTestTwoVariantsTwoLabels(Const AHint : string);
+    procedure DoTestVariantNestedRecord(Const AHint : string);
+    procedure DoTestVariantNestedVariant(Const AHint : string);
+    procedure DoTestVariantNestedVariantFirstDeprecated(Const AHint : string);
+    procedure DoTestVariantNestedVariantSecondDeprecated(const AHint: string);
+    procedure DoTestVariantNestedVariantBothDeprecated(const AHint: string);
+    Property TheRecord : TPasRecordType Read GetR;
+    Property Field1 : TPasVariable Index 0 Read GetF;
+    Property Field2 : TPasVariable Index 1 Read GetF;
+    Property Variant1 : TPasVariant Index 0 Read GetV;
+    Property Variant2 : TPasVariant Index 1 Read GetV;
+  Published
+    Procedure TestEmpty;
+    Procedure TestEmptyDeprecated;
+    Procedure TestEmptyPlatform;
+    Procedure TestOneField;
+    Procedure TestOneFieldDeprecated;
+    Procedure TestOneFieldPlatform;
+    Procedure TestOneFieldSemicolon;
+    Procedure TestOneFieldSemicolonDeprecated;
+    Procedure TestOneFieldSemicolonPlatform;
+    Procedure TestOneDeprecatedField;
+    Procedure TestOneDeprecatedFieldDeprecated;
+    Procedure TestOneDeprecatedFieldPlatform;
+    Procedure TestOnePlatformField;
+    Procedure TestOnePlatformFieldDeprecated;
+    Procedure TestOnePlatformFieldPlatform;
+    Procedure TestTwoFields;
+    Procedure TestTwoFieldDeprecated;
+    Procedure TestTwoFieldPlatform;
+    Procedure TestTwoFieldsFirstDeprecated;
+    Procedure TestTwoFieldsFirstDeprecatedDeprecated;
+    Procedure TestTwoFieldsFirstDeprecatedPlatform;
+    Procedure TestTwoFieldsSecondDeprecated;
+    Procedure TestTwoFieldsSecondDeprecatedDeprecated;
+    Procedure TestTwoFieldsSecondDeprecatedPlatform;
+    Procedure TestTwoFieldsBothDeprecated;
+    Procedure TestTwoFieldsBothDeprecatedDeprecated;
+    Procedure TestTwoFieldsBothDeprecatedPlatform;
+    Procedure TestTwoFieldsCombined;
+    Procedure TestTwoFieldsCombinedDeprecated;
+    Procedure TestTwoFieldsCombinedPlatform;
+    Procedure TestTwoDeprecatedFieldsCombined;
+    Procedure TestTwoDeprecatedFieldsCombinedDeprecated;
+    Procedure TestTwoDeprecatedFieldsCombinedPlatform;
+    Procedure TestNested;
+    Procedure TestNestedDeprecated;
+    Procedure TestNestedPlatform;
+    procedure TestNestedSemicolon;
+    procedure TestNestedSemicolonDeprecated;
+    procedure TestNestedSemicolonPlatform;
+    procedure TestNestedFirst;
+    procedure TestNestedFirstDeprecated;
+    procedure TestNestedFirstPlatform;
+    Procedure TestDeprecatedNested;
+    Procedure TestDeprecatedNestedDeprecated;
+    Procedure TestDeprecatedNestedPlatform;
+    procedure TestDeprecatedNestedFirst;
+    procedure TestDeprecatedNestedFirstDeprecated;
+    procedure TestDeprecatedNestedFirstPlatform;
+    Procedure TestVariantNoStorage;
+    procedure TestVariantNoStorageDeprecated;
+    procedure TestVariantNoStoragePlatform;
+    Procedure TestVariantStorage;
+    procedure TestVariantStorageDeprecated;
+    procedure TestVariantStoragePlatform;
+    Procedure TestDeprecatedVariantNoStorage;
+    procedure TestDeprecatedVariantNoStorageDeprecated;
+    procedure TestDeprecatedVariantNoStoragePlatform;
+    Procedure TestDeprecatedVariantStorage;
+    procedure TestDeprecatedVariantStorageDeprecated;
+    procedure TestDeprecatedVariantStoragePlatform;
+    Procedure TestTwoVariantsNoStorage;
+    procedure TestTwoVariantsNoStorageDeprecated;
+    procedure TestTwoVariantsNoStoragePlatform;
+    Procedure TestTwoVariantsStorage;
+    procedure TestTwoVariantsStorageDeprecated;
+    procedure TestTwoVariantsStoragePlatform;
+    Procedure TestTwoVariantsFirstDeprecatedStorage;
+    procedure TestTwoVariantsFirstDeprecatedStorageDeprecated;
+    procedure TestTwoVariantsFirstDeprecatedStoragePlatform;
+    Procedure TestTwoVariantsSecondDeprecatedStorage;
+    procedure TestTwoVariantsSecondDeprecatedStorageDeprecated;
+    procedure TestTwoVariantsSecondDeprecatedStoragePlatform;
+    Procedure TestVariantTwoLabels;
+    Procedure TestVariantTwoLabelsDeprecated;
+    Procedure TestVariantTwoLabelsPlatform;
+    Procedure TestTwoVariantsTwoLabels;
+    Procedure TestTwoVariantsTwoLabelsDeprecated;
+    Procedure TestTwoVariantsTwoLabelsPlatform;
+    Procedure TestVariantNestedRecord;
+    Procedure TestVariantNestedRecordDeprecated;
+    Procedure TestVariantNestedRecordPlatform;
+    Procedure TestVariantNestedVariant;
+    Procedure TestVariantNestedVariantDeprecated;
+    Procedure TestVariantNestedVariantPlatForm;
+    Procedure TestVariantNestedVariantFirstDeprecated;
+    Procedure TestVariantNestedVariantFirstDeprecatedDeprecated;
+    Procedure TestVariantNestedVariantFirstDeprecatedPlatform;
+    Procedure TestVariantNestedVariantSecondDeprecated;
+    Procedure TestVariantNestedVariantSecondDeprecatedDeprecated;
+    Procedure TestVariantNestedVariantSecondDeprecatedPlatform;
+    Procedure TestVariantNestedVariantBothDeprecated;
+    Procedure TestVariantNestedVariantBothDeprecatedDeprecated;
+    Procedure TestVariantNestedVariantBothDeprecatedPlatform;
+  end;
+
+  { TTestProcedureTypeParser }
+  TCallingConventionTest = Procedure (CC : TCallingConvention;Const AHint : String) of object;
+
+  TTestProcedureTypeParser = Class(TBaseTestTypeParser)
+  Private
+    FProc : TPasProcedureType;
+    procedure CheckArrayOfConstArgument(Aindex: Integer; Ac: TArgumentAccess);
+  Protected
+    procedure DoTestFunction(CC: TCallingConvention; const AHint: String);
+    procedure DoTestFunctionOfObject(CC: TCallingConvention; const AHint: String);
+    procedure DoTestFunctionOneArg(CC: TCallingConvention; const AHint: String);
+    procedure DoTestFunctionOneArgOfObject(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureOfObject(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureOfObjectOneArg(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureIsNested(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureIsNestedOneArg(CC: TCallingConvention; const AHint: String);
+    procedure CheckOpenArrayArgument(Ac: TArgumentAccess);
+    procedure DoTestProcedureArrayOfConst(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureOpenArray(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureConstOpenArray(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureVarOpenArray(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureOutOpenArray(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureOneArgDefault(CC: TCallingConvention;const AHint: String);
+    procedure DoTestProcedureOneArgDefaultExpr(CC: TCallingConvention;const AHint: String);
+    procedure DoTestProcedureOneArgDefaultSet(CC: TCallingConvention;const AHint: String);
+    procedure DoTestProcedureOneConstArgDefault(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureOneVarArgDefault(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureOneOutArgDefault(CC: TCallingConvention; const AHint: String);
+    function CheckArgument(AIndex : Integer; Const AName,ATypeName : String; AAccess : TArgumentAccess) : TPasArgument;
+    Function ParseType(ASource : String; CC : TCallingConvention; ATypeClass : TClass;Const AHint : String = '') : TPasProcedureType; virtual; overload;
+    Procedure DoTestProcedureDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureOneArgDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureOneVarArgDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureOneConstArgDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureOneOutArgDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureTwoArgsDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureTwoVarArgsDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureTwoConstArgsDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureTwoOutArgsDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureTwoCombinedArgsDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureTwoCombinedVarArgsDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureTwoCombinedConstArgsDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureTwoCombinedOutArgsDecl(CC : TCallingConvention; Const AHint : String);
+    Procedure DoTestProcedureDefaultConstArgsDecl(CC : TCallingConvention; Const AHint : String);
+    procedure DoTestProcedureUntypedArgDecl(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureUntypedConstArgDecl(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureUntypedOutArgDecl(CC: TCallingConvention; const AHint: String);
+    procedure DoTestProcedureUntypedDefArg;
+    Procedure TestCallingConventions(Proc : TCallingConventionTest; Const AHint : String);
+    Procedure TestCallingConventions(Proc : TCallingConventionTest);
+    Function FuncProc : TPasFunctionType;
+    Property Proc : TPasProcedureType Read FProc;
+  Published
+    Procedure TestProcedure;
+    Procedure TestProcedureOneArg;
+    Procedure TestProcedureOneVarArg;
+    Procedure TestProcedureOneConstArg;
+    Procedure TestProcedureOneOutArg;
+    Procedure TestProcedureTwoArgs;
+    Procedure TestProcedureTwoVarArgs;
+    Procedure TestProcedureTwoConstArgs;
+    Procedure TestProcedureTwoOutArgs;
+    Procedure TestProcedureTwoCombinedArgs;
+    Procedure TestProcedureTwoCombinedVarArgs;
+    Procedure TestProcedureTwoCombinedConstArgs;
+    Procedure TestProcedureTwoCombinedOutArgs;
+    Procedure TestProcedureDefaultConstArgs;
+    Procedure TestProcedureUntypedArg;
+    Procedure TestProcedureUntypedConstArg;
+    Procedure TestProcedureUntypedOutArg;
+    Procedure TestProcedureUntypedDefArg;
+    Procedure TestProcedureOneArgDefault;
+    Procedure TestProcedureOneArgDefaultExpr;
+    Procedure TestProcedureOneArgDefaultSet;
+    Procedure TestProcedureOneVarArgDefault;
+    Procedure TestProcedureOneConstArgDefault;
+    Procedure TestProcedureOneOutArgDefault;
+    Procedure TestProcedureNoMultiArgDefaults;
+    Procedure TestProcedureOpenArray;
+    Procedure TestProcedureConstOpenArray;
+    Procedure TestProcedureOutOpenArray;
+    Procedure TestProcedureVarOpenArray;
+    Procedure TestProcedureArrayOfConst;
+    Procedure TestProcedureOfObject;
+    Procedure TestProcedureOfObjectOneArg;
+    Procedure TestProcedureIsNested;
+    Procedure TestProcedureIsNesteOneArg;
+    Procedure TestFunction;
+    Procedure TestFunctionOneArg;
+    Procedure TestFunctionOfObject;
+    Procedure TestFunctionOneArgOfObject;
+  end;
+
+
+
+implementation
+
+uses typinfo;
+
+
+
+{ TTestProcedureTypeParser }
+
+procedure TTestProcedureTypeParser.DoTestProcedureUntypedArgDecl(
+  CC: TCallingConvention; const AHint: String);
+
+Var
+  A : TPasArgument;
+
+begin
+  ParseType('procedure(var A)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  A:=CheckArgument(0,'A','',argVar);
+  AssertNull('No argument type', A.ArgType)
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureUntypedConstArgDecl(
+  CC: TCallingConvention; const AHint: String);
+
+Var
+  A : TPasArgument;
+
+begin
+  ParseType('procedure(const A)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  A:=CheckArgument(0,'A','',argConst);
+  AssertNull('No argument type', A.ArgType)
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureUntypedOutArgDecl(
+  CC: TCallingConvention; const AHint: String);
+Var
+  A : TPasArgument;
+
+begin
+  ParseType('procedure(out A)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  A:=CheckArgument(0,'A','',argOut);
+  AssertNull('No argument type', A.ArgType)
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureUntypedDefArg;
+begin
+  ParseType('procedure(A)',ccdefault,TPasProcedureType,'');
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOneVarArgDefault(
+  CC: TCallingConvention; const AHint: String);
+Var
+  A : TPasArgument;
+
+begin
+  ParseType('procedure(var A : Integer = 1)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  A:=CheckArgument(0,'A','Integer',argVar);
+  AssertNotNull('have default argument type', A.Value);
+  AssertEquals('argument expr type', TPrimitiveExpr, A.ValueExpr.ClassType);
+  AssertEquals('argument expr type', '1', TPrimitiveExpr(A.ValueExpr).Value);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOneOutArgDefault(
+  CC: TCallingConvention; const AHint: String);
+Var
+  A : TPasArgument;
+
+begin
+  ParseType('procedure(out A : Integer = 1)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  A:=CheckArgument(0,'A','Integer',argOut);
+  AssertNotNull('have default argument type', A.Value);
+  AssertEquals('argument expr type', TPrimitiveExpr, A.ValueExpr.ClassType);
+  AssertEquals('argument expr type', '1', TPrimitiveExpr(A.ValueExpr).Value);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOneConstArgDefault(
+  CC: TCallingConvention; const AHint: String);
+Var
+  A : TPasArgument;
+
+begin
+  ParseType('procedure(const A : Integer = 1)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  A:=CheckArgument(0,'A','Integer',argConst);
+  AssertNotNull('have default argument type', A.Value);
+  AssertEquals('argument expr type', TPrimitiveExpr, A.ValueExpr.ClassType);
+  AssertEquals('argument expr type', '1', TPrimitiveExpr(A.ValueExpr).Value);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureArrayOfConst(
+  CC: TCallingConvention; const AHint: String);
+
+begin
+  ParseType('procedure(A : Array of const)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  CheckArrayOfConstArgument(0,argDefault);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOfObject(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure of Object',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',0,Proc.Args.Count);
+  AssertEquals('Is OF Object',True,Proc.IsOfObject);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOfObjectOneArg(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure (A : integer)of Object',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  AssertEquals('Is OF Object',True,Proc.IsOfObject);
+  CheckArgument(0,'A','Integer',argDefault);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureIsNested(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure is nested',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',0,Proc.Args.Count);
+  AssertEquals('Is nested',True,Proc.IsNested);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureIsNestedOneArg(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure (A : integer) is nested',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  AssertEquals('Is nested',True,Proc.IsNested);
+  CheckArgument(0,'A','Integer',argDefault);
+end;
+
+
+procedure TTestProcedureTypeParser.CheckArrayOfConstArgument(Aindex : Integer; Ac : TArgumentAccess);
+Var
+  A : TPasArgument;
+  T : TPasArrayType;
+
+begin
+  A:=CheckArgument(Aindex,'A','',ac);
+  AssertEquals('ArrayType',TPasArrayType,A.ArgType.ClassType);
+  T:=A.ArgType as TPasArrayType;
+  AssertNull('Have Element type',T.ElType);
+end;
+
+procedure TTestProcedureTypeParser.DoTestFunction(CC: TCallingConvention;
+  const AHint: String);
+begin
+  ParseType('function : integer',CC,TPasFunctionType,AHint);
+  AssertEquals('Argument count',0,Proc.Args.Count);
+  AssertEquals('Is OF Object',False,Proc.IsOfObject);
+  AssertNotNull('Have result',FuncProc.ResultEl);
+  AssertEquals('Result type class',TPasResultElement,FuncProc.ResultEl.ClassType);
+  AssertNotNull('Have result',FuncProc.ResultEl.ResultType);
+  AssertEquals('Result type element class ',TPasUnresolvedTypeRef,FuncProc.ResultEl.ResultType.ClassType);
+  AssertEquals('Result type element name','Integer',FuncProc.ResultEl.ResultType.Name);
+end;
+
+procedure TTestProcedureTypeParser.DoTestFunctionOfObject(CC: TCallingConvention;
+  const AHint: String);
+begin
+  ParseType('function : integer of object',CC,TPasFunctionType,AHint);
+  AssertEquals('Argument count',0,Proc.Args.Count);
+  AssertEquals('Is OF Object',True,Proc.IsOfObject);
+  AssertNotNull('Have result',FuncProc.ResultEl);
+  AssertEquals('Result type class',TPasResultElement,FuncProc.ResultEl.ClassType);
+  AssertNotNull('Have result',FuncProc.ResultEl.ResultType);
+  AssertEquals('Result type element class ',TPasUnresolvedTypeRef,FuncProc.ResultEl.ResultType.ClassType);
+  AssertEquals('Result type element name','Integer',FuncProc.ResultEl.ResultType.Name);
+end;
+
+procedure TTestProcedureTypeParser.DoTestFunctionOneArg(CC: TCallingConvention;
+  const AHint: String);
+begin
+  ParseType('function (A : Integer) : Integer',CC,TPasFunctionType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argDefault);
+  AssertNotNull('Have result',FuncProc.ResultEl);
+  AssertEquals('Result type class',TPasResultElement,FuncProc.ResultEl.ClassType);
+  AssertNotNull('Have result',FuncProc.ResultEl.ResultType);
+  AssertEquals('Result type element class ',TPasUnresolvedTypeRef,FuncProc.ResultEl.ResultType.ClassType);
+  AssertEquals('Result type element name','Integer',FuncProc.ResultEl.ResultType.Name);
+end;
+
+procedure TTestProcedureTypeParser.DoTestFunctionOneArgOfObject(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('function (A : Integer) : Integer of object',CC,TPasFunctionType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  AssertEquals('Is OF Object',True,Proc.IsOfObject);
+  CheckArgument(0,'A','Integer',argDefault);
+  AssertNotNull('Have result',FuncProc.ResultEl);
+  AssertEquals('Result type class',TPasResultElement,FuncProc.ResultEl.ClassType);
+  AssertNotNull('Have result',FuncProc.ResultEl.ResultType);
+  AssertEquals('Result type element class ',TPasUnresolvedTypeRef,FuncProc.ResultEl.ResultType.ClassType);
+  AssertEquals('Result type element name','Integer',FuncProc.ResultEl.ResultType.Name);
+end;
+
+procedure TTestProcedureTypeParser.CheckOpenArrayArgument(Ac : TArgumentAccess);
+Var
+  A : TPasArgument;
+  T : TPasArrayType;
+
+begin
+  A:=CheckArgument(0,'A','',ac);
+  AssertEquals('ArrayType',TPasArrayType,A.ArgType.ClassType);
+  T:=A.ArgType as TPasArrayType;
+  AssertNotNull('Have Element type',T.ElType);
+  AssertEquals('Element type',TPasUnresolvedTypeRef,T.ElType.ClassType);
+  AssertEquals('Element type name','Integer',TPasUnresolvedTypeRef(T.ElType).Name);
+  AssertEquals('No boundaries','',T.IndexRange);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOpenArray(
+  CC: TCallingConvention; const AHint: String);
+
+begin
+  ParseType('procedure(A : Array of integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  CheckOpenArrayArgument(argDefault);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureConstOpenArray(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(const A : Array of integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  CheckOpenArrayArgument(argConst);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureVarOpenArray(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(var A : Array of integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  CheckOpenArrayArgument(argVar);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOutOpenArray(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(out A : Array of integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  CheckOpenArrayArgument(argOut);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOneArgDefault(
+  CC: TCallingConvention; const AHint: String);
+Var
+  A : TPasArgument;
+
+begin
+  ParseType('procedure(A : Integer = 1)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  A:=CheckArgument(0,'A','Integer',argDefault);
+  AssertNotNull('have default argument type', A.ValueExpr);
+  AssertEquals('argument expr type', TPrimitiveExpr, A.ValueExpr.ClassType);
+  AssertEquals('argument expr value', '1', TPrimitiveExpr(A.ValueExpr).Value);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOneArgDefaultExpr(
+  CC: TCallingConvention; const AHint: String);
+
+Var
+  A : TPasArgument;
+  B : TBinaryExpr;
+
+begin
+  ParseType('procedure(A : Integer = 1+2)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  A:=CheckArgument(0,'A','Integer',argDefault);
+  AssertNotNull('have default argument type', A.ValueExpr);
+  AssertEquals('argument expr type', TBinaryExpr, A.ValueExpr.ClassType);
+  B:=TBinaryExpr(A.ValueExpr);
+  AssertNotNull('have left expr', B.Left);
+  AssertEquals('argument left expr type', TPrimitiveExpr, B.left.ClassType);
+  AssertEquals('argument left expr value', '1', TPrimitiveExpr(B.Left).Value);
+  AssertNotNull('have right expr', B.Right);
+  AssertEquals('argument right expr type', TPrimitiveExpr, B.right.ClassType);
+  AssertEquals('argument right expr value', '2', TPrimitiveExpr(B.right).Value);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOneArgDefaultSet(
+  CC: TCallingConvention; const AHint: String);
+Var
+  A : TPasArgument;
+  B : TParamsExpr;
+
+begin
+  ParseType('procedure(A : TB = [])',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  A:=CheckArgument(0,'A','TB',argDefault);
+  AssertNotNull('have default argument type', A.ValueExpr);
+  AssertEquals('argument expr type', TParamsExpr, A.ValueExpr.ClassType);
+  B:=TParamsExpr(A.ValueExpr);
+  AssertEquals('No params',0,Length(B.Params));
+end;
+
+Function TTestProcedureTypeParser.CheckArgument(AIndex: Integer; const AName,
+  ATypeName: String; AAccess: TArgumentAccess) : TPAsArgument;
+Var
+  A : TPasArgument;
+  C : String;
+begin
+  C:='Argument '+IntToStr(AIndex)+' : ';
+  AssertNotNull(C+'assigned',Proc.Args[AIndex]);
+  AssertEquals(C+'class',TPasArgument,TObject(Proc.Args[AIndex]).ClassType);
+  A:=TPasArgument(Proc.Args[AIndex]);
+  AssertEquals(C+'Access',AAccess,A.Access);
+  AssertEquals(C+'name',AName,A.Name);
+  if (ATypeName<>'') then
+    begin
+    AssertNotNull(C+'type assigned',A.ArgType);
+    if (ATypeName[1]='[') then
+      AssertEquals(C+'type classname',LowerCase(Copy(ATypeName,2,Length(ATypeName)-2)),LowerCase(A.ArgType.ClassName))
+    else
+      AssertEquals(C+'type name',ATypeName,A.ArgType.Name);
+    end;
+  Result:=A;
+end;
+
+function TTestProcedureTypeParser.ParseType(ASource: String;
+  CC: TCallingConvention; ATypeClass: TClass; const AHint: String): TPasProcedureType;
+begin
+  if CC=ccdefault then
+    Result:=TPasProcedureType(ParseType(ASource,ATypeClass,AHint))
+  else
+    begin
+    if (AHint<>'') then
+      Result:=TPasProcedureType(ParseType(ASource+';' +cCallingConventions[CC]+';',ATypeClass,AHint))
+    else
+      Result:=TPasProcedureType(ParseType(ASource+';' +cCallingConventions[CC],ATypeClass,AHint));
+    end;
+  FProc:=Result;
+  AssertEquals('Correct calling convention for procedural type',cc,Result.CallingConvention);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureDecl(CC: TCallingConvention; Const AHint : String);
+
+begin
+  ParseType('procedure',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',0,Proc.Args.Count);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOneArgDecl(
+  CC: TCallingConvention; const AHint: String);
+
+begin
+  ParseType('procedure(A : Integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argDefault);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOneVarArgDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(var A : Integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argVar);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOneConstArgDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(const A : Integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argConst);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureOneOutArgDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(out A : Integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',1,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argOut);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureTwoArgsDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(A : Integer;B : String)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',2,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argDefault);
+  CheckArgument(1,'B','[TPasAliasType]',argDefault);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureTwoVarArgsDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(Var A : Integer;Var B : String)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',2,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argVar);
+  CheckArgument(1,'B','[TPasAliasType]',argVar);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureTwoConstArgsDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(const A : Integer;Const B : String)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',2,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argConst);
+  CheckArgument(1,'B','[TPasAliasType]',argConst);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureTwoOutArgsDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(out A : Integer;Out B : String)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',2,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argOut);
+  CheckArgument(1,'B','[TPasAliasType]',argOut);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureTwoCombinedArgsDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(A,B : Integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',2,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argDefault);
+  CheckArgument(1,'B','Integer',argDefault);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureTwoCombinedVarArgsDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(Var A,B : Integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',2,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argVar);
+  CheckArgument(1,'B','Integer',argVar);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureTwoCombinedConstArgsDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(Const A,B : Integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',2,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argConst);
+  CheckArgument(1,'B','Integer',argConst);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureTwoCombinedOutArgsDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(Out A,B : Integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',2,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argOut);
+  CheckArgument(1,'B','Integer',argOut);
+end;
+
+procedure TTestProcedureTypeParser.DoTestProcedureDefaultConstArgsDecl(
+  CC: TCallingConvention; const AHint: String);
+begin
+  ParseType('procedure(A : Integer; Const B : Integer)',CC,TPasProcedureType,AHint);
+  AssertEquals('Argument count',2,Proc.Args.Count);
+  CheckArgument(0,'A','Integer',argDefault);
+  CheckArgument(1,'B','Integer',argConst);
+end;
+
+procedure TTestProcedureTypeParser.TestCallingConventions(
+  Proc: TCallingConventionTest; Const AHint : String);
+
+Var
+  CC : TCallingConvention;
+
+begin
+  For cc:=ccDefault to High(TCallingConvention) do
+    begin
+    if CC<>ccDefault then
+      Setup;
+    try
+      Proc(cc,AHint);
+    finally
+      tearDown;
+    end;
+    end;
+end;
+
+procedure TTestProcedureTypeParser.TestCallingConventions(
+  Proc: TCallingConventionTest);
+begin
+  TestCallingConventions(Proc,'');
+  Setup;
+  TestCallingConventions(Proc,'deprecated');
+  Setup;
+  TestCallingConventions(Proc,'platform');
+end;
+
+function TTestProcedureTypeParser.FuncProc: TPasFunctionType;
+begin
+  Result:=Proc as TPasFunctionType;
+end;
+
+procedure TTestProcedureTypeParser.TestProcedure;
+begin
+  TestCallingConventions(@DoTestProcedureDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOneArg;
+begin
+  TestCallingConventions(@DoTestProcedureOneArgDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOneVarArg;
+begin
+  TestCallingConventions(@DoTestProcedureOneVarArgDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOneConstArg;
+begin
+  TestCallingConventions(@DoTestProcedureOneConstArgDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOneOutArg;
+begin
+  TestCallingConventions(@DoTestProcedureOneOutArgDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureTwoArgs;
+begin
+  TestCallingConventions(@DoTestProcedureTwoArgsDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureTwoVarArgs;
+begin
+  TestCallingConventions(@DoTestProcedureTwoVarArgsDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureTwoConstArgs;
+begin
+  TestCallingConventions(@DoTestProcedureTwoConstArgsDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureTwoOutArgs;
+begin
+  TestCallingConventions(@DoTestProcedureTwoOutArgsDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureTwoCombinedArgs;
+begin
+  TestCallingConventions(@DoTestProcedureTwoCombinedArgsDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureTwoCombinedVarArgs;
+begin
+  TestCallingConventions(@DoTestProcedureTwoCombinedVarArgsDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureTwoCombinedConstArgs;
+begin
+  TestCallingConventions(@DoTestProcedureTwoCombinedConstArgsDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureTwoCombinedOutArgs;
+begin
+  TestCallingConventions(@DoTestProcedureTwoCombinedOutArgsDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureDefaultConstArgs;
+begin
+  TestCallingConventions(@DoTestProcedureDefaultConstArgsDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureUntypedArg;
+begin
+  TestCallingConventions(@DoTestProcedureUntypedArgDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureUntypedConstArg;
+begin
+  TestCallingConventions(@DoTestProcedureUntypedConstArgDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureUntypedOutArg;
+begin
+  TestCallingConventions(@DoTestProcedureUntypedOutArgDecl);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureUntypedDefArg;
+begin
+  AssertException('No untyped arg by value',EParserError,@DoTestProcedureUntypedDefArg)
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOneArgDefault;
+begin
+  TestCallingConventions(@DoTestProcedureOneArgDefault);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOneArgDefaultExpr;
+begin
+  TestCallingConventions(@DoTestProcedureOneArgDefaultExpr);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOneArgDefaultSet;
+begin
+  TestCallingConventions(@DoTestProcedureOneArgDefaultSet);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOneVarArgDefault;
+begin
+  TestCallingConventions(@DoTestProcedureOneVarArgDefault);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOneConstArgDefault;
+begin
+  TestCallingConventions(@DoTestProcedureOneConstArgDefault);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOneOutArgDefault;
+begin
+  TestCallingConventions(@DoTestProcedureOneOutArgDefault);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureNoMultiArgDefaults;
+begin
+  AssertParseTypeError('procedure (A,B : Integer = 1)');
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOpenArray;
+begin
+  TestCallingConventions(@DoTestProcedureOpenArray);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureConstOpenArray;
+begin
+  TestCallingConventions(@DoTestProcedureConstOpenArray);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOutOpenArray;
+begin
+  TestCallingConventions(@DoTestProcedureVarOpenArray);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureVarOpenArray;
+begin
+  TestCallingConventions(@DoTestProcedureOutOpenArray);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureArrayOfConst;
+begin
+  TestCallingConventions(@DoTestProcedureArrayOfConst);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOfObject;
+begin
+  TestCallingConventions(@DoTestProcedureOfObject);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureOfObjectOneArg;
+begin
+  TestCallingConventions(@DoTestProcedureOfObjectOneArg);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureIsNested;
+begin
+  TestCallingConventions(@DoTestProcedureIsNested);
+end;
+
+procedure TTestProcedureTypeParser.TestProcedureIsNesteOneArg;
+begin
+  TestCallingConventions(@DoTestProcedureIsNestedOneArg);
+end;
+
+procedure TTestProcedureTypeParser.TestFunction;
+begin
+  TestCallingConventions(@DoTestFunction);
+end;
+
+procedure TTestProcedureTypeParser.TestFunctionOneArg;
+begin
+  TestCallingConventions(@DoTestFunctionOneArg);
+end;
+
+procedure TTestProcedureTypeParser.TestFunctionOfObject;
+begin
+  TestCallingConventions(@DoTestFunctionOfObject);
+end;
+
+procedure TTestProcedureTypeParser.TestFunctionOneArgOfObject;
+begin
+  TestCallingConventions(@DoTestFunctionOneArgOfObject);
+
+end;
+
+{ TTestRecordTypeParser }
+
+function TTestRecordTypeParser.GetField(AIndex: Integer; R: TPasRecordType
+  ): TPasVariable;
+begin
+  AssertNotNull(R);
+  AssertNotNull(R.Members);
+  AssertTrue('Have AIndex elements',R.Members.Count>AIndex);
+  AssertEquals('Correct class in member',TPasVariable,TObject(R.Members[AIndex]).ClassType);
+  Result:=TPasVariable(R.Members[AIndex]);
+end;
+
+function TTestRecordTypeParser.GetField(AIndex: Integer; R: TPasVariant
+  ): TPasVariable;
+begin
+  AssertNotNull(R);
+  AssertNotNull('Have variant members', R.Members);
+  AssertNotNull('Have variant members member list',R.Members.Members);
+  AssertTrue('Have AIndex elements',R.Members.Members.Count>AIndex);
+  AssertEquals('Correct class in member',TPasVariable,TObject(R.Members.members[AIndex]).ClassType);
+  Result:=TPasVariable(R.Members.Members[AIndex]);
+end;
+
+function TTestRecordTypeParser.GetF(AIndex: Integer): TPasVariable;
+begin
+  Result:=GetField(AIndex,GetR);
+end;
+
+function TTestRecordTypeParser.GetR: TPasRecordType;
+begin
+  Result:=TheType as TPasRecordType;
+end;
+
+function TTestRecordTypeParser.GetVariant(AIndex: Integer; R: TPasRecordType
+  ): TPasVariant;
+begin
+  AssertNotNull(R);
+  AssertNotNull(R.Variants);
+  AssertTrue('Have AIndex variant elements',R.Variants.Count>AIndex);
+  AssertEquals('Correct class in variant',TPasVariant,TObject(R.Variants[AIndex]).ClassType);
+  Result:=TPasVariant(R.Variants[AIndex]);
+end;
+
+function TTestRecordTypeParser.GetV(AIndex: Integer): TPasVariant;
+begin
+  Result:=GetVariant(AIndex,GetR);
+end;
+
+procedure TTestRecordTypeParser.TestFields(const Fields: array of string;
+  AHint: String; HaveVariant: Boolean);
+
+Var
+  S : String;
+  I : integer;
+
+begin
+  S:='';
+  For I:=Low(Fields) to High(Fields) do
+    begin
+    if (S<>'') then
+      S:=S+sLineBreak;
+    S:=S+'    '+Fields[i];
+    end;
+  if (S<>'') then
+    S:=S+sLineBreak;
+  S:='record'+sLineBreak+s+'  end';
+  ParseType(S,TPasRecordType,AHint);
+  if HaveVariant then
+    begin
+    AssertNotNull('Have variants',TheRecord.Variants);
+    AssertNotNull('Have variant type',TheRecord.VariantType);
+    end
+  else
+    begin
+    AssertNull('No variants',TheRecord.Variants);
+    AssertNull('No variant type',TheRecord.VariantType);
+    AssertEquals('No variant name','',TheRecord.VariantName);
+    end;
+end;
+
+procedure TTestRecordTypeParser.AssertVariantSelector(AName,AType : string);
+
+begin
+  if (AType='') then
+    AType:='Integer';
+  AssertEquals('Have variant selector storage name',AName,TheRecord.VariantName);
+  AssertNotNull('Have variant selector type',TheRecord.VariantType);
+  AssertEquals('Have variant selector type',TPasUnresolvedTypeRef,TheRecord.VariantType.ClassType);
+  AssertEquals('Have variant selector type name',AType,TheRecord.VariantType.Name);
+end;
+
+
+procedure TTestRecordTypeParser.DoTestEmpty(const AHint: String);
+begin
+  TestFields([],AHint);
+  AssertNotNull('Have members array',TheRecord.Members);
+  AssertEquals('Zero members in array',0,TheRecord.Members.Count);
+end;
+
+procedure TTestRecordTypeParser.AssertVariant1(Hints: TPasMemberHints);
+begin
+  AssertVariant1(Hints,['0']);
+end;
+
+
+procedure TTestRecordTypeParser.AssertVariant1(Hints: TPasMemberHints; VariantLabels : Array of string);
+
+Var
+  I : Integer;
+
+begin
+  AssertNotNull('Have variant 1',Variant1);
+  AssertNotNull('Variant 1 has Values ',Variant1.Values);
+  if Length(VariantLabels)=0 then
+    begin
+    AssertEquals('Have 1 value',1,Variant1.Values.Count);
+    AssertNotNull('Assigned value',Variant1.Values[0]);
+    AssertEquals('Expression',TPrimitiveExpr,TObject(Variant1.Values[0]).CLassType);
+    AssertExpression('First value is 0',TPasExpr(Variant1.Values[0]),pekNumber,'0');
+    end
+  else
+    begin
+    AssertEquals('Have correct number of values',Length(VariantLabels),Variant1.Values.Count);
+    For I:=0 to Length(VariantLabels)-1 do
+      begin
+      AssertEquals(Format('Expression for variant %d',[I]),TPrimitiveExpr,TObject(Variant1.Values[0]).CLassType);
+      AssertExpression(Format('Value %d is %s',[i,VariantLabels[i]]),TPasExpr(Variant1.Values[I]),pekNumber,VariantLabels[i]);
+      end;
+    end;
+  AssertNotNull('Have members',Variant1.Members);
+  AssertNotNull('Have member members',Variant1.Members.Members);
+  AssertNotNull('member 0 not null',Variant1.Members.Members[0]);
+  AssertEquals('Member 0 has correct name',TPasVariable,TObject(Variant1.Members.Members[0]).ClassType);
+  AssertEquals('Member 0 has correct name','y',TPasVariable(Variant1.Members.Members[0]).Name);
+  AssertNotNull('member 0 has not null type',TPasVariable(Variant1.Members.Members[0]).VarType);
+  AssertEquals('member 0 has correct type',TPasUnresolvedTypeRef,TPasVariable(Variant1.Members.Members[0]).VarType.ClassType);
+  AssertEquals('member 0 has correct type name','Integer',TPasVariable(Variant1.Members.Members[0]).VarType.Name);
+  AssertTrue('Field 1 hints match',TPasVariable(Variant1.Members.Members[0]).Hints=Hints)
+end;
+
+procedure TTestRecordTypeParser.AssertVariant2(Hints: TPasMemberHints);
+begin
+  AssertVariant2(Hints,['1']);
+end;
+
+procedure TTestRecordTypeParser.AssertVariant2(Hints: TPasMemberHints; VariantLabels : Array of string);
+
+Var
+  I : Integer;
+
+begin
+  AssertNotNull('Have variant 2',Variant2);
+  AssertNotNull('Variant 2 has Values ',Variant2.Values);
+  if Length(VariantLabels)=0 then
+    begin
+    AssertEquals('Variant 2 has 1 value',2,Variant2.Values.Count);
+    AssertEquals('Expression',TPrimitiveExpr,TObject(Variant2.Values[0]).CLassType);
+    AssertExpression('First value is 1',TPasExpr(Variant2.Values[0]),pekNumber,'1');
+    end
+  else
+    begin
+    AssertEquals('Variant 2 Has correct number of values',Length(VariantLabels),Variant2.Values.Count);
+    For I:=0 to Length(VariantLabels)-1 do
+      begin
+      AssertEquals(Format('Expression for variant %d',[I]),TPrimitiveExpr,TObject(Variant2.Values[I]).CLassType);
+      AssertExpression(Format('Value %d is %s',[i,VariantLabels[i]]),TPasExpr(Variant2.Values[I]),pekNumber,VariantLabels[i]);
+//      AssertEquals(Format('Variant 2, Value %d is %s',[i,VariantLabels[i]]),VariantLabels[i],Variant2.Values[I]);
+      end;
+    end;
+  AssertNotNull('Have members',Variant2.Members);
+  AssertNotNull('Have member members',Variant2.Members.Members);
+  AssertNotNull('member 1 not null',Variant2.Members.Members[0]);
+  AssertEquals('Member 1 has correct name',TPasVariable,TObject(Variant2.Members.Members[0]).ClassType);
+  AssertEquals('Member 1 has correct name','z',TPasVariable(Variant2.Members.Members[0]).Name);
+  AssertNotNull('member 1 has not null type',TPasVariable(Variant2.Members.Members[0]).VarType);
+  AssertEquals('member 1 has correct type',TPasUnresolvedTypeRef,TPasVariable(Variant2.Members.Members[0]).VarType.ClassType);
+  AssertEquals('member 1 has correct type name','Integer',TPasVariable(Variant2.Members.Members[0]).VarType.Name);
+  AssertTrue('Field 1 hints match',TPasVariable(Variant2.Members.Members[0]).Hints=Hints)
+end;
+
+procedure TTestRecordTypeParser.DoTestVariantNoStorage(const AHint: string);
+begin
+  TestFields(['x : integer;','case integer of','0 : (y : integer;)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('','');
+  AssertVariant1([]);
+end;
+
+procedure TTestRecordTypeParser.DoTestDeprecatedVariantNoStorage(
+  const AHint: string);
+begin
+  TestFields(['x : integer;','case integer of','0 : (y : integer deprecated;)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('','');
+  AssertVariant1([hDeprecated]);
+end;
+
+procedure TTestRecordTypeParser.DoTestDeprecatedVariantStorage(
+  const AHint: string);
+begin
+  TestFields(['x : integer;','case s : integer of','0 : (y : integer deprecated;)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('s','');
+  AssertVariant1([hDeprecated]);
+end;
+
+procedure TTestRecordTypeParser.DoTestVariantStorage(const AHint: string);
+begin
+  TestFields(['x : integer;','case s : integer of','0 : (y : integer;)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('s','');
+  AssertVariant1([]);
+end;
+
+procedure TTestRecordTypeParser.DoTestTwoVariantsNoStorage(const AHint: string
+  );
+begin
+  TestFields(['x : integer;','case integer of','0 : (y : integer;);','1 : (z : integer;)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('','');
+  AssertVariant1([]);
+  AssertVariant2([]);
+end;
+
+procedure TTestRecordTypeParser.DoTestTwoVariantsStorage(const AHint: string);
+begin
+  TestFields(['x : integer;','case s : integer of','0 : (y : integer;);','1 : (z : integer;)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('s','');
+  AssertVariant1([]);
+  AssertVariant2([]);
+end;
+
+procedure TTestRecordTypeParser.DoTestTwoVariantsFirstDeprecatedStorage(
+  const AHint: string);
+begin
+  TestFields(['x : integer;','case s : integer of','0 : (y : integer deprecated;);','1 : (z : integer;)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('s','');
+  AssertVariant1([hdeprecated]);
+  AssertVariant2([]);
+end;
+
+procedure TTestRecordTypeParser.DoTestTwoVariantsSecondDeprecatedStorage(
+  const AHint: string);
+begin
+  TestFields(['x : integer;','case s : integer of','0 : (y : integer ;);','1 : (z : integer deprecated;)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('s','');
+  AssertVariant1([]);
+  AssertVariant2([hdeprecated]);
+end;
+
+procedure TTestRecordTypeParser.DoTestVariantTwoLabels(const AHint: string);
+begin
+  TestFields(['x : integer;','case integer of','0,1 : (y : integer)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('','');
+  AssertVariant1([],['0','1']);
+end;
+
+procedure TTestRecordTypeParser.DoTestTwoVariantsTwoLabels(const AHint: string
+  );
+begin
+  TestFields(['x : integer;','case integer of','0,1 : (y : integer);','2,3 : (z : integer);'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('','');
+  AssertVariant1([],['0','1']);
+  AssertVariant2([],['2','3']);
+end;
+
+procedure TTestRecordTypeParser.DoTestVariantNestedRecord(const AHint: string);
+begin
+  TestFields(['x : integer;','case integer of','0 : ( y : record','  z : integer;','end)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('','');
+  AssertRecordVariant(0,[],['0']);
+end;
+
+procedure TTestRecordTypeParser.DoTestVariantNestedVariant(const AHint: string
+  );
+begin
+  TestFields(['x : integer;','case integer of','0 : ( y : record','  z : integer;','  case byte of ','    1 : (i : integer);','    2 : ( j :  byte)', 'end)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('','');
+  AssertRecordVariant(0,[],['0']);
+  AssertRecordVariantVariant(0,'i','Integer',[],['1']);
+  AssertRecordVariantVariant(1,'j','Byte',[],['2'])
+end;
+
+procedure TTestRecordTypeParser.DoTestVariantNestedVariantFirstDeprecated(
+  const AHint: string);
+begin
+  TestFields(['x : integer;','case integer of','0 : ( y : record','  z : integer;','  case byte of ','    1 : (i : integer deprecated);','    2 : ( j :  byte)', 'end)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('','');
+  AssertRecordVariant(0,[],['0']);
+  AssertRecordVariantVariant(0,'i','Integer',[hDeprecated],['1']);
+  AssertRecordVariantVariant(1,'j','Byte',[],['2'])
+end;
+
+procedure TTestRecordTypeParser.DoTestVariantNestedVariantSecondDeprecated(
+  const AHint: string);
+begin
+  TestFields(['x : integer;','case integer of','0 : ( y : record','  z : integer;','  case byte of ','    1 : (i : integer );','    2 : ( j :  byte deprecated)', 'end)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('','');
+  AssertRecordVariant(0,[],['0']);
+  AssertRecordVariantVariant(0,'i','Integer',[],['1']);
+  AssertRecordVariantVariant(1,'j','Byte',[hDeprecated],['2'])
+end;
+
+procedure TTestRecordTypeParser.DoTestVariantNestedVariantBothDeprecated(const AHint: string);
+
+begin
+  TestFields(['x : integer;','case integer of','0 : ( y : record','  z : integer;','  case byte of ','    1 : (i : integer deprecated );','    2 : ( j :  byte deprecated)', 'end)'],AHint,True);
+  AssertField1([]);
+  AssertVariantSelector('','');
+  AssertRecordVariant(0,[],['0']);
+  AssertRecordVariantVariant(0,'i','Integer',[hdeprecated],['1']);
+  AssertRecordVariantVariant(1,'j','Byte',[hDeprecated],['2'])
+end;
+
+procedure TTestRecordTypeParser.TestEmpty;
+begin
+  DoTestEmpty('')
+end;
+
+procedure TTestRecordTypeParser.TestEmptyDeprecated;
+begin
+  DoTestEmpty('Deprecated')
+end;
+
+procedure TTestRecordTypeParser.TestEmptyPlatform;
+begin
+  DoTestEmpty('Platform')
+end;
+
+procedure TTestRecordTypeParser.AssertField1(Hints : TPasMemberHints);
+
+begin
+  AssertEquals('Member 1 field type',TPasVariable,TObject(TheRecord.Members[0]).ClassType);
+  AssertEquals('Field 1 name','x',Field1.Name);
+  AssertNotNull('Have 1 Field type',Field1.VarType);
+  AssertEquals('Field 1 type',TPasUnresolvedTypeRef,Field1.VarType.ClassType);
+  AssertEquals('Field 1 type name','Integer',Field1.VarType.Name);
+  AssertTrue('Field 1 hints match',Field1.Hints=Hints)
+end;
+
+procedure TTestRecordTypeParser.AssertField2(Hints : TPasMemberHints);
+
+begin
+  AssertEquals('Member 2 field type',TPasVariable,TObject(TheRecord.Members[1]).ClassType);
+  AssertEquals('Field 2 name','y',Field2.Name);
+  AssertNotNull('Have 2 Field type',Field2.VarType);
+  AssertEquals('Field 2 type',TPasUnresolvedTypeRef,Field2.VarType.ClassType);
+  AssertEquals('Field 2 type name','Integer',Field2.VarType.Name);
+  AssertTrue('Field 2 hints match',Field2.Hints=Hints)
+end;
+
+procedure TTestRecordTypeParser.AssertOneIntegerField(Hints : TPasMemberHints);
+
+begin
+  AssertEquals('One field',1,TheRecord.Members.Count);
+  AssertField1(Hints);
+end;
+
+procedure TTestRecordTypeParser.AssertTwoIntegerFields(Hints1,Hints2: TPasMemberHints);
+
+begin
+  AssertEquals('Two field',2,TheRecord.Members.Count);
+  AssertField1(Hints1);
+  AssertField2(Hints2);
+end;
+
+procedure TTestRecordTypeParser.AssertRecordField(AIndex: Integer;
+  Hints: TPasMemberHints);
+
+Var
+  F : TPasVariable;
+  R : TPasRecordtype;
+
+begin
+  AssertEquals('Member 2 field type',TPasVariable,TObject(TheRecord.Members[AIndex]).ClassType);
+  F:=GetF(AIndex);
+  if AIndex=1 then
+    AssertEquals('Field 2 name','y',F.Name)
+  else
+    AssertEquals('Field 1 name','x',F.Name);
+  AssertNotNull('Have 2 Field type',F.VarType);
+  AssertEquals('Field 2 type',TPasRecordType,F.VarType.ClassType);
+  R:=F.VarType as TPasRecordType;
+  AssertNotNull('Record field has members',R.Members);
+  AssertEquals('Record field has 1 member',1,R.Members.Count);
+  AssertTrue('Record field hints match',F.Hints=Hints)
+end;
+
+procedure TTestRecordTypeParser.AssertRecordVariant(AIndex: Integer;
+  Hints: TPasMemberHints; VariantLabels : Array of string);
+
+Var
+  F : TPasVariant;
+  V : TPasVariable;
+  R : TPasRecordtype;
+  I : Integer;
+  MN : String;
+
+begin
+  F:=GetV(AIndex);
+  MN:='Variant '+IntToStr(AIndex)+' ';
+  AssertNotNull('Have variant 1',F);
+  AssertEquals('Have correct number of values',Length(VariantLabels),F.Values.Count);
+  For I:=0 to Length(VariantLabels)-1 do
+    begin
+    AssertEquals(Format('Expression for variant %d',[I]),TPrimitiveExpr,TObject(Variant1.Values[i]).CLassType);
+    AssertExpression(Format('Value %d is %s',[i,VariantLabels[i]]),TPasExpr(Variant1.Values[I]),pekNumber,VariantLabels[i]);
+    end;
+  V:=GetField(0,F);
+  AssertEquals(MN+'has correct name','y',V.Name);
+  AssertNotNull(MN+'has not null type',V.VarType);
+  AssertEquals(MN+'has correct type',TPasRecordType,V.VarType.ClassType);
+  AssertTrue(MN+'hints match',V.Hints=Hints);
+  R:=TPasVariable(F.Members.Members[0]).VarType as TPasRecordType;
+  V:=GetField(0,R);
+  AssertEquals('Field 1 has correct name','z',V.Name);
+  AssertNotNull('Record field has members',R.Members);
+  AssertEquals('Record field has 1 member',1,R.Members.Count);
+
+end;
+
+procedure TTestRecordTypeParser.AssertRecordVariantVariant(AIndex: Integer; Const AFieldName,ATypeName: string;
+  Hints: TPasMemberHints; VariantLabels: array of string);
+
+Var
+  F : TPasVariant;
+  V : TPasVariable;
+  R : TPasRecordtype;
+  I : Integer;
+  MN : String;
+
+begin
+  F:=GetV(0);
+  MN:='Nested Variant '+IntToStr(AIndex)+' ';
+  AssertNotNull('Have variant 1',F);
+  AssertEquals('Have correct number of values',1,F.Values.Count);
+  AssertEquals('Expression',TPrimitiveExpr,TObject(F.Values[0]).CLassType);
+  AssertExpression('First value is 0',TPasExpr(F.Values[0]),pekNumber,'0');
+  // First variant, Y, record
+  V:=GetField(0,F);
+  AssertEquals(MN+'has correct name','y',V.Name);
+  AssertNotNull(MN+'has not null type',V.VarType);
+  AssertEquals(MN+'has correct type',TPasRecordType,V.VarType.ClassType);
+  R:=TPasVariable(F.Members.Members[0]).VarType as TPasRecordType;
+  AssertNotNull('Record field has members',R.Members);
+  AssertEquals('Record field has 2 members',1,R.Members.Count);
+  // First variant
+  F:=GetVariant(Aindex,R);
+  // First field of first variant, i
+  AssertEquals('Have correct number of values',Length(VariantLabels),F.Values.Count);
+  For I:=0 to Length(VariantLabels)-1 do
+    begin
+    AssertEquals(Format('Expression for variant %d',[I]),TPrimitiveExpr,TObject(F.Values[i]).CLassType);
+    AssertExpression(Format('Value %d is %s',[i,VariantLabels[i]]),TPasExpr(F.Values[I]),pekNumber,VariantLabels[i]);
+    end;
+  V:=GetField(0,F);
+  AssertEquals('Nested Variant 0 has correct name',AFieldName,V.Name);
+  AssertEquals('Nested variant 0 has correct type',TPasUnresolvedTypeRef,V.VarType.ClassType);
+  AssertEquals('Nested variant 0 has correct type name',ATypeName,V.VarType.Name);
+  AssertTrue(MN+'hints match',V.Hints=Hints);
+end;
+
+procedure TTestRecordTypeParser.TestOneField;
+begin
+  TestFields(['x : integer'],'',False);
+  AssertOneIntegerField([]);
+end;
+
+procedure TTestRecordTypeParser.TestOneFieldDeprecated;
+begin
+  TestFields(['x : integer'],'deprecated',False);
+  AssertOneIntegerField([]);
+end;
+
+procedure TTestRecordTypeParser.TestOneFieldPlatform;
+begin
+  TestFields(['x : integer'],'platform',False);
+  AssertOneIntegerField([]);
+end;
+
+procedure TTestRecordTypeParser.TestOneFieldSemicolon;
+begin
+  TestFields(['x : integer;'],'',False);
+  AssertOneIntegerField([]);
+end;
+
+procedure TTestRecordTypeParser.TestOneFieldSemicolonDeprecated;
+begin
+  TestFields(['x : integer;'],'deprecated',False);
+  AssertOneIntegerField([]);
+
+end;
+
+procedure TTestRecordTypeParser.TestOneFieldSemicolonPlatform;
+begin
+  TestFields(['x : integer;'],'platform',False);
+  AssertOneIntegerField([]);
+end;
+
+procedure TTestRecordTypeParser.TestOneDeprecatedField;
+begin
+  TestFields(['x : integer deprecated;'],'',False);
+  AssertOneIntegerField([hDeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestOneDeprecatedFieldDeprecated;
+begin
+  TestFields(['x : integer deprecated;'],'deprecated',False);
+  AssertOneIntegerField([hDeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestOneDeprecatedFieldPlatform;
+begin
+  TestFields(['x : integer deprecated;'],'platform',False);
+  AssertOneIntegerField([hDeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestOnePlatformField;
+begin
+  TestFields(['x : integer platform;'],'',False);
+  AssertOneIntegerField([hplatform]);
+end;
+
+procedure TTestRecordTypeParser.TestOnePlatformFieldDeprecated;
+begin
+  TestFields(['x : integer platform;'],'Deprecated',False);
+  AssertOneIntegerField([hplatform]);
+end;
+
+procedure TTestRecordTypeParser.TestOnePlatformFieldPlatform;
+begin
+  TestFields(['x : integer platform;'],'Platform',False);
+  AssertOneIntegerField([hplatform]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFields;
+begin
+  TestFields(['x : integer;','y : integer'],'',False);
+  AssertTwoIntegerFields([],[]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldDeprecated;
+begin
+  TestFields(['x : integer;','y : integer'],'deprecated',False);
+  AssertTwoIntegerFields([],[]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldPlatform;
+begin
+  TestFields(['x : integer;','y : integer'],'platform',False);
+  AssertTwoIntegerFields([],[]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsFirstDeprecated;
+begin
+  TestFields(['x : integer deprecated;','y : integer'],'',False);
+  AssertTwoIntegerFields([hdeprecated],[]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsFirstDeprecatedDeprecated;
+begin
+  TestFields(['x : integer deprecated;','y : integer'],'deprecated',False);
+  AssertTwoIntegerFields([hdeprecated],[]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsFirstDeprecatedPlatform;
+begin
+  TestFields(['x : integer deprecated;','y : integer'],'platform',False);
+  AssertTwoIntegerFields([hdeprecated],[]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsSecondDeprecated;
+begin
+  TestFields(['x : integer;','y : integer deprecated;'],'',False);
+  AssertTwoIntegerFields([],[hdeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsSecondDeprecatedDeprecated;
+begin
+  TestFields(['x : integer;','y : integer deprecated;'],'deprecated',False);
+  AssertTwoIntegerFields([],[hdeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsSecondDeprecatedPlatform;
+begin
+  TestFields(['x : integer;','y : integer deprecated;'],'platform',False);
+  AssertTwoIntegerFields([],[hdeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsBothDeprecated;
+begin
+  TestFields(['x : integer deprecated;','y : integer deprecated;'],'',False);
+  AssertTwoIntegerFields([hdeprecated],[hdeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsBothDeprecatedDeprecated;
+begin
+  TestFields(['x : integer deprecated;','y : integer deprecated;'],'deprecated',False);
+  AssertTwoIntegerFields([hdeprecated],[hdeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsBothDeprecatedPlatform;
+begin
+  TestFields(['x : integer deprecated;','y : integer deprecated;'],'platform',False);
+  AssertTwoIntegerFields([hdeprecated],[hdeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsCombined;
+begin
+  TestFields(['x,y : integer;'],'',False);
+  AssertTwoIntegerFields([],[]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsCombinedDeprecated;
+begin
+  TestFields(['x,y : integer;'],'deprecated',False);
+  AssertTwoIntegerFields([],[]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoFieldsCombinedPlatform;
+begin
+  TestFields(['x,y : integer;'],'platform',False);
+  AssertTwoIntegerFields([],[]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoDeprecatedFieldsCombined;
+begin
+  TestFields(['x,y : integer deprecated;'],'',False);
+  AssertTwoIntegerFields([hdeprecated],[hdeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoDeprecatedFieldsCombinedDeprecated;
+begin
+  TestFields(['x,y : integer deprecated;'],'deprecated',False);
+  AssertTwoIntegerFields([hdeprecated],[hdeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestTwoDeprecatedFieldsCombinedPlatform;
+begin
+  TestFields(['x,y : integer deprecated;'],'platform',False);
+  AssertTwoIntegerFields([hdeprecated],[hdeprecated]);
+end;
+
+procedure TTestRecordTypeParser.TestNested;
+begin
+  TestFields(['x : integer;','y : record','  z : integer;','end'],'',False);
+  AssertField1([]);
+  AssertRecordField(1,[])
+end;
+
+procedure TTestRecordTypeParser.TestNestedSemicolon;
+begin
+  TestFields(['x : integer;','y : record','  z : integer;','end;'],'',False);
+  AssertField1([]);
+  AssertRecordField(1,[])
+end;
+
+procedure TTestRecordTypeParser.TestNestedSemicolonDeprecated;
+begin
+  TestFields(['x : integer;','y : record','  z : integer;','end;'],'deprecated',False);
+  AssertField1([]);
+  AssertRecordField(1,[])
+end;
+
+procedure TTestRecordTypeParser.TestNestedSemicolonPlatform;
+begin
+  TestFields(['x : integer;','y : record','  z : integer;','end;'],'platform',False);
+  AssertField1([]);
+  AssertRecordField(1,[])
+end;
+
+procedure TTestRecordTypeParser.TestNestedDeprecated;
+begin
+  TestFields(['x : integer;','y : record','  z : integer;','end'],'deprecated',False);
+  AssertField1([]);
+  AssertRecordField(1,[])
+end;
+
+procedure TTestRecordTypeParser.TestNestedPlatform;
+begin
+  TestFields(['x : integer;','y : record','  z : integer;','end'],'platform',False);
+  AssertField1([]);
+  AssertRecordField(1,[])
+end;
+
+procedure TTestRecordTypeParser.TestNestedFirst;
+begin
+  TestFields(['x : record','  z : integer;','end;','y : integer;'],'',False);
+  AssertField2([]);
+  AssertRecordField(0,[])
+end;
+
+procedure TTestRecordTypeParser.TestNestedFirstDeprecated;
+begin
+  TestFields(['x : record','  z : integer;','end;','y : integer;'],'deprecated',False);
+  AssertField2([]);
+  AssertRecordField(0,[])
+end;
+
+procedure TTestRecordTypeParser.TestNestedFirstPlatform;
+begin
+  TestFields(['x : record','  z : integer;','end;','y : integer;'],'platform',False);
+  AssertField2([]);
+  AssertRecordField(0,[])
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedNested;
+begin
+  TestFields(['x : integer;','y : record','  z : integer;','end deprecated;'],'',False);
+  AssertField1([]);
+  AssertRecordField(1,[hdeprecated])
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedNestedDeprecated;
+begin
+  TestFields(['x : integer;','y : record','  z : integer;','end deprecated;'],'deprecated',False);
+  AssertField1([]);
+  AssertRecordField(1,[hdeprecated])
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedNestedPlatform;
+begin
+  TestFields(['x : integer;','y : record','  z : integer;','end deprecated;'],'platform',False);
+  AssertField1([]);
+  AssertRecordField(1,[hdeprecated])
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedNestedFirst;
+begin
+  TestFields(['x : record','  z : integer;','end deprecated;','y : integer;'],'',False);
+  AssertField2([]);
+  AssertRecordField(0,[hdeprecated])
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedNestedFirstDeprecated;
+begin
+  TestFields(['x : record','  z : integer;','end deprecated;','y : integer;'],'deprecated',False);
+  AssertField2([]);
+  AssertRecordField(0,[hdeprecated])
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedNestedFirstPlatform;
+begin
+  TestFields(['x : record','  z : integer;','end deprecated;','y : integer;'],'platform',False);
+  AssertField2([]);
+  AssertRecordField(0,[hdeprecated])
+end;
+
+procedure TTestRecordTypeParser.TestVariantNoStorage;
+begin
+  DoTestVariantNoStorage('');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNoStorageDeprecated;
+
+begin
+  DoTestVariantNoStorage('deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNoStoragePlatform;
+
+begin
+  DoTestVariantNoStorage('platform');
+end;
+
+procedure TTestRecordTypeParser.TestVariantStorage;
+begin
+  DoTestVariantStorage('');
+end;
+
+procedure TTestRecordTypeParser.TestVariantStorageDeprecated;
+begin
+  DoTestVariantStorage('deprecated');
+
+end;
+
+procedure TTestRecordTypeParser.TestVariantStoragePlatform;
+begin
+  DoTestVariantStorage('platform');
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedVariantNoStorage;
+begin
+  DoTestDeprecatedVariantNoStorage('');
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedVariantNoStorageDeprecated;
+begin
+  DoTestDeprecatedVariantNoStorage('Deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedVariantNoStoragePlatform;
+begin
+  DoTestDeprecatedVariantNoStorage('Platform');
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedVariantStorage;
+begin
+  DoTestDeprecatedVariantStorage('');
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedVariantStorageDeprecated;
+begin
+  DoTestDeprecatedVariantStorage('Deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestDeprecatedVariantStoragePlatform;
+begin
+  DoTestDeprecatedVariantStorage('Platform');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsNoStorage;
+begin
+  DoTestTwoVariantsNoStorage('');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsNoStorageDeprecated;
+begin
+  DoTestTwoVariantsNoStorage('deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsNoStoragePlatform;
+begin
+  DoTestTwoVariantsNoStorage('platform');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsStorage;
+begin
+  DoTestTwoVariantsStorage('');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsStorageDeprecated;
+begin
+  DoTestTwoVariantsStorage('deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsStoragePlatform;
+begin
+  DoTestTwoVariantsStorage('platform');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsFirstDeprecatedStorage;
+begin
+  DoTestTwoVariantsFirstDeprecatedStorage('');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsFirstDeprecatedStorageDeprecated;
+begin
+  DoTestTwoVariantsFirstDeprecatedStorage('deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsFirstDeprecatedStoragePlatform;
+begin
+  DoTestTwoVariantsFirstDeprecatedStorage('platform');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsSecondDeprecatedStorage;
+begin
+  DoTestTwoVariantsSecondDeprecatedStorage('');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsSecondDeprecatedStorageDeprecated;
+begin
+  DoTestTwoVariantsSecondDeprecatedStorage('deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsSecondDeprecatedStoragePlatform;
+begin
+  DoTestTwoVariantsSecondDeprecatedStorage('platform');
+end;
+
+procedure TTestRecordTypeParser.TestVariantTwoLabels;
+begin
+  DoTestVariantTwoLabels('');
+end;
+
+procedure TTestRecordTypeParser.TestVariantTwoLabelsDeprecated;
+begin
+  DoTestVariantTwoLabels('Deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestVariantTwoLabelsPlatform;
+begin
+  DoTestVariantTwoLabels('Platform');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsTwoLabels;
+begin
+  DoTestTwoVariantsTwoLabels('');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsTwoLabelsDeprecated;
+begin
+  DoTestTwoVariantsTwoLabels('Deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestTwoVariantsTwoLabelsPlatform;
+begin
+  DoTestTwoVariantsTwoLabels('Platform');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedRecord;
+begin
+  DoTestVariantNestedRecord('');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedRecordDeprecated;
+begin
+  DoTestVariantNestedRecord('Deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedRecordPlatform;
+begin
+  DoTestVariantNestedRecord('Platform');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariant;
+begin
+  DoTestVariantNestedVariant('');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantDeprecated;
+begin
+  DoTestVariantNestedVariant('deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantPlatForm;
+begin
+  DoTestVariantNestedVariant('Platform');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantFirstDeprecated;
+begin
+  DoTestVariantNestedVariantFirstDeprecated('');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantFirstDeprecatedDeprecated;
+begin
+  DoTestVariantNestedVariantFirstDeprecated('deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantFirstDeprecatedPlatform;
+begin
+  DoTestVariantNestedVariantFirstDeprecated('platform');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantSecondDeprecated;
+begin
+  DoTestVariantNestedVariantSecondDeprecated('');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantSecondDeprecatedDeprecated;
+begin
+  DoTestVariantNestedVariantSecondDeprecated('deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantSecondDeprecatedPlatform;
+begin
+  DoTestVariantNestedVariantSecondDeprecated('platform');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantBothDeprecated;
+begin
+  DoTestVariantNestedVariantBothDeprecated('');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantBothDeprecatedDeprecated;
+begin
+  DoTestVariantNestedVariantBothDeprecated('deprecated');
+end;
+
+procedure TTestRecordTypeParser.TestVariantNestedVariantBothDeprecatedPlatform;
+begin
+  DoTestVariantNestedVariantBothDeprecated('platform');
+end;
+
+{ TBaseTestTypeParser }
+
+function TBaseTestTypeParser.ParseType(ASource: String; ATypeClass: TClass;Const AHint : String = ''): TPasType;
+
+Var
+  D : String;
+begin
+  Hint:=AHint;
+  Add('Type');
+  D:='A = '+ASource;
+  If Hint<>'' then
+    D:=D+' '+Hint;
+  Add('  '+D+';');
+//  Writeln(source.text);
+  ParseDeclarations;
+  AssertEquals('One type definition',1,Declarations.Types.Count);
+  If (AtypeClass<>Nil) then
+    AssertEquals('First declaration is type definition.',ATypeClass,TObject(Declarations.Types[0]).ClassType);
+  AssertEquals('First declaration has correct name.','A',TPasType(Declarations.Types[0]).Name);
+  Result:=TPasType(Declarations.Types[0]);
+  FType:=Result;
+  Definition:=Result;
+  if (Hint<>'') then
+    CheckHint(TPasMemberHint(Getenumvalue(typeinfo(TPasMemberHint),'h'+Hint)));
+end;
+
+procedure TBaseTestTypeParser.AssertParseTypeError(ASource: String);
+begin
+  try
+    ParseType(ASource,Nil,'');
+    Fail('Expected parser error');
+  except
+    // all OK.
+  end;
+end;
+
+procedure TBaseTestTypeParser.SetUp;
+begin
+  Inherited;
+  FErrorSource:='';
+  FHint:='';
+  FType:=Nil;
+end;
+
+procedure TBaseTestTypeParser.TearDown;
+begin
+  inherited TearDown;
+  FType:=Nil;
+end;
+
+{ TTestTypeParser }
+
+procedure TTestTypeParser.DoTestAliasType(const AnAliasType: String;
+  const AHint: String);
+begin
+  ParseType(AnAliasType,TPasAliasType,AHint);
+  AssertEquals('Unresolved type',TPasUnresolvedTypeRef,TPasAliasType(TheType).DestType.ClassType);
+end;
+
+procedure TTestTypeParser.DoTestStringType(const AnAliasType: String;
+  const AHint: String);
+begin
+  ParseType(AnAliasType,TPasAliasType,AHint);
+  AssertEquals('String type',TPasStringType,TPasAliasType(TheType).DestType.ClassType);
+end;
+
+procedure TTestTypeParser.DoTypeError(Const AMsg,ASource : string);
+
+begin
+  FErrorSource:=ASource;
+  AssertException(AMsg,EParserError,@DoParseError);
+end;
+
+procedure TTestTypeParser.DoParseError;
+begin
+  ParseType(FErrorSource,Nil);
+end;
+
+procedure TTestTypeParser.DoParsePointer(const ASource: String;
+  const AHint: String; ADestType: TClass);
+
+begin
+  ParseType('^'+ASource,TPasPointerType,AHint);
+  if ADestType = Nil then
+    ADestType:=TPasUnresolvedTypeRef;
+  AssertEquals('Destination type '+ADestType.ClassName,ADestType,TPasPointerType(TheType).DestType.ClassType);
+end;
+
+procedure TTestTypeParser.DoParseArray(const ASource: String;
+  const AHint: String; ADestType: TClass);
+begin
+  ParseType(ASource,TPasArrayType,AHint);
+  if ADestType = Nil then
+    ADestType:=TPasUnresolvedTypeRef;
+  AssertEquals('Destination type '+ADestType.ClassName,ADestType,TPasArrayType(TheType).ElType.ClassType);
+end;
+
+procedure TTestTypeParser.DoParseEnumerated(const ASource: String;
+  const AHint: String; ACount: integer);
+
+Var
+  I : Integer;
+
+begin
+  ParseType(ASource,TPasEnumType,AHint);
+  AssertNotNull('Have values',TPasEnumType(TheType).Values);
+  AssertEquals('Value count',ACount,TPasEnumType(TheType).Values.Count);
+  For I:=0 to TPasEnumType(TheType).Values.Count-1 do
+    AssertEquals('Enum value typed element '+IntToStr(I),TPasEnumValue,TObject(TPasEnumType(TheType).Values[i]).ClassType);
+end;
+
+procedure TTestTypeParser.DoTestFileType(const AType: String;
+  const AHint: String; ADestType: TClass);
+begin
+  ParseType('File of '+AType,TPasFileType,AHint);
+  AssertNotNull('Have element type',TPasFileType(TheType).ElType);
+  if ADestType = Nil then
+    ADestType:=TPasUnresolvedTypeRef;
+  AssertEquals('Element type '+ADestType.ClassName,ADestType,TPasFileType(TheType).ElType.ClassType);
+end;
+
+procedure TTestTypeParser.DoTestRangeType(const AStart, AStop, AHint: String);
+begin
+  ParseType(AStart+'..'+AStop,TPasRangeType,AHint);
+  AssertEquals('Range start',AStart,TPasRangeType(TheType).RangeStart);
+  AssertEquals('Range start',AStop,TPasRangeType(TheType).RangeEnd);
+end;
+
+procedure TTestTypeParser.DoParseSimpleSet(const ASource: String;
+  const AHint: String);
+begin
+  ParseType('Set of '+ASource,TPasSetType,AHint);
+  AssertNotNull('Have enumtype',TPasSetType(TheType).EnumType);
+  AssertEquals('Element type ',TPasUnresolvedTypeRef,TPasSetType(TheType).EnumType.ClassType);
+end;
+
+procedure TTestTypeParser.DoParseComplexSet(const ASource: String;
+  const AHint: String);
+
+begin
+  ParseType('Set of '+ASource,TPasSetType,AHint);
+  AssertNotNull('Have enumtype',TPasSetType(TheType).EnumType);
+  AssertEquals('Element type ',TPasEnumType,TPasSetType(TheType).EnumType.ClassType);
+end;
+
+procedure TTestTypeParser.DoParseRangeSet(const ASource: String;
+  const AHint: String);
+
+begin
+  ParseType('Set of '+ASource,TPasSetType,AHint);
+  AssertNotNull('Have enumtype',TPasSetType(TheType).EnumType);
+  AssertEquals('Element type ',TPasRangeType,TPasSetType(TheType).EnumType.ClassType);
+end;
+
+procedure TTestTypeParser.DoTestComplexSet;
+
+Var
+  I : integer;
+
+begin
+  AssertNotNull('Have values',TPasEnumType(TPasSetType(TheType).EnumType).Values);
+  AssertEquals('Have 3 values',3, TPasEnumType(TPasSetType(TheType).EnumType).Values.Count);
+  For I:=0 to TPasEnumType(TPasSetType(TheType).EnumType).Values.Count-1 do
+    AssertEquals('Enum value typed element '+IntToStr(I),TPasEnumValue,TObject(TPasEnumType(TPasSetType(TheType).EnumType).Values[i]).ClassType);
+  AssertEquals('First enumerated value','one',TPasEnumValue(TPasEnumType(TPasSetType(TheType).EnumType).Values[0]).Name);
+  AssertEquals('Second enumerated value','two',TPasEnumValue(TPasEnumType(TPasSetType(TheType).EnumType).Values[1]).Name);
+  AssertEquals('Third enumerated value','three',TPasEnumValue(TPasEnumType(TPasSetType(TheType).EnumType).Values[2]).Name);
+  AssertEquals('Assigned value first enumerated empty','',TPasEnumValue(TPasEnumType(TPasSetType(TheType).EnumType).Values[0]).AssignedValue);
+  AssertEquals('Assigned value second enumerated empty','',TPasEnumValue(TPasEnumType(TPasSetType(TheType).EnumType).Values[1]).AssignedValue);
+  AssertEquals('Assigned value third enumerated empty','',TPasEnumValue(TPasEnumType(TPasSetType(TheType).EnumType).Values[2]).AssignedValue);
+end;
+
+procedure TTestTypeParser.DoTestClassOf(const AHint: string);
+
+begin
+  ParseType('Class of TSomeClass',TPasClassOfType,AHint);
+  AssertNotNull('Have class type',TPasClassOfType(TheType).DestType);
+  AssertEquals('Element type ',TPasUnresolvedTypeRef,TPasClassOfType(TheType).DestType.ClassType);
+end;
+
+procedure TTestTypeParser.TestAliasType;
+begin
+  DoTestAliasType('othertype','');
+  AssertEquals('Unresolved type name ','othertype',TPasUnresolvedTypeRef(TPasAliasType(TheType).DestType).name);
+end;
+
+procedure TTestTypeParser.TestCrossUnitAliasType;
+begin
+  DoTestAliasType('otherunit.othertype','');
+end;
+
+procedure TTestTypeParser.TestAliasTypeDeprecated;
+begin
+  DoTestALiasType('othertype','deprecated');
+end;
+
+procedure TTestTypeParser.TestAliasTypePlatform;
+begin
+  DoTestALiasType('othertype','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeByte;
+begin
+  DoTestAliasType('BYTE','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeByteDeprecated;
+begin
+  DoTestAliasType('BYTE','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeBytePlatform;
+begin
+  DoTestAliasType('BYTE','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeBoolean;
+begin
+  DoTestAliasType('BOOLEAN','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeBooleanDeprecated;
+begin
+  DoTestAliasType('BOOLEAN','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeBooleanPlatform;
+begin
+  DoTestAliasType('BOOLEAN','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeChar;
+begin
+  DoTestAliasType('CHAR','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeCharDeprecated;
+begin
+  DoTestAliasType('CHAR','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeCharPlatform;
+begin
+  DoTestAliasType('CHAR','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeInteger;
+begin
+  DoTestAliasType('INTEGER','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeIntegerDeprecated;
+begin
+  DoTestAliasType('INTEGER','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeIntegerPlatform;
+begin
+  DoTestAliasType('INTEGER','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeInt64;
+begin
+  DoTestAliasType('INT64','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeInt64Deprecated;
+begin
+  DoTestAliasType('INT64','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeInt64Platform;
+begin
+  DoTestAliasType('INT64','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeLongInt;
+begin
+  DoTestAliasType('LONGINT','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeLongIntDeprecated;
+begin
+  DoTestAliasType('LONGINT','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeLongIntPlatform;
+begin
+  DoTestAliasType('LONGINT','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeLongWord;
+begin
+  DoTestAliasType('LONGWORD','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeLongWordDeprecated;
+begin
+  DoTestAliasType('LONGWORD','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeLongWordPlatform;
+begin
+  DoTestAliasType('LONGWORD','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeDouble;
+begin
+  DoTestAliasType('Double','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeDoubleDeprecated;
+begin
+  DoTestAliasType('Double','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeDoublePlatform;
+begin
+  DoTestAliasType('Double','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeShortInt;
+begin
+  DoTestAliasType('SHORTINT','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeShortIntDeprecated;
+begin
+  DoTestAliasType('SHORTINT','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeShortIntPlatform;
+begin
+  DoTestAliasType('SHORTINT','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeSmallInt;
+begin
+  DoTestAliasType('SMALLINT','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeSmallIntDeprecated;
+begin
+  DoTestAliasType('SMALLINT','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeSmallIntPlatform;
+begin
+  DoTestAliasType('SMALLINT','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeString;
+begin
+  DoTestAliasType('STRING','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeStringDeprecated;
+begin
+  DoTestAliasType('STRING','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeStringPlatform;
+begin
+  DoTestAliasType('STRING','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeStringSize;
+begin
+  DoTestStringType('String[10]','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeStringSizeIncomplete;
+begin
+  DoTypeError('Incomplete string: missing ]','string[10');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeStringSizeWrong;
+begin
+  DoTypeError('Incomplete string, ) instead of ]','string[10)');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeStringSizeDeprecated;
+begin
+  DoTestStringType('String[10]','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeStringSizePlatform;
+begin
+  DoTestStringType('String[10]','Platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeWord;
+BEGIN
+  DoTestAliasType('WORD','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeWordDeprecated;
+begin
+  DoTestAliasType('WORD','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeWordPlatform;
+begin
+  DoTestAliasType('WORD','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeQWord;
+BEGIN
+  DoTestAliasType('QWORD','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeQWordDeprecated;
+begin
+  DoTestAliasType('QWORD','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeQWordPlatform;
+begin
+  DoTestAliasType('QWORD','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeCardinal;
+begin
+  DoTestAliasType('CARDINAL','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeCardinalDeprecated;
+begin
+  DoTestAliasType('CARDINAL','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeCardinalPlatform;
+begin
+  DoTestAliasType('CARDINAL','platform');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeWideChar;
+begin
+  DoTestAliasType('WIDECHAR','');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeWideCharDeprecated;
+begin
+  DoTestAliasType('WIDECHAR','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleTypeWideCharPlatform;
+begin
+  DoTestAliasType('WIDECHAR','platform');
+end;
+
+procedure TTestTypeParser.TestPointerSimple;
+begin
+  DoParsePointer('integer','');
+end;
+
+procedure TTestTypeParser.TestPointerSimpleDeprecated;
+begin
+  DoParsePointer('integer','deprecated');
+end;
+
+procedure TTestTypeParser.TestPointerSimplePlatform;
+begin
+  DoParsePointer('integer','platform');
+end;
+
+procedure TTestTypeParser.TestStaticArray;
+begin
+  DoParseArray('array [0..2] of integer','',Nil);
+  AssertEquals('Array type','0..2',TPasArrayType(TheType).IndexRange);
+end;
+
+procedure TTestTypeParser.TestStaticArrayDeprecated;
+begin
+  DoParseArray('array [0..2] of integer','deprecated',Nil);
+  AssertEquals('Array type','0..2',TPasArrayType(TheType).IndexRange);
+end;
+
+procedure TTestTypeParser.TestStaticArrayPlatform;
+begin
+  DoParseArray('array [0..2] of integer','platform',Nil);
+  AssertEquals('Array type','0..2',TPasArrayType(TheType).IndexRange);
+end;
+
+procedure TTestTypeParser.TestStaticArrayPacked;
+begin
+  DoParseArray('packed array [0..2] of integer','',Nil);
+  AssertEquals('Array type','0..2',TPasArrayType(TheType).IndexRange);
+  AssertEquals('Packed',True,TPasArrayType(TheType).IsPacked);
+end;
+
+procedure TTestTypeParser.TestStaticArrayTypedIndex;
+begin
+  DoParseArray('array [Boolean] of integer','',Nil);
+  AssertEquals('Array type','Boolean',TPasArrayType(TheType).IndexRange);
+end;
+
+procedure TTestTypeParser.TestDynamicArray;
+begin
+  DoParseArray('array of integer','',Nil);
+  AssertEquals('Array type','',TPasArrayType(TheType).IndexRange);
+end;
+
+procedure TTestTypeParser.TestSimpleEnumerated;
+
+begin
+  DoParseEnumerated('(one,two,three)','',3);
+  AssertEquals('First enumerated value','one',TPasEnumValue(TPasEnumType(TheType).Values[0]).Name);
+  AssertEquals('Second enumerated value','two',TPasEnumValue(TPasEnumType(TheType).Values[1]).Name);
+  AssertEquals('Third enumerated value','three',TPasEnumValue(TPasEnumType(TheType).Values[2]).Name);
+  AssertEquals('Assigned value first enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[0]).AssignedValue);
+  AssertEquals('Assigned value second enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[1]).AssignedValue);
+  AssertEquals('Assigned value third enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[2]).AssignedValue);
+end;
+
+procedure TTestTypeParser.TestSimpleEnumeratedDeprecated;
+begin
+  DoParseEnumerated('(one,two,three)','deprecated',3);
+  AssertEquals('First enumerated value','one',TPasEnumValue(TPasEnumType(TheType).Values[0]).Name);
+  AssertEquals('Second enumerated value','two',TPasEnumValue(TPasEnumType(TheType).Values[1]).Name);
+  AssertEquals('Third enumerated value','three',TPasEnumValue(TPasEnumType(TheType).Values[2]).Name);
+  AssertEquals('Assigned value first enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[0]).AssignedValue);
+  AssertEquals('Assigned value second enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[1]).AssignedValue);
+  AssertEquals('Assigned value third enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[2]).AssignedValue);
+end;
+
+procedure TTestTypeParser.TestSimpleEnumeratedPlatform;
+begin
+  DoParseEnumerated('(one,two,three)','platform',3);
+  AssertEquals('First enumerated value','one',TPasEnumValue(TPasEnumType(TheType).Values[0]).Name);
+  AssertEquals('Second enumerated value','two',TPasEnumValue(TPasEnumType(TheType).Values[1]).Name);
+  AssertEquals('Third enumerated value','three',TPasEnumValue(TPasEnumType(TheType).Values[2]).Name);
+  AssertEquals('Assigned value first enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[0]).AssignedValue);
+  AssertEquals('Assigned value second enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[1]).AssignedValue);
+  AssertEquals('Assigned value third enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[2]).AssignedValue);
+end;
+
+procedure TTestTypeParser.TestAssignedEnumerated;
+begin
+  DoParseEnumerated('(one,two:=2,three)','',3);
+  AssertEquals('First enumerated value','one',TPasEnumValue(TPasEnumType(TheType).Values[0]).Name);
+  AssertEquals('Assigned value first enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[0]).AssignedValue);
+  AssertEquals('Second enumerated value','two',TPasEnumValue(TPasEnumType(TheType).Values[1]).Name);
+  AssertEquals('Assigned value enumerated','2',TPasEnumValue(TPasEnumType(TheType).Values[1]).AssignedValue);
+  AssertEquals('Third enumerated value','three',TPasEnumValue(TPasEnumType(TheType).Values[2]).Name);
+  AssertEquals('Assigned value first enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[2]).AssignedValue);
+end;
+
+procedure TTestTypeParser.TestAssignedEnumeratedDeprecated;
+begin
+  DoParseEnumerated('(one,two:=2,three)','',3);
+  AssertEquals('First enumerated value','one',TPasEnumValue(TPasEnumType(TheType).Values[0]).Name);
+  AssertEquals('Assigned value first enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[0]).AssignedValue);
+  AssertEquals('Second enumerated value','two',TPasEnumValue(TPasEnumType(TheType).Values[1]).Name);
+  AssertEquals('Assigned value enumerated','2',TPasEnumValue(TPasEnumType(TheType).Values[1]).AssignedValue);
+  AssertEquals('Third enumerated value','three',TPasEnumValue(TPasEnumType(TheType).Values[2]).Name);
+  AssertEquals('Assigned value first enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[2]).AssignedValue);
+end;
+
+procedure TTestTypeParser.TestAssignedEnumeratedPlatform;
+begin
+  DoParseEnumerated('(one,two:=2,three)','',3);
+  AssertEquals('First enumerated value','one',TPasEnumValue(TPasEnumType(TheType).Values[0]).Name);
+  AssertEquals('Assigned value first enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[0]).AssignedValue);
+  AssertEquals('Second enumerated value','two',TPasEnumValue(TPasEnumType(TheType).Values[1]).Name);
+  AssertEquals('Assigned value enumerated','2',TPasEnumValue(TPasEnumType(TheType).Values[1]).AssignedValue);
+  AssertEquals('Third enumerated value','three',TPasEnumValue(TPasEnumType(TheType).Values[2]).Name);
+  AssertEquals('Assigned value first enumerated empty','',TPasEnumValue(TPasEnumType(TheType).Values[2]).AssignedValue);
+end;
+
+procedure TTestTypeParser.TestFileType;
+begin
+  DoTestFileType('integer','');
+end;
+
+procedure TTestTypeParser.TestFileTypeDeprecated;
+begin
+  DoTestFileType('integer','deprecated');
+end;
+
+procedure TTestTypeParser.TestFileTypePlatform;
+begin
+  DoTestFileType('integer','platform');
+end;
+
+procedure TTestTypeParser.TestRangeType;
+begin
+  DoTestRangeType('1','4','');
+end;
+
+procedure TTestTypeParser.TestRangeTypeDeprecated;
+begin
+  DoTestRangeType('1','4','deprecated');
+end;
+
+procedure TTestTypeParser.TestRangeTypePlatform;
+begin
+  DoTestRangeType('1','4','platform');
+end;
+
+procedure TTestTypeParser.TestIdentifierRangeType;
+begin
+  DoTestRangeType('tkFirst','tkLast','');
+end;
+
+procedure TTestTypeParser.TestIdentifierRangeTypeDeprecated;
+begin
+  DoTestRangeType('tkFirst','tkLast','deprecated');
+end;
+
+procedure TTestTypeParser.TestIdentifierRangeTypePlatform;
+begin
+  DoTestRangeType('tkFirst','tkLast','platform');
+end;
+
+procedure TTestTypeParser.TestNegativeIdentifierRangeType;
+begin
+  DoTestRangeType('-tkLast','tkLast','');
+end;
+
+procedure TTestTypeParser.TestSimpleSet;
+begin
+  DoParseSimpleSet('Byte','');
+end;
+
+procedure TTestTypeParser.TestSimpleSetDeprecated;
+begin
+  DoParseSimpleSet('Byte','deprecated');
+end;
+
+procedure TTestTypeParser.TestSimpleSetPlatform;
+begin
+  DoParseSimpleSet('Byte','platform');
+end;
+
+
+procedure TTestTypeParser.TestComplexSet;
+
+
+begin
+  DoParseComplexSet('(one, two, three)','');
+  DoTestComplexSet;
+end;
+
+procedure TTestTypeParser.TestComplexSetDeprecated;
+
+begin
+  DoParseComplexSet('(one, two, three)','deprecated');
+  DoTestComplexSet;
+end;
+
+procedure TTestTypeParser.TestComplexSetPlatform;
+
+begin
+  DoParseComplexSet('(one, two, three)','platform');
+  DoTestComplexSet;
+end;
+
+procedure TTestTypeParser.TestRangeSet;
+begin
+  DoParseRangeSet('0..SizeOf(Integer)*8-1','');
+end;
+
+procedure TTestTypeParser.TestRangeSetDeprecated;
+begin
+  DoParseRangeSet('0..SizeOf(Integer)*8-1','deprecated');
+end;
+
+procedure TTestTypeParser.TestRangeSetPlatform;
+begin
+  DoParseRangeSet('0..SizeOf(Integer)*8-1','platform');
+end;
+
+procedure TTestTypeParser.TestClassOf;
+begin
+  DoTestClassOf('');
+end;
+
+procedure TTestTypeParser.TestClassOfDeprecated;
+begin
+  DoTestClassOf('deprecated');
+end;
+
+procedure TTestTypeParser.TestClassOfPlatform;
+begin
+  DoTestClassOf('Platform');
+end;
+
+procedure TTestTypeParser.TestReferenceAlias;
+begin
+  Add('Type');
+  Add(' Type1 = Integer;');
+  Add(' Type2 = Type1;');
+  Add('end.');
+  ParseDeclarations;
+  AssertEquals('Two type definitions',2,Declarations.Types.Count);
+  AssertEquals('First declaration is type definition.',TPasAliasType,TObject(Declarations.Types[0]).ClassType);
+  AssertEquals('Second declaration is type definition.',TPasAliasType,TObject(Declarations.Types[1]).ClassType);
+  AssertEquals('First declaration has correct name.','Type1',TPasType(Declarations.Types[0]).Name);
+  AssertEquals('Second declaration has correct name.','Type2',TPasType(Declarations.Types[1]).Name);
+  AssertSame('Second declaration references first.',Declarations.Types[0],TPasAliasType(Declarations.Types[1]).DestType);
+end;
+
+procedure TTestTypeParser.TestReferenceSet;
+
+begin
+  Add('Type');
+  Add(' Type1 = (a,b,c);');
+  Add(' Type2 = set of Type1;');
+  Add('end.');
+  ParseDeclarations;
+  AssertEquals('Two type definitions',2,Declarations.Types.Count);
+  AssertEquals('First declaration is type definition.',TPasEnumType,TObject(Declarations.Types[0]).ClassType);
+  AssertEquals('Second declaration is type definition.',TPasSetType,TObject(Declarations.Types[1]).ClassType);
+  AssertEquals('First declaration has correct name.','Type1',TPasType(Declarations.Types[0]).Name);
+  AssertEquals('Second declaration has correct name.','Type2',TPasType(Declarations.Types[1]).Name);
+  AssertSame('Second declaration references first.',Declarations.Types[0],TPasSetType(Declarations.Types[1]).EnumType);
+end;
+
+procedure TTestTypeParser.TestReferenceClassOf;
+begin
+  Add('Type');
+  Add(' Type1 = Class(TObject);');
+  Add(' Type2 = Class of Type1;');
+  Add('end.');
+  ParseDeclarations;
+  AssertEquals('1 type definitions',1,Declarations.Types.Count);
+  AssertEquals('1 class definitions',1,Declarations.Classes.Count);
+  AssertEquals('First declaration is class definition.',TPasClassType,TObject(Declarations.Classes[0]).ClassType);
+  AssertEquals('Second declaration is type definition.',TPasClassOfType,TObject(Declarations.Types[0]).ClassType);
+  AssertEquals('First declaration has correct name.','Type2',TPasType(Declarations.Types[0]).Name);
+  AssertEquals('Second declaration has correct name.','Type1',TPasType(Declarations.Classes[0]).Name);
+  AssertSame('Second declaration references first.',Declarations.Classes[0],TPasClassOfType(Declarations.Types[0]).DestType);
+end;
+
+procedure TTestTypeParser.TestReferenceFile;
+begin
+  Add('Type');
+  Add(' Type1 = (a,b,c);');
+  Add(' Type2 = File of Type1;');
+  Add('end.');
+  ParseDeclarations;
+  AssertEquals('Two type definitions',2,Declarations.Types.Count);
+  AssertEquals('First declaration is type definition.',TPasEnumType,TObject(Declarations.Types[0]).ClassType);
+  AssertEquals('Second declaration is type definition.',TPasFileType,TObject(Declarations.Types[1]).ClassType);
+  AssertEquals('First declaration has correct name.','Type1',TPasType(Declarations.Types[0]).Name);
+  AssertEquals('Second declaration has correct name.','Type2',TPasType(Declarations.Types[1]).Name);
+  AssertSame('Second declaration references first.',Declarations.Types[0],TPasFileType(Declarations.Types[1]).elType);
+end;
+
+procedure TTestTypeParser.TestReferenceArray;
+begin
+  Add('Type');
+  Add(' Type1 = (a,b,c);');
+  Add(' Type2 = Array of Type1;');
+  Add('end.');
+  ParseDeclarations;
+  AssertEquals('Two type definitions',2,Declarations.Types.Count);
+  AssertEquals('First declaration is type definition.',TPasEnumType,TObject(Declarations.Types[0]).ClassType);
+  AssertEquals('Second declaration is type definition.',TPasArrayType,TObject(Declarations.Types[1]).ClassType);
+  AssertEquals('First declaration has correct name.','Type1',TPasType(Declarations.Types[0]).Name);
+  AssertEquals('Second declaration has correct name.','Type2',TPasType(Declarations.Types[1]).Name);
+  AssertSame('Second declaration references first.',Declarations.Types[0],TPasArrayType(Declarations.Types[1]).elType);
+end;
+
+procedure TTestTypeParser.TestReferencePointer;
+begin
+  Add('Type');
+  Add(' Type1 = (a,b,c);');
+  Add(' Type2 = ^Type1;');
+  Add('end.');
+  ParseDeclarations;
+  AssertEquals('Two type definitions',2,Declarations.Types.Count);
+  AssertEquals('First declaration is type definition.',TPasEnumType,TObject(Declarations.Types[0]).ClassType);
+  AssertEquals('Second declaration is type definition.',TPasPointerType,TObject(Declarations.Types[1]).ClassType);
+  AssertEquals('First declaration has correct name.','Type1',TPasType(Declarations.Types[0]).Name);
+  AssertEquals('Second declaration has correct name.','Type2',TPasType(Declarations.Types[1]).Name);
+  AssertSame('Second declaration references first.',Declarations.Types[0],TPasPointerType(Declarations.Types[1]).DestType);
+end;
+
+
+initialization
+  RegisterTests([TTestTypeParser,TTestRecordTypeParser,TTestProcedureTypeParser]);
+end.
+

+ 300 - 0
packages/fcl-passrc/tests/tcvarparser.pas

@@ -0,0 +1,300 @@
+unit tcvarparser;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit, pastree, pscanner,
+  tcbaseparser, testregistry;
+
+Type
+  { TTestVarParser }
+
+  TTestVarParser = Class(TTestParser)
+  private
+    FHint: string;
+    FVar: TPasVariable;
+  Protected
+    Function ParseVar(ASource : String; Const AHint : String = '') : TPasVariable; virtual; overload;
+    Procedure AssertVariableType(Const ATypeName : String);
+    Procedure AssertVariableType(Const AClass : TClass);
+    Procedure AssertParseVarError(ASource : String);
+    Property TheVar : TPasVariable Read FVar;
+    Property Hint : string Read FHint Write FHint;
+    procedure SetUp; override;
+    Procedure TearDown; override;
+  Published
+    Procedure TestSimpleVar;
+    Procedure TestSimpleVarDeprecated;
+    Procedure TestSimpleVarPlatform;
+    Procedure TestSimpleVarInitialized;
+    procedure TestSimpleVarInitializedDeprecated;
+    procedure TestSimpleVarInitializedPlatform;
+    Procedure TestVarProcedure;
+    Procedure TestVarProcedureDeprecated;
+    Procedure TestVarRecord;
+    Procedure TestVarRecordDeprecated;
+    Procedure TestVarRecordPlatform;
+    Procedure TestVarArray;
+    Procedure TestVarArrayDeprecated;
+    Procedure TestVarDynArray;
+    Procedure TestVarExternal;
+    Procedure TestVarExternalLib;
+    Procedure TestVarExternalLibName;
+    Procedure TestVarCVar;
+    Procedure TestVarCVarExternal;
+    Procedure TestVarPublic;
+    Procedure TestVarPublicName;
+    Procedure TestVarDeprecatedExternalName;
+  end;
+
+implementation
+
+uses typinfo;
+
+{ TTestVarParser }
+
+function TTestVarParser.ParseVar(ASource: String; const AHint: String
+  ): TPasVariable;
+Var
+  D : String;
+begin
+  Hint:=AHint;
+  Add('Var');
+  D:='A : '+ASource;
+  If Hint<>'' then
+    D:=D+' '+Hint;
+  Add('  '+D+';');
+//  Writeln(source.text);
+  ParseDeclarations;
+  AssertEquals('One variable definition',1,Declarations.Variables.Count);
+  AssertEquals('First declaration is type definition.',TPasVariable,TObject(Declarations.Variables[0]).ClassType);
+  Result:=TPasVariable(Declarations.Variables[0]);
+  AssertEquals('First declaration has correct name.','A',Result.Name);
+  FVar:=Result;
+  Definition:=Result;
+  if (Hint<>'') then
+    CheckHint(TPasMemberHint(Getenumvalue(typeinfo(TPasMemberHint),'h'+Hint)));
+end;
+
+procedure TTestVarParser.AssertVariableType(const ATypeName: String);
+begin
+  AssertVariableType(TPasUnresolvedTypeRef);
+  AssertEquals('Correct unresolved type name',ATypeName,theVar.VarType.Name);
+end;
+
+procedure TTestVarParser.AssertVariableType(const AClass: TClass);
+begin
+  AssertNotNull('Have variable type',theVar.VarType);
+  AssertEquals('Correct type class',AClass,theVar.VarType.ClassType);
+end;
+
+procedure TTestVarParser.AssertParseVarError(ASource: String);
+begin
+  try
+    ParseVar(ASource,'');
+    Fail('Expected parser error');
+  except
+    // all OK.
+  end;
+end;
+
+procedure TTestVarParser.SetUp;
+begin
+  inherited SetUp;
+  FHint:='';
+  FVar:=Nil;
+end;
+
+procedure TTestVarParser.TearDown;
+begin
+  FVar:=Nil;
+  inherited TearDown;
+end;
+
+procedure TTestVarParser.TestSimpleVar;
+begin
+  ParseVar('b','');
+  AssertVariableType('b');
+end;
+
+procedure TTestVarParser.TestSimpleVarDeprecated;
+begin
+  ParseVar('b','deprecated');
+  AssertVariableType('b');
+end;
+
+procedure TTestVarParser.TestSimpleVarPlatform;
+begin
+  ParseVar('b','platform');
+  AssertVariableType('b');
+end;
+
+procedure TTestVarParser.TestSimpleVarInitialized;
+begin
+  ParseVar('b = 123','');
+  AssertVariableType('b');
+  AssertNotNull(TheVar.expr);
+  AssertExpression('Variable value',TheVar.expr,pekNumber,'123');
+end;
+
+procedure TTestVarParser.TestSimpleVarInitializedDeprecated;
+begin
+  ParseVar('b = 123','deprecated');
+  AssertVariableType('b');
+  AssertNotNull(TheVar.expr);
+  AssertExpression('Variable value',TheVar.expr,pekNumber,'123');
+end;
+
+procedure TTestVarParser.TestSimpleVarInitializedPlatform;
+begin
+  ParseVar('b = 123','platform');
+  AssertVariableType('b');
+  AssertNotNull(TheVar.expr);
+  AssertExpression('Variable value',TheVar.expr,pekNumber,'123');
+end;
+
+procedure TTestVarParser.TestVarProcedure;
+begin
+  ParseVar('procedure','');
+  AssertVariableType(TPasProcedureType);
+end;
+
+procedure TTestVarParser.TestVarProcedureDeprecated;
+begin
+  ParseVar('procedure','deprecated');
+  AssertVariableType(TPasProcedureType);
+end;
+
+procedure TTestVarParser.TestVarRecord;
+
+Var
+  R : TPasRecordtype;
+begin
+  ParseVar('record x,y : intger; end','');
+  AssertVariableType(TPasRecordType);
+  R:=TheVar.VarType as TPasRecordType;
+  AssertEquals('Correct number of fields',2,R.Members.Count);
+end;
+
+procedure TTestVarParser.TestVarRecordDeprecated;
+Var
+  R : TPasRecordtype;
+begin
+  ParseVar('record x,y : integer; end','deprecated');
+  AssertVariableType(TPasRecordType);
+  R:=TheVar.VarType as TPasRecordType;
+  AssertEquals('Correct number of fields',2,R.Members.Count);
+end;
+
+procedure TTestVarParser.TestVarRecordPlatform;
+Var
+  R : TPasRecordtype;
+begin
+  ParseVar('record x,y : integer; end','platform');
+  AssertVariableType(TPasRecordType);
+  R:=TheVar.VarType as TPasRecordType;
+  AssertEquals('Correct number of fields',2,R.Members.Count);
+end;
+
+procedure TTestVarParser.TestVarArray;
+
+Var
+  R : TPasArrayType;
+
+begin
+  ParseVar('Array[1..20] of integer','');
+  AssertVariableType(TPasArrayType);
+  R:=TheVar.VarType as TPasArrayType;
+  AssertNotNull('Correct array type name',R.ElType);
+  AssertEquals('Correct array type name',TPasunresolvedTypeRef,R.ElType.ClassType);
+end;
+
+procedure TTestVarParser.TestVarArrayDeprecated;
+
+Var
+  R : TPasArrayType;
+
+begin
+  ParseVar('Array[1..20] of integer','Deprecated');
+  AssertVariableType(TPasArrayType);
+  R:=TheVar.VarType as TPasArrayType;
+  AssertNotNull('Correct array type name',R.ElType);
+  AssertEquals('Correct array type name',TPasunresolvedTypeRef,R.ElType.ClassType);
+end;
+
+procedure TTestVarParser.TestVarDynArray;
+
+Var
+  R : TPasArrayType;
+
+begin
+  ParseVar('Array of integer','');
+  AssertVariableType(TPasArrayType);
+  R:=TheVar.VarType as TPasArrayType;
+  AssertEquals('No index','',R.IndexRange);
+  AssertNotNull('Correct array type name',R.ElType);
+  AssertEquals('Correct array type name',TPasunresolvedTypeRef,R.ElType.ClassType);
+end;
+
+procedure TTestVarParser.TestVarExternal;
+begin
+  ParseVar('integer; external','');
+  AssertEquals('Variable modifiers',[vmexternal],TheVar.VarModifiers);
+end;
+
+procedure TTestVarParser.TestVarExternalLib;
+begin
+  ParseVar('integer; external name ''mylib''','');
+  AssertEquals('Variable modifiers',[vmexternal],TheVar.VarModifiers);
+  AssertEquals('Library name','',TheVar.LibraryName);
+  AssertEquals('Library name','''mylib''',TheVar.ExportName);
+end;
+
+procedure TTestVarParser.TestVarExternalLibName;
+begin
+  ParseVar('integer; external ''mylib'' name ''d''','');
+  AssertEquals('Variable modifiers',[vmexternal],TheVar.VarModifiers);
+  AssertEquals('Library name','''mylib''',TheVar.LibraryName);
+  AssertEquals('Library name','''d''',TheVar.ExportName);
+end;
+
+procedure TTestVarParser.TestVarCVar;
+begin
+  ParseVar('integer; cvar','');
+  AssertEquals('Variable modifiers',[vmcvar],TheVar.VarModifiers);
+end;
+
+procedure TTestVarParser.TestVarCVarExternal;
+begin
+  ParseVar('integer; cvar;external','');
+  AssertEquals('Variable modifiers',[vmcvar,vmexternal],TheVar.VarModifiers);
+end;
+
+procedure TTestVarParser.TestVarPublic;
+begin
+  ParseVar('integer; public','');
+  AssertEquals('Variable modifiers',[vmpublic],TheVar.VarModifiers);
+end;
+
+procedure TTestVarParser.TestVarPublicName;
+begin
+  ParseVar('integer; public name ''c''','');
+  AssertEquals('Variable modifiers',[vmpublic],TheVar.VarModifiers);
+  AssertEquals('Public export name','''c''',TheVar.ExportName);
+end;
+
+procedure TTestVarParser.TestVarDeprecatedExternalName;
+begin
+  ParseVar('integer deprecated; external name ''me''','');
+  CheckHint(TPasMemberHint(Getenumvalue(typeinfo(TPasMemberHint),'hdeprecated')));
+  AssertEquals('Variable modifiers',[vmexternal],TheVar.VarModifiers);
+  AssertEquals('Library name','''me''',TheVar.ExportName);
+end;
+
+initialization
+
+  RegisterTests([TTestVarParser]);
+end.
+

+ 53 - 2
packages/fcl-passrc/tests/testpassrc.lpi

@@ -25,7 +25,8 @@
     <RunParams>
     <RunParams>
       <local>
       <local>
         <FormatVersion Value="1"/>
         <FormatVersion Value="1"/>
-        <LaunchingApplication PathPlusParams="/usr/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
+        <CommandLineParams Value="--suite=TTestTypeParser"/>
+        <LaunchingApplication Use="True" PathPlusParams="/usr/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
       </local>
       </local>
     </RunParams>
     </RunParams>
     <RequiredPackages Count="2">
     <RequiredPackages Count="2">
@@ -36,7 +37,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item2>
       </Item2>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="2">
+    <Units Count="12">
       <Unit0>
       <Unit0>
         <Filename Value="testpassrc.lpr"/>
         <Filename Value="testpassrc.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -47,6 +48,56 @@
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="tcscanner"/>
         <UnitName Value="tcscanner"/>
       </Unit1>
       </Unit1>
+      <Unit2>
+        <Filename Value="tctypeparser.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tctypeparser"/>
+      </Unit2>
+      <Unit3>
+        <Filename Value="tcstatements.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcstatements"/>
+      </Unit3>
+      <Unit4>
+        <Filename Value="tcbaseparser.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcbaseparser"/>
+      </Unit4>
+      <Unit5>
+        <Filename Value="tcmoduleparser.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcmoduleparser"/>
+      </Unit5>
+      <Unit6>
+        <Filename Value="tconstparser.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tconstparser"/>
+      </Unit6>
+      <Unit7>
+        <Filename Value="tcvarparser.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcvarparser"/>
+      </Unit7>
+      <Unit8>
+        <Filename Value="tcclasstype.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcclasstype"/>
+      </Unit8>
+      <Unit9>
+        <Filename Value="tcexprparser.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcexprparser"/>
+      </Unit9>
+      <Unit10>
+        <Filename Value="tcprocfunc.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcprocfunc"/>
+      </Unit10>
+      <Unit11>
+        <Filename Value="tcpassrcutil.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcpassrcutil"/>
+      </Unit11>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

+ 5 - 1
packages/fcl-passrc/tests/testpassrc.lpr

@@ -3,7 +3,9 @@ program testpassrc;
 {$mode objfpc}{$H+}
 {$mode objfpc}{$H+}
 
 
 uses
 uses
-  Classes, consoletestrunner, tcscanner;
+  Classes, consoletestrunner, tcscanner, tctypeparser, tcstatements,
+  tcbaseparser, tcmoduleparser, tconstparser, tcvarparser, tcclasstype,
+  tcexprparser, tcprocfunc, tcpassrcutil;
 
 
 type
 type
 
 
@@ -19,6 +21,8 @@ var
 
 
 begin
 begin
   Application := TMyTestRunner.Create(nil);
   Application := TMyTestRunner.Create(nil);
+  DefaultFormat:=fplain;
+  DefaultRunAllTests:=True;
   Application.Initialize;
   Application.Initialize;
   Application.Run;
   Application.Run;
   Application.Free;
   Application.Free;

+ 0 - 4
rtl/objpas/classes/classesh.inc

@@ -250,12 +250,8 @@ type
     procedure SetCount(NewCount: Integer);
     procedure SetCount(NewCount: Integer);
     Procedure RaiseIndexError(Index: Integer);
     Procedure RaiseIndexError(Index: Integer);
   public
   public
-{$IFNDEF VER2_4}
-{$ifndef fpdocsystem}
     Type
     Type
       TDirection = (FromBeginning, FromEnd);
       TDirection = (FromBeginning, FromEnd);
-{$endif}
-{$ENDIF}
     destructor Destroy; override;
     destructor Destroy; override;
     Procedure AddList(AList : TFPList);
     Procedure AddList(AList : TFPList);
     function Add(Item: Pointer): Integer; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}
     function Add(Item: Pointer): Integer; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE}

+ 285 - 65
utils/Makefile

@@ -289,199 +289,199 @@ endif
 override PACKAGE_NAME=utils
 override PACKAGE_NAME=utils
 override PACKAGE_VERSION=2.6.3
 override PACKAGE_VERSION=2.6.3
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  rmwait
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  rmwait
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpmc fpcres rmwait instantfpc importtl
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpmc fpcres rmwait instantfpc importtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpmc fpcres rmwait
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpmc fpcres rmwait
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres fpcreslipo instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres fpcreslipo instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpmc fpcres rmwait
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpmc fpcres rmwait
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres rmwait instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres rmwait instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres fpcreslipo instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres fpcreslipo instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres fpcreslipo instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres fpcreslipo instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
 ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
 ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres fpcreslipo instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres fpcreslipo instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpmc fpcres rmwait instantfpc importtl
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpmc fpcres rmwait instantfpc importtl
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres fpcreslipo instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres fpcreslipo instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres rmwait instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres rmwait instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres fpcreslipo instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres fpcreslipo instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg  fpcres instantfpc
+override TARGET_DIRS+=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm  fpcres instantfpc
 endif
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
 override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32 rmcvsdir  grab_vcsa
 override TARGET_PROGRAMS+=ppdep ptop rstconv data2inc delp bin2obj postw32 rmcvsdir  grab_vcsa
@@ -2851,6 +2851,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -2863,6 +2865,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_RMWAIT=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
@@ -2874,6 +2878,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_RMWAIT=1
@@ -2889,6 +2895,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_RMWAIT=1
@@ -2902,6 +2910,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -2914,6 +2924,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -2924,6 +2936,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -2936,6 +2950,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -2948,6 +2964,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -2960,6 +2978,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -2970,6 +2990,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -2980,6 +3002,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -2992,6 +3016,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3002,6 +3028,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3015,6 +3043,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_RMWAIT=1
@@ -3028,6 +3058,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3038,6 +3070,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3048,6 +3082,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3061,6 +3097,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3071,6 +3109,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 ifeq ($(FULL_TARGET),i386-nativent)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3081,6 +3121,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 ifeq ($(FULL_TARGET),i386-iphonesim)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3091,6 +3133,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3104,6 +3148,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3116,6 +3162,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3128,6 +3176,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3140,6 +3190,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3150,6 +3202,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3160,6 +3214,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3172,6 +3228,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3182,6 +3240,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3192,6 +3252,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3204,6 +3266,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3216,6 +3280,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3226,6 +3292,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3236,6 +3304,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3249,6 +3319,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3259,6 +3331,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 ifeq ($(FULL_TARGET),powerpc-wii)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3269,6 +3343,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3279,6 +3355,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3291,6 +3369,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3303,6 +3383,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3315,6 +3397,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3325,6 +3409,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3337,6 +3423,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3349,6 +3437,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3361,6 +3451,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3373,6 +3465,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3385,6 +3479,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3398,6 +3494,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_RMWAIT=1
@@ -3413,6 +3511,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3423,6 +3523,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3435,6 +3537,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3445,6 +3549,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3458,6 +3564,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3471,6 +3579,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3481,6 +3591,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3491,6 +3603,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3501,6 +3615,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3511,6 +3627,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3523,6 +3641,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3536,6 +3656,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3546,6 +3668,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3556,6 +3680,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3568,6 +3694,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 ifeq ($(FULL_TARGET),mipsel-linux)
 TARGET_DIRS_FPPKG=1
 TARGET_DIRS_FPPKG=1
@@ -3578,6 +3706,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 TARGET_DIRS_INSTANTFPC=1
 endif
 endif
@@ -3941,6 +4071,96 @@ fpcmkcfg:
 	$(MAKE) -C fpcmkcfg all
 	$(MAKE) -C fpcmkcfg all
 .PHONY: fpcmkcfg_all fpcmkcfg_debug fpcmkcfg_smart fpcmkcfg_release fpcmkcfg_units fpcmkcfg_examples fpcmkcfg_shared fpcmkcfg_install fpcmkcfg_sourceinstall fpcmkcfg_exampleinstall fpcmkcfg_distinstall fpcmkcfg_zipinstall fpcmkcfg_zipsourceinstall fpcmkcfg_zipexampleinstall fpcmkcfg_zipdistinstall fpcmkcfg_clean fpcmkcfg_distclean fpcmkcfg_cleanall fpcmkcfg_info fpcmkcfg_makefiles fpcmkcfg
 .PHONY: fpcmkcfg_all fpcmkcfg_debug fpcmkcfg_smart fpcmkcfg_release fpcmkcfg_units fpcmkcfg_examples fpcmkcfg_shared fpcmkcfg_install fpcmkcfg_sourceinstall fpcmkcfg_exampleinstall fpcmkcfg_distinstall fpcmkcfg_zipinstall fpcmkcfg_zipsourceinstall fpcmkcfg_zipexampleinstall fpcmkcfg_zipdistinstall fpcmkcfg_clean fpcmkcfg_distclean fpcmkcfg_cleanall fpcmkcfg_info fpcmkcfg_makefiles fpcmkcfg
 endif
 endif
+ifdef TARGET_DIRS_PAS2UT
+pas2ut_all:
+	$(MAKE) -C pas2ut all
+pas2ut_debug:
+	$(MAKE) -C pas2ut debug
+pas2ut_smart:
+	$(MAKE) -C pas2ut smart
+pas2ut_release:
+	$(MAKE) -C pas2ut release
+pas2ut_units:
+	$(MAKE) -C pas2ut units
+pas2ut_examples:
+	$(MAKE) -C pas2ut examples
+pas2ut_shared:
+	$(MAKE) -C pas2ut shared
+pas2ut_install:
+	$(MAKE) -C pas2ut install
+pas2ut_sourceinstall:
+	$(MAKE) -C pas2ut sourceinstall
+pas2ut_exampleinstall:
+	$(MAKE) -C pas2ut exampleinstall
+pas2ut_distinstall:
+	$(MAKE) -C pas2ut distinstall
+pas2ut_zipinstall:
+	$(MAKE) -C pas2ut zipinstall
+pas2ut_zipsourceinstall:
+	$(MAKE) -C pas2ut zipsourceinstall
+pas2ut_zipexampleinstall:
+	$(MAKE) -C pas2ut zipexampleinstall
+pas2ut_zipdistinstall:
+	$(MAKE) -C pas2ut zipdistinstall
+pas2ut_clean:
+	$(MAKE) -C pas2ut clean
+pas2ut_distclean:
+	$(MAKE) -C pas2ut distclean
+pas2ut_cleanall:
+	$(MAKE) -C pas2ut cleanall
+pas2ut_info:
+	$(MAKE) -C pas2ut info
+pas2ut_makefiles:
+	$(MAKE) -C pas2ut makefiles
+pas2ut:
+	$(MAKE) -C pas2ut all
+.PHONY: pas2ut_all pas2ut_debug pas2ut_smart pas2ut_release pas2ut_units pas2ut_examples pas2ut_shared pas2ut_install pas2ut_sourceinstall pas2ut_exampleinstall pas2ut_distinstall pas2ut_zipinstall pas2ut_zipsourceinstall pas2ut_zipexampleinstall pas2ut_zipdistinstall pas2ut_clean pas2ut_distclean pas2ut_cleanall pas2ut_info pas2ut_makefiles pas2ut
+endif
+ifdef TARGET_DIRS_PAS2FPM
+pas2fpm_all:
+	$(MAKE) -C pas2fpm all
+pas2fpm_debug:
+	$(MAKE) -C pas2fpm debug
+pas2fpm_smart:
+	$(MAKE) -C pas2fpm smart
+pas2fpm_release:
+	$(MAKE) -C pas2fpm release
+pas2fpm_units:
+	$(MAKE) -C pas2fpm units
+pas2fpm_examples:
+	$(MAKE) -C pas2fpm examples
+pas2fpm_shared:
+	$(MAKE) -C pas2fpm shared
+pas2fpm_install:
+	$(MAKE) -C pas2fpm install
+pas2fpm_sourceinstall:
+	$(MAKE) -C pas2fpm sourceinstall
+pas2fpm_exampleinstall:
+	$(MAKE) -C pas2fpm exampleinstall
+pas2fpm_distinstall:
+	$(MAKE) -C pas2fpm distinstall
+pas2fpm_zipinstall:
+	$(MAKE) -C pas2fpm zipinstall
+pas2fpm_zipsourceinstall:
+	$(MAKE) -C pas2fpm zipsourceinstall
+pas2fpm_zipexampleinstall:
+	$(MAKE) -C pas2fpm zipexampleinstall
+pas2fpm_zipdistinstall:
+	$(MAKE) -C pas2fpm zipdistinstall
+pas2fpm_clean:
+	$(MAKE) -C pas2fpm clean
+pas2fpm_distclean:
+	$(MAKE) -C pas2fpm distclean
+pas2fpm_cleanall:
+	$(MAKE) -C pas2fpm cleanall
+pas2fpm_info:
+	$(MAKE) -C pas2fpm info
+pas2fpm_makefiles:
+	$(MAKE) -C pas2fpm makefiles
+pas2fpm:
+	$(MAKE) -C pas2fpm all
+.PHONY: pas2fpm_all pas2fpm_debug pas2fpm_smart pas2fpm_release pas2fpm_units pas2fpm_examples pas2fpm_shared pas2fpm_install pas2fpm_sourceinstall pas2fpm_exampleinstall pas2fpm_distinstall pas2fpm_zipinstall pas2fpm_zipsourceinstall pas2fpm_zipexampleinstall pas2fpm_zipdistinstall pas2fpm_clean pas2fpm_distclean pas2fpm_cleanall pas2fpm_info pas2fpm_makefiles pas2fpm
+endif
 ifdef TARGET_DIRS_FPCRES
 ifdef TARGET_DIRS_FPCRES
 fpcres_all:
 fpcres_all:
 	$(MAKE) -C fpcres all
 	$(MAKE) -C fpcres all

+ 1 - 1
utils/Makefile.fpc

@@ -7,7 +7,7 @@ name=utils
 version=2.6.3
 version=2.6.3
 
 
 [target]
 [target]
-dirs=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg
+dirs=fppkg fpcm tply h2pas fprcp dxegen fpdoc fpcmkcfg pas2ut pas2fpm
 programs=ppdep ptop rstconv data2inc delp bin2obj postw32 rmcvsdir
 programs=ppdep ptop rstconv data2inc delp bin2obj postw32 rmcvsdir
 programs_linux=grab_vcsa
 programs_linux=grab_vcsa
 dirs_win32=fpmc fpcres rmwait instantfpc importtl
 dirs_win32=fpmc fpcres rmwait instantfpc importtl

+ 113 - 2
utils/fpdoc/Makefile

@@ -1693,13 +1693,14 @@ else
 TAROPT=vz
 TAROPT=vz
 TAREXT=.tar.gz
 TAREXT=.tar.gz
 endif
 endif
-override REQUIRE_PACKAGES=rtl fcl-base fcl-xml fcl-passrc chm
+override REQUIRE_PACKAGES=rtl fcl-base fcl-xml fcl-passrc fcl-process chm
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
@@ -1707,6 +1708,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
@@ -1714,6 +1716,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
@@ -1721,6 +1724,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
@@ -1729,6 +1733,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
@@ -1737,6 +1742,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
@@ -1745,6 +1751,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
@@ -1752,6 +1759,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
@@ -1759,6 +1767,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
@@ -1766,6 +1775,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
@@ -1773,6 +1783,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
@@ -1780,6 +1791,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
@@ -1787,6 +1799,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
@@ -1796,6 +1809,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
@@ -1803,6 +1817,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
@@ -1810,6 +1825,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
@@ -1817,6 +1833,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
@@ -1824,6 +1841,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
@@ -1831,6 +1849,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
@@ -1838,6 +1857,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 ifeq ($(FULL_TARGET),i386-nativent)
@@ -1845,6 +1865,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 ifeq ($(FULL_TARGET),i386-iphonesim)
@@ -1854,6 +1875,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
@@ -1862,6 +1884,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
@@ -1870,6 +1893,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
@@ -1877,6 +1901,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
@@ -1884,6 +1909,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
@@ -1891,6 +1917,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
@@ -1898,6 +1925,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
@@ -1905,6 +1933,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
@@ -1912,6 +1941,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
@@ -1920,6 +1950,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
@@ -1927,6 +1958,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
@@ -1934,6 +1966,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
@@ -1941,6 +1974,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
@@ -1950,6 +1984,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
@@ -1957,6 +1992,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
@@ -1964,6 +2000,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 ifeq ($(FULL_TARGET),powerpc-wii)
@@ -1971,6 +2008,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
@@ -1979,6 +2017,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
@@ -1986,6 +2025,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
@@ -1993,6 +2033,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
@@ -2000,6 +2041,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
@@ -2008,6 +2050,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
@@ -2016,6 +2059,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
 ifeq ($(FULL_TARGET),x86_64-netbsd)
@@ -2023,6 +2067,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
@@ -2030,6 +2075,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
 ifeq ($(FULL_TARGET),x86_64-openbsd)
@@ -2037,6 +2083,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
@@ -2046,6 +2093,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
@@ -2053,6 +2101,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
@@ -2060,6 +2109,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
@@ -2068,6 +2118,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
@@ -2075,6 +2126,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
@@ -2084,6 +2136,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
@@ -2091,6 +2144,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
@@ -2098,6 +2152,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
@@ -2105,6 +2160,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
@@ -2112,6 +2168,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
@@ -2119,6 +2176,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
@@ -2127,6 +2185,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
@@ -2136,6 +2195,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
@@ -2143,6 +2203,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
@@ -2150,6 +2211,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
@@ -2158,6 +2220,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
@@ -2165,6 +2228,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 ifeq ($(FULL_TARGET),mipsel-linux)
@@ -2173,6 +2237,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 REQUIRE_PACKAGES_CHM=1
 endif
 endif
 ifdef REQUIRE_PACKAGES_RTL
 ifdef REQUIRE_PACKAGES_RTL
@@ -2365,6 +2430,44 @@ ifdef UNITDIR_FPMAKE_FCL-PASSRC
 override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FCL-PASSRC)
 override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FCL-PASSRC)
 endif
 endif
 endif
 endif
+ifdef REQUIRE_PACKAGES_FCL-PROCESS
+PACKAGEDIR_FCL-PROCESS:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-process/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-PROCESS),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PROCESS)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PROCESS)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PROCESS)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-PROCESS)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-PROCESS) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-PROCESS)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-PROCESS=
+UNITDIR_FCL-PROCESS:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-process/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-PROCESS),)
+UNITDIR_FCL-PROCESS:=$(firstword $(UNITDIR_FCL-PROCESS))
+else
+UNITDIR_FCL-PROCESS=
+endif
+endif
+ifdef UNITDIR_FCL-PROCESS
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-PROCESS)
+endif
+ifdef UNITDIR_FPMAKE_FCL-PROCESS
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FCL-PROCESS)
+endif
+endif
 ifdef REQUIRE_PACKAGES_CHM
 ifdef REQUIRE_PACKAGES_CHM
 PACKAGEDIR_CHM:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /chm/Makefile.fpc,$(PACKAGESDIR))))))
 PACKAGEDIR_CHM:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /chm/Makefile.fpc,$(PACKAGESDIR))))))
 ifneq ($(PACKAGEDIR_CHM),)
 ifneq ($(PACKAGEDIR_CHM),)
@@ -3066,5 +3169,13 @@ include fpcmake.loc
 endif
 endif
 .NOTPARALLEL:
 .NOTPARALLEL:
 fpdoc$(EXEEXT): fpdoc.pp dglobals.pp dwriter.pp dw_xml.pp sh_pas.pp dw_html.pp\
 fpdoc$(EXEEXT): fpdoc.pp dglobals.pp dwriter.pp dw_xml.pp sh_pas.pp dw_html.pp\
-  dw_latex.pp dwlinear.pp dw_txt.pp dw_linrtf.pp
+  dw_latex.pp dwlinear.pp dw_txt.pp dw_linrtf.pp css.inc plusimage.inc minusimage.inc
 makeskel$(EXEEXT): makeskel.pp dglobals.pp
 makeskel$(EXEEXT): makeskel.pp dglobals.pp
+css.inc: fpdoc.css ../bin2obj$(EXEEXT)
+	../bin2obj$(EXEEXT) -o css.inc -c DefaultCSS fpdoc.css
+plusimage.inc: images/plus.png ../bin2obj$(EXEEXT)
+	../bin2obj$(EXEEXT) -o plusimage.inc -c PlusImageData images/plus.png
+minusimage.inc: images/minus.png ../bin2obj$(EXEEXT)
+	../bin2obj$(EXEEXT) -o minusimage.inc -c MinusImageData images/minus.png
+../bin2obj$(EXEEXT):
+	$(MAKE) -C .. bin2obj$(EXEEXT)

+ 14 - 2
utils/fpdoc/Makefile.fpc

@@ -7,7 +7,7 @@ name=fpdoc
 version=2.6.3
 version=2.6.3
 
 
 [require]
 [require]
-packages=fcl-base fcl-xml fcl-passrc chm
+packages=fcl-base fcl-xml fcl-passrc fcl-process chm
 packages_darwin=univint
 packages_darwin=univint
 
 
 [target]
 [target]
@@ -33,6 +33,18 @@ files=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 [rules]
 [rules]
 .NOTPARALLEL:
 .NOTPARALLEL:
 fpdoc$(EXEEXT): fpdoc.pp dglobals.pp dwriter.pp dw_xml.pp sh_pas.pp dw_html.pp\
 fpdoc$(EXEEXT): fpdoc.pp dglobals.pp dwriter.pp dw_xml.pp sh_pas.pp dw_html.pp\
-  dw_latex.pp dwlinear.pp dw_txt.pp dw_linrtf.pp
+  dw_latex.pp dwlinear.pp dw_txt.pp dw_linrtf.pp css.inc plusimage.inc minusimage.inc
 
 
 makeskel$(EXEEXT): makeskel.pp dglobals.pp
 makeskel$(EXEEXT): makeskel.pp dglobals.pp
+
+css.inc: fpdoc.css ../bin2obj$(EXEEXT)
+	../bin2obj$(EXEEXT) -o css.inc -c DefaultCSS fpdoc.css
+
+plusimage.inc: images/plus.png ../bin2obj$(EXEEXT)
+	../bin2obj$(EXEEXT) -o plusimage.inc -c PlusImageData images/plus.png
+
+minusimage.inc: images/minus.png ../bin2obj$(EXEEXT)
+	../bin2obj$(EXEEXT) -o minusimage.inc -c MinusImageData images/minus.png
+
+../bin2obj$(EXEEXT):
+	$(MAKE) -C .. bin2obj$(EXEEXT)

+ 8 - 0
utils/fpdoc/README.txt

@@ -52,6 +52,13 @@ dw_man.pp
 fpdoc.pp
 fpdoc.pp
   * Main program
   * Main program
 
 
+fpdocstripper.lpr
+fpdocstripper.lpi
+  * Utility program that strips fpdoc xml files of all elements 
+    that have no documentation in them. Useful before submitting
+	a documentation patch as it keeps file sizes down and makes
+	it clearer what exactly is documented.
+  
 makeskel.pp
 makeskel.pp
   * Skeleton XML description file generator
   * Skeleton XML description file generator
 
 
@@ -66,3 +73,4 @@ Contributors
 ------------
 ------------
 Initial French output strings by Pierre Muller
 Initial French output strings by Pierre Muller
 Initial Dutch output strings by Marco van de Voort
 Initial Dutch output strings by Marco van de Voort
+fpdocstripper by Reinier OliSlagers

+ 135 - 0
utils/fpdoc/css.inc

@@ -0,0 +1,135 @@
+
+Const
+  DefaultCSS : Array[0..2242] of byte = (
+      47, 42, 10, 32, 32, 36, 73,100, 58, 32,102,112,100,111, 99, 46, 99,
+     115,116, 44,118, 32, 49, 46, 49, 32, 50, 48, 48, 53, 47, 48, 49, 47,
+      48, 50, 32, 49, 54, 58, 50, 50, 58, 49, 54, 32,109,105, 99,104, 97,
+     101,108, 32, 69,120,112, 32, 36, 10, 10, 32, 32, 68,101,102, 97,117,
+     108,116, 32,115,116,121,108,101, 32,115,104,101,101,116, 32,102,111,
+     114, 32, 70, 80, 68,111, 99, 32,114,101,102,101,114,101,110, 99,101,
+      32,100,111, 99,117,109,101,110,116, 97,116,105,111,110, 10, 32, 32,
+      98,121, 32, 83,101, 98, 97,115,116,105, 97,110, 32, 71,117,101,110,
+     116,104,101,114, 44, 32,115,103, 64,102,114,101,101,112, 97,115, 99,
+      97,108, 46,111,114,103, 10, 10, 32, 32, 70,101,101,108, 32,102,114,
+     101,101, 32,116,111, 32,117,115,101, 32,116,104,105,115, 32,102,105,
+     108,101, 32, 97,115, 32, 97, 32,116,101,109,112,108, 97,116,101, 32,
+     102,111,114, 32,121,111,117,114, 32,111,119,110, 32,115,116,121,108,
+     101, 32,115,104,101,101,116,115, 46, 10, 42, 47, 10, 10, 98,111,100,
+     121, 32,123, 10, 32, 32, 98, 97, 99,107,103,114,111,117,110,100, 58,
+      32,119,104,105,116,101, 10,125, 10, 10, 98,111,100,121, 44, 32,112,
+      44, 32,116,104, 44, 32,116,100, 44, 32, 99, 97,112,116,105,111,110,
+      44, 32,104, 49, 44, 32,104, 50, 44, 32,104, 51, 44, 32,117,108, 44,
+      32,111,108, 44, 32,100,108, 32,123, 10, 32, 32, 99,111,108,111,114,
+      58, 32, 98,108, 97, 99,107, 59, 10, 32, 32,102,111,110,116, 45,102,
+      97,109,105,108,121, 58, 32,115, 97,110,115, 45,115,101,114,105,102,
+      10,125, 10, 10,116,116, 44, 32,115,112, 97,110, 46,107,119, 44, 32,
+     112,114,101, 32,123, 10, 32, 32,102,111,110,116, 45,102, 97,109,105,
+     108,121, 58, 32, 67,111,117,114,105,101,114, 44, 32,109,111,110,111,
+     115,112, 97, 99,101, 10,125, 10, 10, 98,111,100,121, 44, 32,112, 44,
+      32,116,104, 44, 32,116,100, 44, 32, 99, 97,112,116,105,111,110, 44,
+      32,117,108, 44, 32,111,108, 44, 32,100,108, 44, 32,116,116, 44, 32,
+     115,112, 97,110, 46,107,119, 44, 32,112,114,101, 32,123, 10, 32, 32,
+     102,111,110,116, 45,115,105,122,101, 58, 32, 49, 52,112,120, 10,125,
+      10, 10, 65, 58,108,105,110,107, 32,123, 10, 32, 32, 99,111,108,111,
+     114, 58, 32, 98,108,117,101, 10,125, 10, 10, 65, 58,118,105,115,105,
+     116,101,100, 32,123, 10, 32, 32, 99,111,108,111,114, 58, 32,100, 97,
+     114,107, 98,108,117,101, 10,125, 10, 10, 65, 58, 97, 99,116,105,118,
+     101, 32,123, 10, 32, 32, 99,111,108,111,114, 58, 32,114,101,100, 10,
+     125, 10, 10, 65, 32,123, 10, 32, 32,116,101,120,116, 45,100,101, 99,
+     111,114, 97,116,105,111,110, 58, 32,110,111,110,101, 10,125, 10, 10,
+      65, 58,104,111,118,101,114, 32,123, 10, 32, 32,116,101,120,116, 45,
+     100,101, 99,111,114, 97,116,105,111,110, 58, 32,117,110,100,101,114,
+     108,105,110,101, 10,125, 10, 10,104, 49, 44, 32,104, 50, 44, 32,116,
+     100, 46,104, 50, 32,123, 10, 32, 32, 99,111,108,111,114, 58, 32, 35,
+      48, 48, 53, 65, 57, 67, 10,125, 10, 10, 47, 42, 32, 69,115,112,101,
+      99,105, 97,108,108,121, 32,102,111,114, 32, 78,101,116,115, 99, 97,
+     112,101, 32,111,110, 32, 76,105,110,117,120, 58, 32, 42, 47, 10,104,
+      51, 44, 32,116,100, 46,104, 51, 32,123, 10, 32, 32,102,111,110,116,
+      45,115,105,122,101, 58, 32, 49, 50,112,116, 10,125, 10, 10, 47, 42,
+      32,115,111,117,114, 99,101, 32,102,114, 97,103,109,101,110,116,115,
+      32, 42, 47, 10,115,112, 97,110, 46, 99,111,100,101, 32,123, 10, 32,
+      32,119,104,105,116,101, 45,115,112, 97, 99,101, 58, 32,110,111,119,
+     114, 97,112, 10,125, 10, 10, 47, 42, 32,115,121,109, 98,111,108,115,
+      32,105,110, 32,115,111,117,114, 99,101, 32,102,114, 97,103,109,101,
+     110,116,115, 32, 42, 47, 10,115,112, 97,110, 46,115,121,109, 32,123,
+      10, 32, 32, 99,111,108,111,114, 58, 32,100, 97,114,107,114,101,100,
+      10,125, 10, 47, 42, 32, 78,111, 32,119,111,114,100,119,114, 97,112,
+      32,105,110, 32, 99,111,100,101, 32,102,114, 97,103,109,101,110,116,
+     115, 32, 42, 47, 10,115,112, 97,110, 46, 99,111,100,101, 32,123, 10,
+      32, 32, 32,119,104,105,116,101, 45,115,112, 97, 99,101, 58, 32,110,
+     111,119,114, 97,112, 10,125, 10, 10, 47, 42, 32,107,101,121,119,111,
+     114,100,115, 32,105,110, 32,115,111,117,114, 99,101, 32,102,114, 97,
+     103,109,101,110,116,115, 32, 42, 47, 10,115,112, 97,110, 46,107,119,
+      32,123, 10, 32, 32,102,111,110,116, 45,119,101,105,103,104,116, 58,
+      32, 98,111,108,100, 10,125, 10, 10, 47, 42, 32, 99,111,109,109,101,
+     110,116,115, 32,105,110, 32,115,111,117,114, 99,101, 32,102,114, 97,
+     103,109,101,110,116,115, 32, 42, 47, 10,115,112, 97,110, 46, 99,109,
+     116, 32,123, 10, 32, 32, 99,111,108,111,114, 58, 32,100, 97,114,107,
+      99,121, 97,110, 59, 10, 32, 32,102,111,110,116, 45,115,116,121,108,
+     101, 58, 32,105,116, 97,108,105, 99, 10,125, 10, 10, 47, 42, 32,100,
+     105,114,101, 99,116,105,118,101,115, 32,105,110, 32,115,111,117,114,
+      99,101, 32,102,114, 97,103,109,101,110,116,115, 32, 42, 47, 10,115,
+     112, 97,110, 46,100,105,114, 32,123, 10, 32, 32, 99,111,108,111,114,
+      58, 32,100, 97,114,107,121,101,108,108,111,119, 59, 10, 32, 32,102,
+     111,110,116, 45,115,116,121,108,101, 58, 32,105,116, 97,108,105, 99,
+      10,125, 10, 10, 47, 42, 32,110,117,109, 98,101,114,115, 32,105,110,
+      32,115,111,117,114, 99,101, 32,102,114, 97,103,109,101,110,116,115,
+      32, 42, 47, 10,115,112, 97,110, 46,110,117,109, 32,123, 10, 32, 32,
+      99,111,108,111,114, 58, 32,100, 97,114,107,109, 97,103,101,110,116,
+      97, 10,125, 10, 10, 47, 42, 32, 99,104, 97,114, 97, 99,116,101,114,
+     115, 32, 40, 35, 46, 46, 46, 41, 32,105,110, 32,115,111,117,114, 99,
+     101, 32,102,114, 97,103,109,101,110,116,115, 32, 42, 47, 10,115,112,
+      97,110, 46, 99,104,114, 32,123, 10, 32, 32, 99,111,108,111,114, 58,
+      32,100, 97,114,107, 99,121, 97,110, 10,125, 10, 10, 47, 42, 32,115,
+     116,114,105,110,103,115, 32,105,110, 32,115,111,117,114, 99,101, 32,
+     102,114, 97,103,109,101,110,116,115, 32, 42, 47, 10,115,112, 97,110,
+      46,115,116,114, 32,123, 10, 32, 32, 99,111,108,111,114, 58, 32, 98,
+     108,117,101, 10,125, 10, 10, 47, 42, 32, 97,115,115,101,109, 98,108,
+     101,114, 32,112, 97,115,115, 97,103,101,115, 32,105,110, 32,115,111,
+     117,114, 99,101, 32,102,114, 97,103,109,101,110,116,115, 32, 42, 47,
+      10,115,112, 97,110, 46, 97,115,109, 32,123, 10, 32, 32, 99,111,108,
+     111,114, 58, 32,103,114,101,101,110, 10,125, 10, 10, 10,116,100, 46,
+     112,114,101, 32,123, 10, 32, 32,119,104,105,116,101, 45,115,112, 97,
+      99,101, 58, 32,112,114,101, 10,125, 10, 10,112, 46, 99,109,116, 32,
+     123, 10, 32, 32, 99,111,108,111,114, 58, 32,103,114, 97,121, 10,125,
+      10, 10,115,112, 97,110, 46,119, 97,114,110,105,110,103, 32,123, 10,
+      32, 32, 99,111,108,111,114, 58, 32,114,101,100, 59, 10, 32, 32,102,
+     111,110,116, 45,119,101,105,103,104,116, 58, 32, 98,111,108,100, 10,
+     125, 10, 10, 47, 42, 32, 33, 33, 33, 58, 32, 72,111,119, 32,115,104,
+     111,117,108,100, 32,119,101, 32,100,101,102,105,110,101, 32,116,104,
+     105,115, 46, 46, 46, 63, 32, 42, 47, 10,115,112, 97,110, 46,102,105,
+     108,101, 32,123, 10, 32, 32, 99,111,108,111,114, 58, 32,100, 97,114,
+     107,103,114,101,101,110, 10,125, 10, 10,116, 97, 98,108,101, 46,114,
+     101,109, 97,114,107, 32,123, 10, 32, 32, 98, 97, 99,107,103,114,111,
+     117,110,100, 45, 99,111,108,111,114, 58, 32, 35,102,102,102,102, 99,
+      48, 59, 10,125, 10, 10,116, 97, 98,108,101, 46, 98, 97,114, 32,123,
+      10, 32, 32, 98, 97, 99,107,103,114,111,117,110,100, 45, 99,111,108,
+     111,114, 58, 32, 35, 97, 48, 99, 48,102,102, 59, 10,125, 10, 10,116,
+     100, 32,112, 32,123, 10, 32,109, 97,114,103,105,110, 58, 32, 48, 59,
+      10,125, 10, 10,115,112, 97,110, 46, 98, 97,114,116,105,116,108,101,
+      32,123, 10, 32, 32,102,111,110,116, 45,119,101,105,103,104,116, 58,
+      32, 98,111,108,100, 59, 10, 32, 32,102,111,110,116, 45,115,116,121,
+     108,101, 58, 32,105,116, 97,108,105, 99, 59, 10, 32, 32, 99,111,108,
+     111,114, 58, 32,100, 97,114,107, 98,108,117,101, 10,125, 10, 10,115,
+     112, 97,110, 46,116,111,103,103,108,101,116,114,101,101, 99,108,111,
+     115,101, 32,123, 10, 32, 32, 32, 32, 98, 97, 99,107,103,114,111,117,
+     110,100, 58, 32,117,114,108, 40,109,105,110,117,115, 46,112,110,103,
+      41, 32, 99,101,110,116,101,114, 32,108,101,102,116, 32,110,111, 45,
+     114,101,112,101, 97,116, 59, 10, 32, 32, 32, 32,112, 97,100,100,105,
+     110,103, 45,108,101,102,116, 58, 32, 50, 48,112,120, 59, 32, 10,125,
+      10, 10,115,112, 97,110, 46,116,111,103,103,108,101,116,114,101,101,
+     111,112,101,110, 32,123, 10, 32, 32, 32, 32, 98, 97, 99,107,103,114,
+     111,117,110,100, 58, 32,117,114,108, 40,112,108,117,115, 46,112,110,
+     103, 41, 32, 99,101,110,116,101,114, 32,108,101,102,116, 32,110,111,
+      45,114,101,112,101, 97,116, 59, 10, 32, 32, 32, 32,112, 97,100,100,
+     105,110,103, 45,108,101,102,116, 58, 32, 50, 48,112,120, 59, 32, 10,
+     125, 10, 10,117,108, 46, 99,108, 97,115,115,116,114,101,101,108,105,
+     115,116, 32,108,105, 32,123, 32,112, 97,100,100,105,110,103, 45,108,
+     101,102,116, 58, 32, 48,112,120, 59, 32,125, 10, 10,117,108, 46, 99,
+     108, 97,115,115,116,114,101,101,108,105,115,116, 32,123, 32,108,105,
+     115,116, 45,115,116,121,108,101, 45,116,121,112,101, 58,110,111,110,
+     101, 59, 32,125, 10, 10,108,105, 46, 99,108, 97,115,115,116,114,101,
+     101, 32,117,108, 32,123, 32,100,105,115,112,108, 97,121, 58, 32, 98,
+     108,111, 99,107, 59, 32,125, 10, 10,108,105, 46, 99,108, 97,115,115,
+     116,114,101,101, 99,108,111,115,101,100, 32,117,108, 32,123, 32,100,
+     105,115,112,108, 97,121, 58, 32,110,111,110,101, 59, 32,125, 10);

+ 115 - 96
utils/fpdoc/dglobals.pp

@@ -25,6 +25,10 @@ interface
 
 
 uses Classes, DOM, PasTree, PParser, StrUtils,uriparser;
 uses Classes, DOM, PasTree, PParser, StrUtils,uriparser;
 
 
+Const
+  CacheSize = 20;
+  ContentBufSize = 4096 * 8;
+
 Var
 Var
   LEOL : Integer;
   LEOL : Integer;
   modir : string;
   modir : string;
@@ -35,6 +39,7 @@ resourcestring
   SDocPrograms               = 'Programs';
   SDocPrograms               = 'Programs';
   SDocUnits                  = 'Units';
   SDocUnits                  = 'Units';
   SDocUnitTitle              = 'Reference for unit ''%s''';
   SDocUnitTitle              = 'Reference for unit ''%s''';
+  SDocInheritanceHierarchy   = 'Inheritance Hierarchy';
   SDocInterfaceSection       = 'Interface section';
   SDocInterfaceSection       = 'Interface section';
   SDocImplementationSection  = 'Implementation section';
   SDocImplementationSection  = 'Implementation section';
   SDocUsedUnits              = 'Used units';
   SDocUsedUnits              = 'Used units';
@@ -47,6 +52,7 @@ resourcestring
   SDocProceduresAndFunctions = 'Procedures and functions';
   SDocProceduresAndFunctions = 'Procedures and functions';
   SDocVariables              = 'Variables';
   SDocVariables              = 'Variables';
   SDocIdentifierIndex        = 'Index';
   SDocIdentifierIndex        = 'Index';
+  SDocPackageClassHierarchy  = 'Class hierarchy';
   SDocModuleIndex            = 'Index of all identifiers in unit ''%s''';
   SDocModuleIndex            = 'Index of all identifiers in unit ''%s''';
   SDocPackageIndex           = 'Index of all identifiers in package ''%s''';
   SDocPackageIndex           = 'Index of all identifiers in package ''%s''';
   SDocUnitOverview           = 'Overview of unit ''%s''';
   SDocUnitOverview           = 'Overview of unit ''%s''';
@@ -82,6 +88,8 @@ resourcestring
   SDocVisibility             = 'Visibility';
   SDocVisibility             = 'Visibility';
   SDocOpaque                 = 'Opaque type';
   SDocOpaque                 = 'Opaque type';
   SDocDateGenerated          = 'Documentation generated on: %s';
   SDocDateGenerated          = 'Documentation generated on: %s';
+  // The next line requires leading/trailing space due to XML comment layout:
+  SDocGeneratedByComment     = ' Generated using FPDoc - (c) 2000-2012 FPC contributors and Sebastian Guenther, [email protected] ';
   SDocNotes                  = 'Notes';
   SDocNotes                  = 'Notes';
   
   
   // Topics
   // Topics
@@ -129,37 +137,43 @@ resourcestring
 
 
   STitle           = 'FPDoc - Free Pascal Documentation Tool';
   STitle           = 'FPDoc - Free Pascal Documentation Tool';
   SVersion         = 'Version %s [%s]';
   SVersion         = 'Version %s [%s]';
-  SCopyright       = '(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, [email protected]';
+  SCopyright1      = '(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, [email protected]';
+  SCopyright2      = '(c) 2005 - 2012 various FPC contributors';
 
 
   SCmdLineHelp     = 'Usage: %s [options]';
   SCmdLineHelp     = 'Usage: %s [options]';
   SUsageOption010  = '--content         Create content file for package cross-references';
   SUsageOption010  = '--content         Create content file for package cross-references';
   SUsageOption020  = '--cputarget=value Set the target CPU for the scanner.';
   SUsageOption020  = '--cputarget=value Set the target CPU for the scanner.';
-  SUsageOption030  = '--descr=name      use name as description file. ';
+  SUsageOption030  = '--descr=file      use file as description file, e.g.: ';
+  SUsageOption035  = '                  --descr=c:\WIP\myzipperdoc.xml';
   SUsageOption040  = '                  This option is allowed more than once';
   SUsageOption040  = '                  This option is allowed more than once';
-  SUsageOption050  = '--format=fmt      Select output format.';
-  SUsageOption060  = '--help            Show this help.';
-  SUsageOption070  = '--hide-protected  Do not show protected methods in overview';
-  SUsageOption080  = '--import=file     Import content file for package cross-references';
-  SUsageOption090  = '--input=cmd       use cmd as input for the parser.';
-  SUsageOption100  = '                  At least one input option is required.';
-  SUsageOption110  = '--lang=lng        Select output language.';
-  SUsageOption120  = '--ostarget=value  Set the target OS for the scanner.';
-  SUsageOption130  = '--output=name     use name as the output name.';
-  SUsageOption140  = '                  Each backend interpretes this as needed.';
-  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.';
-  SUsageOption170  = '--warn-no-node    Warn if no documentation node was found.';
-  SUsageOption180  = '--mo-dir=dir      Set directory where language files reside to dir';
-  SUsageOption190  = '--parse-impl      (Experimental) try to parse implementation too';
-  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';
-  
+  SUsageOption050  = '--descr-dir=Dir   Add All XML files in Dir to list of description files';
+  SUsageOption060  = '--format=fmt      Select output format.';
+  SUsageOption070  = '--help            Show this help.';
+  SUsageOption080  = '--hide-protected  Do not show protected methods in overview';
+  SUsageOption090  = '--import=file     Import content file for package cross-references';
+  SUsageOption100  = '--input=cmd       use cmd as input for the parser, e.g.:';
+  SUsageOption110  = '           --input=C:\fpc\packages\paszlib\src\zipper.pp';
+  SUsageOption120  = '                  At least one input option is required.';
+  SUsageOption130  = '--input-dir=Dir   Add All *.pp and *.pas files in Dir to list of input files';
+  SUsageOption140  = '--lang=lng        Select output language.';
+  SUsageOption150  = '--ostarget=value  Set the target OS for the scanner.';
+  SUsageOption160  = '--output=name     use name as the output name.';
+  SUsageOption170  = '                  Each backend interpretes this as needed.';
+  SUsageOption180  = '--package=name    Set the package name for which to create output,';
+  SUsageOption190  = '                  e.g. --package=fcl';
+  SUsageOption200  = '--project=file    Use file as project file';
+  SUsageOption210  = '--show-private    Show private methods.';
+  SUsageOption220  = '--warn-no-node    Warn if no documentation node was found.';
+  SUsageOption230  = '--mo-dir=dir      Set directory where language files reside to dir';
+  SUsageOption240  = '--parse-impl      (Experimental) try to parse implementation too';
+  SUsageOption250  = '--dont-trim       Do not trim XML contents. Useful for preserving';
+  SUsageOption260  = '                  formatting inside e.g <pre> tags';
+  SUsageOption270  = '--write-project=file';
+  SUsageOption280  = '                  Do not write documentation, create project file instead';
+  SUsageOption290  = '--verbose         Write more information on the screen';
+  SUsageOption300  = '--dry-run         Only parse sources and XML, do not create output';
+  SUsageOption310  = '--write-project=file';
+  SUsageOption320  = '                  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.';
@@ -170,6 +184,7 @@ resourcestring
   SCmdLineOutputOptionMissing = 'Need an output filename, please specify one with --output=<filename>';
   SCmdLineOutputOptionMissing = 'Need an output filename, please specify one with --output=<filename>';
   SWritingPages               = 'Writing %d pages...';
   SWritingPages               = 'Writing %d pages...';
   SNeedPackageName            = 'No package name specified. Please specify one using the --package option.';
   SNeedPackageName            = 'No package name specified. Please specify one using the --package option.';
+  SAvailablePackages          = 'Available packages: ';
   SDone                       = 'Done.';
   SDone                       = 'Done.';
   SErrCouldNotCreateOutputDir = 'Could not create output directory "%s"';
   SErrCouldNotCreateOutputDir = 'Could not create output directory "%s"';
   SErrCouldNotCreateFile      = 'Could not create file "%s": %s';
   SErrCouldNotCreateFile      = 'Could not create file "%s": %s';
@@ -190,6 +205,8 @@ type
     destructor Destroy; override;
     destructor Destroy; override;
   end;
   end;
 
 
+  TPasExternalClassType = Class(TPasClassType);
+  TPasExternalModule = Class(TPasModule);
 
 
   { Link entry tree
   { Link entry tree
     TFPDocEngine stores the root of the entry tree in its property
     TFPDocEngine stores the root of the entry tree in its property
@@ -284,6 +301,8 @@ type
   private
   private
     FDocLogLevels: TFPDocLogLevels;
     FDocLogLevels: TFPDocLogLevels;
     FOnParseUnit: TOnParseUnitEvent;
     FOnParseUnit: TOnParseUnitEvent;
+    function ResolveLinkInPackages(AModule: TPasModule; const ALinkDest: String; Strict: Boolean=False): String;
+    function ResolveLinkInUsedUnits(AModule: TPasModule; const ALinkDest: String; Strict: Boolean=False): String;
   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
@@ -319,7 +338,7 @@ type
     // Link tree support
     // Link tree support
     procedure AddLink(const APathName, ALinkTo: String);
     procedure AddLink(const APathName, ALinkTo: String);
     function FindAbsoluteLink(const AName: String): String;
     function FindAbsoluteLink(const AName: String): String;
-    function ResolveLink(AModule: TPasModule; const ALinkDest: String): String;
+    function ResolveLink(AModule: TPasModule; const ALinkDest: String; Strict : Boolean = False): String;
     function FindLinkedNode(ANode: TDocNode): TDocNode;
     function FindLinkedNode(ANode: TDocNode): TDocNode;
 
 
     // Documentation file support
     // Documentation file support
@@ -453,7 +472,6 @@ begin
     end;
     end;
     { 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
       Raise Exception.CreateFmt('Link path does not exist: %s',[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
@@ -603,7 +621,6 @@ var
 begin
 begin
   for i := 0 to FPackages.Count - 1 do
   for i := 0 to FPackages.Count - 1 do
     TPasPackage(FPackages[i]).Release;
     TPasPackage(FPackages[i]).Release;
-  FPackages.Free;
   FRootDocNode.Free;
   FRootDocNode.Free;
   FRootLinkNode.Free;
   FRootLinkNode.Free;
   DescrDocNames.Free;
   DescrDocNames.Free;
@@ -675,6 +692,8 @@ var
         Inc(i);
         Inc(i);
       NewNode := TLinkNode.Create(Copy(s, ThisSpaces + 1, i - ThisSpaces - 1),
       NewNode := TLinkNode.Create(Copy(s, ThisSpaces + 1, i - ThisSpaces - 1),
         ALinkPrefix + Copy(s, i + 1, Length(s)));
         ALinkPrefix + Copy(s, i + 1, Length(s)));
+      if pos(' ',newnode.link)>0 then
+        writeln(stderr,'Bad format imported node: name="',newnode.name,'" link="',newnode.link,'"');
       if Assigned(PrevSibling) then
       if Assigned(PrevSibling) then
         PrevSibling.FNextSibling := NewNode
         PrevSibling.FNextSibling := NewNode
       else
       else
@@ -728,7 +747,7 @@ var
       begin
       begin
         if not CreateNew then
         if not CreateNew then
           exit;
           exit;
-        Module := TPasModule.Create(s, HPackage);
+        Module := TPasExternalModule.Create(s, HPackage);
         Module.InterfaceSection := TInterfaceSection.Create('', Module);
         Module.InterfaceSection := TInterfaceSection.Create('', Module);
         HPackage.Modules.Add(Module);
         HPackage.Modules.Add(Module);
       end;
       end;
@@ -789,7 +808,7 @@ var
     begin
     begin
       s:= ResolvePackageModule(AName,HPackage,Module,True);
       s:= ResolvePackageModule(AName,HPackage,Module,True);
       // Create node for class
       // Create node for class
-      Result := TPasClassType.Create(s, Module.InterfaceSection);
+      Result := TPasExternalClassType.Create(s, Module.InterfaceSection);
       Result.ObjKind := okClass;
       Result.ObjKind := okClass;
       Module.InterfaceSection.Declarations.Add(Result);
       Module.InterfaceSection.Declarations.Add(Result);
       Module.InterfaceSection.Classes.Add(Result);
       Module.InterfaceSection.Classes.Add(Result);
@@ -965,11 +984,14 @@ end;
 
 
 var
 var
   s: String;
   s: String;
+  buf : Array[1..ContentBufSize-1] of byte;
+
 begin
 begin
   if not FileExists(AFileName) then
   if not FileExists(AFileName) then
     raise EInOutError.Create('File not found: ' + AFileName);
     raise EInOutError.Create('File not found: ' + AFileName);
   Assign(f, AFilename);
   Assign(f, AFilename);
   Reset(f);
   Reset(f);
+  SetTextBuf(F,Buf,SizeOf(Buf));
   while not EOF(f) do
   while not EOF(f) do
   begin
   begin
     ReadLn(f, s);
     ReadLn(f, s);
@@ -1019,9 +1041,11 @@ var
   ClassDecl: TPasClassType;
   ClassDecl: TPasClassType;
   Member: TPasElement;
   Member: TPasElement;
   s: String;
   s: String;
+  Buf : Array[0..ContentBufSize-1] of byte;
 begin
 begin
   Assign(ContentFile, AFilename);
   Assign(ContentFile, AFilename);
   Rewrite(ContentFile);
   Rewrite(ContentFile);
+  SetTextBuf(ContentFile,Buf,SizeOf(Buf));
   try
   try
     WriteLn(ContentFile, '# FPDoc Content File');
     WriteLn(ContentFile, '# FPDoc Content File');
     WriteLn(ContentFile, ':link tree');
     WriteLn(ContentFile, ':link tree');
@@ -1042,6 +1066,8 @@ begin
     for i := 0 to Package.Modules.Count - 1 do
     for i := 0 to Package.Modules.Count - 1 do
     begin
     begin
       Module := TPasModule(Package.Modules[i]);
       Module := TPasModule(Package.Modules[i]);
+      if not assigned(Module.InterfaceSection) then
+        continue;
       for j := 0 to Module.InterfaceSection.Classes.Count - 1 do
       for j := 0 to Module.InterfaceSection.Classes.Count - 1 do
       begin
       begin
         ClassDecl := TPasClassType(Module.InterfaceSection.Classes[j]);
         ClassDecl := TPasClassType(Module.InterfaceSection.Classes[j]);
@@ -1147,11 +1173,11 @@ var
   Module: TPasElement;
   Module: TPasElement;
 begin
 begin
   Result := FindInModule(CurModule, AName);
   Result := FindInModule(CurModule, AName);
-  if not Assigned(Result) then
+  if not Assigned(Result) and assigned (CurModule.InterfaceSection) then
     for i := CurModule.InterfaceSection.UsesList.Count - 1 downto 0 do
     for i := CurModule.InterfaceSection.UsesList.Count - 1 downto 0 do
     begin
     begin
       Module := TPasElement(CurModule.InterfaceSection.UsesList[i]);
       Module := TPasElement(CurModule.InterfaceSection.UsesList[i]);
-      if Module.ClassType = TPasModule then
+      if Module.ClassType.InheritsFrom(TPasModule) then
       begin
       begin
         Result := FindInModule(TPasModule(Module), AName);
         Result := FindInModule(TPasModule(Module), AName);
         if Assigned(Result) then
         if Assigned(Result) then
@@ -1231,84 +1257,77 @@ begin
     SetLength(Result, 0);
     SetLength(Result, 0);
 end;
 end;
 
 
-function TFPDocEngine.ResolveLink(AModule: TPasModule;
-  const ALinkDest: String): String;
-var
-  i: Integer;
-  ThisPackage: TLinkNode;
-  UnitList: TFPList;
+function TFPDocEngine.ResolveLinkInPackages(AModule: TPasModule; const ALinkDest: String; Strict : Boolean = False): String;
 
 
-  function CanWeExit(AResult: string): boolean;
-  var
-    s: string;
-  begin
-    s := StringReplace(Lowercase(ALinkDest), '.', '_', [rfReplaceAll]);
-    Result := pos(s, AResult) > 0;
-  end;
+Var
+  ThisPackage: TLinkNode;
 
 
 begin
 begin
-  // system.WriteLn('ResolveLink(', AModule.Name, ' - ', ALinkDest, ')... ');
-  if Length(ALinkDest) = 0 then
-  begin
-    SetLength(Result, 0);
-    exit;
-  end;
-
-  if (ALinkDest[1] = '#') or (not assigned(AModule)) then
-    Result := FindAbsoluteLink(ALinkDest)
-  else
-  begin
-    if Pos(AModule.Name, ALinkDest) = 1 then
-    begin
-      Result := ResolveLink(AModule, amodule.packagename + '.' + ALinkDest);
-      if CanWeExit(Result) then
-        Exit;
-    end
-    else
+  { Try all packages }
+  Result:='';
+  ThisPackage:=RootLinkNode.FirstChild;
+  while Assigned(ThisPackage) and (Result='') do
     begin
     begin
-      Result := ResolveLink(AModule, AModule.PathName + '.' + ALinkDest);
-      if CanWeExit(Result) then
-        Exit;
+    Result:=ResolveLink(AModule, ThisPackage.Name + '.' + ALinkDest, Strict);
+    ThisPackage := ThisPackage.NextSibling;
     end;
     end;
+end;
 
 
-    { Try all packages }
-    SetLength(Result, 0);
-    ThisPackage := RootLinkNode.FirstChild;
-    while Assigned(ThisPackage) do
+function TFPDocEngine.ResolveLinkInUsedUnits(AModule: TPasModule; const ALinkDest: String; Strict : Boolean = False): String;
+
+var
+  i: Integer;
+  UL: TFPList;
+
+begin
+  Result:='';
+  UL:=AModule.InterfaceSection.UsesList;
+  I:=UL.Count-1;
+  While (Result='') and (I>=0) do
     begin
     begin
-      Result := ResolveLink(AModule, ThisPackage.Name + '.' + ALinkDest);
-      if CanWeExit(Result) then
-        Exit;
-      ThisPackage := ThisPackage.NextSibling;
+    Result:=ResolveLinkInPackages(AModule,TPasType(UL[i]).Name+'.'+ALinkDest, strict);
+    Dec(I);
     end;
     end;
+end;
+
+function TFPDocEngine.ResolveLink(AModule: TPasModule; const ALinkDest: String; Strict : Boolean = False): String;
+var
+  i: Integer;
 
 
-    if not CanWeExit(Result) then
+begin
+{
+  if Assigned(AModule) then
+      system.WriteLn('ResolveLink(', AModule.Name, ' - ', ALinkDest, ')... ')
+    else
+      system.WriteLn('ResolveLink(Nil - ', ALinkDest, ')... ');
+}
+  if (ALinkDest='') then
+    Exit('');
+  if (ALinkDest[1] = '#') then
+    Result := FindAbsoluteLink(ALinkDest)
+  else if (AModule=Nil) then
+    Result:= FindAbsoluteLink(RootLinkNode.FirstChild.Name+'.'+ALinkDest)
+  else
     begin
     begin
-      { Okay, then we have to try all imported units of the current module }
-      UnitList := AModule.InterfaceSection.UsesList;
-      for i := UnitList.Count - 1 downto 0 do
+    if Pos(AModule.Name,ALinkDest) = 1 then
+      Result := ResolveLink(AModule, AModule.packagename + '.' + ALinkDest, Strict)
+    else
+      Result := ResolveLink(AModule, AModule.PathName + '.' + ALinkDest, Strict);
+    if (Result='') then
       begin
       begin
-        { Try all packages }
-        ThisPackage := RootLinkNode.FirstChild;
-        while Assigned(ThisPackage) do
-        begin
-          Result := ResolveLink(AModule, ThisPackage.Name + '.' +
-            TPasType(UnitList[i]).Name + '.' + ALinkDest);
-            if CanWeExit(Result) then
-              Exit;
-          ThisPackage := ThisPackage.NextSibling;
-        end;
+      Result:=ResolveLinkInPackages(AModule,ALinkDest,Strict);
+      if (Result='') then
+        Result:=ResolveLinkInUsedUnits(Amodule,AlinkDest,Strict);
       end;
       end;
     end;
     end;
-  end;
-
-  if Length(Result) = 0 then
+  // Match on parent : class/enumerated/record/module
+  if (Result='') and not strict then
     for i := Length(ALinkDest) downto 1 do
     for i := Length(ALinkDest) downto 1 do
       if ALinkDest[i] = '.' then
       if ALinkDest[i] = '.' then
-      begin
-        Result := ResolveLink(AModule, Copy(ALinkDest, 1, i - 1));
+        begin
+        Result := ResolveLink(AModule, Copy(ALinkDest, 1, i - 1), Strict);
         exit;
         exit;
-      end;
+        end;
 end;
 end;
 
 
 procedure ReadXMLFileALT(OUT ADoc:TXMLDocument;const AFileName:ansistring);
 procedure ReadXMLFileALT(OUT ADoc:TXMLDocument;const AFileName:ansistring);
@@ -1503,7 +1522,7 @@ begin
           break;
           break;
         CurPackage := CurPackage.NextSibling;
         CurPackage := CurPackage.NextSibling;
       end;
       end;
-      if not Assigned(Result) then
+      if not Assigned(Result) and assigned(CurModule.InterfaceSection) then
       begin
       begin
         { Okay, then we have to try all imported units of the current module }
         { Okay, then we have to try all imported units of the current module }
         UnitList := CurModule.InterfaceSection.UsesList;
         UnitList := CurModule.InterfaceSection.UsesList;

File diff suppressed because it is too large
+ 526 - 249
utils/fpdoc/dw_html.pp


+ 23 - 2
utils/fpdoc/dw_htmlchm.inc

@@ -32,7 +32,7 @@ type
 
 
     class procedure Usage(List: TStrings); override;
     class procedure Usage(List: TStrings); override;
     Class Function FileNameExtension : String; override;
     Class Function FileNameExtension : String; override;
-    
+    Class procedure SplitImport(var AFilename, ALinkPrefix: String); override;
   end;
   end;
 {$ELSE} // implementation
 {$ELSE} // implementation
 
 
@@ -175,6 +175,8 @@ begin
     for i := 0 to Package.Modules.Count - 1 do
     for i := 0 to Package.Modules.Count - 1 do
     begin
     begin
       AModule := TPasModule(Package.Modules[i]);
       AModule := TPasModule(Package.Modules[i]);
+      If not assigned(AModule.InterfaceSection) Then
+         Continue;
       ObjUnitItem := ObjByUnitItem.Children.NewItem;
       ObjUnitItem := ObjByUnitItem.Children.NewItem;
       ObjUnitItem.Text := AModule.Name;
       ObjUnitItem.Text := AModule.Name;
       RoutinesUnitItem := RoutinesByUnitItem.Children.NewItem;
       RoutinesUnitItem := RoutinesByUnitItem.Children.NewItem;
@@ -292,6 +294,8 @@ begin
     for i := 0 to Package.Modules.Count - 1 do
     for i := 0 to Package.Modules.Count - 1 do
     begin
     begin
       AModule := TPasModule(Package.Modules[i]);
       AModule := TPasModule(Package.Modules[i]);
+      if not assigned(AModule.InterfaceSection) then
+        continue;
       ParentItem := Index.Items.NewItem;
       ParentItem := Index.Items.NewItem;
       ParentItem.Text := AModule.Name;
       ParentItem.Text := AModule.Name;
       ParentItem.Local := FixHTMLpath(Allocator.GetFilename(AModule, 0));
       ParentItem.Local := FixHTMLpath(Allocator.GetFilename(AModule, 0));
@@ -341,7 +345,7 @@ begin
       begin
       begin
         ParentElement := TPasProcedureType(AModule.InterfaceSection.Functions[j]);
         ParentElement := TPasProcedureType(AModule.InterfaceSection.Functions[j]);
         TmpItem := Index.Items.NewItem;
         TmpItem := Index.Items.NewItem;
-        TmpItem.Text := ParentElement.Name + ' ' + TPasFunction(ParentElement).ElementTypeName;
+        TmpItem.Text := ParentElement.Name + ' ' + ParentElement.ElementTypeName;
         TmpItem.Local := FixHTMLpath(Allocator.GetFilename(ParentElement, 0));
         TmpItem.Local := FixHTMLpath(Allocator.GetFilename(ParentElement, 0));
       end;
       end;
       // consts
       // consts
@@ -565,4 +569,21 @@ begin
   result:='.chm';
   result:='.chm';
 end;
 end;
 
 
+class procedure TCHMHTMLWriter.SplitImport(var AFilename, ALinkPrefix: String);
+var
+  i: integer;
+begin
+  i := Pos(',', AFilename);
+  if i > 0 then
+    begin  //split into filename and prefix
+    ALinkPrefix := Copy(AFilename,i+1,Length(AFilename));
+    SetLength(AFilename, i-1);
+    end
+  else if ALinkPrefix = '' then
+    begin  //synthesize outdir\pgk.xct, ms-its:pkg.chm::/
+    ALinkPrefix := 'ms-its:' + ChangeFileExt(ExtractFileName(AFilename), '.chm') + '::/';
+    AFilename := ChangeFileExt(AFilename, '.xct');
+    end;
+end;
+
 {$ENDIF}
 {$ENDIF}

+ 119 - 10
utils/fpdoc/dw_ipflin.pas

@@ -141,6 +141,7 @@ type
   public
   public
     constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
     constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
     class function FileNameExtension: string; override;
     class function FileNameExtension: string; override;
+    procedure WriteClassInheritanceOverview(ClassDecl: TPasClassType); override;
   end;
   end;
 
 
 
 
@@ -148,7 +149,7 @@ type
 implementation
 implementation
 
 
 uses
 uses
-  SysUtils, dwriter;
+  SysUtils, dwriter, dbugintf;
 
 
 
 
 { TFPDocWriter overrides }
 { TFPDocWriter overrides }
@@ -195,7 +196,6 @@ const
   cMax = 100;
   cMax = 100;
 var
 var
   sl: TStringlist;
   sl: TStringlist;
-  ns: string;
   i: integer;
   i: integer;
   lText: string;
   lText: string;
 begin
 begin
@@ -500,6 +500,117 @@ begin
   InTypesDeclaration := False;
   InTypesDeclaration := False;
 end;
 end;
 
 
+procedure TIPFNewWriter.WriteClassInheritanceOverview(ClassDecl: TPasClassType);
+var
+  DocNode: TDocNode;
+  ancestor: TPasClassType;
+  ancestor2: TPasType;
+  List: TStringList;
+  i: integer;
+  indent: integer;
+
+  procedure WriteDescription(const Idx: integer);
+  var
+    s: string;
+    o: TPasClassType;
+    t: string;
+  begin
+    if List.Objects[i] <> nil then
+    begin
+      o := List.Objects[i] as TPasClassType;
+      if ClassDecl.Name <> o.Name then
+      begin
+        s := ChangeFileExt(ExtractFileName(o.SourceFilename), '');
+        s := '#' + PackageName + '.' + s + '.' + o.Name;
+        DescrBeginLink(s);
+        Write(o.Name);
+        DescrEndLink;
+        writeln('');
+      end
+      else
+      begin
+        { The topic being viewed doesn't need a link to itself }
+        writeln(List[i]);
+      end;
+    end
+    else
+    begin
+      { we only have text for it. }
+      Writeln(List[i]);
+    end;
+  end;
+
+begin
+  List := TStringList.Create;
+  List.Sorted := False;
+  { add the initial class }
+  List.AddObject(ClassDecl.Name, ClassDecl);
+
+  ancestor := nil;
+
+  if Assigned(ClassDecl.AncestorType) and ClassDecl.AncestorType.InheritsFrom(TPasClassType) then
+    { all is well, we have our first ancestor to get us started with the hierarchy traversal }
+    ancestor := TPasClassType(ClassDecl.AncestorType)
+  else
+  begin
+    { here we only have one history item to output - and not part of fpdoc hierarchy data }
+    if Assigned(ClassDecl.AncestorType) then
+    begin
+      ancestor2 := ClassDecl.AncestorType;
+      if Assigned(ancestor2) then
+      begin
+        List.AddObject(ancestor2.Name, nil);
+        ancestor2 := nil; { prevent any further attempts at traversal }
+      end;
+    end;
+  end;
+
+  while Assigned(ancestor) do
+  begin
+    List.AddObject(ancestor.Name, ancestor);
+    if Assigned(ancestor.AncestorType) and ancestor.AncestorType.InheritsFrom(TPasClassType) then
+      ancestor := TPasClassType(ancestor.AncestorType)
+    else
+    begin
+      { we hit the end of the road }
+      ancestor2 := ancestor.AncestorType;
+      if Assigned(ancestor2) then
+        List.AddObject(ancestor2.Name, nil);
+      ancestor := nil;  { prevent any further attempts at traversal }
+    end;
+  end;
+
+  if List.Count > 1 then
+  begin
+    { output a title }
+    Writeln(':p.');
+    writeln(':lm margin=1.');
+    DescrBeginBold;
+    WriteLn(SDocInheritanceHierarchy);
+    DescrEndBold;
+    { now output the hierarchy }
+    indent := 3;
+    { we go from least significant to most, hence the reversed loop }
+    for i := List.Count-1 downto 0 do
+    begin
+      Write(Format(':lm margin=%d.', [indent]));
+      { each level is indented 2 character positions more than the previous one }
+      if (indent > 3) then
+      begin
+        writeln('|');
+        write('+--');
+      end
+      else
+        write(':xmp.');
+      WriteDescription(i);
+      inc(indent, 2);
+    end;
+    WriteLn(':lm margin=1.:exmp.');
+  end;
+
+  List.Free;
+end;
+
 { TLinearWriter overrides}
 { TLinearWriter overrides}
 
 
 class function TIPFNewWriter.FileNameExtension: String;
 class function TIPFNewWriter.FileNameExtension: String;
@@ -509,17 +620,15 @@ end;
 
 
 procedure TIPFNewWriter.DescrBeginURL(const AURL: DOMString);
 procedure TIPFNewWriter.DescrBeginURL(const AURL: DOMString);
 begin
 begin
-  //Write(EscapeText(AURL));
+  Write(':link reftype=launch object=''netscape'' data=''' + AURL + '''.');
 end;
 end;
 
 
 procedure TIPFNewWriter.DescrEndURL;
 procedure TIPFNewWriter.DescrEndURL;
 begin
 begin
-  // do nothing
+  Write(':elink.');
 end;
 end;
 
 
 function TIPFNewWriter.GetLabel(AElement: TPasElement): String;
 function TIPFNewWriter.GetLabel(AElement: TPasElement): String;
-var
-  i: Integer;
 begin
 begin
   if AElement.ClassType = TPasUnresolvedTypeRef then
   if AElement.ClassType = TPasUnresolvedTypeRef then
     Result := Engine.ResolveLink(Module, AElement.Name)
     Result := Engine.ResolveLink(Module, AElement.Name)
@@ -590,7 +699,7 @@ end;
 
 
 Function TIPFNewWriter.StripText(S : String) : String;
 Function TIPFNewWriter.StripText(S : String) : String;
 var
 var
-  I,L: Integer;
+  I: Integer;
 begin
 begin
   //Result := S;
   //Result := S;
   SetLength(Result, 0);
   SetLength(Result, 0);
@@ -611,7 +720,7 @@ begin
   fColCount := 0;
   fColCount := 0;
   Writeln(':userdoc.');
   Writeln(':userdoc.');
   WriteComment('This file has been created automatically by FPDoc');
   WriteComment('This file has been created automatically by FPDoc');
-  WriteComment('IPF output (c) 2010 by Graeme Geldenhuys ([email protected])');
+  WriteComment('IPF output (c) 2010-2012 by Graeme Geldenhuys ([email protected])');
   writeln('');
   writeln('');
   Writeln(':docprof toc=12345.');
   Writeln(':docprof toc=12345.');
   WriteLn(':title.' + PackageName);
   WriteLn(':title.' + PackageName);
@@ -735,9 +844,9 @@ begin
     DescrEndBold;
     DescrEndBold;
 //    writeln(':lm margin=3.');
 //    writeln(':lm margin=3.');
     writeln('.br');
     writeln('.br');
-  end;
+  end
 
 
-  if InPackageOverview then
+  else if InPackageOverview then
   begin
   begin
     FInHeadingText := ':h2%s. ' + SectionName;
     FInHeadingText := ':h2%s. ' + SectionName;
 //    Writeln(':h2.' + SectionName);
 //    Writeln(':h2.' + SectionName);

+ 1 - 1
utils/fpdoc/dw_latex.pp

@@ -128,9 +128,9 @@ Type
     procedure DescrBeginTableCell; override;
     procedure DescrBeginTableCell; override;
     procedure DescrEndTableCell; override;
     procedure DescrEndTableCell; override;
     // TFPDocWriter class methods
     // TFPDocWriter class methods
-    Function InterPretOption(Const Cmd,Arg : String) : boolean; override;
     Property ImageDir : String Read FImageDir Write FImageDir;
     Property ImageDir : String Read FImageDir Write FImageDir;
   public
   public
+    Function InterPretOption(Const Cmd,Arg : String) : boolean; override;
     Class Function FileNameExtension : String; override;
     Class Function FileNameExtension : String; override;
   end;
   end;
 
 

+ 4 - 2
utils/fpdoc/dw_xml.pp

@@ -3,6 +3,8 @@
     FPDoc  -  Free Pascal Documentation Tool
     FPDoc  -  Free Pascal Documentation Tool
     Copyright (C) 2000 - 2003 by
     Copyright (C) 2000 - 2003 by
       Areca Systems GmbH / Sebastian Guenther, [email protected]
       Areca Systems GmbH / Sebastian Guenther, [email protected]
+    2005-2012 by
+      various FPC contributors
 
 
     * 'XML struct' output generator
     * 'XML struct' output generator
 
 
@@ -21,7 +23,7 @@ unit dw_XML;
 
 
 interface
 interface
 
 
-uses DOM, PasTree, dwriter, xmlWrite, SysUtils;
+uses DOM, PasTree, dGlobals, dwriter, xmlWrite, SysUtils;
 
 
 Type
 Type
 
 
@@ -93,7 +95,7 @@ var
 
 
 begin
 begin
   Result := TXMLDocument.Create;
   Result := TXMLDocument.Create;
-  Result.AppendChild(Result.CreateComment(' Generated using FPDoc - (c) 2000-2003 Sebastian Guenther, [email protected] '));
+  Result.AppendChild(Result.CreateComment(SDocGeneratedByComment));
   Result.AppendChild(Result.CreateElement('fp-refdoc'));
   Result.AppendChild(Result.CreateElement('fp-refdoc'));
   ModuleElement := Result.CreateElement('unit');
   ModuleElement := Result.CreateElement('unit');
   ModuleElement['name'] := AModule.Name;
   ModuleElement['name'] := AModule.Name;

+ 15 - 4
utils/fpdoc/dwlinear.pp

@@ -86,6 +86,8 @@ Type
     procedure WriteUnitEntry(UnitRef : TPasType);virtual; Abstract;
     procedure WriteUnitEntry(UnitRef : TPasType);virtual; Abstract;
     procedure EndUnitOverview; virtual; Abstract;
     procedure EndUnitOverview; virtual; Abstract;
     Property LastURL : DomString Read FLastURL Write FLastURL;
     Property LastURL : DomString Read FLastURL Write FLastURL;
+    // Overriden from fpdocwriter;
+    procedure DescrWriteText(const AText: DOMString); override;
   Public
   Public
     Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
     Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
     function InterpretOption(const Cmd, Arg: String): Boolean; override;
     function InterpretOption(const Cmd, Arg: String): Boolean; override;
@@ -107,13 +109,12 @@ Type
     procedure WriteClassDecl(ClassDecl: TPasClassType);
     procedure WriteClassDecl(ClassDecl: TPasClassType);
     procedure WriteClassMethodOverview(ClassDecl: TPasClassType);
     procedure WriteClassMethodOverview(ClassDecl: TPasClassType);
     procedure WriteClassPropertyOverview(ClassDecl: TPasClassType);
     procedure WriteClassPropertyOverview(ClassDecl: TPasClassType);
-    procedure WriteClassInterfacesOverView(ClassDecl: TPasClassType);
+    procedure WriteClassInterfacesOverview(ClassDecl: TPasClassType);
+    procedure WriteClassInheritanceOverview(ClassDecl: TPasClassType); virtual;
     procedure WriteProperty(PropDecl: TPasProperty);
     procedure WriteProperty(PropDecl: TPasProperty);
     procedure WriteExample(ADocNode: TDocNode);
     procedure WriteExample(ADocNode: TDocNode);
     procedure WriteSeeAlso(ADocNode: TDocNode);
     procedure WriteSeeAlso(ADocNode: TDocNode);
     Procedure WriteTopicNode(Node : TDocNode; Level : Integer);
     Procedure WriteTopicNode(Node : TDocNode; Level : Integer);
-    // Overriden from fpdocwriter;
-    procedure DescrWriteText(const AText: DOMString); override;
   end;
   end;
 
 
 implementation
 implementation
@@ -415,6 +416,10 @@ begin
     ConvertNotes(ClassDecl,DocNode.Notes);
     ConvertNotes(ClassDecl,DocNode.Notes);
   end;
   end;
 
 
+  // graemeg: this must move above SeeAlso, Version and Notes written above.
+  // Write Class Hierarchy (Inheritance) Overview;
+  WriteClassInheritanceOverView(ClassDecl);
+
   // Write Interfaces Overview;
   // Write Interfaces Overview;
   WriteClassInterfacesOverView(ClassDecl);
   WriteClassInterfacesOverView(ClassDecl);
   // Write method overview
   // Write method overview
@@ -517,7 +522,7 @@ begin
 end;
 end;
 
 
 
 
-procedure TLinearWriter.WriteClassInterfacesOverView(ClassDecl: TPasClassType);
+procedure TLinearWriter.WriteClassInterfacesOverview(ClassDecl: TPasClassType);
 var
 var
   lInterface: TPasElement;
   lInterface: TPasElement;
   i: Integer;
   i: Integer;
@@ -571,6 +576,12 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TLinearWriter.WriteClassInheritanceOverview(ClassDecl: TPasClassType);
+begin
+  { Do nothing by default. This will be implemented by descendant writers. See
+    the IPF Writer for an example. }
+end;
+
 
 
 function TLinearWriter.ConstValue(ConstDecl: TPasConst): String;
 function TLinearWriter.ConstValue(ConstDecl: TPasConst): String;
 begin
 begin

+ 89 - 56
utils/fpdoc/dwriter.pp

@@ -3,6 +3,8 @@
     FPDoc  -  Free Pascal Documentation Tool
     FPDoc  -  Free Pascal Documentation Tool
     Copyright (C) 2000 - 2003 by
     Copyright (C) 2000 - 2003 by
       Areca Systems GmbH / Sebastian Guenther, [email protected]
       Areca Systems GmbH / Sebastian Guenther, [email protected]
+    2005-2012 by
+      various FPC contributors
 
 
     * Output string definitions
     * Output string definitions
     * Basic writer (output generator) class
     * Basic writer (output generator) class
@@ -45,7 +47,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> in unit "%s" is unknown: "%s"';
+  SErrUnknownLinkID = 'Warning: Target ID of <link> in unit "%s", element "%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';
@@ -73,6 +75,7 @@ type
     FEmitNotes: Boolean;
     FEmitNotes: Boolean;
     FEngine  : TFPDocEngine;
     FEngine  : TFPDocEngine;
     FPackage : TPasPackage;
     FPackage : TPasPackage;
+    FContext : TPasElement;
     FTopics  : TList;
     FTopics  : TList;
     FImgExt : String;
     FImgExt : String;
     FBeforeEmitNote : TWriterNoteEvent;
     FBeforeEmitNote : TWriterNoteEvent;
@@ -157,6 +160,7 @@ type
     procedure DescrEndTableRow; virtual; abstract;
     procedure DescrEndTableRow; virtual; abstract;
     procedure DescrBeginTableCell; virtual; abstract;
     procedure DescrBeginTableCell; virtual; abstract;
     procedure DescrEndTableCell; virtual; abstract;
     procedure DescrEndTableCell; virtual; abstract;
+    Property CurrentContext : TPasElement Read FContext ;
   public
   public
     Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); virtual;
     Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); virtual;
     destructor Destroy;  override;
     destructor Destroy;  override;
@@ -168,6 +172,7 @@ type
     Function InterpretOption(Const Cmd,Arg : String) : Boolean; Virtual;
     Function InterpretOption(Const Cmd,Arg : String) : Boolean; Virtual;
     Class Function FileNameExtension : String; virtual;
     Class Function FileNameExtension : String; virtual;
     Class Procedure Usage(List : TStrings); virtual;
     Class Procedure Usage(List : TStrings); virtual;
+    Class procedure SplitImport(var AFilename, ALinkPrefix: String); virtual;
     procedure WriteDoc; virtual; Abstract;
     procedure WriteDoc; virtual; Abstract;
     Function WriteDescr(Element: TPasElement) : TDocNode;
     Function WriteDescr(Element: TPasElement) : TDocNode;
     procedure WriteDescr(Element: TPasElement; DocNode: TDocNode);
     procedure WriteDescr(Element: TPasElement; DocNode: TDocNode);
@@ -370,6 +375,19 @@ begin
   // Do nothing.
   // Do nothing.
 end;
 end;
 
 
+class procedure TFPDocWriter.SplitImport(var AFilename, ALinkPrefix: String);
+var
+  i: integer;
+begin
+//override in HTML and CHM writer
+  i := Pos(',', AFilename);
+  if i > 0 then
+    begin  //split CSV into filename and prefix
+    ALinkPrefix := Copy(AFilename,i+1,Length(AFilename));
+    SetLength(AFilename, i-1);
+    end;
+end;
+
 Function TFPDocWriter.FindTopicElement(Node : TDocNode): TTopicElement;
 Function TFPDocWriter.FindTopicElement(Node : TDocNode): TTopicElement;
 
 
 Var
 Var
@@ -475,20 +493,24 @@ begin
   Result := False;
   Result := False;
   if not Assigned(El) then
   if not Assigned(El) then
     exit;
     exit;
-
-  Node := El.FirstChild;
-  while Assigned(Node) do
-  begin
-    if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'link') then
-      ConvertLink(AContext, TDOMElement(Node))
-    else if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'url') then
-      ConvertURL(AContext, TDOMElement(Node))
-    else
-      if not ConvertBaseShort(AContext, Node) then
-        exit;
-    Node := Node.NextSibling;
+  FContext:=AContext;
+  try
+    Node := El.FirstChild;
+    while Assigned(Node) do
+    begin
+      if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'link') then
+        ConvertLink(AContext, TDOMElement(Node))
+      else if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'url') then
+        ConvertURL(AContext, TDOMElement(Node))
+      else
+        if not ConvertBaseShort(AContext, Node) then
+          exit;
+      Node := Node.NextSibling;
+    end;
+    Result := True;
+  finally
+    FContext:=Nil;
   end;
   end;
-  Result := True;
 end;
 end;
 
 
 function TFPDocWriter.ConvertNotes(AContext: TPasElement; El: TDOMElement
 function TFPDocWriter.ConvertNotes(AContext: TPasElement; El: TDOMElement
@@ -594,6 +616,7 @@ function TFPDocWriter.ConvertBaseShort(AContext: TPasElement;
 var
 var
   El, DescrEl: TDOMElement;
   El, DescrEl: TDOMElement;
   FPEl: TPasElement;
   FPEl: TPasElement;
+  hlp : TPasElement;
 begin
 begin
   Result := True;
   Result := True;
   if Node.NodeType = ELEMENT_NODE then
   if Node.NodeType = ELEMENT_NODE then
@@ -622,7 +645,12 @@ begin
     else if Node.NodeName = 'printshort' then
     else if Node.NodeName = 'printshort' then
     begin
     begin
       El := TDOMElement(Node);
       El := TDOMElement(Node);
-      DescrEl := Engine.FindShortDescr(AContext.GetModule, El['id']);
+      hlp:=AContext;
+      while assigned(hlp) and not (hlp is TPasModule) do 
+        hlp:=hlp.parent;
+      if not (hlp is TPasModule) then
+        hlp:=nil;
+      DescrEl := Engine.FindShortDescr(TPasModule(hlp), El['id']);
       if Assigned(DescrEl) then
       if Assigned(DescrEl) then
         ConvertShort(AContext, DescrEl)
         ConvertShort(AContext, DescrEl)
       else
       else
@@ -716,53 +744,58 @@ var
   Node, Child: TDOMNode;
   Node, Child: TDOMNode;
   ParaCreated: Boolean;
   ParaCreated: Boolean;
 begin
 begin
-  if AutoInsertBlock then
-    if IsExtShort(El.FirstChild) then
-      DescrBeginParagraph
-    else
-      AutoInsertBlock := False;
+  FContext:=AContext;
+  try
+    if AutoInsertBlock then
+      if IsExtShort(El.FirstChild) then
+        DescrBeginParagraph
+      else
+        AutoInsertBlock := False;
 
 
-  Node := El.FirstChild;
-  if not ConvertExtShort(AContext, Node) then
-  begin
-    while Assigned(Node) do
+    Node := El.FirstChild;
+    if not ConvertExtShort(AContext, Node) then
     begin
     begin
-      if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'section') then
+      while Assigned(Node) do
       begin
       begin
-        DescrBeginSectionTitle;
-        Child := Node.FirstChild;
-        while Assigned(Child) and (Child.NodeType <> ELEMENT_NODE) do
+        if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'section') then
         begin
         begin
-          if not IsDescrNodeEmpty(Child) then
-            Warning(AContext, SErrInvalidContentBeforeSectionTitle);
-          Child := Child.NextSibling;
-        end;
-        if not Assigned(Child) or (Child.NodeName <> 'title') then
-          Warning(AContext, SErrSectionTitleExpected)
-        else
-          ConvertShort(AContext, TDOMElement(Child));
-
-        DescrBeginSectionBody;
-
-        if IsExtShort(Child) then
-        begin
-          DescrBeginParagraph;
-          ParaCreated := True;
-        end else
-          ParaCreated := False;
+          DescrBeginSectionTitle;
+          Child := Node.FirstChild;
+          while Assigned(Child) and (Child.NodeType <> ELEMENT_NODE) do
+          begin
+            if not IsDescrNodeEmpty(Child) then
+              Warning(AContext, SErrInvalidContentBeforeSectionTitle);
+            Child := Child.NextSibling;
+          end;
+          if not Assigned(Child) or (Child.NodeName <> 'title') then
+            Warning(AContext, SErrSectionTitleExpected)
+          else
+            ConvertShort(AContext, TDOMElement(Child));
 
 
-        ConvertExtShortOrNonSectionBlocks(AContext, Child.NextSibling);
+          DescrBeginSectionBody;
 
 
-        if ParaCreated then
-          DescrEndParagraph;
-        DescrEndSection;
-      end else if not ConvertNonSectionBlock(AContext, Node) then
-        Warning(AContext, SErrInvalidDescr, [Node.NodeName]);
-      Node := Node.NextSibling;
-    end;
-  end else
-    if AutoInsertBlock then
-      DescrEndParagraph;
+          if IsExtShort(Child) then
+          begin
+            DescrBeginParagraph;
+            ParaCreated := True;
+          end else
+            ParaCreated := False;
+
+          ConvertExtShortOrNonSectionBlocks(AContext, Child.NextSibling);
+
+          if ParaCreated then
+            DescrEndParagraph;
+          DescrEndSection;
+        end else if not ConvertNonSectionBlock(AContext, Node) then
+          Warning(AContext, SErrInvalidDescr, [Node.NodeName]);
+        Node := Node.NextSibling;
+      end;
+    end else
+      if AutoInsertBlock then
+        DescrEndParagraph;
+  finally
+    FContext:=Nil;
+  end;
 end;
 end;
 
 
 procedure TFPDocWriter.ConvertExtShortOrNonSectionBlocks(AContext: TPasElement;
 procedure TFPDocWriter.ConvertExtShortOrNonSectionBlocks(AContext: TPasElement;

+ 18 - 6
utils/fpdoc/fpclasschart.lpi

@@ -1,22 +1,24 @@
 <?xml version="1.0"?>
 <?xml version="1.0"?>
 <CONFIG>
 <CONFIG>
   <ProjectOptions>
   <ProjectOptions>
-    <PathDelim Value="/"/>
-    <Version Value="6"/>
+    <Version Value="9"/>
     <General>
     <General>
       <Flags>
       <Flags>
         <SaveOnlyProjectUnits Value="True"/>
         <SaveOnlyProjectUnits Value="True"/>
         <MainUnitHasUsesSectionForAllUnits Value="False"/>
         <MainUnitHasUsesSectionForAllUnits Value="False"/>
         <MainUnitHasCreateFormStatements Value="False"/>
         <MainUnitHasCreateFormStatements Value="False"/>
         <MainUnitHasTitleStatement Value="False"/>
         <MainUnitHasTitleStatement Value="False"/>
+        <LRSInOutputDirectory Value="False"/>
       </Flags>
       </Flags>
       <SessionStorage Value="InProjectDir"/>
       <SessionStorage Value="InProjectDir"/>
       <MainUnit Value="0"/>
       <MainUnit Value="0"/>
-      <TargetFileExt Value=""/>
     </General>
     </General>
     <VersionInfo>
     <VersionInfo>
-      <ProjectVersion Value=""/>
+      <StringTable ProductVersion=""/>
     </VersionInfo>
     </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="default" Default="True"/>
+    </BuildModes>
     <PublishOptions>
     <PublishOptions>
       <Version Value="2"/>
       <Version Value="2"/>
       <IgnoreBinaries Value="False"/>
       <IgnoreBinaries Value="False"/>
@@ -29,7 +31,7 @@
         <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
         <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
       </local>
       </local>
     </RunParams>
     </RunParams>
-    <Units Count="2">
+    <Units Count="3">
       <Unit0>
       <Unit0>
         <Filename Value="fpclasschart.pp"/>
         <Filename Value="fpclasschart.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -40,10 +42,20 @@
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="dGlobals"/>
         <UnitName Value="dGlobals"/>
       </Unit1>
       </Unit1>
+      <Unit2>
+        <Filename Value="fpdocclasstree.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="fpdocclasstree"/>
+      </Unit2>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>
-    <Version Value="8"/>
+    <Version Value="11"/>
+    <Parsing>
+      <SyntaxOptions>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
     <Other>
     <Other>
       <CompilerPath Value="$(CompPath)"/>
       <CompilerPath Value="$(CompPath)"/>
     </Other>
     </Other>

+ 11 - 108
utils/fpdoc/fpclasschart.pp

@@ -19,7 +19,7 @@ program fpclasschart;
 
 
 uses
 uses
   SysUtils, Classes, Typinfo, Gettext, dom, xmlread,
   SysUtils, Classes, Typinfo, Gettext, dom, xmlread,
-  dGlobals, PasTree, PParser,PScanner, xmlwrite;
+  dGlobals, PasTree, PParser,PScanner, xmlwrite, fpdocclasstree;
 
 
 resourcestring
 resourcestring
   STitle = 'fpClassTree - Create class tree from pascal sources';
   STitle = 'fpClassTree - Create class tree from pascal sources';
@@ -33,28 +33,18 @@ resourcestring
   SMergedFile = 'Merged %d classes from file %s.';
   SMergedFile = 'Merged %d classes from file %s.';
   SClassesAdded = 'Added %d classes from %d files.';
   SClassesAdded = 'Added %d classes from %d files.';
 
 
-Const
-  RootNames : Array[TPasObjKind] of string
-            = ('Objects', 'Classes', 'Interfaces','Generics','Specializations');
-
 type
 type
 
 
   { TClassTreeEngine }
   { TClassTreeEngine }
 
 
+
   TClassTreeEngine = class(TFPDocEngine)
   TClassTreeEngine = class(TFPDocEngine)
   Private
   Private
-    FClassTree : TXMLDocument;
-    FTreeStart : TDomElement;
+    FTree : TClassTreeBuilder;
     FObjects : TStringList;
     FObjects : TStringList;
-    FObjectKind : TPasObjKind;
-    FParentObject : TPasClassType;
-    function LookForElement(PE: TDomElement; AElement: TPasElement): TDomNode;
-    function NodeMatch(N: TDomNode; AElement: TPasElement): Boolean;
-    Function AddToClassTree(AElement : TPasElement; Var ACount : Integer) : TDomElement;
   public
   public
     Constructor Create(AClassTree : TXMLDocument; AObjectKind : TPasObjKind);
     Constructor Create(AClassTree : TXMLDocument; AObjectKind : TPasObjKind);
     Destructor Destroy; override;
     Destructor Destroy; override;
-    Function BuildTree : Integer;
     function CreateElement(AClass: TPTreeElement; const AName: String;
     function CreateElement(AClass: TPTreeElement; const AName: String;
       AParent: TPasElement; AVisibility :TPasMemberVisibility;
       AParent: TPasElement; AVisibility :TPasMemberVisibility;
       const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement; override;
       const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement; override;
@@ -99,6 +89,11 @@ type
     Property MaxObjectsPerColumn : Integer Read FMaxObjectsPerColumn Write FMaxObjectsPerColumn;
     Property MaxObjectsPerColumn : Integer Read FMaxObjectsPerColumn Write FMaxObjectsPerColumn;
   end;
   end;
 
 
+{ TClassTreeBuilder }
+
+
+
+
 { TChartFormatter }
 { TChartFormatter }
 
 
 constructor TClassChartFormatter.Create(AXML: TXMLDocument);
 constructor TClassChartFormatter.Create(AXML: TXMLDocument);
@@ -454,21 +449,11 @@ end;
 
 
 Constructor TClassTreeEngine.Create(AClassTree : TXMLDocument; AObjectKind : TPasObjKind);
 Constructor TClassTreeEngine.Create(AClassTree : TXMLDocument; AObjectKind : TPasObjKind);
 
 
-Var
-  N : TDomNode;
 
 
 begin
 begin
-  FClassTree:=AClassTree;
-  FTreeStart:=FClassTree.DocumentElement;
   FPackage:=TPasPackage.Create('dummy',Nil);
   FPackage:=TPasPackage.Create('dummy',Nil);
-  FObjectKind:=AObjectKind;
+  FTree:=TClassTreeBuilder.Create(FPackage,AObjectKind);
   FObjects:=TStringList.Create;
   FObjects:=TStringList.Create;
-  Case FObjectkind of
-    okObject    : FParentObject:=TPasClassType.Create('TObject',FPackage);
-    okClass     : FParentObject:=TPasClassType.Create('TObject',FPackage);
-    okInterface : FParentObject:=TPasClassType.Create('IInterface',FPackage);
-  end;
-  FParentObject.ObjKind:=FObjectKind;
   Inherited Create;
   Inherited Create;
 end;
 end;
 
 
@@ -478,89 +463,7 @@ begin
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
-Function TClassTreeEngine.BuildTree : Integer;
-
-Var
-  I : Integer;
-  PC : TPasClassType;
-
-begin
-  Result:=0;
-  FObjects.Sorted:=True;
-  For I:=0 to FObjects.Count-1 do
-    begin
-    PC:=TPasClassType(FObjects.Objects[i]);
-    If (PC.ObjKind=FObjectKind) and Not PC.IsForward then
-      AddToClassTree(PC as TPasElement,Result)
-    end;
-end;
-
-Function TClassTreeEngine.NodeMatch(N : TDomNode; AElement : TPasElement) : Boolean;
-
-begin
-  Result:=(N.NodeType=ELEMENT_NODE) and (CompareText(N.NodeName,AElement.Name)=0)
-end;
-
-Function TClassTreeEngine.LookForElement(PE : TDomElement; AElement : TPasElement) : TDomNode;
 
 
-Var
-  N : TDomNode;
-
-begin
-  Result:=PE.FirstChild;
-  While (Result<>Nil) and Not NodeMatch(Result,AElement) do
-    Result:=Result.NextSibling;
-  If (Result=Nil) then
-    begin
-    N:=PE.FirstChild;
-    While (Result=Nil) and (N<>Nil) do
-      begin
-      if (N.NodeType=ELEMENT_NODE) then
-        begin
-        Result:=LookForElement(N as TDomElement,AElement);
-        end;
-      N:=N.NextSibling;
-      end;
-    end
-end;
-
-Function TClassTreeEngine.AddToClassTree(AElement : TPasElement; Var ACount : Integer) : TDomElement;
-
-Var
-  PC : TPasClassType;
-  PE : TDomElement;
-  M : TPasModule;
-  N : TDomNode;
-
-begin
-  PE:=Nil;
-  If (AElement is TPasClassType) then
-    begin
-    PC:=AElement as TPasClassType;
-    If not Assigned(PC.AncestorType) and (CompareText(PC.Name,FParentObject.Name)<>0) then
-      PC.AncestorType:=FParentObject;
-    If Assigned(PC.AncestorType) then
-      PE:=AddToClassTree(PC.AncestorType,ACount);
-    end;
-  If (PE=Nil) then
-    PE:=FTreeStart;
-  N:=LookForElement(PE,AElement);
-  If (N<>Nil) then
-    Result:=N as TDomElement
-  else
-    begin
-    Inc(ACount);
-    Result:=FClassTree.CreateElement(AElement.Name);
-    If Not (AElement is TPasUnresolvedTypeRef) then
-      begin
-      M:=AElement.GetModule;
-      if Assigned(M) then
-        Result['unit']:=M.Name;
-      end;
-    PE.AppendChild(Result);
-    end;
-end;    
-    
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
   Main program. Document all units.    
   Main program. Document all units.    
   ---------------------------------------------------------------------}
   ---------------------------------------------------------------------}
@@ -622,7 +525,7 @@ begin
   XML:=TXMLDocument.Create;
   XML:=TXMLDocument.Create;
   Try
   Try
     //XML.
     //XML.
-    XML.AppendChild(XML.CreateElement(RootNames[AObjectKind]));
+    XML.AppendChild(XML.CreateElement(ObjKindNames[AObjectKind]));
     For I:=0 to MergeFiles.Count-1 do
     For I:=0 to MergeFiles.Count-1 do
       begin
       begin
       XMl2:=TXMLDocument.Create;
       XMl2:=TXMLDocument.Create;
@@ -640,7 +543,7 @@ begin
       Engine := TClassTreeEngine.Create(XML,AObjectKind);
       Engine := TClassTreeEngine.Create(XML,AObjectKind);
       Try
       Try
         ParseSource(Engine,InputFiles[I],OSTarget,CPUTarget);
         ParseSource(Engine,InputFiles[I],OSTarget,CPUTarget);
-        ACount:=ACount+Engine.BuildTree;
+        ACount:=ACount+Engine.Ftree.BuildTree(Engine.FObjects);
       Finally
       Finally
         Engine.Free;
         Engine.Free;
       end;
       end;

+ 20 - 26
utils/fpdoc/fpdoc.css

@@ -1,5 +1,5 @@
 /*
 /*
-  $Id: fpdoc.css,v 1.1 2003/03/17 23:03:20 michael Exp $
+  $Id: fpdoc.cst,v 1.1 2005/01/02 16:22:16 michael Exp $
 
 
   Default style sheet for FPDoc reference documentation
   Default style sheet for FPDoc reference documentation
   by Sebastian Guenther, [email protected]
   by Sebastian Guenther, [email protected]
@@ -62,6 +62,10 @@ span.code {
 span.sym {
 span.sym {
   color: darkred
   color: darkred
 }
 }
+/* No wordwrap in code fragments */
+span.code {
+   white-space: nowrap
+}
 
 
 /* keywords in source fragments */
 /* keywords in source fragments */
 span.kw {
 span.kw {
@@ -127,40 +131,30 @@ table.bar {
   background-color: #a0c0ff;
   background-color: #a0c0ff;
 }
 }
 
 
+td p {
+ margin: 0;
+}
+
 span.bartitle {
 span.bartitle {
   font-weight: bold;
   font-weight: bold;
   font-style: italic;
   font-style: italic;
   color: darkblue
   color: darkblue
 }
 }
 
 
-span.footer {
-  font-style: italic;
-  color: darkblue
+span.toggletreeclose {
+    background: url(minus.png) center left no-repeat;
+    padding-left: 20px; 
 }
 }
 
 
-/* definition list */
-dl {
- border: 3px double #ccc;
- padding: 0.5em;
+span.toggletreeopen {
+    background: url(plus.png) center left no-repeat;
+    padding-left: 20px; 
 }
 }
 
 
-/* definition list: term */
-dt {
- float: left;
- clear: left;
- width: auto; /* normally browsers default width of largest item */
- padding-right: 20px;
- font-weight: bold;
- color: darkgreen;
-}
+ul.classtreelist li { padding-left: 0px; }
 
 
-/* definition list: description */
-dd {
- margin: 0 0 0 110px;
- padding: 0 0 0.5em 0;
-}
+ul.classtreelist { list-style-type:none; }
 
 
-/* for browsers in standards compliance mode */
-td p {
-  margin: 0;
-}
+li.classtree ul { display: block; }
+
+li.classtreeclosed ul { display: none; }

+ 7 - 2
utils/fpdoc/fpdoc.lpi

@@ -31,7 +31,7 @@
     <RunParams>
     <RunParams>
       <local>
       <local>
         <FormatVersion Value="1"/>
         <FormatVersion Value="1"/>
-        <CommandLineParams Value="--project=fpdoc.xml"/>
+        <CommandLineParams Value="--package=me --output=me --input=ct.pp --format=html"/>
         <LaunchingApplication PathPlusParams="/usr/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
         <LaunchingApplication PathPlusParams="/usr/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
       </local>
       </local>
     </RunParams>
     </RunParams>
@@ -40,7 +40,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item1>
       </Item1>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="15">
+    <Units Count="16">
       <Unit0>
       <Unit0>
         <Filename Value="fpdoc.pp"/>
         <Filename Value="fpdoc.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -116,6 +116,11 @@
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="mkfpdoc"/>
         <UnitName Value="mkfpdoc"/>
       </Unit14>
       </Unit14>
+      <Unit15>
+        <Filename Value="fpdocclasstree.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="fpdocclasstree"/>
+      </Unit15>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

+ 41 - 19
utils/fpdoc/fpdoc.pp

@@ -3,6 +3,8 @@
     FPDoc  -  Free Pascal Documentation Tool
     FPDoc  -  Free Pascal Documentation Tool
     Copyright (C) 2000 - 2003 by
     Copyright (C) 2000 - 2003 by
       Areca Systems GmbH / Sebastian Guenther, [email protected]
       Areca Systems GmbH / Sebastian Guenther, [email protected]
+    2005-2012 by
+      various FPC contributors
 
 
     See the file COPYING, included in this distribution,
     See the file COPYING, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -20,7 +22,8 @@ uses
   cwstring,
   cwstring,
 {$endif}
 {$endif}
   SysUtils, Classes, Gettext, custapp,
   SysUtils, Classes, Gettext, custapp,
-  dGlobals,  // GLobal definitions, constants.
+  dGlobals,  // Global definitions, constants.
+  fpdocclasstree, // Class tree builder
   dwriter,   // TFPDocWriter definition.
   dwriter,   // TFPDocWriter definition.
   dwlinear,  // Linear (abstract) writer
   dwlinear,  // Linear (abstract) writer
   dw_LaTeX,  // TLaTex writer
   dw_LaTeX,  // TLaTex writer
@@ -30,14 +33,15 @@ 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, mkfpdoc;    // TXT writer
+  dw_txt,    // TXT writer
+  fpdocproj, mkfpdoc;
 
 
 
 
 Type
 Type
 
 
-  { TFPDocAplication }
+  { TFPDocApplication }
 
 
-  TFPDocAplication = Class(TCustomApplication)
+  TFPDocApplication = Class(TCustomApplication)
   private
   private
     FCreator : TFPDocCreator;
     FCreator : TFPDocCreator;
     FPackage : TFPDocPackage;
     FPackage : TFPDocPackage;
@@ -47,7 +51,7 @@ Type
   Protected
   Protected
     procedure OutputLog(Sender: TObject; const Msg: String);
     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 DoRun; override;
     Procedure DoRun; override;
   Public
   Public
@@ -57,7 +61,7 @@ Type
   end;
   end;
 
 
 
 
-Procedure TFPDocAplication.Usage(AnExitCode : Byte);
+Procedure TFPDocApplication.Usage(AnExitCode : Byte);
 
 
 Var
 Var
   I,P : Integer;
   I,P : Integer;
@@ -71,6 +75,7 @@ begin
   Writeln(SUsageOption010);
   Writeln(SUsageOption010);
   Writeln(SUsageOption020);
   Writeln(SUsageOption020);
   Writeln(SUsageOption030);
   Writeln(SUsageOption030);
+  Writeln(SUsageOption035);
   Writeln(SUsageOption040);
   Writeln(SUsageOption040);
   Writeln(SUsageOption050);
   Writeln(SUsageOption050);
   Writeln(SUsageOption060);
   Writeln(SUsageOption060);
@@ -83,7 +88,6 @@ 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);
@@ -95,6 +99,12 @@ begin
   Writeln(SUsageOption240);
   Writeln(SUsageOption240);
   Writeln(SUsageOption250);
   Writeln(SUsageOption250);
   Writeln(SUsageOption260);
   Writeln(SUsageOption260);
+  Writeln(SUsageOption270);
+  Writeln(SUsageOption280);
+  Writeln(SUsageOption290);
+  Writeln(SUsageOption300);
+  Writeln(SUsageOption310);
+  Writeln(SUsageOption320);
   L:=TStringList.Create;
   L:=TStringList.Create;
   Try
   Try
     Backend:=FCreator.OPtions.Backend;
     Backend:=FCreator.OPtions.Backend;
@@ -130,29 +140,40 @@ begin
   Halt(AnExitCode);
   Halt(AnExitCode);
 end;
 end;
 
 
-destructor TFPDocAplication.Destroy;
+destructor TFPDocApplication.Destroy;
 
 
 begin
 begin
   FreeAndNil(FCreator);
   FreeAndNil(FCreator);
   Inherited;
   Inherited;
 end;
 end;
 
 
-function TFPDocAplication.SelectedPackage: TFPDocPackage;
+function TFPDocApplication.SelectedPackage: TFPDocPackage;
+var
+  i:integer;
 begin
 begin
   Result:=FPackage;
   Result:=FPackage;
   if (FPackage=Nil) or (FPackage.Name='') then
   if (FPackage=Nil) or (FPackage.Name='') then
     begin
     begin
     Writeln(SNeedPackageName);
     Writeln(SNeedPackageName);
+    if FCreator.Packages.Count>0 then
+      begin
+      if (FCreator.Packages[0].Name<>'') then
+        Writeln(SAvailablePackages);
+      for i:=0 to FCreator.Packages.Count-1 do
+        begin
+        Writeln(FCreator.Packages[i].Name);
+        end;
+      end;
     Usage(1);
     Usage(1);
     end;
     end;
 end;
 end;
 
 
-procedure TFPDocAplication.OutputLog(Sender: TObject; const Msg: String);
+procedure TFPDocApplication.OutputLog(Sender: TObject; const Msg: String);
 begin
 begin
   Writeln(StdErr,Msg);
   Writeln(StdErr,Msg);
 end;
 end;
 
 
-procedure TFPDocAplication.ParseCommandLine;
+procedure TFPDocApplication.ParseCommandLine;
 
 
   Function ProjectOpt(Const s : string) : boolean;
   Function ProjectOpt(Const s : string) : boolean;
 
 
@@ -183,8 +204,8 @@ begin
       Fpackage:=FCreator.Packages.FindPackage(FCreator.Options.DefaultPackageName);
       Fpackage:=FCreator.Packages.FindPackage(FCreator.Options.DefaultPackageName);
     end;
     end;
   If FCreator.Project.Packages.Count=0 then
   If FCreator.Project.Packages.Count=0 then
-    begin
-    FPackage:=FCreator.Packages.Add as  TFPDocPackage;
+    begin // Add default package if none defined
+    FPackage:=FCreator.Packages.Add as TFPDocPackage;
     end;
     end;
   // Check package
   // Check package
   for i := 1 to ParamCount do
   for i := 1 to ParamCount do
@@ -202,7 +223,7 @@ begin
   SelectedPackage; // Will print error if none available.
   SelectedPackage; // Will print error if none available.
 end;
 end;
 
 
-procedure TFPDocAplication.Parseoption(Const S : String);
+procedure TFPDocApplication.ParseOption(Const S : String);
 
 
   procedure AddDirToFileList(List: TStrings; const ADirName, AMask: String);
   procedure AddDirToFileList(List: TStrings; const ADirName, AMask: String);
 
 
@@ -266,7 +287,7 @@ begin
   else if s = '--stop-on-parser-error' then
   else if s = '--stop-on-parser-error' then
     FCreator.Options.StopOnParseError := True
     FCreator.Options.StopOnParseError := True
   else if s = '--dont-trim' then
   else if s = '--dont-trim' then
-    FCreator.Options.donttrim := True
+    FCreator.Options.DontTrim := True
   else
   else
     begin
     begin
     i := Pos('=', s);
     i := Pos('=', s);
@@ -343,7 +364,7 @@ begin
     end;
     end;
 end;
 end;
 
 
-Procedure TFPDocAplication.DoRun;
+Procedure TFPDocApplication.DoRun;
 
 
 begin
 begin
 {$IFDEF Unix}
 {$IFDEF Unix}
@@ -353,7 +374,8 @@ begin
 {$ENDIF}
 {$ENDIF}
   WriteLn(STitle);
   WriteLn(STitle);
   WriteLn(Format(SVersion, [DefFPCVersion, DefFPCDate]));
   WriteLn(Format(SVersion, [DefFPCVersion, DefFPCDate]));
-  WriteLn(SCopyright);
+  WriteLn(SCopyright1);
+  WriteLn(SCopyright2);
   WriteLn;
   WriteLn;
   ParseCommandLine;
   ParseCommandLine;
   if (FWriteProjectFile<>'') then
   if (FWriteProjectFile<>'') then
@@ -364,7 +386,7 @@ begin
   Terminate;
   Terminate;
 end;
 end;
 
 
-constructor TFPDocAplication.Create(AOwner: TComponent);
+constructor TFPDocApplication.Create(AOwner: TComponent);
 begin
 begin
   inherited Create(AOwner);
   inherited Create(AOwner);
   StopOnException:=true;
   StopOnException:=true;
@@ -373,7 +395,7 @@ begin
 end;
 end;
 
 
 begin
 begin
-  With TFPDocAplication.Create(Nil) do
+  With TFPDocApplication.Create(Nil) do
     try
     try
       Run;
       Run;
     finally
     finally

+ 182 - 0
utils/fpdoc/fpdocclasstree.pp

@@ -0,0 +1,182 @@
+unit fpdocclasstree;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, DOM, pastree;
+
+Type
+  TClassTreeBuilder = Class
+  Private
+    FClassTree : TXMLDocument;
+    FTreeStart : TDomElement;
+    FObjectKind : TPasObjKind;
+    FPackage: TPasPackage;
+    FParentObject : TPasClassType;
+  Protected
+    function LookForElement(PE: TDomElement; AElement: TPasElement; NoPath : Boolean): TDomNode;
+    function NodeMatch(N: TDomNode; AElement: TPasElement; NoPath : Boolean): Boolean;
+    Function AddToClassTree(AElement : TPasElement; ACount : Integer) : TDomElement;
+  Public
+    Constructor Create(APackage : TPasPackage; AObjectKind : TPasObjKind = okClass);
+    Destructor Destroy; override;
+    Function BuildTree(AObjects : TStringList) : Integer;
+    Property ClassTree : TXMLDocument Read FClassTree;
+  end;
+
+implementation
+
+constructor TClassTreeBuilder.Create(APackage : TPasPackage;
+  AObjectKind: TPasObjKind);
+Var
+  N : TDomNode;
+begin
+  FCLassTree:=TXMLDocument.Create;
+  FPackage:=APAckage;
+  FObjectKind:=AObjectKind;
+  Case FObjectkind of
+    okObject    : FParentObject:=TPasClassType.Create('System.TObject',FPackage);
+    okClass     : FParentObject:=TPasClassType.Create('System.TObject',FPackage);
+    okInterface : FParentObject:=TPasClassType.Create('System.IInterface',FPackage);
+  end;
+  FParentObject.ObjKind:=FObjectKind;
+  FTreeStart:=FClassTree.CreateElement('TObject');
+  FTreeStart['unit']:='System';
+  ClassTree.AppendChild(FTreeStart);
+end;
+
+destructor TClassTreeBuilder.Destroy;
+begin
+  FreeAndNil(FClassTree);
+  Inherited;
+end;
+Function TClassTreeBuilder.BuildTree(AObjects : TStringList) : Integer;
+
+Var
+  I : Integer;
+  PC : TPasClassType;
+
+begin
+  Result:=0;
+  AObjects.Sorted:=True;
+  For I:=0 to AObjects.Count-1 do
+    begin
+    PC:=TPasClassType(AObjects.Objects[i]);
+    If (PC.ObjKind=FObjectKind) and Not PC.IsForward then
+      begin
+      AddToClassTree(PC as TPasElement,Result)
+      end;
+    end;
+end;
+
+Function TClassTreeBuilder.NodeMatch(N : TDomNode; AElement : TPasElement; NoPath : Boolean) : Boolean;
+
+Var
+  PN,S : String;
+
+begin
+  Result:=(N.NodeType=ELEMENT_NODE);
+  if Result then
+    begin
+    S:=N.NodeName;
+    if NoPath then
+      Begin
+      Result:= (CompareText(S,AElement.Name)=0);
+      end
+    else
+      begin
+      IF Assigned(Aelement.GetModule) then
+        PN:=Aelement.GetModule.PackageName
+      else
+        PN:=FPackage.Name;
+      S:=PN+'.'+TDomElement(N)['unit']+'.'+S;
+      Result:= (CompareText(S,AElement.PathName)=0);
+      end;
+   end;
+end;
+
+Function TClassTreeBuilder.LookForElement(PE : TDomElement; AElement : TPasElement; NoPath : boolean) : TDomNode;
+
+Var
+  N : TDomNode;
+
+begin
+  Result:=PE;
+  While (Result<>Nil) and Not NodeMatch(Result,AElement,NoPath) do
+    Result:=Result.NextSibling;
+  If (Result=Nil) then
+    if  Assigned(PE) then
+      begin
+      N:=PE.FirstChild;
+      While (Result=Nil) and (N<>Nil) do
+        begin
+        if (N.NodeType=ELEMENT_NODE) then
+          begin
+          Result:=LookForElement(N as TDomElement,AElement,NoPath);
+          end;
+        N:=N.NextSibling;
+        end;
+      end;
+end;
+
+Function TClassTreeBuilder.AddToClassTree(AElement : TPasElement; ACount : Integer) : TDomElement;
+// there are several codepaths that use uninitialized variables. (N,PE)
+// I initialized them to nil to at least make failures deterministic.
+Var
+  PC : TPasClassType;
+  PE : TDomElement;
+  M : TPasModule;
+  N : TDomNode;
+  PF : String;
+
+begin
+  PF:=StringOfChar(' ',ACount);
+  Result:=Nil; N:=Nil;PE:=NIL;
+  If (AElement=Nil) then
+    begin
+    Result:=FTreeStart;
+    Exit;
+    end
+  else If (AElement is TPasUnresolvedTypeRef) then
+    begin
+    N:=LookForElement(FTreeStart,AElement,True);
+    If (N=Nil) then
+      begin
+      PE:=FTreeStart;
+      end
+    end
+  else If (AElement is TPasClassType) then
+    begin
+    if (AElement=FParentObject) then
+      Result:=FTreeStart
+    else
+      begin
+      PC:=AElement as TPasClassType;
+      PE:=AddToClassTree(PC.AncestorType,ACount+1);
+      if PE=Nil then
+        PE:=FTreeStart;
+      N:=LookForElement(PE,PC,False);
+      end
+    end;
+  If (N<>Nil) then
+    Result:=N as TDomElement
+  else
+    begin // N=NIL, PE might be nil.
+    Inc(ACount);
+    Result:=FClassTree.CreateElement(AElement.Name);
+    If Not (AElement is TPasUnresolvedTypeRef) then
+      begin
+      M:=AElement.GetModule;
+      if Assigned(M) then
+        Result['unit']:=M.Name;
+      end;
+      if assigned(PE) then  // if not assigned, probably needs to be
+			    // assigned to something else.
+        PE.AppendChild(Result);
+    end;
+end;
+
+end.
+

+ 2 - 2
utils/fpdoc/fpdocproj.pas

@@ -15,8 +15,8 @@ Type
   private
   private
     FContent: String;
     FContent: String;
     FDescriptions: TStrings;
     FDescriptions: TStrings;
-    FIMports: TStrings;
-    FinPuts: TStrings;
+    FImports: TStrings;
+    FInputs: TStrings;
     FName: String;
     FName: String;
     FOutput: String;
     FOutput: String;
   Public
   Public

+ 89 - 0
utils/fpdoc/fpdocstripper.lpi

@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <Title Value="fpdocstripper"/>
+      <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=""/>
+      </local>
+    </RunParams>
+    <Units Count="1">
+      <Unit0>
+        <Filename Value="fpdocstripper.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="fpdocstripper"/>
+      </Unit0>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <CodeGeneration>
+      <SmartLinkUnit Value="True"/>
+      <Checks>
+        <IOChecks Value="True"/>
+        <RangeChecks Value="True"/>
+        <OverflowChecks Value="True"/>
+        <StackChecks Value="True"/>
+      </Checks>
+      <Optimizations>
+        <OptimizationLevel Value="2"/>
+      </Optimizations>
+    </CodeGeneration>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+        <UseLineInfoUnit Value="False"/>
+      </Debugging>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CustomOptions Value="-dDEBUG"/>
+      <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>

+ 191 - 0
utils/fpdoc/fpdocstripper.pp

@@ -0,0 +1,191 @@
+program fpdocstripper;
+
+{
+  fpdocstripper  -  Free Pascal fpdoc file stripper
+  Copyright (C) 2012-2013 by Reinier Olislagers
+
+  * Takes an FPDoc XML file and removes all elements that have no documentation in them
+  * Useful before submitting a documentation patch as it keeps file size down and
+    makes it clearer what exactly is documented.
+
+  See the file COPYING, included in this distribution,
+  for details about the copyright and license.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  To do: currently parses the raw XML; it may be possible to reuse the fpdoc format
+  reading code in other units.
+}
+{$mode objfpc}{$H+}
+
+uses
+  {$IFDEF UNIX}
+  cwstring,
+  {$ENDIF}
+  Classes, SysUtils, CustApp,
+  DOM, xmlread, xmlwrite;
+type
+
+  { TFPDocStripper }
+
+  TFPDocStripper = class(TCustomApplication)
+  protected
+    FInputFile: string;
+    FOutputFile: string;
+    FStripComments : Boolean;
+    procedure DoRun; override;
+  public
+    constructor Create(TheOwner: TComponent); override;
+    destructor Destroy; override;
+    procedure StripEmptyXML(Node:TDOMNode);
+    procedure WriteHelp; virtual;
+    Property StripComments : Boolean Read FStripComments Write FStripComments;
+  end;
+
+
+procedure TFPDocStripper.StripEmptyXML(Node:TDOMNode);
+
+// Recursive function to process a node and all its child nodes
+var
+  i: integer;
+  E : TDomElement;
+  CN : TDomNode;
+  B : Boolean;
+  
+begin
+  // Exit procedure if no more nodes to process
+  if Node = nil then Exit;
+
+  for i:=Node.ChildNodes.Count-1 downto 0 do
+    begin
+    StripEmptyXML(Node.ChildNodes[i]);
+    end;
+
+  for i:=Node.ChildNodes.Count-1 downto 0 do
+    begin
+    CN:=Node.ChildNodes[i];
+    // Remove all comments
+    B:=StripComments and (CN.NodeType=COMMENT_NODE);
+    if not B then
+      begin
+      // Remove children without children or attributes
+      B:=(CN.HasChildNodes=false) and
+         (CN.HasAttributes=false) and
+         (CN.TextContent='');
+      // Empty elements that do not link to others   
+      if not B then
+        begin
+        if (CN is TDomElement) then
+          begin
+          E:=CN as TDomElement;
+          B:=(E.NodeName='element') 
+             and (E.HasChildNodes=false)
+             and (E['name']<>'') and (E['link']='');
+          end;
+        end;   
+      end;
+    if B then
+      Node.RemoveChild(CN);
+    end;
+end;
+
+{ TFPDocStripper }
+
+procedure TFPDocStripper.DoRun;
+var
+  ErrorMsg: String;
+  Doc: TXMLDocument;
+begin
+  // check parameters
+  ErrorMsg:=CheckOptions('h','help input: output: keepcomments');
+  if ErrorMsg<>'' then begin
+    writeln(ErrorMsg);
+    writeln();
+    Terminate;
+    Exit;
+  end;
+
+  // parse parameters
+  if HasOption('h','help') then begin
+    WriteHelp;
+    Terminate;
+    Exit;
+  end;
+
+  if HasOption('input') then begin
+    FInputFile:=ExpandFileName(GetOptionValue('input'));
+  end else begin
+    writeln('Error: no input file specified.');
+    writeln();
+    WriteHelp;
+    Terminate;
+    Exit;
+  end;
+
+  FStripComments:=not HasOption('keepcomments');
+  
+  if HasOption('output') then begin
+    FOutputFile:=ExpandFileName(GetOptionValue('output'));
+  end else begin
+    writeln('Error: no output file specified.');
+    writeln();
+    WriteHelp;
+    Terminate;
+    Exit;
+  end;
+
+  if FInputFile=FOutputfile then
+    raise Exception.CreateFmt('Input file %s must not be the same as output file.',[FInputFile]);
+
+  if fileexists(FInputFile)=false then
+    raise Exception.CreateFmt('Input file %s does not exist.',[FInputFile]);
+
+  try
+    ReadXMLFile(Doc,FInputFile);
+    StripEmptyXML(Doc.DocumentElement);
+    WriteXMLFile(Doc,FOutputFile);
+  finally
+    Doc.Free;
+  end;
+  Terminate;
+end;
+
+constructor TFPDocStripper.Create(TheOwner: TComponent);
+begin
+  inherited Create(TheOwner);
+  StopOnException:=True;
+end;
+
+destructor TFPDocStripper.Destroy;
+begin
+  inherited Destroy;
+end;
+
+procedure TFPDocStripper.WriteHelp;
+begin
+  writeln('Strips undocumented elements and comments');
+  writeln('from an fpdoc XML (description/documentation) file.');
+  writeln('');
+  writeln('Useful before submitting a documentation patch as');
+  writeln('it keeps file size down and makes it clear what exactly');
+  writeln('is documented.');
+  writeln('');
+  writeln('Usage: ',ExeName,' -h');
+  writeln('--keepcomments');
+  writeln('  Do not strip comments');
+  writeln('--input=file');
+  writeln('  Read specified fpdoc XML file.');
+  writeln('--output=file');
+  writeln('  Write cleaned output to this file.');
+end;
+
+var
+  Application: TFPDocStripper;
+begin
+  Application:=TFPDocStripper.Create(nil);
+  Application.Run;
+  Application.Free;
+end.
+

BIN
utils/fpdoc/images/minus.png


BIN
utils/fpdoc/images/plus.png


+ 18 - 3
utils/fpdoc/makeskel.pp

@@ -3,8 +3,13 @@
     FPDoc  -  Free Pascal Documentation Tool
     FPDoc  -  Free Pascal Documentation Tool
     Copyright (C) 2000 - 2003 by
     Copyright (C) 2000 - 2003 by
       Areca Systems GmbH / Sebastian Guenther, [email protected]
       Areca Systems GmbH / Sebastian Guenther, [email protected]
+    2005-2012 by
+      various FPC contributors
 
 
-    * Skeleton XML description file generator
+    * Skeleton XML description file generator.
+    This generator scans Pascal source code for identifiers and emits XML files
+    suitable for further processing with the fpdoc documentation system:
+    users can edit the XML file and add (help) description.
 
 
     See the file COPYING, included in this distribution,
     See the file COPYING, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -28,7 +33,6 @@ uses
 resourcestring
 resourcestring
   STitle = 'MakeSkel - FPDoc skeleton XML description file generator';
   STitle = 'MakeSkel - FPDoc skeleton XML description file generator';
   SVersion = 'Version %s [%s]';
   SVersion = 'Version %s [%s]';
-  SCopyright = '(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, [email protected]';
   SCmdLineHelp = 'See documentation for usage.';
   SCmdLineHelp = 'See documentation for usage.';
   SCmdLineInvalidOption = 'Ignoring unknown option "%s"';
   SCmdLineInvalidOption = 'Ignoring unknown option "%s"';
   SNoPackageNameProvided = 'Please specify a package name with --package=<name>';
   SNoPackageNameProvided = 'Please specify a package name with --package=<name>';
@@ -188,6 +192,14 @@ Var
 begin
 begin
   Result := AClass.Create(AName, AParent);
   Result := AClass.Create(AName, AParent);
   Result.Visibility:=AVisibility;
   Result.Visibility:=AVisibility;
+  // Let function/procedure arguments and function results
+  // inherit visibility from their parents if visDefault visibility is
+  // specified.
+  // This allows easier text searches on visibility in the resulting XML
+  if (AVisibility=visDefault) and
+    ((Result is TPasArgument) or (Result is TPasResultElement)) then
+    Result.Visibility:=AParent.Visibility;
+
   if AClass.InheritsFrom(TPasModule) then
   if AClass.InheritsFrom(TPasModule) then
     CurModule := TPasModule(Result);
     CurModule := TPasModule(Result);
   // Track this element
   // Track this element
@@ -344,6 +356,8 @@ Var
   N : TDocNode;
   N : TDocNode;
      
      
 begin
 begin
+  if not(FileExists(AFileName)) then
+    raise Exception.CreateFmt('Cannot find source file %s to document.',[AFileName]);
   FNodeList:=TStringList.Create;
   FNodeList:=TStringList.Create;
   Try
   Try
     FEmittedList:=TStringList.Create;
     FEmittedList:=TStringList.Create;
@@ -614,7 +628,8 @@ var
 begin
 begin
   WriteLn(STitle);
   WriteLn(STitle);
   WriteLn(Format(SVersion, [FPCVersion, FPCDate]));
   WriteLn(Format(SVersion, [FPCVersion, FPCDate]));
-  WriteLn(SCopyright);
+  WriteLn(SCopyright1);
+  WriteLn(SCopyright2);
   InitOptions;
   InitOptions;
   Try
   Try
     E:=ParseCommandLine;
     E:=ParseCommandLine;

+ 20 - 0
utils/fpdoc/minusimage.inc

@@ -0,0 +1,20 @@
+
+Const
+  MinusImageData : Array[0..273] of byte = (
+     137, 80, 78, 71, 13, 10, 26, 10,  0,  0,  0, 13, 73, 72, 68, 82,  0,
+       0,  0, 19,  0,  0,  0, 19,  8,  4,  0,  0,  0,216, 89,254, 71,  0,
+       0,  0,  2, 98, 75, 71, 68,  0,238,237, 63,236, 77,  0,  0,  0,  9,
+     112, 72, 89,115,  0,  0,  0, 72,  0,  0,  0, 72,  0, 70,201,107, 62,
+       0,  0,  0,  9,118,112, 65,103,  0,  0,  0, 19,  0,  0,  0, 19,  0,
+     241,127,140,174,  0,  0,  0, 63, 73, 68, 65, 84, 40,207, 99,124,199,
+      64, 12, 96, 34, 74,213,192, 40, 99, 65, 48, 39,253, 71,151,204, 99,
+     196,162,140,129,161, 30, 69, 81, 35, 61,220,198,192,192,192,  0,119,
+      12,195,127,124,202,254,227, 48,141,134,110,107,196,169,140,113,232,
+     167, 16,  0,229, 60,  7,139,203,229, 71,  3,  0,  0,  0, 37,116, 69,
+      88,116,100, 97,116,101, 58, 99,114,101, 97,116,101,  0, 50, 48, 49,
+      50, 45, 49, 50, 45, 50, 48, 84, 49, 53, 58, 48, 52, 58, 52, 48, 43,
+      48, 49, 58, 48, 48, 36,251,160,191,  0,  0,  0, 37,116, 69, 88,116,
+     100, 97,116,101, 58,109,111,100,105,102,121,  0, 50, 48, 49, 50, 45,
+      49, 50, 45, 50, 48, 84, 49, 53, 58, 48, 52, 58, 52, 48, 43, 48, 49,
+      58, 48, 48, 85,166, 24,  3,  0,  0,  0,  0, 73, 69, 78, 68,174, 66,
+      96,130);

+ 7 - 4
utils/fpdoc/mkfpdoc.pp

@@ -38,8 +38,8 @@ Type
   Public
   Public
     Constructor Create(AOwner : TComponent); override;
     Constructor Create(AOwner : TComponent); override;
     Destructor Destroy; override;
     Destructor Destroy; override;
-    Procedure CreateDocumentation(APackage : TFPDocPackage; ParseOnly : Boolean); virtual;
-    Procedure CreateProjectFile(Const AFileName : string);
+    Procedure CreateDocumentation(APackage : TFPDocPackage; ParseOnly : Boolean); virtual; //Writes out documentation in selected format
+    Procedure CreateProjectFile(Const AFileName : string); //Writes out project file with the chosen options
     Procedure LoadProjectFile(Const AFileName: string);
     Procedure LoadProjectFile(Const AFileName: string);
     Property Project : TFPDocProject Read FProject;
     Property Project : TFPDocProject Read FProject;
     Property ScannerLogEvents : TPScannerLogEvents Read FScannerLogEvents Write FScannerLogEvents;
     Property ScannerLogEvents : TPScannerLogEvents Read FScannerLogEvents Write FScannerLogEvents;
@@ -186,16 +186,19 @@ var
   i,j: Integer;
   i,j: Integer;
   Engine : TFPDocEngine;
   Engine : TFPDocEngine;
   Cmd,Arg : String;
   Cmd,Arg : String;
+  WriterClass: TFPDocWriterClass;
 
 
 begin
 begin
+  Cmd:='';
   FCurPackage:=APackage;
   FCurPackage:=APackage;
   Engine:=TFPDocEngine.Create;
   Engine:=TFPDocEngine.Create;
   try
   try
+    WriterClass:=GetWriterClass(Options.Backend);
     For J:=0 to Apackage.Imports.Count-1 do
     For J:=0 to Apackage.Imports.Count-1 do
       begin
       begin
       Arg:=Apackage.Imports[j];
       Arg:=Apackage.Imports[j];
-      i := Pos(',', Arg);
-      Engine.ReadContentFile(Copy(Arg,1,i-1),Copy(Arg,i+1,Length(Arg)));
+      WriterClass.SplitImport(Arg,Cmd);
+      Engine.ReadContentFile(Arg, Cmd);
       end;
       end;
     for i := 0 to APackage.Descriptions.Count - 1 do
     for i := 0 to APackage.Descriptions.Count - 1 do
       Engine.AddDocFile(APackage.Descriptions[i],Options.donttrim);
       Engine.AddDocFile(APackage.Descriptions[i],Options.donttrim);

+ 21 - 0
utils/fpdoc/plusimage.inc

@@ -0,0 +1,21 @@
+
+Const
+  PlusImageData : Array[0..288] of byte = (
+     137, 80, 78, 71, 13, 10, 26, 10,  0,  0,  0, 13, 73, 72, 68, 82,  0,
+       0,  0, 19,  0,  0,  0, 19,  8,  4,  0,  0,  0,216, 89,254, 71,  0,
+       0,  0,  2, 98, 75, 71, 68,  0,238,237, 63,236, 77,  0,  0,  0,  9,
+     112, 72, 89,115,  0,  0,  0, 72,  0,  0,  0, 72,  0, 70,201,107, 62,
+       0,  0,  0,  9,118,112, 65,103,  0,  0,  0, 19,  0,  0,  0, 19,  0,
+     241,127,140,174,  0,  0,  0, 78, 73, 68, 65, 84, 40,207, 99,124,199,
+      64, 12, 96, 34, 74,213,192, 40, 99, 65, 48, 39,253, 71,151,204, 99,
+     196,162,140,129,161, 30, 69, 81, 35,126, 75, 25, 49,133,200,112, 27,
+     194, 36, 70,  6,  6,134,255,248,148,253,103, 96, 96, 96,100,192,240,
+      11,  5,225,246, 31,139, 50, 20, 75, 27, 25,112,  1,198,161,159, 66,
+       0, 47,159,  9,140, 36, 84,124, 38,  0,  0,  0, 37,116, 69, 88,116,
+     100, 97,116,101, 58, 99,114,101, 97,116,101,  0, 50, 48, 49, 50, 45,
+      49, 50, 45, 50, 48, 84, 49, 53, 58, 48, 52, 58, 50, 50, 43, 48, 49,
+      58, 48, 48,117, 11,184, 17,  0,  0,  0, 37,116, 69, 88,116,100, 97,
+     116,101, 58,109,111,100,105,102,121,  0, 50, 48, 49, 50, 45, 49, 50,
+      45, 50, 48, 84, 49, 53, 58, 48, 52, 58, 50, 50, 43, 48, 49, 58, 48,
+      48,  4, 86,  0,173,  0,  0,  0,  0, 73, 69, 78, 68,174, 66, 96,130
+     );

+ 3 - 1
utils/fpdoc/testunit.xml

@@ -28,6 +28,8 @@ Appears in 2.0
 </seealso>
 </seealso>
 </element>
 </element>
 
 
+<element name="AStringConst" link="ABooleanConst"/>
+
 <!-- constant Visibility: default -->
 <!-- constant Visibility: default -->
 <element name="AStringConst">
 <element name="AStringConst">
 <short></short>
 <short></short>
@@ -488,7 +490,7 @@ Appears in 2.0
 
 
 <!-- function result Visibility: default -->
 <!-- function result Visibility: default -->
 <element name="OverloadedFunc.Result">
 <element name="OverloadedFunc.Result">
-<short></short>
+<short>Soso</short>
 </element>
 </element>
 
 
 <!-- argument Visibility: default -->
 <!-- argument Visibility: default -->

+ 2974 - 0
utils/pas2fpm/Makefile

@@ -0,0 +1,2974 @@
+#
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2012/08/21]
+#
+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 powerpc-aix 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 powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux jvm-java jvm-android
+BSDs = freebsd netbsd openbsd darwin
+UNIXs = linux $(BSDs) solaris qnx haiku aix
+LIMIT83fs = go32v2 os2 emx watcom
+OSNeedsComspecToRunBatch = go32v2 watcom
+FORCE:
+.PHONY: FORCE
+override PATH:=$(patsubst %/,%,$(subst \,/,$(PATH)))
+ifneq ($(findstring darwin,$(OSTYPE)),)
+inUnix=1 #darwin
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+ifeq ($(findstring ;,$(PATH)),)
+inUnix=1
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+SEARCHPATH:=$(subst ;, ,$(PATH))
+endif
+endif
+SEARCHPATH+=$(patsubst %/,%,$(subst \,/,$(dir $(MAKE))))
+PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
+ifeq ($(PWD),)
+PWD:=$(strip $(wildcard $(addsuffix /pwd,$(SEARCHPATH))))
+ifeq ($(PWD),)
+$(error You need the GNU utils package to use this Makefile)
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=
+endif
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=.exe
+endif
+ifndef inUnix
+ifeq ($(OS),Windows_NT)
+inWinNT=1
+else
+ifdef OS2_SHELL
+inOS2=1
+endif
+endif
+else
+ifneq ($(findstring cygdrive,$(PATH)),)
+inCygWin=1
+endif
+endif
+ifdef inUnix
+SRCBATCHEXT=.sh
+else
+ifdef inOS2
+SRCBATCHEXT=.cmd
+else
+SRCBATCHEXT=.bat
+endif
+endif
+ifdef COMSPEC
+ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
+ifndef RUNBATCH
+RUNBATCH=$(COMSPEC) /C
+endif
+endif
+endif
+ifdef inUnix
+PATHSEP=/
+else
+PATHSEP:=$(subst /,\,/)
+ifdef inCygWin
+PATHSEP=/
+endif
+endif
+ifdef PWD
+BASEDIR:=$(subst \,/,$(shell $(PWD)))
+ifdef inCygWin
+ifneq ($(findstring /cygdrive/,$(BASEDIR)),)
+BASENODIR:=$(patsubst /cygdrive%,%,$(BASEDIR))
+BASEDRIVE:=$(firstword $(subst /, ,$(BASENODIR)))
+BASEDIR:=$(subst /cygdrive/$(BASEDRIVE)/,$(BASEDRIVE):/,$(BASEDIR))
+endif
+endif
+else
+BASEDIR=.
+endif
+ifdef inOS2
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO=echo
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+endif
+override DEFAULT_FPCDIR=../..
+ifndef FPC
+ifdef PP
+FPC=$(PP)
+endif
+endif
+ifndef FPC
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+ifneq ($(CPU_TARGET),)
+FPC:=$(shell $(FPCPROG) -P$(CPU_TARGET) -PB)
+else
+FPC:=$(shell $(FPCPROG) -PB)
+endif
+ifneq ($(findstring Error,$(FPC)),)
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+else
+ifeq ($(strip $(wildcard $(FPC))),)
+FPC:=$(firstword $(FPCPROG))
+endif
+endif
+else
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+endif
+override FPC:=$(subst $(SRCEXEEXT),,$(FPC))
+override FPC:=$(subst \,/,$(FPC))$(SRCEXEEXT)
+FOUNDFPC:=$(strip $(wildcard $(FPC)))
+ifeq ($(FOUNDFPC),)
+FOUNDFPC=$(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))
+ifeq ($(FOUNDFPC),)
+$(error Compiler $(FPC) not found)
+endif
+endif
+ifndef FPC_COMPILERINFO
+FPC_COMPILERINFO:=$(shell $(FPC) -iVSPTPSOTO)
+endif
+ifndef FPC_VERSION
+FPC_VERSION:=$(word 1,$(FPC_COMPILERINFO))
+endif
+export FPC FPC_VERSION FPC_COMPILERINFO
+unexport CHECKDEPEND ALLDEPENDENCIES
+ifndef CPU_TARGET
+ifdef CPU_TARGET_DEFAULT
+CPU_TARGET=$(CPU_TARGET_DEFAULT)
+endif
+endif
+ifndef OS_TARGET
+ifdef OS_TARGET_DEFAULT
+OS_TARGET=$(OS_TARGET_DEFAULT)
+endif
+endif
+ifndef CPU_SOURCE
+CPU_SOURCE:=$(word 2,$(FPC_COMPILERINFO))
+endif
+ifndef CPU_TARGET
+CPU_TARGET:=$(word 3,$(FPC_COMPILERINFO))
+endif
+ifndef OS_SOURCE
+OS_SOURCE:=$(word 4,$(FPC_COMPILERINFO))
+endif
+ifndef OS_TARGET
+OS_TARGET:=$(word 5,$(FPC_COMPILERINFO))
+endif
+FULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+FULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifeq ($(CPU_TARGET),armeb)
+ARCH=arm
+override FPCOPT+=-Cb
+else
+ifeq ($(CPU_TARGET),armel)
+ARCH=arm
+override FPCOPT+=-CaEABI
+else
+ARCH=$(CPU_TARGET)
+endif
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+ifeq ($(SUBARCH),)
+$(error When compiling for arm-embedded, a sub-architecture (e.g. SUBARCH=armv4t or SUBARCH=armv7m) must be defined)
+endif
+override FPCOPT+=-Cp$(SUBARCH)
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+SOURCESUFFIX=$(OS_SOURCE)
+else
+ifneq ($(findstring $(OS_TARGET),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+else
+TARGETSUFFIX=$(FULL_TARGET)
+endif
+SOURCESUFFIX=$(FULL_SOURCE)
+endif
+ifneq ($(FULL_TARGET),$(FULL_SOURCE))
+CROSSCOMPILE=1
+endif
+ifeq ($(findstring makefile,$(MAKECMDGOALS)),)
+ifeq ($(findstring $(FULL_TARGET),$(MAKEFILETARGETS)),)
+$(error The Makefile doesn't support target $(FULL_TARGET), please run fpcmake first)
+endif
+endif
+ifneq ($(findstring $(OS_TARGET),$(BSDs)),)
+BSDhier=1
+endif
+ifeq ($(OS_TARGET),linux)
+linuxHier=1
+endif
+export OS_TARGET OS_SOURCE ARCH CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
+ifdef FPCDIR
+override FPCDIR:=$(subst \,/,$(FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+else
+override FPCDIR=wrong
+endif
+ifdef DEFAULT_FPCDIR
+ifeq ($(FPCDIR),wrong)
+override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+endif
+endif
+ifeq ($(FPCDIR),wrong)
+ifdef inUnix
+override FPCDIR=/usr/local/lib/fpc/$(FPC_VERSION)
+ifeq ($(wildcard $(FPCDIR)/units),)
+override FPCDIR=/usr/lib/fpc/$(FPC_VERSION)
+endif
+else
+override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(BASEDIR)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=c:/pp
+endif
+endif
+endif
+endif
+endif
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(FPCDIR)/bin/$(TARGETSUFFIX))
+endif
+ifneq ($(findstring $(OS_TARGET),darwin iphonesim),)
+ifeq ($(OS_SOURCE),darwin)
+DARWIN2DARWIN=1
+endif
+endif
+ifndef BINUTILSPREFIX
+ifndef CROSSBINDIR
+ifdef CROSSCOMPILE
+ifndef DARWIN2DARWIN
+ifneq ($(CPU_TARGET),jvm)
+BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+endif
+endif
+endif
+endif
+endif
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
+ifeq ($(UNITSDIR),)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+endif
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
+ifndef FPCFPMAKE
+ifdef CROSSCOMPILE
+ifeq ($(strip $(wildcard $(addsuffix /compiler/ppc$(SRCEXEEXT),$(FPCDIR)))),)
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+FPCFPMAKE:=$(shell $(FPCPROG) -PB)
+ifeq ($(strip $(wildcard $(FPCFPMAKE))),)
+FPCFPMAKE:=$(firstword $(FPCPROG))
+endif
+else
+override FPCFPMAKE=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+else
+FPCFPMAKE=$(strip $(wildcard $(addsuffix /compiler/ppc$(SRCEXEEXT),$(FPCDIR))))
+FPMAKE_SKIP_CONFIG=-n
+export FPCFPMAKE
+export FPMAKE_SKIP_CONFIG
+endif
+else
+FPMAKE_SKIP_CONFIG=-n
+FPCFPMAKE=$(FPC)
+endif
+endif
+override PACKAGE_NAME=pas2fpm
+override PACKAGE_VERSION=2.7.1
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-nativent)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),i386-iphonesim)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc-wii)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc-aix)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),x86_64-solaris)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),powerpc64-aix)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),mips-linux)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),mipsel-linux)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),jvm-java)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+ifeq ($(FULL_TARGET),jvm-android)
+override TARGET_PROGRAMS+=pas2fpm
+endif
+override INSTALL_FPCPACKAGE=y
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-nativent)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-iphonesim)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-wii)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-aix)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-solaris)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc64-aix)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),mips-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),mipsel-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),jvm-java)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),jvm-android)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifdef REQUIRE_UNITSDIR
+override UNITSDIR+=$(REQUIRE_UNITSDIR)
+endif
+ifdef REQUIRE_PACKAGESDIR
+override PACKAGESDIR+=$(REQUIRE_PACKAGESDIR)
+endif
+ifdef ZIPINSTALL
+ifneq ($(findstring $(OS_TARGET),$(UNIXs)),)
+UNIXHier=1
+endif
+else
+ifneq ($(findstring $(OS_SOURCE),$(UNIXs)),)
+UNIXHier=1
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef PREFIX
+INSTALL_PREFIX=$(PREFIX)
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef UNIXHier
+INSTALL_PREFIX=/usr/local
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=/pp
+else
+INSTALL_BASEDIR:=/$(PACKAGE_NAME)
+endif
+endif
+endif
+export INSTALL_PREFIX
+ifdef INSTALL_FPCSUBDIR
+export INSTALL_FPCSUBDIR
+endif
+ifndef DIST_DESTDIR
+DIST_DESTDIR:=$(BASEDIR)
+endif
+export DIST_DESTDIR
+ifndef COMPILER_UNITTARGETDIR
+ifdef PACKAGEDIR_MAIN
+COMPILER_UNITTARGETDIR=$(PACKAGEDIR_MAIN)/units/$(TARGETSUFFIX)
+else
+COMPILER_UNITTARGETDIR=units/$(TARGETSUFFIX)
+endif
+endif
+ifndef COMPILER_TARGETDIR
+COMPILER_TARGETDIR=.
+endif
+ifndef INSTALL_BASEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION)
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/$(PACKAGE_NAME)
+endif
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)
+endif
+endif
+ifndef INSTALL_BINDIR
+ifdef UNIXHier
+INSTALL_BINDIR:=$(INSTALL_PREFIX)/bin
+else
+INSTALL_BINDIR:=$(INSTALL_BASEDIR)/bin
+ifdef INSTALL_FPCPACKAGE
+ifdef CROSSCOMPILE
+ifdef CROSSINSTALL
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(SOURCESUFFIX)
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+endif
+endif
+endif
+ifndef INSTALL_UNITDIR
+INSTALL_UNITDIR:=$(INSTALL_BASEDIR)/units/$(TARGETSUFFIX)
+ifdef INSTALL_FPCPACKAGE
+ifdef PACKAGE_NAME
+INSTALL_UNITDIR:=$(INSTALL_UNITDIR)/$(PACKAGE_NAME)
+endif
+endif
+endif
+ifndef INSTALL_LIBDIR
+ifdef UNIXHier
+INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib
+else
+INSTALL_LIBDIR:=$(INSTALL_UNITDIR)
+endif
+endif
+ifndef INSTALL_SOURCEDIR
+ifdef UNIXHier
+ifdef BSDhier
+SRCPREFIXDIR=share/src
+else
+ifdef linuxHier
+SRCPREFIXDIR=share/src
+else
+SRCPREFIXDIR=src
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source
+endif
+endif
+endif
+ifndef INSTALL_DOCDIR
+ifdef UNIXHier
+ifdef BSDhier
+DOCPREFIXDIR=share/doc
+else
+ifdef linuxHier
+DOCPREFIXDIR=share/doc
+else
+DOCPREFIXDIR=doc
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc
+endif
+endif
+endif
+ifndef INSTALL_EXAMPLEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/fpc-$(FPC_VERSION)/examples/$(PACKAGE_NAME)
+endif
+endif
+else
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+endif
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples/$(PACKAGE_NAME)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples
+endif
+endif
+endif
+ifndef INSTALL_DATADIR
+INSTALL_DATADIR=$(INSTALL_BASEDIR)
+endif
+ifndef INSTALL_SHAREDDIR
+INSTALL_SHAREDDIR=$(INSTALL_PREFIX)/lib
+endif
+ifdef CROSSCOMPILE
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(CROSSTARGETDIR)/bin/$(SOURCESUFFIX))
+ifeq ($(CROSSBINDIR),)
+CROSSBINDIR:=$(wildcard $(INSTALL_BASEDIR)/cross/$(TARGETSUFFIX)/bin/$(FULL_SOURCE))
+endif
+endif
+else
+CROSSBINDIR=
+endif
+BATCHEXT=.bat
+LOADEREXT=.as
+EXEEXT=.exe
+PPLEXT=.ppl
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.so
+SHAREDLIBPREFIX=libfp
+STATICLIBPREFIX=libp
+IMPORTLIBPREFIX=libimp
+RSTEXT=.rst
+EXEDBGEXT=.dbg
+ifeq ($(OS_TARGET),go32v1)
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+OEXT=.obj
+ASMEXT=.asm
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=wat
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),emx)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=emx
+ECHO=echo
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),morphos)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=mos
+endif
+ifeq ($(OS_TARGET),atari)
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),haiku)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=hai
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nw
+IMPORTLIBPREFIX=imp
+endif
+ifeq ($(OS_TARGET),netwlibc)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nwl
+IMPORTLIBPREFIX=imp
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+IMPORTLIBPREFIX=imp
+endif
+ifneq ($(findstring $(OS_TARGET),darwin iphonesim),)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=dwn
+EXEDBGEXT=.dSYM
+endif
+ifeq ($(OS_TARGET),gba)
+EXEEXT=.gba
+SHAREDLIBEXT=.so
+SHORTSUFFIX=gba
+endif
+ifeq ($(OS_TARGET),symbian)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=symbian
+endif
+ifeq ($(OS_TARGET),NativeNT)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=nativent
+endif
+ifeq ($(OS_TARGET),wii)
+EXEEXT=.dol
+SHAREDLIBEXT=.so
+SHORTSUFFIX=wii
+endif
+ifeq ($(OS_TARGET),aix)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=aix
+endif
+ifeq ($(OS_TARGET),java)
+OEXT=.class
+ASMEXT=.j
+SHAREDLIBEXT=.jar
+SHORTSUFFIX=java
+endif
+ifeq ($(OS_TARGET),android)
+OEXT=.class
+ASMEXT=.j
+SHAREDLIBEXT=.jar
+SHORTSUFFIX=android
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+FPCMADE=fpcmade.$(SHORTSUFFIX)
+ZIPSUFFIX=$(SHORTSUFFIX)
+ZIPCROSSPREFIX=
+ZIPSOURCESUFFIX=src
+ZIPEXAMPLESUFFIX=exm
+else
+FPCMADE=fpcmade.$(TARGETSUFFIX)
+ZIPSOURCESUFFIX=.source
+ZIPEXAMPLESUFFIX=.examples
+ifdef CROSSCOMPILE
+ZIPSUFFIX=.$(SOURCESUFFIX)
+ZIPCROSSPREFIX=$(TARGETSUFFIX)-
+else
+ZIPSUFFIX=.$(TARGETSUFFIX)
+ZIPCROSSPREFIX=
+endif
+endif
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO= __missing_command_ECHO
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+ifndef DATE
+DATE:=$(strip $(wildcard $(addsuffix /gdate$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE:=$(strip $(wildcard $(addsuffix /date$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE= __missing_command_DATE
+else
+DATE:=$(firstword $(DATE))
+endif
+else
+DATE:=$(firstword $(DATE))
+endif
+endif
+export DATE
+ifndef GINSTALL
+GINSTALL:=$(strip $(wildcard $(addsuffix /ginstall$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL:=$(strip $(wildcard $(addsuffix /install$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL= __missing_command_GINSTALL
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+endif
+export GINSTALL
+ifndef CPPROG
+CPPROG:=$(strip $(wildcard $(addsuffix /cp$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(CPPROG),)
+CPPROG= __missing_command_CPPROG
+else
+CPPROG:=$(firstword $(CPPROG))
+endif
+endif
+export CPPROG
+ifndef RMPROG
+RMPROG:=$(strip $(wildcard $(addsuffix /rm$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(RMPROG),)
+RMPROG= __missing_command_RMPROG
+else
+RMPROG:=$(firstword $(RMPROG))
+endif
+endif
+export RMPROG
+ifndef MVPROG
+MVPROG:=$(strip $(wildcard $(addsuffix /mv$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MVPROG),)
+MVPROG= __missing_command_MVPROG
+else
+MVPROG:=$(firstword $(MVPROG))
+endif
+endif
+export MVPROG
+ifndef MKDIRPROG
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /gmkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /mkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG= __missing_command_MKDIRPROG
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+endif
+export MKDIRPROG
+ifndef ECHOREDIR
+ifndef inUnix
+ECHOREDIR=echo
+else
+ECHOREDIR=$(ECHO)
+endif
+endif
+ifndef COPY
+COPY:=$(CPPROG) -fp
+endif
+ifndef COPYTREE
+COPYTREE:=$(CPPROG) -Rfp
+endif
+ifndef MKDIRTREE
+MKDIRTREE:=$(MKDIRPROG) -p
+endif
+ifndef MOVE
+MOVE:=$(MVPROG) -f
+endif
+ifndef DEL
+DEL:=$(RMPROG) -f
+endif
+ifndef DELTREE
+DELTREE:=$(RMPROG) -rf
+endif
+ifndef INSTALL
+ifdef inUnix
+INSTALL:=$(GINSTALL) -c -m 644
+else
+INSTALL:=$(COPY)
+endif
+endif
+ifndef INSTALLEXE
+ifdef inUnix
+INSTALLEXE:=$(GINSTALL) -c -m 755
+else
+INSTALLEXE:=$(COPY)
+endif
+endif
+ifndef MKDIR
+MKDIR:=$(GINSTALL) -m 755 -d
+endif
+export ECHOREDIR COPY COPYTREE MOVE DEL DELTREE INSTALL INSTALLEXE MKDIR
+ifndef PPUMOVE
+PPUMOVE:=$(strip $(wildcard $(addsuffix /ppumove$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUMOVE),)
+PPUMOVE= __missing_command_PPUMOVE
+else
+PPUMOVE:=$(firstword $(PPUMOVE))
+endif
+endif
+export PPUMOVE
+ifndef FPCMAKE
+FPCMAKE:=$(strip $(wildcard $(addsuffix /fpcmake$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(FPCMAKE),)
+FPCMAKE= __missing_command_FPCMAKE
+else
+FPCMAKE:=$(firstword $(FPCMAKE))
+endif
+endif
+export FPCMAKE
+ifndef ZIPPROG
+ZIPPROG:=$(strip $(wildcard $(addsuffix /zip$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ZIPPROG),)
+ZIPPROG= __missing_command_ZIPPROG
+else
+ZIPPROG:=$(firstword $(ZIPPROG))
+endif
+endif
+export ZIPPROG
+ifndef TARPROG
+TARPROG:=$(strip $(wildcard $(addsuffix /gtar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG= __missing_command_TARPROG
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+endif
+export TARPROG
+ASNAME=$(BINUTILSPREFIX)as
+LDNAME=$(BINUTILSPREFIX)ld
+ARNAME=$(BINUTILSPREFIX)ar
+RCNAME=$(BINUTILSPREFIX)rc
+ifndef ASPROG
+ifdef CROSSBINDIR
+ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
+else
+ASPROG=$(ASNAME)
+endif
+endif
+ifndef LDPROG
+ifdef CROSSBINDIR
+LDPROG=$(CROSSBINDIR)/$(LDNAME)$(SRCEXEEXT)
+else
+LDPROG=$(LDNAME)
+endif
+endif
+ifndef RCPROG
+ifdef CROSSBINDIR
+RCPROG=$(CROSSBINDIR)/$(RCNAME)$(SRCEXEEXT)
+else
+RCPROG=$(RCNAME)
+endif
+endif
+ifndef ARPROG
+ifdef CROSSBINDIR
+ARPROG=$(CROSSBINDIR)/$(ARNAME)$(SRCEXEEXT)
+else
+ARPROG=$(ARNAME)
+endif
+endif
+AS=$(ASPROG)
+LD=$(LDPROG)
+RC=$(RCPROG)
+AR=$(ARPROG)
+PPAS=ppas$(SRCBATCHEXT)
+ifdef inUnix
+LDCONFIG=ldconfig
+else
+LDCONFIG=
+endif
+ifdef DATE
+DATESTR:=$(shell $(DATE) +%Y%m%d)
+else
+DATESTR=
+endif
+ZIPOPT=-9
+ZIPEXT=.zip
+ifeq ($(USETAR),bz2)
+TAROPT=vj
+TAREXT=.tar.bz2
+else
+TAROPT=vz
+TAREXT=.tar.gz
+endif
+override REQUIRE_PACKAGES=rtl fcl-passrc fcl-base
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-nativent)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-iphonesim)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-wii)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-aix)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-aix)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),mips-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),mipsel-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),jvm-java)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),jvm-android)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifdef REQUIRE_PACKAGES_RTL
+PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_RTL),)
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)),)
+UNITDIR_RTL=$(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)
+else
+UNITDIR_RTL=$(PACKAGEDIR_RTL)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_RTL=$(PACKAGEDIR_RTL)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_RTL=$(PACKAGEDIR_RTL)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_RTL=$(PACKAGEDIR_RTL)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_RTL)/$(OS_TARGET)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_RTL)/$(OS_TARGET) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(OS_TARGET)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_RTL=
+UNITDIR_RTL:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /rtl/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_RTL),)
+UNITDIR_RTL:=$(firstword $(UNITDIR_RTL))
+else
+UNITDIR_RTL=
+endif
+endif
+ifdef UNITDIR_RTL
+override COMPILER_UNITDIR+=$(UNITDIR_RTL)
+endif
+ifdef UNITDIR_FPMAKE_RTL
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_RTL)
+endif
+endif
+ifdef REQUIRE_PACKAGES_PASZLIB
+PACKAGEDIR_PASZLIB:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /paszlib/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_PASZLIB),)
+ifneq ($(wildcard $(PACKAGEDIR_PASZLIB)/units/$(TARGETSUFFIX)),)
+UNITDIR_PASZLIB=$(PACKAGEDIR_PASZLIB)/units/$(TARGETSUFFIX)
+else
+UNITDIR_PASZLIB=$(PACKAGEDIR_PASZLIB)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_PASZLIB)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_PASZLIB=$(PACKAGEDIR_PASZLIB)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_PASZLIB)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_PASZLIB=$(PACKAGEDIR_PASZLIB)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_PASZLIB=$(PACKAGEDIR_PASZLIB)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_PASZLIB)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_PASZLIB) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_PASZLIB)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_PASZLIB=
+UNITDIR_PASZLIB:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /paszlib/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_PASZLIB),)
+UNITDIR_PASZLIB:=$(firstword $(UNITDIR_PASZLIB))
+else
+UNITDIR_PASZLIB=
+endif
+endif
+ifdef UNITDIR_PASZLIB
+override COMPILER_UNITDIR+=$(UNITDIR_PASZLIB)
+endif
+ifdef UNITDIR_FPMAKE_PASZLIB
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_PASZLIB)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FCL-PROCESS
+PACKAGEDIR_FCL-PROCESS:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-process/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-PROCESS),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PROCESS)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PROCESS)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PROCESS)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-PROCESS)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-PROCESS) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-PROCESS)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-PROCESS=
+UNITDIR_FCL-PROCESS:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-process/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-PROCESS),)
+UNITDIR_FCL-PROCESS:=$(firstword $(UNITDIR_FCL-PROCESS))
+else
+UNITDIR_FCL-PROCESS=
+endif
+endif
+ifdef UNITDIR_FCL-PROCESS
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-PROCESS)
+endif
+ifdef UNITDIR_FPMAKE_FCL-PROCESS
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FCL-PROCESS)
+endif
+endif
+ifdef REQUIRE_PACKAGES_HASH
+PACKAGEDIR_HASH:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /hash/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_HASH),)
+ifneq ($(wildcard $(PACKAGEDIR_HASH)/units/$(TARGETSUFFIX)),)
+UNITDIR_HASH=$(PACKAGEDIR_HASH)/units/$(TARGETSUFFIX)
+else
+UNITDIR_HASH=$(PACKAGEDIR_HASH)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_HASH)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_HASH=$(PACKAGEDIR_HASH)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_HASH)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_HASH=$(PACKAGEDIR_HASH)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_HASH=$(PACKAGEDIR_HASH)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_HASH)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_HASH) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_HASH)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_HASH=
+UNITDIR_HASH:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /hash/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_HASH),)
+UNITDIR_HASH:=$(firstword $(UNITDIR_HASH))
+else
+UNITDIR_HASH=
+endif
+endif
+ifdef UNITDIR_HASH
+override COMPILER_UNITDIR+=$(UNITDIR_HASH)
+endif
+ifdef UNITDIR_FPMAKE_HASH
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_HASH)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FPMKUNIT
+PACKAGEDIR_FPMKUNIT:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fpmkunit/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FPMKUNIT),)
+ifneq ($(wildcard $(PACKAGEDIR_FPMKUNIT)/units/$(TARGETSUFFIX)),)
+UNITDIR_FPMKUNIT=$(PACKAGEDIR_FPMKUNIT)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FPMKUNIT=$(PACKAGEDIR_FPMKUNIT)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_FPMKUNIT)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FPMKUNIT=$(PACKAGEDIR_FPMKUNIT)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_FPMKUNIT)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FPMKUNIT=$(PACKAGEDIR_FPMKUNIT)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_FPMKUNIT=$(PACKAGEDIR_FPMKUNIT)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FPMKUNIT)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FPMKUNIT) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FPMKUNIT)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FPMKUNIT=
+UNITDIR_FPMKUNIT:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fpmkunit/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FPMKUNIT),)
+UNITDIR_FPMKUNIT:=$(firstword $(UNITDIR_FPMKUNIT))
+else
+UNITDIR_FPMKUNIT=
+endif
+endif
+ifdef UNITDIR_FPMKUNIT
+override COMPILER_UNITDIR+=$(UNITDIR_FPMKUNIT)
+endif
+ifdef UNITDIR_FPMAKE_FPMKUNIT
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FPMKUNIT)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FCL-PASSRC
+PACKAGEDIR_FCL-PASSRC:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-passrc/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-PASSRC),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PASSRC)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-PASSRC=$(PACKAGEDIR_FCL-PASSRC)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-PASSRC=$(PACKAGEDIR_FCL-PASSRC)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PASSRC)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-PASSRC=$(PACKAGEDIR_FCL-PASSRC)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PASSRC)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-PASSRC=$(PACKAGEDIR_FCL-PASSRC)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_FCL-PASSRC=$(PACKAGEDIR_FCL-PASSRC)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-PASSRC)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-PASSRC) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-PASSRC)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-PASSRC=
+UNITDIR_FCL-PASSRC:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-passrc/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-PASSRC),)
+UNITDIR_FCL-PASSRC:=$(firstword $(UNITDIR_FCL-PASSRC))
+else
+UNITDIR_FCL-PASSRC=
+endif
+endif
+ifdef UNITDIR_FCL-PASSRC
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-PASSRC)
+endif
+ifdef UNITDIR_FPMAKE_FCL-PASSRC
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FCL-PASSRC)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FCL-BASE
+PACKAGEDIR_FCL-BASE:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-base/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-BASE),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-BASE)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-BASE=$(PACKAGEDIR_FCL-BASE)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-BASE=$(PACKAGEDIR_FCL-BASE)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_FCL-BASE)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-BASE=$(PACKAGEDIR_FCL-BASE)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_FCL-BASE)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-BASE=$(PACKAGEDIR_FCL-BASE)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_FCL-BASE=$(PACKAGEDIR_FCL-BASE)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-BASE)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-BASE) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-BASE)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-BASE=
+UNITDIR_FCL-BASE:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-base/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-BASE),)
+UNITDIR_FCL-BASE:=$(firstword $(UNITDIR_FCL-BASE))
+else
+UNITDIR_FCL-BASE=
+endif
+endif
+ifdef UNITDIR_FCL-BASE
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-BASE)
+endif
+ifdef UNITDIR_FPMAKE_FCL-BASE
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FCL-BASE)
+endif
+endif
+ifdef REQUIRE_PACKAGES_UNIVINT
+PACKAGEDIR_UNIVINT:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /univint/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_UNIVINT),)
+ifneq ($(wildcard $(PACKAGEDIR_UNIVINT)/units/$(TARGETSUFFIX)),)
+UNITDIR_UNIVINT=$(PACKAGEDIR_UNIVINT)/units/$(TARGETSUFFIX)
+else
+UNITDIR_UNIVINT=$(PACKAGEDIR_UNIVINT)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_UNIVINT)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_UNIVINT=$(PACKAGEDIR_UNIVINT)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_UNIVINT)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_UNIVINT=$(PACKAGEDIR_UNIVINT)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_UNIVINT=$(PACKAGEDIR_UNIVINT)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_UNIVINT)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_UNIVINT) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_UNIVINT)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_UNIVINT=
+UNITDIR_UNIVINT:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /univint/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_UNIVINT),)
+UNITDIR_UNIVINT:=$(firstword $(UNITDIR_UNIVINT))
+else
+UNITDIR_UNIVINT=
+endif
+endif
+ifdef UNITDIR_UNIVINT
+override COMPILER_UNITDIR+=$(UNITDIR_UNIVINT)
+endif
+ifdef UNITDIR_FPMAKE_UNIVINT
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_UNIVINT)
+endif
+endif
+ifndef NOCPUDEF
+override FPCOPTDEF=$(ARCH)
+endif
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifneq ($(CPU_TARGET),$(CPU_SOURCE))
+override FPCOPT+=-P$(ARCH)
+endif
+ifeq ($(OS_SOURCE),openbsd)
+override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
+override FPCMAKEOPT+=-FD$(NEW_BINUTILS_PATH)
+endif
+ifndef CROSSBOOTSTRAP
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-XP$(BINUTILSPREFIX)
+endif
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-Xr$(RLINKPATH)
+endif
+endif
+ifndef CROSSCOMPILE
+ifneq ($(BINUTILSPREFIX),)
+override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
+endif
+endif
+ifdef UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(UNITDIR))
+endif
+ifdef LIBDIR
+override FPCOPT+=$(addprefix -Fl,$(LIBDIR))
+endif
+ifdef OBJDIR
+override FPCOPT+=$(addprefix -Fo,$(OBJDIR))
+endif
+ifdef INCDIR
+override FPCOPT+=$(addprefix -Fi,$(INCDIR))
+endif
+ifdef LINKSMART
+override FPCOPT+=-XX
+endif
+ifdef CREATESMART
+override FPCOPT+=-CX
+endif
+ifdef DEBUG
+override FPCOPT+=-gl
+override FPCOPTDEF+=DEBUG
+endif
+ifdef RELEASE
+ifneq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(CPU_TARGET),i386)
+FPCCPUOPT:=-OG2p3
+endif
+ifeq ($(CPU_TARGET),powerpc)
+FPCCPUOPT:=-O1r
+endif
+else
+FPCCPUOPT:=-O2
+endif
+override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n
+override FPCOPTDEF+=RELEASE
+endif
+ifdef STRIP
+override FPCOPT+=-Xs
+endif
+ifdef OPTIMIZE
+override FPCOPT+=-O2
+endif
+ifdef VERBOSE
+override FPCOPT+=-vwni
+endif
+ifdef COMPILER_OPTIONS
+override FPCOPT+=$(COMPILER_OPTIONS)
+endif
+ifdef COMPILER_UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))
+endif
+ifdef COMPILER_LIBRARYDIR
+override FPCOPT+=$(addprefix -Fl,$(COMPILER_LIBRARYDIR))
+endif
+ifdef COMPILER_OBJECTDIR
+override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))
+endif
+ifdef COMPILER_INCLUDEDIR
+override FPCOPT+=$(addprefix -Fi,$(COMPILER_INCLUDEDIR))
+endif
+ifdef CROSSBINDIR
+override FPCOPT+=-FD$(CROSSBINDIR)
+endif
+ifdef COMPILER_TARGETDIR
+override FPCOPT+=-FE$(COMPILER_TARGETDIR)
+ifeq ($(COMPILER_TARGETDIR),.)
+override TARGETDIRPREFIX=
+else
+override TARGETDIRPREFIX=$(COMPILER_TARGETDIR)/
+endif
+endif
+ifdef COMPILER_UNITTARGETDIR
+override FPCOPT+=-FU$(COMPILER_UNITTARGETDIR)
+ifeq ($(COMPILER_UNITTARGETDIR),.)
+override UNITTARGETDIRPREFIX=
+else
+override UNITTARGETDIRPREFIX=$(COMPILER_UNITTARGETDIR)/
+endif
+else
+ifdef COMPILER_TARGETDIR
+override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR)
+override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX)
+endif
+endif
+ifdef CREATESHARED
+override FPCOPT+=-Cg
+endif
+ifneq ($(findstring $(OS_TARGET),freebsd openbsd netbsd linux solaris),)
+ifeq ($(CPU_TARGET),x86_64)
+override FPCOPT+=-Cg
+endif
+endif
+ifdef LINKSHARED
+endif
+ifdef OPT
+override FPCOPT+=$(OPT)
+endif
+ifdef FPCOPTDEF
+override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
+endif
+ifdef CFGFILE
+override FPCOPT+=@$(CFGFILE)
+endif
+ifdef USEENV
+override FPCEXTCMD:=$(FPCOPT)
+override FPCOPT:=!FPCEXTCMD
+export FPCEXTCMD
+endif
+override AFULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+override AFULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(AFULL_TARGET),$(AFULL_SOURCE))
+override ACROSSCOMPILE=1
+endif
+ifdef ACROSSCOMPILE
+override FPCOPT+=$(CROSSOPT)
+endif
+override COMPILER:=$(FPC) $(FPCOPT)
+ifeq (,$(findstring -s ,$(COMPILER)))
+EXECPPAS=
+else
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+ifdef RUNBATCH
+EXECPPAS:=@$(RUNBATCH) $(PPAS)
+else
+EXECPPAS:=@$(PPAS)
+endif
+endif
+endif
+.PHONY: fpc_exes
+ifndef CROSSINSTALL
+ifneq ($(TARGET_PROGRAMS),)
+override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))
+override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS))) $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS)))
+override EXEDBGFILES:=$(addsuffix $(EXEDBGEXT),$(TARGET_PROGRAMS))
+override ALLTARGET+=fpc_exes
+override INSTALLEXEFILES+=$(EXEFILES)
+override CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)
+override CLEANEXEDBGFILES+=$(EXEDBGFILES)
+ifeq ($(OS_TARGET),os2)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+ifeq ($(OS_TARGET),emx)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+endif
+endif
+fpc_exes: $(COMPILER_TARGETDIR) $(COMPILER_UNITTARGETDIR) $(EXEFILES)
+ifdef TARGET_RSTS
+override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
+override CLEANRSTFILES+=$(RSTFILES)
+endif
+.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared
+$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)
+	@$(ECHOREDIR) Compiled > $(FPCMADE)
+fpc_all: $(FPCMADE)
+fpc_smart:
+	$(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+	$(MAKE) all DEBUG=1
+fpc_release:
+	$(MAKE) all RELEASE=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res
+$(COMPILER_UNITTARGETDIR):
+	$(MKDIRTREE) $(COMPILER_UNITTARGETDIR)
+$(COMPILER_TARGETDIR):
+	$(MKDIRTREE) $(COMPILER_TARGETDIR)
+%$(PPUEXT): %.pp
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(PPUEXT): %.pas
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.pp
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.pas
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.lpr
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.dpr
+	$(COMPILER) $<
+	$(EXECPPAS)
+%.res: %.rc
+	windres -i $< -o $@
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.inc $(COMPILER_INCLUDEDIR)
+vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_shared
+override INSTALLTARGET+=fpc_shared_install
+ifndef SHARED_LIBVERSION
+SHARED_LIBVERSION=$(FPC_VERSION)
+endif
+ifndef SHARED_LIBNAME
+SHARED_LIBNAME=$(PACKAGE_NAME)
+endif
+ifndef SHARED_FULLNAME
+SHARED_FULLNAME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERSION)$(SHAREDLIBEXT)
+endif
+ifndef SHARED_LIBUNITS
+SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS)
+override SHARED_LIBUNITS:=$(filter-out $(INSTALL_BUILDUNIT),$(SHARED_LIBUNITS))
+endif
+fpc_shared:
+ifdef HASSHAREDLIB
+	$(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1
+ifneq ($(SHARED_BUILD),n)
+	$(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)
+endif
+else
+	@$(ECHO) Shared Libraries not supported
+endif
+fpc_shared_install:
+ifneq ($(SHARED_BUILD),n)
+ifneq ($(SHARED_LIBUNITS),)
+ifneq ($(wildcard $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME)),)
+	$(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INSTALL_SHAREDDIR)
+endif
+endif
+endif
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALL_BUILDUNIT
+override INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT),$(INSTALLPPUFILES))
+endif
+ifdef INSTALLPPUFILES
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+ifneq ($(UNITTARGETDIRPREFIX),)
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPUFILES)))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPULINKFILES))))
+endif
+override INSTALL_CREATEPACKAGEFPC=1
+endif
+ifdef INSTALLEXEFILES
+ifneq ($(TARGETDIRPREFIX),)
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(INSTALLEXEFILES)))
+endif
+endif
+fpc_install: all $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+	$(MKDIR) $(INSTALL_BINDIR)
+	$(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+endif
+ifdef INSTALL_CREATEPACKAGEFPC
+ifdef FPCMAKE
+ifdef PACKAGE_VERSION
+ifneq ($(wildcard Makefile.fpc),)
+	$(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc
+	$(MKDIR) $(INSTALL_UNITDIR)
+	$(INSTALL) Package.fpc $(INSTALL_UNITDIR)
+endif
+endif
+endif
+endif
+ifdef INSTALLPPUFILES
+	$(MKDIR) $(INSTALL_UNITDIR)
+	$(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)
+ifneq ($(INSTALLPPULINKFILES),)
+	$(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)
+endif
+ifneq ($(wildcard $(LIB_FULLNAME)),)
+	$(MKDIR) $(INSTALL_LIBDIR)
+	$(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)
+ifdef inUnix
+	ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)
+endif
+endif
+endif
+ifdef INSTALL_FILES
+	$(MKDIR) $(INSTALL_DATADIR)
+	$(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADIR)
+endif
+fpc_sourceinstall: distclean
+	$(MKDIR) $(INSTALL_SOURCEDIR)
+	$(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
+fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+ifdef HASEXAMPLES
+	$(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
+	$(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef TARGET_EXAMPLEDIRS
+	$(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
+endif
+.PHONY: fpc_distinstall
+fpc_distinstall: install exampleinstall
+.PHONY: fpc_zipinstall fpc_zipsourceinstall fpc_zipexampleinstall
+ifndef PACKDIR
+ifndef inUnix
+PACKDIR=$(BASEDIR)/../fpc-pack
+else
+PACKDIR=/tmp/fpc-pack
+endif
+endif
+ifndef ZIPNAME
+ifdef DIST_ZIPNAME
+ZIPNAME=$(DIST_ZIPNAME)
+else
+ZIPNAME=$(PACKAGE_NAME)
+endif
+endif
+ifndef FULLZIPNAME
+FULLZIPNAME=$(ZIPCROSSPREFIX)$(ZIPPREFIX)$(ZIPNAME)$(ZIPSUFFIX)
+endif
+ifndef ZIPTARGET
+ifdef DIST_ZIPTARGET
+ZIPTARGET=DIST_ZIPTARGET
+else
+ZIPTARGET=install
+endif
+endif
+ifndef USEZIP
+ifdef inUnix
+USETAR=1
+endif
+endif
+ifndef inUnix
+USEZIPWRAPPER=1
+endif
+ifdef USEZIPWRAPPER
+ZIPPATHSEP=$(PATHSEP)
+ZIPWRAPPER=$(subst /,$(PATHSEP),$(DIST_DESTDIR)/fpczip$(SRCBATCHEXT))
+else
+ZIPPATHSEP=/
+endif
+ZIPCMD_CDPACK:=cd $(subst /,$(ZIPPATHSEP),$(PACKDIR))
+ZIPCMD_CDBASE:=cd $(subst /,$(ZIPPATHSEP),$(BASEDIR))
+ifdef USETAR
+ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(TAREXT)
+ZIPCMD_ZIP:=$(TARPROG) c$(TAROPT)f $(ZIPDESTFILE) *
+else
+ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(ZIPEXT)
+ZIPCMD_ZIP:=$(subst /,$(ZIPPATHSEP),$(ZIPPROG)) -Dr $(ZIPOPT) $(ZIPDESTFILE) *
+endif
+fpc_zipinstall:
+	$(MAKE) $(ZIPTARGET) INSTALL_PREFIX=$(PACKDIR) ZIPINSTALL=1
+	$(MKDIR) $(DIST_DESTDIR)
+	$(DEL) $(ZIPDESTFILE)
+ifdef USEZIPWRAPPER
+ifneq ($(ECHOREDIR),echo)
+	$(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDPACK))" > $(ZIPWRAPPER)
+	$(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_ZIP))" >> $(ZIPWRAPPER)
+	$(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDBASE))" >> $(ZIPWRAPPER)
+else
+	echo $(ZIPCMD_CDPACK) > $(ZIPWRAPPER)
+	echo $(ZIPCMD_ZIP) >> $(ZIPWRAPPER)
+	echo $(ZIPCMD_CDBASE) >> $(ZIPWRAPPER)
+endif
+ifdef inUnix
+	/bin/sh $(ZIPWRAPPER)
+else
+ifdef RUNBATCH
+	$(RUNBATCH) $(ZIPWRAPPER)
+else
+	$(ZIPWRAPPER)
+endif
+endif
+	$(DEL) $(ZIPWRAPPER)
+else
+	$(ZIPCMD_CDPACK) ; $(ZIPCMD_ZIP) ; $(ZIPCMD_CDBASE)
+endif
+	$(DELTREE) $(PACKDIR)
+fpc_zipsourceinstall:
+	$(MAKE) fpc_zipinstall ZIPTARGET=sourceinstall ZIPSUFFIX=$(ZIPSOURCESUFFIX)
+fpc_zipexampleinstall:
+ifdef HASEXAMPLES
+	$(MAKE) fpc_zipinstall ZIPTARGET=exampleinstall ZIPSUFFIX=$(ZIPEXAMPLESUFFIX)
+endif
+fpc_zipdistinstall:
+	$(MAKE) fpc_zipinstall ZIPTARGET=distinstall
+.PHONY: fpc_clean fpc_cleanall fpc_distclean
+ifdef EXEFILES
+override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
+override CLEANEXEDBGFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEDBGFILES))
+endif
+ifdef CLEAN_PROGRAMS
+override CLEANEXEFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix $(EXEEXT), $(CLEAN_PROGRAMS)))
+override CLEANEXEDBGFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix $(EXEDBGEXT), $(CLEAN_PROGRAMS)))
+endif
+ifdef CLEAN_UNITS
+override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
+endif
+ifdef CLEANPPUFILES
+override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES)))
+ifdef DEBUGSYMEXT
+override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPPUFILES))
+endif
+override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUFILES))
+override CLEANPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPULINKFILES)))
+endif
+fpc_clean: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+	-$(DEL) $(CLEANEXEFILES)
+endif
+ifdef CLEANEXEDBGFILES
+	-$(DELTREE) $(CLEANEXEDBGFILES)
+endif
+ifdef CLEANPPUFILES
+	-$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+	-$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+	-$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+ifdef CLEAN_FILES
+	-$(DEL) $(CLEAN_FILES)
+endif
+ifdef LIB_NAME
+	-$(DEL) $(LIB_NAME) $(LIB_FULLNAME)
+endif
+	-$(DEL) $(FPCMADE) Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+	-$(DEL) *$(ASMEXT) *_ppas$(BATCHEXT)
+fpc_cleanall: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+	-$(DEL) $(CLEANEXEFILES)
+endif
+ifdef COMPILER_UNITTARGETDIR
+ifdef CLEANPPUFILES
+	-$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+	-$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+	-$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+endif
+ifdef CLEAN_FILES
+	-$(DEL) $(CLEAN_FILES)
+endif
+	-$(DELTREE) units
+	-$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
+ifneq ($(PPUEXT),.ppu)
+	-$(DEL) *.o *.ppu *.a
+endif
+	-$(DELTREE) *$(SMARTEXT)
+	-$(DEL) fpcmade.* Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+	-$(DEL) *_ppas$(BATCHEXT)
+ifdef AOUTEXT
+	-$(DEL) *$(AOUTEXT)
+endif
+ifdef DEBUGSYMEXT
+	-$(DEL) *$(DEBUGSYMEXT)
+endif
+fpc_distclean: cleanall
+.PHONY: fpc_baseinfo
+override INFORULES+=fpc_baseinfo
+fpc_baseinfo:
+	@$(ECHO)
+	@$(ECHO)  == Package info ==
+	@$(ECHO)  Package Name..... $(PACKAGE_NAME)
+	@$(ECHO)  Package Version.. $(PACKAGE_VERSION)
+	@$(ECHO)
+	@$(ECHO)  == Configuration info ==
+	@$(ECHO)
+	@$(ECHO)  FPC.......... $(FPC)
+	@$(ECHO)  FPC Version.. $(FPC_VERSION)
+	@$(ECHO)  Source CPU... $(CPU_SOURCE)
+	@$(ECHO)  Target CPU... $(CPU_TARGET)
+	@$(ECHO)  Source OS.... $(OS_SOURCE)
+	@$(ECHO)  Target OS.... $(OS_TARGET)
+	@$(ECHO)  Full Source.. $(FULL_SOURCE)
+	@$(ECHO)  Full Target.. $(FULL_TARGET)
+	@$(ECHO)  SourceSuffix. $(SOURCESUFFIX)
+	@$(ECHO)  TargetSuffix. $(TARGETSUFFIX)
+	@$(ECHO)  FPC fpmake... $(FPCFPMAKE)
+	@$(ECHO)
+	@$(ECHO)  == Directory info ==
+	@$(ECHO)
+	@$(ECHO)  Required pkgs... $(REQUIRE_PACKAGES)
+	@$(ECHO)
+	@$(ECHO)  Basedir......... $(BASEDIR)
+	@$(ECHO)  FPCDir.......... $(FPCDIR)
+	@$(ECHO)  CrossBinDir..... $(CROSSBINDIR)
+	@$(ECHO)  UnitsDir........ $(UNITSDIR)
+	@$(ECHO)  PackagesDir..... $(PACKAGESDIR)
+	@$(ECHO)
+	@$(ECHO)  GCC library..... $(GCCLIBDIR)
+	@$(ECHO)  Other library... $(OTHERLIBDIR)
+	@$(ECHO)
+	@$(ECHO)  == Tools info ==
+	@$(ECHO)
+	@$(ECHO)  As........ $(AS)
+	@$(ECHO)  Ld........ $(LD)
+	@$(ECHO)  Ar........ $(AR)
+	@$(ECHO)  Rc........ $(RC)
+	@$(ECHO)
+	@$(ECHO)  Mv........ $(MVPROG)
+	@$(ECHO)  Cp........ $(CPPROG)
+	@$(ECHO)  Rm........ $(RMPROG)
+	@$(ECHO)  GInstall.. $(GINSTALL)
+	@$(ECHO)  Echo...... $(ECHO)
+	@$(ECHO)  Shell..... $(SHELL)
+	@$(ECHO)  Date...... $(DATE)
+	@$(ECHO)  FPCMake... $(FPCMAKE)
+	@$(ECHO)  PPUMove... $(PPUMOVE)
+	@$(ECHO)  Zip....... $(ZIPPROG)
+	@$(ECHO)
+	@$(ECHO)  == Object info ==
+	@$(ECHO)
+	@$(ECHO)  Target Loaders........ $(TARGET_LOADERS)
+	@$(ECHO)  Target Units.......... $(TARGET_UNITS)
+	@$(ECHO)  Target Implicit Units. $(TARGET_IMPLICITUNITS)
+	@$(ECHO)  Target Programs....... $(TARGET_PROGRAMS)
+	@$(ECHO)  Target Dirs........... $(TARGET_DIRS)
+	@$(ECHO)  Target Examples....... $(TARGET_EXAMPLES)
+	@$(ECHO)  Target ExampleDirs.... $(TARGET_EXAMPLEDIRS)
+	@$(ECHO)
+	@$(ECHO)  Clean Units......... $(CLEAN_UNITS)
+	@$(ECHO)  Clean Files......... $(CLEAN_FILES)
+	@$(ECHO)
+	@$(ECHO)  Install Units....... $(INSTALL_UNITS)
+	@$(ECHO)  Install Files....... $(INSTALL_FILES)
+	@$(ECHO)
+	@$(ECHO)  == Install info ==
+	@$(ECHO)
+	@$(ECHO)  DateStr.............. $(DATESTR)
+	@$(ECHO)  ZipName.............. $(ZIPNAME)
+	@$(ECHO)  ZipPrefix............ $(ZIPPREFIX)
+	@$(ECHO)  ZipCrossPrefix....... $(ZIPCROSSPREFIX)
+	@$(ECHO)  ZipSuffix............ $(ZIPSUFFIX)
+	@$(ECHO)  FullZipName.......... $(FULLZIPNAME)
+	@$(ECHO)  Install FPC Package.. $(INSTALL_FPCPACKAGE)
+	@$(ECHO)
+	@$(ECHO)  Install base dir..... $(INSTALL_BASEDIR)
+	@$(ECHO)  Install binary dir... $(INSTALL_BINDIR)
+	@$(ECHO)  Install library dir.. $(INSTALL_LIBDIR)
+	@$(ECHO)  Install units dir.... $(INSTALL_UNITDIR)
+	@$(ECHO)  Install source dir... $(INSTALL_SOURCEDIR)
+	@$(ECHO)  Install doc dir...... $(INSTALL_DOCDIR)
+	@$(ECHO)  Install example dir.. $(INSTALL_EXAMPLEDIR)
+	@$(ECHO)  Install data dir..... $(INSTALL_DATADIR)
+	@$(ECHO)
+	@$(ECHO)  Dist destination dir. $(DIST_DESTDIR)
+	@$(ECHO)  Dist zip name........ $(DIST_ZIPNAME)
+	@$(ECHO)
+.PHONY: fpc_info
+fpc_info: $(INFORULES)
+.PHONY: fpc_makefile fpc_makefiles fpc_makefile_sub1 fpc_makefile_sub2 \
+	fpc_makefile_dirs
+fpc_makefile:
+	$(FPCMAKE) -w -T$(OS_TARGET) Makefile.fpc
+fpc_makefile_sub1:
+ifdef TARGET_DIRS
+	$(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_DIRS))
+endif
+ifdef TARGET_EXAMPLEDIRS
+	$(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_EXAMPLEDIRS))
+endif
+fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_EXAMPLEDIRS))
+fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
+fpc_makefiles: fpc_makefile fpc_makefile_dirs
+ifdef TARGET_DIRS_TARGET_DIRS
+TARGET_DIRS_all:
+	$(MAKE) -C TARGET_DIRS all
+TARGET_DIRS_debug:
+	$(MAKE) -C TARGET_DIRS debug
+TARGET_DIRS_smart:
+	$(MAKE) -C TARGET_DIRS smart
+TARGET_DIRS_release:
+	$(MAKE) -C TARGET_DIRS release
+TARGET_DIRS_units:
+	$(MAKE) -C TARGET_DIRS units
+TARGET_DIRS_examples:
+	$(MAKE) -C TARGET_DIRS examples
+TARGET_DIRS_shared:
+	$(MAKE) -C TARGET_DIRS shared
+TARGET_DIRS_install:
+	$(MAKE) -C TARGET_DIRS install
+TARGET_DIRS_sourceinstall:
+	$(MAKE) -C TARGET_DIRS sourceinstall
+TARGET_DIRS_exampleinstall:
+	$(MAKE) -C TARGET_DIRS exampleinstall
+TARGET_DIRS_distinstall:
+	$(MAKE) -C TARGET_DIRS distinstall
+TARGET_DIRS_zipinstall:
+	$(MAKE) -C TARGET_DIRS zipinstall
+TARGET_DIRS_zipsourceinstall:
+	$(MAKE) -C TARGET_DIRS zipsourceinstall
+TARGET_DIRS_zipexampleinstall:
+	$(MAKE) -C TARGET_DIRS zipexampleinstall
+TARGET_DIRS_zipdistinstall:
+	$(MAKE) -C TARGET_DIRS zipdistinstall
+TARGET_DIRS_clean:
+	$(MAKE) -C TARGET_DIRS clean
+TARGET_DIRS_distclean:
+	$(MAKE) -C TARGET_DIRS distclean
+TARGET_DIRS_cleanall:
+	$(MAKE) -C TARGET_DIRS cleanall
+TARGET_DIRS_info:
+	$(MAKE) -C TARGET_DIRS info
+TARGET_DIRS_makefiles:
+	$(MAKE) -C TARGET_DIRS makefiles
+TARGET_DIRS:
+	$(MAKE) -C TARGET_DIRS all
+.PHONY: TARGET_DIRS_all TARGET_DIRS_debug TARGET_DIRS_smart TARGET_DIRS_release TARGET_DIRS_units TARGET_DIRS_examples TARGET_DIRS_shared TARGET_DIRS_install TARGET_DIRS_sourceinstall TARGET_DIRS_exampleinstall TARGET_DIRS_distinstall TARGET_DIRS_zipinstall TARGET_DIRS_zipsourceinstall TARGET_DIRS_zipexampleinstall TARGET_DIRS_zipdistinstall TARGET_DIRS_clean TARGET_DIRS_distclean TARGET_DIRS_cleanall TARGET_DIRS_info TARGET_DIRS_makefiles TARGET_DIRS
+endif
+ifdef TARGET_EXAMPLEDIRS_TARGET_EXAMPLEDIRS
+TARGET_EXAMPLEDIRS_all:
+	$(MAKE) -C TARGET_EXAMPLEDIRS all
+TARGET_EXAMPLEDIRS_debug:
+	$(MAKE) -C TARGET_EXAMPLEDIRS debug
+TARGET_EXAMPLEDIRS_smart:
+	$(MAKE) -C TARGET_EXAMPLEDIRS smart
+TARGET_EXAMPLEDIRS_release:
+	$(MAKE) -C TARGET_EXAMPLEDIRS release
+TARGET_EXAMPLEDIRS_units:
+	$(MAKE) -C TARGET_EXAMPLEDIRS units
+TARGET_EXAMPLEDIRS_examples:
+	$(MAKE) -C TARGET_EXAMPLEDIRS examples
+TARGET_EXAMPLEDIRS_shared:
+	$(MAKE) -C TARGET_EXAMPLEDIRS shared
+TARGET_EXAMPLEDIRS_install:
+	$(MAKE) -C TARGET_EXAMPLEDIRS install
+TARGET_EXAMPLEDIRS_sourceinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS sourceinstall
+TARGET_EXAMPLEDIRS_exampleinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS exampleinstall
+TARGET_EXAMPLEDIRS_distinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS distinstall
+TARGET_EXAMPLEDIRS_zipinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS zipinstall
+TARGET_EXAMPLEDIRS_zipsourceinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS zipsourceinstall
+TARGET_EXAMPLEDIRS_zipexampleinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS zipexampleinstall
+TARGET_EXAMPLEDIRS_zipdistinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS zipdistinstall
+TARGET_EXAMPLEDIRS_clean:
+	$(MAKE) -C TARGET_EXAMPLEDIRS clean
+TARGET_EXAMPLEDIRS_distclean:
+	$(MAKE) -C TARGET_EXAMPLEDIRS distclean
+TARGET_EXAMPLEDIRS_cleanall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS cleanall
+TARGET_EXAMPLEDIRS_info:
+	$(MAKE) -C TARGET_EXAMPLEDIRS info
+TARGET_EXAMPLEDIRS_makefiles:
+	$(MAKE) -C TARGET_EXAMPLEDIRS makefiles
+TARGET_EXAMPLEDIRS:
+	$(MAKE) -C TARGET_EXAMPLEDIRS all
+.PHONY: TARGET_EXAMPLEDIRS_all TARGET_EXAMPLEDIRS_debug TARGET_EXAMPLEDIRS_smart TARGET_EXAMPLEDIRS_release TARGET_EXAMPLEDIRS_units TARGET_EXAMPLEDIRS_examples TARGET_EXAMPLEDIRS_shared TARGET_EXAMPLEDIRS_install TARGET_EXAMPLEDIRS_sourceinstall TARGET_EXAMPLEDIRS_exampleinstall TARGET_EXAMPLEDIRS_distinstall TARGET_EXAMPLEDIRS_zipinstall TARGET_EXAMPLEDIRS_zipsourceinstall TARGET_EXAMPLEDIRS_zipexampleinstall TARGET_EXAMPLEDIRS_zipdistinstall TARGET_EXAMPLEDIRS_clean TARGET_EXAMPLEDIRS_distclean TARGET_EXAMPLEDIRS_cleanall TARGET_EXAMPLEDIRS_info TARGET_EXAMPLEDIRS_makefiles TARGET_EXAMPLEDIRS
+endif
+all: fpc_all
+debug: fpc_debug
+smart: fpc_smart
+release: fpc_release
+units: fpc_units
+examples:
+shared: fpc_shared
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
+distinstall: fpc_distinstall
+zipinstall: fpc_zipinstall
+zipsourceinstall: fpc_zipsourceinstall
+zipexampleinstall: fpc_zipexampleinstall
+zipdistinstall: fpc_zipdistinstall
+clean: fpc_clean
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+makefiles: fpc_makefiles
+.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
+.NOTPARALLEL:
+pas2fm$(EXEEXT): pas2fpm.pp

+ 30 - 0
utils/pas2fpm/Makefile.fpc

@@ -0,0 +1,30 @@
+#
+#   Makefile.fpc for pas2fpm
+#
+
+[package]
+name=pas2fpm
+version=2.7.1
+
+[require]
+packages=fcl-passrc fcl-base
+packages_darwin=univint
+packages_iphonesim=univint
+
+[target]
+programs=pas2fpm
+rst=pas2fpm
+
+[compiler]
+options=-S2h
+
+[install]
+fpcpackage=y
+
+[default]
+fpcdir=../..
+
+[rules]
+.NOTPARALLEL:
+pas2fm$(EXEEXT): pas2fpm.pp
+

+ 72 - 0
utils/pas2fpm/pas2fpm.lpi

@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <Title Value="Pascal to FPMake application"/>
+      <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>
+    <Units Count="1">
+      <Unit0>
+        <Filename Value="pas2fpm.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="pas2fpm"/>
+      </Unit0>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target>
+      <Filename Value="pas2fpm"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <MsgFileName Value=""/>
+      </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>

+ 560 - 0
utils/pas2fpm/pas2fpm.pp

@@ -0,0 +1,560 @@
+program pas2fpm;
+
+{$mode objfpc}{$H+}
+
+uses
+  {$IFDEF UNIX}{$IFDEF UseCThreads}
+  cthreads,
+  {$ENDIF}{$ENDIF}
+  Classes, SysUtils, CustApp, passrcutil;
+
+type
+
+  { TUnitEntry }
+
+  TUnitEntry = Class(TCollectionItem)
+  private
+    FIntfDeps: TStrings;
+    FImplDeps: TStrings;
+    FDone: Boolean;
+    FErr: String;
+    FFileName : String;
+    FName: String;
+    FProcessing: Boolean;
+    Fres: Boolean;
+    function GetName: String;
+  Public
+    constructor Create(ACollection: TCollection); override;
+    destructor Destroy; override;
+    Procedure CleanIntfDependencies(Verbose : Boolean);
+    Procedure CleanImplDependencies(Verbose : Boolean);
+    Procedure OrderDependencies(Order : TStrings);
+    Function Nodependencies : Boolean;
+    Property FileName : String Read FFileName Write FFileName;
+    Property Name : String Read GetName;
+    Property IntfDependencies : TStrings Read FIntfDeps;
+    Property ImplDependencies : TStrings Read FImplDeps;
+    Property Resources : Boolean Read Fres Write Fres;
+    Property Err : String Read FErr Write Ferr;
+    Property Done : Boolean Read FDone Write FDone;
+    Property Processing : Boolean Read FProcessing Write FProcessing;
+  end;
+
+  { TUnitEntries }
+
+  TUnitEntries = Class(TCollection)
+  private
+    function GetE(AIndex : Integer): TUnitEntry;
+  public
+    Function IndexOfEntry(Const AName : String) : Integer;
+    Function FindEntry(Const AName : string) : TUnitEntry;
+    Function AddEntry(Const AFileName : String) : TUnitEntry;
+    Property Units[AIndex : Integer] : TUnitEntry Read GetE; default;
+  end;
+
+
+  { TPas2FPMakeApp }
+
+  TPas2FPMakeApp = class(TCustomApplication)
+  private
+    procedure AddLine(const ALine: String);
+    function CheckParams : boolean;
+    procedure CreateSources;
+    Procedure ProcessUnits;
+    function  GetUnitProps(const FN: String; out Res: Boolean; UIn,UIm: TStrings; Out Err : string): Boolean;
+    Function SimulateCompile(E,EFrom: TUnitEntry) : Boolean;
+    procedure WriteProgEnd;
+    procedure WriteProgStart;
+    procedure WriteSources;
+  protected
+    FVerbose : Boolean;
+    FFiles : TUnitEntries;
+    FSrc,
+    FUnits: TStrings;
+    InterfaceUnitsOnly : Boolean;
+    FPackageName : string;
+    FOutputFile : string;
+    procedure DoRun; override;
+  public
+    constructor Create(TheOwner: TComponent); override;
+    destructor Destroy; override;
+    procedure WriteHelp; virtual;
+  end;
+
+{ TUnitEntries }
+
+function TUnitEntries.GetE(AIndex : Integer): TUnitEntry;
+begin
+  Result:=Items[AIndex] as TUnitEntry;
+end;
+
+function TUnitEntries.IndexOfEntry(const AName: String): Integer;
+begin
+  Result:=Count-1;
+  While (Result>=0) and (CompareText(GetE(Result).Name,AName)<>0) do
+    Dec(Result);
+end;
+
+function TUnitEntries.FindEntry(const AName: string): TUnitEntry;
+
+Var
+  I:Integer;
+begin
+  I:=IndexofEntry(Aname);
+  If (I<>-1) then
+    Result:=GetE(I)
+  else
+    Result:=Nil;
+end;
+
+function TUnitEntries.AddEntry(Const AFileName: String): TUnitEntry;
+begin
+  Result:=Add as TunitEntry;
+  Result.FileName:=AFileName;
+end;
+
+{ TUnitEntry }
+
+function TUnitEntry.GetName: String;
+begin
+  Result:=ChangeFileExt(ExtractFileName(FileName),'');
+end;
+
+constructor TUnitEntry.Create(ACollection: TCollection);
+begin
+  inherited Create(ACollection);
+  FIntfDeps:=TStringList.Create;
+  FImplDeps:=TStringList.Create;
+end;
+
+destructor TUnitEntry.Destroy;
+begin
+  FreeAndNil(FIntfDeps);
+  FreeAndNil(FImplDeps);
+  inherited Destroy;
+end;
+
+procedure TUnitEntry.CleanIntfDependencies(Verbose : Boolean);
+
+Var
+  I,J : Integer;
+  U : TUnitEntry;
+
+begin
+  For I:=FintfDeps.Count-1 downto 0 do
+    begin
+    U:=FIntfDeps.Objects[i] as TUnitEntry;
+    J:=U.ImplDependencies.IndexOf(Name);
+    if J<>-1 then
+      begin
+      U.ImplDependencies.Delete(J);
+      If Verbose then
+        Writeln(StdErr,'Removing interdependency of ',Name,' from ',U.Name);
+      end;
+    end;
+
+end;
+
+procedure TUnitEntry.CleanImplDependencies(Verbose : Boolean);
+
+Var
+  I,J : Integer;
+  U : TUnitEntry;
+
+begin
+  For I:=FImplDeps.Count-1 downto 0 do
+    begin
+    U:=FImplDeps.Objects[i] as TUnitEntry;
+    J:=U.ImplDependencies.IndexOf(Name);
+    if J<>-1 then
+      begin
+      U.ImplDependencies.Delete(J);
+      If Verbose then
+        Writeln(StdErr,'Removing interdependency of ',Name,' from ',U.Name);
+      end;
+    end;
+end;
+
+procedure TUnitEntry.OrderDependencies(Order: TStrings);
+
+Var
+  L : TStringList;
+  I,CC : integer;
+
+begin
+  L:=TstringList.Create;
+  try
+    L.Assign(FintfDeps);
+    L.Sorted:=True;
+    CC:=L.Count;
+    FintfDeps.Clear;
+    For I:=0 to Order.Count-1 do
+      if L.Indexof(Order[i])<>-1 then
+        FIntfDeps.Add(Order[i]);
+    If FintfDeps.Count<>CC then
+      Writeln('Internal error 1');
+    L.Sorted:=False;
+    L.Assign(FimplDeps);
+    CC:=L.Count;
+    L.Sorted:=True;
+    FImplDeps.Clear;
+    For I:=0 to Order.Count-1 do
+      if L.Indexof(Order[i])<>-1 then
+        FImplDeps.Add(Order[i]);
+    If FImplDeps.Count<>CC then
+      Writeln('Internal error 2');
+  finally
+    L.free;
+  end;
+end;
+
+function TUnitEntry.Nodependencies: Boolean;
+begin
+  Result:=(FIntfDeps.Count=0) and (FImplDeps.Count=0);
+end;
+
+{ TPas2FPMakeApp }
+
+Function TPas2FPMakeApp.CheckParams : Boolean;
+
+  Procedure AddFileMask(S : String);
+
+  Var
+    Info : TSearchRec;
+    D : String;
+
+  begin
+    D:=ExtractFilePath(S);
+    If FindFirst(S,0,Info)=0 then
+      try
+        Repeat
+          FFiles.AddEntry(D+Info.Name);
+          FUnits.Add(ChangeFileExt(ExtractFileName(info.name),''));
+        until (FindNext(Info)<>0);
+      finally
+        FindClose(Info);
+      end;
+  end;
+
+Var
+  I : Integer;
+  S : String;
+
+begin
+  Result:=True;
+  I:=1;
+  While I<=ParamCount do
+    begin
+    S:=Paramstr(i);
+    if (S<>'') then
+      begin
+      if S[1]<>'-' then
+        begin
+        If (Pos('?',S)<>0) or (Pos('*',S)<>0) then
+          AddFileMask(S)
+        else if comparetext(ChangeFileExt(extractfilename(s),''),'fpmake')<>0 then
+          begin
+          FFiles.AddEntry(S);
+          FUnits.Add(ChangeFileExt(ExtractFileName(S),''));
+          end;
+        end
+      else
+        begin
+        If (s='o') then
+          begin
+          inc(I);
+          FoutputFile:=ParamStr(i);
+          end
+        else If (s='-i') then
+          InterfaceUnitsOnly:=True
+        else If (s='-v') then
+          FVerbose:=True
+        else if (s='-p') then
+          begin
+          Inc(i);
+          FPackageName:=ParamStr(i);
+          end
+        else
+          begin
+          Result:=False;
+          exit;
+          end;
+        end;
+      end;
+    Inc(i);
+    end;
+  Result:=(FFiles.Count>0);
+end;
+
+procedure TPas2FPMakeApp.AddLine(Const ALine : String);
+
+begin
+  FSrc.Add(ALine);
+end;
+
+Function TPas2FPMakeApp.GetUnitProps(Const FN : String; Out Res : Boolean; UIn,UIm : TStrings; Out Err : string) : Boolean;
+
+Var
+  I,J : Integer;
+  A : TPasSrcAnalysis;
+
+begin
+  Result:=False;
+  try
+    If FVerbose then
+      Writeln(StdErr,'Analysing unit ',FN);
+    A:=TPasSrcAnalysis.Create(Self);
+    try
+      A.FileName:=FN;
+      Res:=A.HasResourcestrings;
+        A.GetInterfaceUnits(Uin);
+      if Not InterfaceUnitsOnly then
+        A.GetImplementationUnits(Uim);
+      For I:=Uin.Count-1 downto 0 do
+        begin
+        J:=FUnits.IndexOf(UIN[i]);
+        if (j=-1) then
+          Uin.Delete(i)
+        else
+          Uin.Objects[i]:=FUnits.Objects[J];
+        end;
+      For I:=Uim.Count-1 downto 0 do
+        begin
+        J:=FUnits.IndexOf(UIm[i]);
+        if (j=-1) then
+          Uim.Delete(i)
+        else
+          Uim.Objects[i]:=FUnits.Objects[J];
+        end;
+    finally
+      A.Free;
+    end;
+    Result:=True;
+  except
+    On E : Exception do
+      Err:=E.Message;
+    // Ignore
+  end;
+
+end;
+
+procedure TPas2FPMakeApp.WriteProgStart;
+
+begin
+  AddLine('program fpmake;');
+  AddLine('');
+  AddLine('uses fpmkunit;');
+  AddLine('');
+  AddLine('Var');
+  AddLine('  T : TTarget;');
+  AddLine('  P : TPackage;');
+  AddLine('begin');
+  AddLine('  With Installer do');
+  AddLine('    begin');
+  AddLine('    P:=AddPackage('''+FPackageName+''');');
+  AddLine('    P.Version:=''0.0'';');
+//  AddLine('    P.Dependencies.Add('fcl-base');
+  AddLine('    P.Author := ''Your name'';');
+  AddLine('    P.License := ''LGPL with modification'';');
+  AddLine('    P.HomepageURL := ''www.yourcompany.com'';');
+  AddLine('    P.Email := ''[email protected]'';');
+  AddLine('    P.Description := ''Your very nice program'';');
+  AddLine('    // P.NeedLibC:= false;');
+end;
+
+procedure TPas2FPMakeApp.WriteProgEnd;
+
+begin
+  AddLine('    Run;');
+  AddLine('    end;');
+  AddLine('end.');
+end;
+
+procedure TPas2FPMakeApp.CreateSources;
+
+
+Var
+  I,j : Integer;
+  U : TStrings;
+  F : TUnitEntry;
+  FN : String;
+
+begin
+  WriteProgStart;
+  For I:=0 to FUnits.Count-1 do
+    begin
+    F:=FFiles.FindEntry(FUnits[i]);
+    FN:=F.FileName;
+    AddLine('    T:=P.Targets.AddUnit('''+FN+''');');
+    if F.Err<>'' then
+      AddLine('    // Failed to analyse unit "'+Fn+'". Error: "'+F.Err+'"')
+    else
+      begin
+      if F.Resources then
+        AddLine('    T.ResourceStrings := True;');
+      U:=TStringList.Create;
+      try
+        U.AddStrings(F.IntfDependencies);
+        U.AddStrings(F.ImplDependencies);
+        if (U.Count>0) then
+          begin
+          AddLine('    with T.Dependencies do');
+          AddLine('      begin');
+          For J:=0 to U.Count-1 do
+            AddLine('      AddUnit('''+U[j]+''');');
+          AddLine('      end;');
+          end;
+      finally
+        U.Free;
+      end;
+      end;
+    end;
+  WriteProgEnd;
+end;
+
+function TPas2FPMakeApp.SimulateCompile(E,EFrom: TUnitEntry): Boolean;
+
+Var
+  I : Integer;
+
+begin
+  Result:=True;
+  if E.Done then
+    begin
+    Result:=Not E.Processing;
+    if FVerbose then
+      if Not Result then
+        Writeln(StdErr,'Detected circular reference ',E.Name,' coming from ',EFrom.Name)
+      else if Assigned(EFrom) then
+        Writeln(StdErr,'Attempt to recompile ',E.Name,' coming from ',EFrom.Name)
+      else
+        Writeln(StdErr,'Attempt to recompile ',E.Name);
+    exit;
+    end;
+  E.Done:=True;
+  E.Processing:=True;
+  For I:=0 to E.IntfDependencies.Count-1 do
+    SimulateCompile(E.IntfDependencies.Objects[I] as TUnitEntry,E);
+  For I:=0 to E.ImplDependencies.Count-1 do
+    SimulateCompile(E.ImplDependencies.Objects[I] as TUnitEntry,E);
+  E.Processing:=False;
+  FUnits.Add(E.Name);
+end;
+
+procedure TPas2FPMakeApp.ProcessUnits;
+
+Var
+  I,J,k : integer;
+  Err : String;
+  F : TUnitEntry;
+  R : Boolean;
+
+begin
+  For I:=0 to Funits.Count-1 do
+    begin
+    J:=FFiles.IndexOfEntry(FUnits[i]);
+    Funits.Objects[i]:=FFiles[J];
+    end;
+  TStringList(FUnits).Sorted:=True;
+  For I:=0 to FFiles.Count-1 do
+    begin
+    F:=FFiles[i];
+    if not GetUnitProps(F.FileName,R,F.IntfDependencies,F.ImplDependencies,Err) then
+      F.Err:=Err
+    else
+      F.Resources:=R;
+    end;
+  For I:=0 to FFiles.Count-1 do
+    FFiles[i].CleanIntfDependencies(FVerbose);
+  For I:=0 to FFiles.Count-1 do
+    FFiles[i].CleanImplDependencies(FVerbose);
+  TStringList(FUnits).Sorted:=False;
+  FUnits.Clear;
+  For I:=0 to FFiles.Count-1 do
+    if FFiles[i].NoDependencies then
+      begin
+      FUnits.Add(FFiles[i].Name);
+      FFiles[i].Done:=True;
+      end;
+  For I:=0 to FFiles.Count-1 do
+    SimulateCompile(FFiles[i],Nil);
+  // At this point, FUnits is in the order that the compiler should compile them.
+   //  Now we order the dependencies.
+   For I:=0 to FFiles.Count-1 do
+     FFiles[i].OrderDependencies(FUnits);
+end;
+
+procedure TPas2FPMakeApp.WriteSources;
+
+Var
+  F : Text;
+
+begin
+  AssignFile(F,FOutputFile);
+  Rewrite(F);
+  try
+    Write(F,FSrc.Text);
+  finally
+    CloseFile(F);
+  end;
+end;
+
+procedure TPas2FPMakeApp.DoRun;
+
+var
+  ErrorMsg: String;
+
+begin
+  // parse parameters
+  if HasOption('h','help') or Not CheckParams then
+    begin
+    WriteHelp;
+    Terminate;
+    exit;
+    end;
+  ProcessUnits;
+  CreateSources;
+  WriteSources;
+  // stop program loop
+  Terminate;
+end;
+
+constructor TPas2FPMakeApp.Create(TheOwner: TComponent);
+begin
+  inherited Create(TheOwner);
+  StopOnException:=True;
+  FFiles:=TUnitEntries.Create(TUnitEntry);
+  FSrc:=TStringList.Create;
+  FUnits:=TStringList.Create;
+  FPackageName:='Your package name here';
+end;
+
+destructor TPas2FPMakeApp.Destroy;
+begin
+  FreeAndNil(FFiles);
+  FreeAndNil(FSrc);
+  FreeAndNil(FUnits);
+  inherited Destroy;
+end;
+
+procedure TPas2FPMakeApp.WriteHelp;
+begin
+  { add your help code here }
+  writeln('Usage: ',ExeName,' [options] file1 .. filen');
+  Writeln('Where [options] is one or more of');
+  Writeln(' -h               This help');
+  Writeln(' -p packagename   Set package name');
+  Writeln(' -i               Use interface units only for checking dependencies');
+  Writeln(' -o outputfile    Set output filename (default is standard output)');
+  Writeln(' -v               Write diagnostic output to stderr');
+end;
+
+var
+  Application: TPas2FPMakeApp;
+begin
+  Application:=TPas2FPMakeApp.Create(nil);
+  Application.Title:='Pascal to FPMake application';
+  Application.Run;
+  Application.Free;
+end.
+

+ 2974 - 0
utils/pas2ut/Makefile

@@ -0,0 +1,2974 @@
+#
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2012/08/21]
+#
+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 powerpc-aix 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 powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux jvm-java jvm-android
+BSDs = freebsd netbsd openbsd darwin
+UNIXs = linux $(BSDs) solaris qnx haiku aix
+LIMIT83fs = go32v2 os2 emx watcom
+OSNeedsComspecToRunBatch = go32v2 watcom
+FORCE:
+.PHONY: FORCE
+override PATH:=$(patsubst %/,%,$(subst \,/,$(PATH)))
+ifneq ($(findstring darwin,$(OSTYPE)),)
+inUnix=1 #darwin
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+ifeq ($(findstring ;,$(PATH)),)
+inUnix=1
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+SEARCHPATH:=$(subst ;, ,$(PATH))
+endif
+endif
+SEARCHPATH+=$(patsubst %/,%,$(subst \,/,$(dir $(MAKE))))
+PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
+ifeq ($(PWD),)
+PWD:=$(strip $(wildcard $(addsuffix /pwd,$(SEARCHPATH))))
+ifeq ($(PWD),)
+$(error You need the GNU utils package to use this Makefile)
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=
+endif
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=.exe
+endif
+ifndef inUnix
+ifeq ($(OS),Windows_NT)
+inWinNT=1
+else
+ifdef OS2_SHELL
+inOS2=1
+endif
+endif
+else
+ifneq ($(findstring cygdrive,$(PATH)),)
+inCygWin=1
+endif
+endif
+ifdef inUnix
+SRCBATCHEXT=.sh
+else
+ifdef inOS2
+SRCBATCHEXT=.cmd
+else
+SRCBATCHEXT=.bat
+endif
+endif
+ifdef COMSPEC
+ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
+ifndef RUNBATCH
+RUNBATCH=$(COMSPEC) /C
+endif
+endif
+endif
+ifdef inUnix
+PATHSEP=/
+else
+PATHSEP:=$(subst /,\,/)
+ifdef inCygWin
+PATHSEP=/
+endif
+endif
+ifdef PWD
+BASEDIR:=$(subst \,/,$(shell $(PWD)))
+ifdef inCygWin
+ifneq ($(findstring /cygdrive/,$(BASEDIR)),)
+BASENODIR:=$(patsubst /cygdrive%,%,$(BASEDIR))
+BASEDRIVE:=$(firstword $(subst /, ,$(BASENODIR)))
+BASEDIR:=$(subst /cygdrive/$(BASEDRIVE)/,$(BASEDRIVE):/,$(BASEDIR))
+endif
+endif
+else
+BASEDIR=.
+endif
+ifdef inOS2
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO=echo
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+endif
+override DEFAULT_FPCDIR=../..
+ifndef FPC
+ifdef PP
+FPC=$(PP)
+endif
+endif
+ifndef FPC
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+ifneq ($(CPU_TARGET),)
+FPC:=$(shell $(FPCPROG) -P$(CPU_TARGET) -PB)
+else
+FPC:=$(shell $(FPCPROG) -PB)
+endif
+ifneq ($(findstring Error,$(FPC)),)
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+else
+ifeq ($(strip $(wildcard $(FPC))),)
+FPC:=$(firstword $(FPCPROG))
+endif
+endif
+else
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+endif
+override FPC:=$(subst $(SRCEXEEXT),,$(FPC))
+override FPC:=$(subst \,/,$(FPC))$(SRCEXEEXT)
+FOUNDFPC:=$(strip $(wildcard $(FPC)))
+ifeq ($(FOUNDFPC),)
+FOUNDFPC=$(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))
+ifeq ($(FOUNDFPC),)
+$(error Compiler $(FPC) not found)
+endif
+endif
+ifndef FPC_COMPILERINFO
+FPC_COMPILERINFO:=$(shell $(FPC) -iVSPTPSOTO)
+endif
+ifndef FPC_VERSION
+FPC_VERSION:=$(word 1,$(FPC_COMPILERINFO))
+endif
+export FPC FPC_VERSION FPC_COMPILERINFO
+unexport CHECKDEPEND ALLDEPENDENCIES
+ifndef CPU_TARGET
+ifdef CPU_TARGET_DEFAULT
+CPU_TARGET=$(CPU_TARGET_DEFAULT)
+endif
+endif
+ifndef OS_TARGET
+ifdef OS_TARGET_DEFAULT
+OS_TARGET=$(OS_TARGET_DEFAULT)
+endif
+endif
+ifndef CPU_SOURCE
+CPU_SOURCE:=$(word 2,$(FPC_COMPILERINFO))
+endif
+ifndef CPU_TARGET
+CPU_TARGET:=$(word 3,$(FPC_COMPILERINFO))
+endif
+ifndef OS_SOURCE
+OS_SOURCE:=$(word 4,$(FPC_COMPILERINFO))
+endif
+ifndef OS_TARGET
+OS_TARGET:=$(word 5,$(FPC_COMPILERINFO))
+endif
+FULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+FULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifeq ($(CPU_TARGET),armeb)
+ARCH=arm
+override FPCOPT+=-Cb
+else
+ifeq ($(CPU_TARGET),armel)
+ARCH=arm
+override FPCOPT+=-CaEABI
+else
+ARCH=$(CPU_TARGET)
+endif
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+ifeq ($(SUBARCH),)
+$(error When compiling for arm-embedded, a sub-architecture (e.g. SUBARCH=armv4t or SUBARCH=armv7m) must be defined)
+endif
+override FPCOPT+=-Cp$(SUBARCH)
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+SOURCESUFFIX=$(OS_SOURCE)
+else
+ifneq ($(findstring $(OS_TARGET),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+else
+TARGETSUFFIX=$(FULL_TARGET)
+endif
+SOURCESUFFIX=$(FULL_SOURCE)
+endif
+ifneq ($(FULL_TARGET),$(FULL_SOURCE))
+CROSSCOMPILE=1
+endif
+ifeq ($(findstring makefile,$(MAKECMDGOALS)),)
+ifeq ($(findstring $(FULL_TARGET),$(MAKEFILETARGETS)),)
+$(error The Makefile doesn't support target $(FULL_TARGET), please run fpcmake first)
+endif
+endif
+ifneq ($(findstring $(OS_TARGET),$(BSDs)),)
+BSDhier=1
+endif
+ifeq ($(OS_TARGET),linux)
+linuxHier=1
+endif
+export OS_TARGET OS_SOURCE ARCH CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
+ifdef FPCDIR
+override FPCDIR:=$(subst \,/,$(FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+else
+override FPCDIR=wrong
+endif
+ifdef DEFAULT_FPCDIR
+ifeq ($(FPCDIR),wrong)
+override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+endif
+endif
+ifeq ($(FPCDIR),wrong)
+ifdef inUnix
+override FPCDIR=/usr/local/lib/fpc/$(FPC_VERSION)
+ifeq ($(wildcard $(FPCDIR)/units),)
+override FPCDIR=/usr/lib/fpc/$(FPC_VERSION)
+endif
+else
+override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(BASEDIR)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=c:/pp
+endif
+endif
+endif
+endif
+endif
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(FPCDIR)/bin/$(TARGETSUFFIX))
+endif
+ifneq ($(findstring $(OS_TARGET),darwin iphonesim),)
+ifeq ($(OS_SOURCE),darwin)
+DARWIN2DARWIN=1
+endif
+endif
+ifndef BINUTILSPREFIX
+ifndef CROSSBINDIR
+ifdef CROSSCOMPILE
+ifndef DARWIN2DARWIN
+ifneq ($(CPU_TARGET),jvm)
+BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+endif
+endif
+endif
+endif
+endif
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
+ifeq ($(UNITSDIR),)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+endif
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
+ifndef FPCFPMAKE
+ifdef CROSSCOMPILE
+ifeq ($(strip $(wildcard $(addsuffix /compiler/ppc$(SRCEXEEXT),$(FPCDIR)))),)
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+FPCFPMAKE:=$(shell $(FPCPROG) -PB)
+ifeq ($(strip $(wildcard $(FPCFPMAKE))),)
+FPCFPMAKE:=$(firstword $(FPCPROG))
+endif
+else
+override FPCFPMAKE=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+else
+FPCFPMAKE=$(strip $(wildcard $(addsuffix /compiler/ppc$(SRCEXEEXT),$(FPCDIR))))
+FPMAKE_SKIP_CONFIG=-n
+export FPCFPMAKE
+export FPMAKE_SKIP_CONFIG
+endif
+else
+FPMAKE_SKIP_CONFIG=-n
+FPCFPMAKE=$(FPC)
+endif
+endif
+override PACKAGE_NAME=pas2ut
+override PACKAGE_VERSION=2.7.1
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-nativent)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),i386-iphonesim)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc-wii)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc-aix)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),x86_64-solaris)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),powerpc64-aix)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),mips-linux)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),mipsel-linux)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),jvm-java)
+override TARGET_PROGRAMS+=pas2ut
+endif
+ifeq ($(FULL_TARGET),jvm-android)
+override TARGET_PROGRAMS+=pas2ut
+endif
+override INSTALL_FPCPACKAGE=y
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-nativent)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),i386-iphonesim)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-wii)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc-aix)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-solaris)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),powerpc64-aix)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),mips-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),mipsel-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),jvm-java)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),jvm-android)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifdef REQUIRE_UNITSDIR
+override UNITSDIR+=$(REQUIRE_UNITSDIR)
+endif
+ifdef REQUIRE_PACKAGESDIR
+override PACKAGESDIR+=$(REQUIRE_PACKAGESDIR)
+endif
+ifdef ZIPINSTALL
+ifneq ($(findstring $(OS_TARGET),$(UNIXs)),)
+UNIXHier=1
+endif
+else
+ifneq ($(findstring $(OS_SOURCE),$(UNIXs)),)
+UNIXHier=1
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef PREFIX
+INSTALL_PREFIX=$(PREFIX)
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef UNIXHier
+INSTALL_PREFIX=/usr/local
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=/pp
+else
+INSTALL_BASEDIR:=/$(PACKAGE_NAME)
+endif
+endif
+endif
+export INSTALL_PREFIX
+ifdef INSTALL_FPCSUBDIR
+export INSTALL_FPCSUBDIR
+endif
+ifndef DIST_DESTDIR
+DIST_DESTDIR:=$(BASEDIR)
+endif
+export DIST_DESTDIR
+ifndef COMPILER_UNITTARGETDIR
+ifdef PACKAGEDIR_MAIN
+COMPILER_UNITTARGETDIR=$(PACKAGEDIR_MAIN)/units/$(TARGETSUFFIX)
+else
+COMPILER_UNITTARGETDIR=units/$(TARGETSUFFIX)
+endif
+endif
+ifndef COMPILER_TARGETDIR
+COMPILER_TARGETDIR=.
+endif
+ifndef INSTALL_BASEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION)
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/$(PACKAGE_NAME)
+endif
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)
+endif
+endif
+ifndef INSTALL_BINDIR
+ifdef UNIXHier
+INSTALL_BINDIR:=$(INSTALL_PREFIX)/bin
+else
+INSTALL_BINDIR:=$(INSTALL_BASEDIR)/bin
+ifdef INSTALL_FPCPACKAGE
+ifdef CROSSCOMPILE
+ifdef CROSSINSTALL
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(SOURCESUFFIX)
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+endif
+endif
+endif
+ifndef INSTALL_UNITDIR
+INSTALL_UNITDIR:=$(INSTALL_BASEDIR)/units/$(TARGETSUFFIX)
+ifdef INSTALL_FPCPACKAGE
+ifdef PACKAGE_NAME
+INSTALL_UNITDIR:=$(INSTALL_UNITDIR)/$(PACKAGE_NAME)
+endif
+endif
+endif
+ifndef INSTALL_LIBDIR
+ifdef UNIXHier
+INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib
+else
+INSTALL_LIBDIR:=$(INSTALL_UNITDIR)
+endif
+endif
+ifndef INSTALL_SOURCEDIR
+ifdef UNIXHier
+ifdef BSDhier
+SRCPREFIXDIR=share/src
+else
+ifdef linuxHier
+SRCPREFIXDIR=share/src
+else
+SRCPREFIXDIR=src
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source
+endif
+endif
+endif
+ifndef INSTALL_DOCDIR
+ifdef UNIXHier
+ifdef BSDhier
+DOCPREFIXDIR=share/doc
+else
+ifdef linuxHier
+DOCPREFIXDIR=share/doc
+else
+DOCPREFIXDIR=doc
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc
+endif
+endif
+endif
+ifndef INSTALL_EXAMPLEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/fpc-$(FPC_VERSION)/examples/$(PACKAGE_NAME)
+endif
+endif
+else
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+endif
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples/$(PACKAGE_NAME)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples
+endif
+endif
+endif
+ifndef INSTALL_DATADIR
+INSTALL_DATADIR=$(INSTALL_BASEDIR)
+endif
+ifndef INSTALL_SHAREDDIR
+INSTALL_SHAREDDIR=$(INSTALL_PREFIX)/lib
+endif
+ifdef CROSSCOMPILE
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(CROSSTARGETDIR)/bin/$(SOURCESUFFIX))
+ifeq ($(CROSSBINDIR),)
+CROSSBINDIR:=$(wildcard $(INSTALL_BASEDIR)/cross/$(TARGETSUFFIX)/bin/$(FULL_SOURCE))
+endif
+endif
+else
+CROSSBINDIR=
+endif
+BATCHEXT=.bat
+LOADEREXT=.as
+EXEEXT=.exe
+PPLEXT=.ppl
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.so
+SHAREDLIBPREFIX=libfp
+STATICLIBPREFIX=libp
+IMPORTLIBPREFIX=libimp
+RSTEXT=.rst
+EXEDBGEXT=.dbg
+ifeq ($(OS_TARGET),go32v1)
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+OEXT=.obj
+ASMEXT=.asm
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=wat
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),emx)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=emx
+ECHO=echo
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),morphos)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=mos
+endif
+ifeq ($(OS_TARGET),atari)
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),haiku)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=hai
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nw
+IMPORTLIBPREFIX=imp
+endif
+ifeq ($(OS_TARGET),netwlibc)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nwl
+IMPORTLIBPREFIX=imp
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+IMPORTLIBPREFIX=imp
+endif
+ifneq ($(findstring $(OS_TARGET),darwin iphonesim),)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=dwn
+EXEDBGEXT=.dSYM
+endif
+ifeq ($(OS_TARGET),gba)
+EXEEXT=.gba
+SHAREDLIBEXT=.so
+SHORTSUFFIX=gba
+endif
+ifeq ($(OS_TARGET),symbian)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=symbian
+endif
+ifeq ($(OS_TARGET),NativeNT)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=nativent
+endif
+ifeq ($(OS_TARGET),wii)
+EXEEXT=.dol
+SHAREDLIBEXT=.so
+SHORTSUFFIX=wii
+endif
+ifeq ($(OS_TARGET),aix)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=aix
+endif
+ifeq ($(OS_TARGET),java)
+OEXT=.class
+ASMEXT=.j
+SHAREDLIBEXT=.jar
+SHORTSUFFIX=java
+endif
+ifeq ($(OS_TARGET),android)
+OEXT=.class
+ASMEXT=.j
+SHAREDLIBEXT=.jar
+SHORTSUFFIX=android
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+FPCMADE=fpcmade.$(SHORTSUFFIX)
+ZIPSUFFIX=$(SHORTSUFFIX)
+ZIPCROSSPREFIX=
+ZIPSOURCESUFFIX=src
+ZIPEXAMPLESUFFIX=exm
+else
+FPCMADE=fpcmade.$(TARGETSUFFIX)
+ZIPSOURCESUFFIX=.source
+ZIPEXAMPLESUFFIX=.examples
+ifdef CROSSCOMPILE
+ZIPSUFFIX=.$(SOURCESUFFIX)
+ZIPCROSSPREFIX=$(TARGETSUFFIX)-
+else
+ZIPSUFFIX=.$(TARGETSUFFIX)
+ZIPCROSSPREFIX=
+endif
+endif
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO= __missing_command_ECHO
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+ifndef DATE
+DATE:=$(strip $(wildcard $(addsuffix /gdate$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE:=$(strip $(wildcard $(addsuffix /date$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE= __missing_command_DATE
+else
+DATE:=$(firstword $(DATE))
+endif
+else
+DATE:=$(firstword $(DATE))
+endif
+endif
+export DATE
+ifndef GINSTALL
+GINSTALL:=$(strip $(wildcard $(addsuffix /ginstall$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL:=$(strip $(wildcard $(addsuffix /install$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL= __missing_command_GINSTALL
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+endif
+export GINSTALL
+ifndef CPPROG
+CPPROG:=$(strip $(wildcard $(addsuffix /cp$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(CPPROG),)
+CPPROG= __missing_command_CPPROG
+else
+CPPROG:=$(firstword $(CPPROG))
+endif
+endif
+export CPPROG
+ifndef RMPROG
+RMPROG:=$(strip $(wildcard $(addsuffix /rm$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(RMPROG),)
+RMPROG= __missing_command_RMPROG
+else
+RMPROG:=$(firstword $(RMPROG))
+endif
+endif
+export RMPROG
+ifndef MVPROG
+MVPROG:=$(strip $(wildcard $(addsuffix /mv$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MVPROG),)
+MVPROG= __missing_command_MVPROG
+else
+MVPROG:=$(firstword $(MVPROG))
+endif
+endif
+export MVPROG
+ifndef MKDIRPROG
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /gmkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /mkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG= __missing_command_MKDIRPROG
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+endif
+export MKDIRPROG
+ifndef ECHOREDIR
+ifndef inUnix
+ECHOREDIR=echo
+else
+ECHOREDIR=$(ECHO)
+endif
+endif
+ifndef COPY
+COPY:=$(CPPROG) -fp
+endif
+ifndef COPYTREE
+COPYTREE:=$(CPPROG) -Rfp
+endif
+ifndef MKDIRTREE
+MKDIRTREE:=$(MKDIRPROG) -p
+endif
+ifndef MOVE
+MOVE:=$(MVPROG) -f
+endif
+ifndef DEL
+DEL:=$(RMPROG) -f
+endif
+ifndef DELTREE
+DELTREE:=$(RMPROG) -rf
+endif
+ifndef INSTALL
+ifdef inUnix
+INSTALL:=$(GINSTALL) -c -m 644
+else
+INSTALL:=$(COPY)
+endif
+endif
+ifndef INSTALLEXE
+ifdef inUnix
+INSTALLEXE:=$(GINSTALL) -c -m 755
+else
+INSTALLEXE:=$(COPY)
+endif
+endif
+ifndef MKDIR
+MKDIR:=$(GINSTALL) -m 755 -d
+endif
+export ECHOREDIR COPY COPYTREE MOVE DEL DELTREE INSTALL INSTALLEXE MKDIR
+ifndef PPUMOVE
+PPUMOVE:=$(strip $(wildcard $(addsuffix /ppumove$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUMOVE),)
+PPUMOVE= __missing_command_PPUMOVE
+else
+PPUMOVE:=$(firstword $(PPUMOVE))
+endif
+endif
+export PPUMOVE
+ifndef FPCMAKE
+FPCMAKE:=$(strip $(wildcard $(addsuffix /fpcmake$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(FPCMAKE),)
+FPCMAKE= __missing_command_FPCMAKE
+else
+FPCMAKE:=$(firstword $(FPCMAKE))
+endif
+endif
+export FPCMAKE
+ifndef ZIPPROG
+ZIPPROG:=$(strip $(wildcard $(addsuffix /zip$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ZIPPROG),)
+ZIPPROG= __missing_command_ZIPPROG
+else
+ZIPPROG:=$(firstword $(ZIPPROG))
+endif
+endif
+export ZIPPROG
+ifndef TARPROG
+TARPROG:=$(strip $(wildcard $(addsuffix /gtar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG= __missing_command_TARPROG
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+endif
+export TARPROG
+ASNAME=$(BINUTILSPREFIX)as
+LDNAME=$(BINUTILSPREFIX)ld
+ARNAME=$(BINUTILSPREFIX)ar
+RCNAME=$(BINUTILSPREFIX)rc
+ifndef ASPROG
+ifdef CROSSBINDIR
+ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
+else
+ASPROG=$(ASNAME)
+endif
+endif
+ifndef LDPROG
+ifdef CROSSBINDIR
+LDPROG=$(CROSSBINDIR)/$(LDNAME)$(SRCEXEEXT)
+else
+LDPROG=$(LDNAME)
+endif
+endif
+ifndef RCPROG
+ifdef CROSSBINDIR
+RCPROG=$(CROSSBINDIR)/$(RCNAME)$(SRCEXEEXT)
+else
+RCPROG=$(RCNAME)
+endif
+endif
+ifndef ARPROG
+ifdef CROSSBINDIR
+ARPROG=$(CROSSBINDIR)/$(ARNAME)$(SRCEXEEXT)
+else
+ARPROG=$(ARNAME)
+endif
+endif
+AS=$(ASPROG)
+LD=$(LDPROG)
+RC=$(RCPROG)
+AR=$(ARPROG)
+PPAS=ppas$(SRCBATCHEXT)
+ifdef inUnix
+LDCONFIG=ldconfig
+else
+LDCONFIG=
+endif
+ifdef DATE
+DATESTR:=$(shell $(DATE) +%Y%m%d)
+else
+DATESTR=
+endif
+ZIPOPT=-9
+ZIPEXT=.zip
+ifeq ($(USETAR),bz2)
+TAROPT=vj
+TAREXT=.tar.bz2
+else
+TAROPT=vz
+TAREXT=.tar.gz
+endif
+override REQUIRE_PACKAGES=rtl fcl-passrc fcl-base
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-nativent)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),i386-iphonesim)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-wii)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-aix)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_UNIVINT=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-aix)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),mips-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),mipsel-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),jvm-java)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(FULL_TARGET),jvm-android)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifdef REQUIRE_PACKAGES_RTL
+PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_RTL),)
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)),)
+UNITDIR_RTL=$(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)
+else
+UNITDIR_RTL=$(PACKAGEDIR_RTL)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_RTL=$(PACKAGEDIR_RTL)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_RTL=$(PACKAGEDIR_RTL)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_RTL=$(PACKAGEDIR_RTL)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_RTL)/$(OS_TARGET)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_RTL)/$(OS_TARGET) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(OS_TARGET)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_RTL=
+UNITDIR_RTL:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /rtl/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_RTL),)
+UNITDIR_RTL:=$(firstword $(UNITDIR_RTL))
+else
+UNITDIR_RTL=
+endif
+endif
+ifdef UNITDIR_RTL
+override COMPILER_UNITDIR+=$(UNITDIR_RTL)
+endif
+ifdef UNITDIR_FPMAKE_RTL
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_RTL)
+endif
+endif
+ifdef REQUIRE_PACKAGES_PASZLIB
+PACKAGEDIR_PASZLIB:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /paszlib/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_PASZLIB),)
+ifneq ($(wildcard $(PACKAGEDIR_PASZLIB)/units/$(TARGETSUFFIX)),)
+UNITDIR_PASZLIB=$(PACKAGEDIR_PASZLIB)/units/$(TARGETSUFFIX)
+else
+UNITDIR_PASZLIB=$(PACKAGEDIR_PASZLIB)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_PASZLIB)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_PASZLIB=$(PACKAGEDIR_PASZLIB)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_PASZLIB)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_PASZLIB=$(PACKAGEDIR_PASZLIB)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_PASZLIB=$(PACKAGEDIR_PASZLIB)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_PASZLIB)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_PASZLIB) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_PASZLIB)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_PASZLIB=
+UNITDIR_PASZLIB:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /paszlib/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_PASZLIB),)
+UNITDIR_PASZLIB:=$(firstword $(UNITDIR_PASZLIB))
+else
+UNITDIR_PASZLIB=
+endif
+endif
+ifdef UNITDIR_PASZLIB
+override COMPILER_UNITDIR+=$(UNITDIR_PASZLIB)
+endif
+ifdef UNITDIR_FPMAKE_PASZLIB
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_PASZLIB)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FCL-PROCESS
+PACKAGEDIR_FCL-PROCESS:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-process/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-PROCESS),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PROCESS)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PROCESS)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PROCESS)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_FCL-PROCESS=$(PACKAGEDIR_FCL-PROCESS)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-PROCESS)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-PROCESS) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-PROCESS)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-PROCESS=
+UNITDIR_FCL-PROCESS:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-process/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-PROCESS),)
+UNITDIR_FCL-PROCESS:=$(firstword $(UNITDIR_FCL-PROCESS))
+else
+UNITDIR_FCL-PROCESS=
+endif
+endif
+ifdef UNITDIR_FCL-PROCESS
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-PROCESS)
+endif
+ifdef UNITDIR_FPMAKE_FCL-PROCESS
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FCL-PROCESS)
+endif
+endif
+ifdef REQUIRE_PACKAGES_HASH
+PACKAGEDIR_HASH:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /hash/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_HASH),)
+ifneq ($(wildcard $(PACKAGEDIR_HASH)/units/$(TARGETSUFFIX)),)
+UNITDIR_HASH=$(PACKAGEDIR_HASH)/units/$(TARGETSUFFIX)
+else
+UNITDIR_HASH=$(PACKAGEDIR_HASH)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_HASH)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_HASH=$(PACKAGEDIR_HASH)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_HASH)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_HASH=$(PACKAGEDIR_HASH)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_HASH=$(PACKAGEDIR_HASH)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_HASH)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_HASH) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_HASH)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_HASH=
+UNITDIR_HASH:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /hash/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_HASH),)
+UNITDIR_HASH:=$(firstword $(UNITDIR_HASH))
+else
+UNITDIR_HASH=
+endif
+endif
+ifdef UNITDIR_HASH
+override COMPILER_UNITDIR+=$(UNITDIR_HASH)
+endif
+ifdef UNITDIR_FPMAKE_HASH
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_HASH)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FPMKUNIT
+PACKAGEDIR_FPMKUNIT:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fpmkunit/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FPMKUNIT),)
+ifneq ($(wildcard $(PACKAGEDIR_FPMKUNIT)/units/$(TARGETSUFFIX)),)
+UNITDIR_FPMKUNIT=$(PACKAGEDIR_FPMKUNIT)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FPMKUNIT=$(PACKAGEDIR_FPMKUNIT)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_FPMKUNIT)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FPMKUNIT=$(PACKAGEDIR_FPMKUNIT)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_FPMKUNIT)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FPMKUNIT=$(PACKAGEDIR_FPMKUNIT)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_FPMKUNIT=$(PACKAGEDIR_FPMKUNIT)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FPMKUNIT)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FPMKUNIT) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FPMKUNIT)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FPMKUNIT=
+UNITDIR_FPMKUNIT:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fpmkunit/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FPMKUNIT),)
+UNITDIR_FPMKUNIT:=$(firstword $(UNITDIR_FPMKUNIT))
+else
+UNITDIR_FPMKUNIT=
+endif
+endif
+ifdef UNITDIR_FPMKUNIT
+override COMPILER_UNITDIR+=$(UNITDIR_FPMKUNIT)
+endif
+ifdef UNITDIR_FPMAKE_FPMKUNIT
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FPMKUNIT)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FCL-PASSRC
+PACKAGEDIR_FCL-PASSRC:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-passrc/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-PASSRC),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PASSRC)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-PASSRC=$(PACKAGEDIR_FCL-PASSRC)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-PASSRC=$(PACKAGEDIR_FCL-PASSRC)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PASSRC)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-PASSRC=$(PACKAGEDIR_FCL-PASSRC)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_FCL-PASSRC)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-PASSRC=$(PACKAGEDIR_FCL-PASSRC)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_FCL-PASSRC=$(PACKAGEDIR_FCL-PASSRC)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-PASSRC)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-PASSRC) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-PASSRC)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-PASSRC=
+UNITDIR_FCL-PASSRC:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-passrc/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-PASSRC),)
+UNITDIR_FCL-PASSRC:=$(firstword $(UNITDIR_FCL-PASSRC))
+else
+UNITDIR_FCL-PASSRC=
+endif
+endif
+ifdef UNITDIR_FCL-PASSRC
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-PASSRC)
+endif
+ifdef UNITDIR_FPMAKE_FCL-PASSRC
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FCL-PASSRC)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FCL-BASE
+PACKAGEDIR_FCL-BASE:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-base/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-BASE),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-BASE)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-BASE=$(PACKAGEDIR_FCL-BASE)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-BASE=$(PACKAGEDIR_FCL-BASE)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_FCL-BASE)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-BASE=$(PACKAGEDIR_FCL-BASE)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_FCL-BASE)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_FCL-BASE=$(PACKAGEDIR_FCL-BASE)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_FCL-BASE=$(PACKAGEDIR_FCL-BASE)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-BASE)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-BASE) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-BASE)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-BASE=
+UNITDIR_FCL-BASE:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-base/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-BASE),)
+UNITDIR_FCL-BASE:=$(firstword $(UNITDIR_FCL-BASE))
+else
+UNITDIR_FCL-BASE=
+endif
+endif
+ifdef UNITDIR_FCL-BASE
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-BASE)
+endif
+ifdef UNITDIR_FPMAKE_FCL-BASE
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FCL-BASE)
+endif
+endif
+ifdef REQUIRE_PACKAGES_UNIVINT
+PACKAGEDIR_UNIVINT:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /univint/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_UNIVINT),)
+ifneq ($(wildcard $(PACKAGEDIR_UNIVINT)/units/$(TARGETSUFFIX)),)
+UNITDIR_UNIVINT=$(PACKAGEDIR_UNIVINT)/units/$(TARGETSUFFIX)
+else
+UNITDIR_UNIVINT=$(PACKAGEDIR_UNIVINT)
+endif
+ifneq ($(wildcard $(PACKAGEDIR_UNIVINT)/units/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_UNIVINT=$(PACKAGEDIR_UNIVINT)/units/$(SOURCESUFFIX)
+else
+ifneq ($(wildcard $(PACKAGEDIR_UNIVINT)/units_bs/$(SOURCESUFFIX)),)
+UNITDIR_FPMAKE_UNIVINT=$(PACKAGEDIR_UNIVINT)/units_bs/$(SOURCESUFFIX)
+else
+UNITDIR_FPMAKE_UNIVINT=$(PACKAGEDIR_UNIVINT)
+endif
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_UNIVINT)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_UNIVINT) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_UNIVINT)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_UNIVINT=
+UNITDIR_UNIVINT:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /univint/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_UNIVINT),)
+UNITDIR_UNIVINT:=$(firstword $(UNITDIR_UNIVINT))
+else
+UNITDIR_UNIVINT=
+endif
+endif
+ifdef UNITDIR_UNIVINT
+override COMPILER_UNITDIR+=$(UNITDIR_UNIVINT)
+endif
+ifdef UNITDIR_FPMAKE_UNIVINT
+override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_UNIVINT)
+endif
+endif
+ifndef NOCPUDEF
+override FPCOPTDEF=$(ARCH)
+endif
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifneq ($(CPU_TARGET),$(CPU_SOURCE))
+override FPCOPT+=-P$(ARCH)
+endif
+ifeq ($(OS_SOURCE),openbsd)
+override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
+override FPCMAKEOPT+=-FD$(NEW_BINUTILS_PATH)
+endif
+ifndef CROSSBOOTSTRAP
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-XP$(BINUTILSPREFIX)
+endif
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-Xr$(RLINKPATH)
+endif
+endif
+ifndef CROSSCOMPILE
+ifneq ($(BINUTILSPREFIX),)
+override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
+endif
+endif
+ifdef UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(UNITDIR))
+endif
+ifdef LIBDIR
+override FPCOPT+=$(addprefix -Fl,$(LIBDIR))
+endif
+ifdef OBJDIR
+override FPCOPT+=$(addprefix -Fo,$(OBJDIR))
+endif
+ifdef INCDIR
+override FPCOPT+=$(addprefix -Fi,$(INCDIR))
+endif
+ifdef LINKSMART
+override FPCOPT+=-XX
+endif
+ifdef CREATESMART
+override FPCOPT+=-CX
+endif
+ifdef DEBUG
+override FPCOPT+=-gl
+override FPCOPTDEF+=DEBUG
+endif
+ifdef RELEASE
+ifneq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(CPU_TARGET),i386)
+FPCCPUOPT:=-OG2p3
+endif
+ifeq ($(CPU_TARGET),powerpc)
+FPCCPUOPT:=-O1r
+endif
+else
+FPCCPUOPT:=-O2
+endif
+override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n
+override FPCOPTDEF+=RELEASE
+endif
+ifdef STRIP
+override FPCOPT+=-Xs
+endif
+ifdef OPTIMIZE
+override FPCOPT+=-O2
+endif
+ifdef VERBOSE
+override FPCOPT+=-vwni
+endif
+ifdef COMPILER_OPTIONS
+override FPCOPT+=$(COMPILER_OPTIONS)
+endif
+ifdef COMPILER_UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))
+endif
+ifdef COMPILER_LIBRARYDIR
+override FPCOPT+=$(addprefix -Fl,$(COMPILER_LIBRARYDIR))
+endif
+ifdef COMPILER_OBJECTDIR
+override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))
+endif
+ifdef COMPILER_INCLUDEDIR
+override FPCOPT+=$(addprefix -Fi,$(COMPILER_INCLUDEDIR))
+endif
+ifdef CROSSBINDIR
+override FPCOPT+=-FD$(CROSSBINDIR)
+endif
+ifdef COMPILER_TARGETDIR
+override FPCOPT+=-FE$(COMPILER_TARGETDIR)
+ifeq ($(COMPILER_TARGETDIR),.)
+override TARGETDIRPREFIX=
+else
+override TARGETDIRPREFIX=$(COMPILER_TARGETDIR)/
+endif
+endif
+ifdef COMPILER_UNITTARGETDIR
+override FPCOPT+=-FU$(COMPILER_UNITTARGETDIR)
+ifeq ($(COMPILER_UNITTARGETDIR),.)
+override UNITTARGETDIRPREFIX=
+else
+override UNITTARGETDIRPREFIX=$(COMPILER_UNITTARGETDIR)/
+endif
+else
+ifdef COMPILER_TARGETDIR
+override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR)
+override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX)
+endif
+endif
+ifdef CREATESHARED
+override FPCOPT+=-Cg
+endif
+ifneq ($(findstring $(OS_TARGET),freebsd openbsd netbsd linux solaris),)
+ifeq ($(CPU_TARGET),x86_64)
+override FPCOPT+=-Cg
+endif
+endif
+ifdef LINKSHARED
+endif
+ifdef OPT
+override FPCOPT+=$(OPT)
+endif
+ifdef FPCOPTDEF
+override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
+endif
+ifdef CFGFILE
+override FPCOPT+=@$(CFGFILE)
+endif
+ifdef USEENV
+override FPCEXTCMD:=$(FPCOPT)
+override FPCOPT:=!FPCEXTCMD
+export FPCEXTCMD
+endif
+override AFULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+override AFULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(AFULL_TARGET),$(AFULL_SOURCE))
+override ACROSSCOMPILE=1
+endif
+ifdef ACROSSCOMPILE
+override FPCOPT+=$(CROSSOPT)
+endif
+override COMPILER:=$(FPC) $(FPCOPT)
+ifeq (,$(findstring -s ,$(COMPILER)))
+EXECPPAS=
+else
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+ifdef RUNBATCH
+EXECPPAS:=@$(RUNBATCH) $(PPAS)
+else
+EXECPPAS:=@$(PPAS)
+endif
+endif
+endif
+.PHONY: fpc_exes
+ifndef CROSSINSTALL
+ifneq ($(TARGET_PROGRAMS),)
+override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))
+override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS))) $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS)))
+override EXEDBGFILES:=$(addsuffix $(EXEDBGEXT),$(TARGET_PROGRAMS))
+override ALLTARGET+=fpc_exes
+override INSTALLEXEFILES+=$(EXEFILES)
+override CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)
+override CLEANEXEDBGFILES+=$(EXEDBGFILES)
+ifeq ($(OS_TARGET),os2)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+ifeq ($(OS_TARGET),emx)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+endif
+endif
+fpc_exes: $(COMPILER_TARGETDIR) $(COMPILER_UNITTARGETDIR) $(EXEFILES)
+ifdef TARGET_RSTS
+override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
+override CLEANRSTFILES+=$(RSTFILES)
+endif
+.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared
+$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)
+	@$(ECHOREDIR) Compiled > $(FPCMADE)
+fpc_all: $(FPCMADE)
+fpc_smart:
+	$(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+	$(MAKE) all DEBUG=1
+fpc_release:
+	$(MAKE) all RELEASE=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res
+$(COMPILER_UNITTARGETDIR):
+	$(MKDIRTREE) $(COMPILER_UNITTARGETDIR)
+$(COMPILER_TARGETDIR):
+	$(MKDIRTREE) $(COMPILER_TARGETDIR)
+%$(PPUEXT): %.pp
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(PPUEXT): %.pas
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.pp
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.pas
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.lpr
+	$(COMPILER) $<
+	$(EXECPPAS)
+%$(EXEEXT): %.dpr
+	$(COMPILER) $<
+	$(EXECPPAS)
+%.res: %.rc
+	windres -i $< -o $@
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.inc $(COMPILER_INCLUDEDIR)
+vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_shared
+override INSTALLTARGET+=fpc_shared_install
+ifndef SHARED_LIBVERSION
+SHARED_LIBVERSION=$(FPC_VERSION)
+endif
+ifndef SHARED_LIBNAME
+SHARED_LIBNAME=$(PACKAGE_NAME)
+endif
+ifndef SHARED_FULLNAME
+SHARED_FULLNAME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERSION)$(SHAREDLIBEXT)
+endif
+ifndef SHARED_LIBUNITS
+SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS)
+override SHARED_LIBUNITS:=$(filter-out $(INSTALL_BUILDUNIT),$(SHARED_LIBUNITS))
+endif
+fpc_shared:
+ifdef HASSHAREDLIB
+	$(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1
+ifneq ($(SHARED_BUILD),n)
+	$(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)
+endif
+else
+	@$(ECHO) Shared Libraries not supported
+endif
+fpc_shared_install:
+ifneq ($(SHARED_BUILD),n)
+ifneq ($(SHARED_LIBUNITS),)
+ifneq ($(wildcard $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME)),)
+	$(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INSTALL_SHAREDDIR)
+endif
+endif
+endif
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALL_BUILDUNIT
+override INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT),$(INSTALLPPUFILES))
+endif
+ifdef INSTALLPPUFILES
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+ifneq ($(UNITTARGETDIRPREFIX),)
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPUFILES)))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPULINKFILES))))
+endif
+override INSTALL_CREATEPACKAGEFPC=1
+endif
+ifdef INSTALLEXEFILES
+ifneq ($(TARGETDIRPREFIX),)
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(INSTALLEXEFILES)))
+endif
+endif
+fpc_install: all $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+	$(MKDIR) $(INSTALL_BINDIR)
+	$(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+endif
+ifdef INSTALL_CREATEPACKAGEFPC
+ifdef FPCMAKE
+ifdef PACKAGE_VERSION
+ifneq ($(wildcard Makefile.fpc),)
+	$(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc
+	$(MKDIR) $(INSTALL_UNITDIR)
+	$(INSTALL) Package.fpc $(INSTALL_UNITDIR)
+endif
+endif
+endif
+endif
+ifdef INSTALLPPUFILES
+	$(MKDIR) $(INSTALL_UNITDIR)
+	$(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)
+ifneq ($(INSTALLPPULINKFILES),)
+	$(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)
+endif
+ifneq ($(wildcard $(LIB_FULLNAME)),)
+	$(MKDIR) $(INSTALL_LIBDIR)
+	$(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)
+ifdef inUnix
+	ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)
+endif
+endif
+endif
+ifdef INSTALL_FILES
+	$(MKDIR) $(INSTALL_DATADIR)
+	$(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADIR)
+endif
+fpc_sourceinstall: distclean
+	$(MKDIR) $(INSTALL_SOURCEDIR)
+	$(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
+fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+ifdef HASEXAMPLES
+	$(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
+	$(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef TARGET_EXAMPLEDIRS
+	$(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
+endif
+.PHONY: fpc_distinstall
+fpc_distinstall: install exampleinstall
+.PHONY: fpc_zipinstall fpc_zipsourceinstall fpc_zipexampleinstall
+ifndef PACKDIR
+ifndef inUnix
+PACKDIR=$(BASEDIR)/../fpc-pack
+else
+PACKDIR=/tmp/fpc-pack
+endif
+endif
+ifndef ZIPNAME
+ifdef DIST_ZIPNAME
+ZIPNAME=$(DIST_ZIPNAME)
+else
+ZIPNAME=$(PACKAGE_NAME)
+endif
+endif
+ifndef FULLZIPNAME
+FULLZIPNAME=$(ZIPCROSSPREFIX)$(ZIPPREFIX)$(ZIPNAME)$(ZIPSUFFIX)
+endif
+ifndef ZIPTARGET
+ifdef DIST_ZIPTARGET
+ZIPTARGET=DIST_ZIPTARGET
+else
+ZIPTARGET=install
+endif
+endif
+ifndef USEZIP
+ifdef inUnix
+USETAR=1
+endif
+endif
+ifndef inUnix
+USEZIPWRAPPER=1
+endif
+ifdef USEZIPWRAPPER
+ZIPPATHSEP=$(PATHSEP)
+ZIPWRAPPER=$(subst /,$(PATHSEP),$(DIST_DESTDIR)/fpczip$(SRCBATCHEXT))
+else
+ZIPPATHSEP=/
+endif
+ZIPCMD_CDPACK:=cd $(subst /,$(ZIPPATHSEP),$(PACKDIR))
+ZIPCMD_CDBASE:=cd $(subst /,$(ZIPPATHSEP),$(BASEDIR))
+ifdef USETAR
+ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(TAREXT)
+ZIPCMD_ZIP:=$(TARPROG) c$(TAROPT)f $(ZIPDESTFILE) *
+else
+ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(ZIPEXT)
+ZIPCMD_ZIP:=$(subst /,$(ZIPPATHSEP),$(ZIPPROG)) -Dr $(ZIPOPT) $(ZIPDESTFILE) *
+endif
+fpc_zipinstall:
+	$(MAKE) $(ZIPTARGET) INSTALL_PREFIX=$(PACKDIR) ZIPINSTALL=1
+	$(MKDIR) $(DIST_DESTDIR)
+	$(DEL) $(ZIPDESTFILE)
+ifdef USEZIPWRAPPER
+ifneq ($(ECHOREDIR),echo)
+	$(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDPACK))" > $(ZIPWRAPPER)
+	$(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_ZIP))" >> $(ZIPWRAPPER)
+	$(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDBASE))" >> $(ZIPWRAPPER)
+else
+	echo $(ZIPCMD_CDPACK) > $(ZIPWRAPPER)
+	echo $(ZIPCMD_ZIP) >> $(ZIPWRAPPER)
+	echo $(ZIPCMD_CDBASE) >> $(ZIPWRAPPER)
+endif
+ifdef inUnix
+	/bin/sh $(ZIPWRAPPER)
+else
+ifdef RUNBATCH
+	$(RUNBATCH) $(ZIPWRAPPER)
+else
+	$(ZIPWRAPPER)
+endif
+endif
+	$(DEL) $(ZIPWRAPPER)
+else
+	$(ZIPCMD_CDPACK) ; $(ZIPCMD_ZIP) ; $(ZIPCMD_CDBASE)
+endif
+	$(DELTREE) $(PACKDIR)
+fpc_zipsourceinstall:
+	$(MAKE) fpc_zipinstall ZIPTARGET=sourceinstall ZIPSUFFIX=$(ZIPSOURCESUFFIX)
+fpc_zipexampleinstall:
+ifdef HASEXAMPLES
+	$(MAKE) fpc_zipinstall ZIPTARGET=exampleinstall ZIPSUFFIX=$(ZIPEXAMPLESUFFIX)
+endif
+fpc_zipdistinstall:
+	$(MAKE) fpc_zipinstall ZIPTARGET=distinstall
+.PHONY: fpc_clean fpc_cleanall fpc_distclean
+ifdef EXEFILES
+override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
+override CLEANEXEDBGFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEDBGFILES))
+endif
+ifdef CLEAN_PROGRAMS
+override CLEANEXEFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix $(EXEEXT), $(CLEAN_PROGRAMS)))
+override CLEANEXEDBGFILES+=$(addprefix $(TARGETDIRPREFIX),$(addsuffix $(EXEDBGEXT), $(CLEAN_PROGRAMS)))
+endif
+ifdef CLEAN_UNITS
+override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
+endif
+ifdef CLEANPPUFILES
+override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES)))
+ifdef DEBUGSYMEXT
+override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPPUFILES))
+endif
+override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUFILES))
+override CLEANPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPULINKFILES)))
+endif
+fpc_clean: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+	-$(DEL) $(CLEANEXEFILES)
+endif
+ifdef CLEANEXEDBGFILES
+	-$(DELTREE) $(CLEANEXEDBGFILES)
+endif
+ifdef CLEANPPUFILES
+	-$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+	-$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+	-$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+ifdef CLEAN_FILES
+	-$(DEL) $(CLEAN_FILES)
+endif
+ifdef LIB_NAME
+	-$(DEL) $(LIB_NAME) $(LIB_FULLNAME)
+endif
+	-$(DEL) $(FPCMADE) Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+	-$(DEL) *$(ASMEXT) *_ppas$(BATCHEXT)
+fpc_cleanall: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+	-$(DEL) $(CLEANEXEFILES)
+endif
+ifdef COMPILER_UNITTARGETDIR
+ifdef CLEANPPUFILES
+	-$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+	-$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+	-$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+endif
+ifdef CLEAN_FILES
+	-$(DEL) $(CLEAN_FILES)
+endif
+	-$(DELTREE) units
+	-$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
+ifneq ($(PPUEXT),.ppu)
+	-$(DEL) *.o *.ppu *.a
+endif
+	-$(DELTREE) *$(SMARTEXT)
+	-$(DEL) fpcmade.* Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+	-$(DEL) *_ppas$(BATCHEXT)
+ifdef AOUTEXT
+	-$(DEL) *$(AOUTEXT)
+endif
+ifdef DEBUGSYMEXT
+	-$(DEL) *$(DEBUGSYMEXT)
+endif
+fpc_distclean: cleanall
+.PHONY: fpc_baseinfo
+override INFORULES+=fpc_baseinfo
+fpc_baseinfo:
+	@$(ECHO)
+	@$(ECHO)  == Package info ==
+	@$(ECHO)  Package Name..... $(PACKAGE_NAME)
+	@$(ECHO)  Package Version.. $(PACKAGE_VERSION)
+	@$(ECHO)
+	@$(ECHO)  == Configuration info ==
+	@$(ECHO)
+	@$(ECHO)  FPC.......... $(FPC)
+	@$(ECHO)  FPC Version.. $(FPC_VERSION)
+	@$(ECHO)  Source CPU... $(CPU_SOURCE)
+	@$(ECHO)  Target CPU... $(CPU_TARGET)
+	@$(ECHO)  Source OS.... $(OS_SOURCE)
+	@$(ECHO)  Target OS.... $(OS_TARGET)
+	@$(ECHO)  Full Source.. $(FULL_SOURCE)
+	@$(ECHO)  Full Target.. $(FULL_TARGET)
+	@$(ECHO)  SourceSuffix. $(SOURCESUFFIX)
+	@$(ECHO)  TargetSuffix. $(TARGETSUFFIX)
+	@$(ECHO)  FPC fpmake... $(FPCFPMAKE)
+	@$(ECHO)
+	@$(ECHO)  == Directory info ==
+	@$(ECHO)
+	@$(ECHO)  Required pkgs... $(REQUIRE_PACKAGES)
+	@$(ECHO)
+	@$(ECHO)  Basedir......... $(BASEDIR)
+	@$(ECHO)  FPCDir.......... $(FPCDIR)
+	@$(ECHO)  CrossBinDir..... $(CROSSBINDIR)
+	@$(ECHO)  UnitsDir........ $(UNITSDIR)
+	@$(ECHO)  PackagesDir..... $(PACKAGESDIR)
+	@$(ECHO)
+	@$(ECHO)  GCC library..... $(GCCLIBDIR)
+	@$(ECHO)  Other library... $(OTHERLIBDIR)
+	@$(ECHO)
+	@$(ECHO)  == Tools info ==
+	@$(ECHO)
+	@$(ECHO)  As........ $(AS)
+	@$(ECHO)  Ld........ $(LD)
+	@$(ECHO)  Ar........ $(AR)
+	@$(ECHO)  Rc........ $(RC)
+	@$(ECHO)
+	@$(ECHO)  Mv........ $(MVPROG)
+	@$(ECHO)  Cp........ $(CPPROG)
+	@$(ECHO)  Rm........ $(RMPROG)
+	@$(ECHO)  GInstall.. $(GINSTALL)
+	@$(ECHO)  Echo...... $(ECHO)
+	@$(ECHO)  Shell..... $(SHELL)
+	@$(ECHO)  Date...... $(DATE)
+	@$(ECHO)  FPCMake... $(FPCMAKE)
+	@$(ECHO)  PPUMove... $(PPUMOVE)
+	@$(ECHO)  Zip....... $(ZIPPROG)
+	@$(ECHO)
+	@$(ECHO)  == Object info ==
+	@$(ECHO)
+	@$(ECHO)  Target Loaders........ $(TARGET_LOADERS)
+	@$(ECHO)  Target Units.......... $(TARGET_UNITS)
+	@$(ECHO)  Target Implicit Units. $(TARGET_IMPLICITUNITS)
+	@$(ECHO)  Target Programs....... $(TARGET_PROGRAMS)
+	@$(ECHO)  Target Dirs........... $(TARGET_DIRS)
+	@$(ECHO)  Target Examples....... $(TARGET_EXAMPLES)
+	@$(ECHO)  Target ExampleDirs.... $(TARGET_EXAMPLEDIRS)
+	@$(ECHO)
+	@$(ECHO)  Clean Units......... $(CLEAN_UNITS)
+	@$(ECHO)  Clean Files......... $(CLEAN_FILES)
+	@$(ECHO)
+	@$(ECHO)  Install Units....... $(INSTALL_UNITS)
+	@$(ECHO)  Install Files....... $(INSTALL_FILES)
+	@$(ECHO)
+	@$(ECHO)  == Install info ==
+	@$(ECHO)
+	@$(ECHO)  DateStr.............. $(DATESTR)
+	@$(ECHO)  ZipName.............. $(ZIPNAME)
+	@$(ECHO)  ZipPrefix............ $(ZIPPREFIX)
+	@$(ECHO)  ZipCrossPrefix....... $(ZIPCROSSPREFIX)
+	@$(ECHO)  ZipSuffix............ $(ZIPSUFFIX)
+	@$(ECHO)  FullZipName.......... $(FULLZIPNAME)
+	@$(ECHO)  Install FPC Package.. $(INSTALL_FPCPACKAGE)
+	@$(ECHO)
+	@$(ECHO)  Install base dir..... $(INSTALL_BASEDIR)
+	@$(ECHO)  Install binary dir... $(INSTALL_BINDIR)
+	@$(ECHO)  Install library dir.. $(INSTALL_LIBDIR)
+	@$(ECHO)  Install units dir.... $(INSTALL_UNITDIR)
+	@$(ECHO)  Install source dir... $(INSTALL_SOURCEDIR)
+	@$(ECHO)  Install doc dir...... $(INSTALL_DOCDIR)
+	@$(ECHO)  Install example dir.. $(INSTALL_EXAMPLEDIR)
+	@$(ECHO)  Install data dir..... $(INSTALL_DATADIR)
+	@$(ECHO)
+	@$(ECHO)  Dist destination dir. $(DIST_DESTDIR)
+	@$(ECHO)  Dist zip name........ $(DIST_ZIPNAME)
+	@$(ECHO)
+.PHONY: fpc_info
+fpc_info: $(INFORULES)
+.PHONY: fpc_makefile fpc_makefiles fpc_makefile_sub1 fpc_makefile_sub2 \
+	fpc_makefile_dirs
+fpc_makefile:
+	$(FPCMAKE) -w -T$(OS_TARGET) Makefile.fpc
+fpc_makefile_sub1:
+ifdef TARGET_DIRS
+	$(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_DIRS))
+endif
+ifdef TARGET_EXAMPLEDIRS
+	$(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_EXAMPLEDIRS))
+endif
+fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_EXAMPLEDIRS))
+fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
+fpc_makefiles: fpc_makefile fpc_makefile_dirs
+ifdef TARGET_DIRS_TARGET_DIRS
+TARGET_DIRS_all:
+	$(MAKE) -C TARGET_DIRS all
+TARGET_DIRS_debug:
+	$(MAKE) -C TARGET_DIRS debug
+TARGET_DIRS_smart:
+	$(MAKE) -C TARGET_DIRS smart
+TARGET_DIRS_release:
+	$(MAKE) -C TARGET_DIRS release
+TARGET_DIRS_units:
+	$(MAKE) -C TARGET_DIRS units
+TARGET_DIRS_examples:
+	$(MAKE) -C TARGET_DIRS examples
+TARGET_DIRS_shared:
+	$(MAKE) -C TARGET_DIRS shared
+TARGET_DIRS_install:
+	$(MAKE) -C TARGET_DIRS install
+TARGET_DIRS_sourceinstall:
+	$(MAKE) -C TARGET_DIRS sourceinstall
+TARGET_DIRS_exampleinstall:
+	$(MAKE) -C TARGET_DIRS exampleinstall
+TARGET_DIRS_distinstall:
+	$(MAKE) -C TARGET_DIRS distinstall
+TARGET_DIRS_zipinstall:
+	$(MAKE) -C TARGET_DIRS zipinstall
+TARGET_DIRS_zipsourceinstall:
+	$(MAKE) -C TARGET_DIRS zipsourceinstall
+TARGET_DIRS_zipexampleinstall:
+	$(MAKE) -C TARGET_DIRS zipexampleinstall
+TARGET_DIRS_zipdistinstall:
+	$(MAKE) -C TARGET_DIRS zipdistinstall
+TARGET_DIRS_clean:
+	$(MAKE) -C TARGET_DIRS clean
+TARGET_DIRS_distclean:
+	$(MAKE) -C TARGET_DIRS distclean
+TARGET_DIRS_cleanall:
+	$(MAKE) -C TARGET_DIRS cleanall
+TARGET_DIRS_info:
+	$(MAKE) -C TARGET_DIRS info
+TARGET_DIRS_makefiles:
+	$(MAKE) -C TARGET_DIRS makefiles
+TARGET_DIRS:
+	$(MAKE) -C TARGET_DIRS all
+.PHONY: TARGET_DIRS_all TARGET_DIRS_debug TARGET_DIRS_smart TARGET_DIRS_release TARGET_DIRS_units TARGET_DIRS_examples TARGET_DIRS_shared TARGET_DIRS_install TARGET_DIRS_sourceinstall TARGET_DIRS_exampleinstall TARGET_DIRS_distinstall TARGET_DIRS_zipinstall TARGET_DIRS_zipsourceinstall TARGET_DIRS_zipexampleinstall TARGET_DIRS_zipdistinstall TARGET_DIRS_clean TARGET_DIRS_distclean TARGET_DIRS_cleanall TARGET_DIRS_info TARGET_DIRS_makefiles TARGET_DIRS
+endif
+ifdef TARGET_EXAMPLEDIRS_TARGET_EXAMPLEDIRS
+TARGET_EXAMPLEDIRS_all:
+	$(MAKE) -C TARGET_EXAMPLEDIRS all
+TARGET_EXAMPLEDIRS_debug:
+	$(MAKE) -C TARGET_EXAMPLEDIRS debug
+TARGET_EXAMPLEDIRS_smart:
+	$(MAKE) -C TARGET_EXAMPLEDIRS smart
+TARGET_EXAMPLEDIRS_release:
+	$(MAKE) -C TARGET_EXAMPLEDIRS release
+TARGET_EXAMPLEDIRS_units:
+	$(MAKE) -C TARGET_EXAMPLEDIRS units
+TARGET_EXAMPLEDIRS_examples:
+	$(MAKE) -C TARGET_EXAMPLEDIRS examples
+TARGET_EXAMPLEDIRS_shared:
+	$(MAKE) -C TARGET_EXAMPLEDIRS shared
+TARGET_EXAMPLEDIRS_install:
+	$(MAKE) -C TARGET_EXAMPLEDIRS install
+TARGET_EXAMPLEDIRS_sourceinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS sourceinstall
+TARGET_EXAMPLEDIRS_exampleinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS exampleinstall
+TARGET_EXAMPLEDIRS_distinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS distinstall
+TARGET_EXAMPLEDIRS_zipinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS zipinstall
+TARGET_EXAMPLEDIRS_zipsourceinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS zipsourceinstall
+TARGET_EXAMPLEDIRS_zipexampleinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS zipexampleinstall
+TARGET_EXAMPLEDIRS_zipdistinstall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS zipdistinstall
+TARGET_EXAMPLEDIRS_clean:
+	$(MAKE) -C TARGET_EXAMPLEDIRS clean
+TARGET_EXAMPLEDIRS_distclean:
+	$(MAKE) -C TARGET_EXAMPLEDIRS distclean
+TARGET_EXAMPLEDIRS_cleanall:
+	$(MAKE) -C TARGET_EXAMPLEDIRS cleanall
+TARGET_EXAMPLEDIRS_info:
+	$(MAKE) -C TARGET_EXAMPLEDIRS info
+TARGET_EXAMPLEDIRS_makefiles:
+	$(MAKE) -C TARGET_EXAMPLEDIRS makefiles
+TARGET_EXAMPLEDIRS:
+	$(MAKE) -C TARGET_EXAMPLEDIRS all
+.PHONY: TARGET_EXAMPLEDIRS_all TARGET_EXAMPLEDIRS_debug TARGET_EXAMPLEDIRS_smart TARGET_EXAMPLEDIRS_release TARGET_EXAMPLEDIRS_units TARGET_EXAMPLEDIRS_examples TARGET_EXAMPLEDIRS_shared TARGET_EXAMPLEDIRS_install TARGET_EXAMPLEDIRS_sourceinstall TARGET_EXAMPLEDIRS_exampleinstall TARGET_EXAMPLEDIRS_distinstall TARGET_EXAMPLEDIRS_zipinstall TARGET_EXAMPLEDIRS_zipsourceinstall TARGET_EXAMPLEDIRS_zipexampleinstall TARGET_EXAMPLEDIRS_zipdistinstall TARGET_EXAMPLEDIRS_clean TARGET_EXAMPLEDIRS_distclean TARGET_EXAMPLEDIRS_cleanall TARGET_EXAMPLEDIRS_info TARGET_EXAMPLEDIRS_makefiles TARGET_EXAMPLEDIRS
+endif
+all: fpc_all
+debug: fpc_debug
+smart: fpc_smart
+release: fpc_release
+units: fpc_units
+examples:
+shared: fpc_shared
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
+distinstall: fpc_distinstall
+zipinstall: fpc_zipinstall
+zipsourceinstall: fpc_zipsourceinstall
+zipexampleinstall: fpc_zipexampleinstall
+zipdistinstall: fpc_zipdistinstall
+clean: fpc_clean
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+makefiles: fpc_makefiles
+.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
+.NOTPARALLEL:
+pas2ut$(EXEEXT): pas2ut.pp

+ 30 - 0
utils/pas2ut/Makefile.fpc

@@ -0,0 +1,30 @@
+#
+#   Makefile.fpc for pas2ut
+#
+
+[package]
+name=pas2ut
+version=2.7.1
+
+[require]
+packages=fcl-passrc fcl-base
+packages_darwin=univint
+packages_iphonesim=univint
+
+[target]
+programs=pas2ut
+rst=pas2ut
+
+[compiler]
+options=-S2h
+
+[install]
+fpcpackage=y
+
+[default]
+fpcdir=../..
+
+[rules]
+.NOTPARALLEL:
+pas2ut$(EXEEXT): pas2ut.pp
+

+ 77 - 0
utils/pas2ut/pas2ut.lpi

@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <Title Value="Pascal code to Unit Tests"/>
+      <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>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="pas2ut.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="pas2ut"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="pastounittest.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="pastounittest"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target>
+      <Filename Value="pas2ut"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <MsgFileName Value=""/>
+      </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>

+ 314 - 0
utils/pas2ut/pas2ut.pp

@@ -0,0 +1,314 @@
+{
+    This file is part of the Free Pascal project
+    Copyright (c) 2012 by the Free Pascal team
+
+    Pascal source to FPC Unit test generator program
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program pas2ut;
+
+{$mode objfpc}{$H+}
+
+uses
+  Classes, SysUtils, pastounittest, pastree,CustApp;
+
+Resourcestring
+   SErrNoInput = 'Error: No input file specified';
+
+   SHelp0   = 'Usage : pp2ut [options] inputfile [outputfile]';
+   SHelp1   = 'Where options is one or more of';
+   SHelp2   = '--help                   this help';
+   SHelp10  = '--test-protected         also generate tests for protected class members' ;
+   SHelp20  = '--skip-default           skip tests for default visibility members' ;
+   SHelp30  = '--skip-published         skip tests for published members' ;
+   SHelp40  = '--skip-public            skip tests for public members';
+   SHelp50  = '--tiopf                  tiopf tests  (default,bounds,required,notify,maxlen)' ;
+   SHelp60  = '--skip-property-default  generate a default test for each property' ;
+   SHelp70  = '--test-property-bounds   generate a GetBounds test for each property' ;
+   SHelp80  = '--test-property-required generate a Required test for each property' ;
+   SHelp90  = '--test-property-notify   generate a notify test for each property' ;
+   SHelp100 = '--test-property-maxlen   generate a maxlen test for each property' ;
+   SHelp105 = '--skip-declaration       Do not generate declarations for the tests' ;
+   SHelp110 = '--skip-implementation    Do not generate (empty) implementation for the tests' ;
+   SHelp120 = '--skip-fail              Skip fail() statement in test implementations ' ;
+   SHelp130 = '--skip-unit              Do not generate a unit' ;
+   SHelp140 = '--skip-setup             Skip TestCase class Setup() method' ;
+   SHelp150 = '--skip-teardown          Skip testcase class TearDown() method' ;
+   SHelp160 = '--skip-functions         Skip tests for functions/procedures' ;
+   SHelp170 = '--skip-classes           Skip tests for classes' ;
+   SHelp180 = '--skip-register          Do not generate RegisterTests statement' ;
+   SHelp190 = '--singletestclass        Use a single test class' ;
+   SHelp200 = '--skip-methods           Skip tests for methods of classes' ;
+   SHelp210 = '--skip-fields            Skip tests for fields of classes';
+   SHelp220 = '--skip-properties        Skip tests for properties of classes ' ;
+   SHelp230 = '--testparentname=name    Set the name of the parent class of test classes' ;
+   SHelp240 = '--testunitname=name      Set the name of the generated unit (default is taken from output file name)' ;
+   SHelp250 = '--failmessage=Msg        Set the message for the Fail() statement ' ;
+   SHelp260 = '--unittestclassname=name Set the global unit test class name' ;
+   SHelp270 = '--prefix=name            Set the prefix for the test names (default is "Test") ' ;
+   SHelp280 = '--limit=list             Specify a comma-separated list of global identifiers for which to generate tests.' ;
+   SHelp290 = '--defaultclasstest=list  Specify a comma-separated list of default tests for each class' ;
+   SHelp400 = '--limit and --defaultclasstest may be specified multiple times.';
+
+
+type
+  { TPasToUnitTestApplication }
+
+  TPasToUnitTestApplication = class(TCustomApplication)
+  Private
+    FCodeGen : TFPTestCodeCreator;
+    FInputFile,FoutputFile : string;
+    function CheckOptions : Boolean;
+  protected
+    procedure DoRun; override;
+  public
+    constructor Create(TheOwner: TComponent); override;
+    destructor Destroy; override;
+    procedure WriteHelp; virtual;
+  end;
+
+{ TPasToUnitTestApplication }
+
+function TPasToUnitTestApplication.CheckOptions : Boolean;
+
+  Procedure ov(value : TPasMemberVisibility;incl: Boolean);
+
+  begin
+    if incl then
+      FCodeGen.Visibilities:=FCodeGen.Visibilities+[value]
+    else
+      FCodeGen.Visibilities:=FCodeGen.Visibilities-[value]
+  end;
+
+  Procedure op(value : TTestPropertyOption;incl: Boolean);
+
+  begin
+    if incl then
+      FCodeGen.PropertyOptions:=FCodeGen.PropertyOptions+[value]
+    else
+      FCodeGen.PropertyOptions:=FCodeGen.PropertyOptions-[value]
+  end;
+
+  Procedure oc(value : TTestCodeOption;incl: Boolean);
+
+  begin
+    if incl then
+      FCodeGen.CodeOptions:=FCodeGen.CodeOptions+[value]
+    else
+      FCodeGen.CodeOptions:=FCodeGen.CodeOptions-[value]
+  end;
+
+  Procedure om(value : TTestMemberType;incl: Boolean);
+
+  begin
+    if incl then
+      FCodeGen.MemberTypes:=FCodeGen.MemberTypes+[value]
+    else
+      FCodeGen.MemberTypes:=FCodeGen.MemberTypes-[value]
+  end;
+
+  Procedure AddValues(S : String; List : Tstrings);
+
+  Var
+    P : Integer;
+    V : String;
+
+  begin
+    Repeat
+      P:=Pos(',',S);
+      If P=0 then
+        P:=Length(S)+1;
+      V:=Trim(Copy(S,1,P-1));
+      If (V<>'') then
+        List.Add(V);
+      Delete(S,1,P);  
+    until (S='');
+  end;
+
+Var
+  S,O : string;
+  I,p : Integer;
+
+begin
+  Result:=False;
+  I:=1;
+  While (I<=ParamCount) do
+    begin
+    S:=ParamStr(I);
+    P:=pos('=',S);
+    if (P>0) then
+      begin
+      O:=S;
+      Delete(O,1,P);
+      S:=lowercase(Copy(S,1,P-1));
+      end
+    else
+      O:='';
+    if s='--test-protected' then
+      ov(visProtected,true)
+    else  if s='--skip-default' then
+      ov(visDefault,false)
+    else  if s='--skip-published' then
+      ov(visPublished,false)
+    else  if s='--skip-public' then
+      ov(visPublic,false)
+    else if s='--tiopf' then
+      begin
+      FCodeGen.PropertyOptions:=[tDefault,tGetBounds,tRequired,tNotify,tMaxLen];
+      end
+    else if s='--skip-property-default' then
+      op(tdefault,false)
+    else if s='--test-property-bounds' then
+      op(tgetBounds,true)
+    else if s='--test-property-required' then
+      op(trequired,true)
+    else if s='--test-property-notify' then
+      op(tNotify,true)
+    else if s='--test-property-maxlen' then
+      op(tMaxLen,true)
+    else if s='--skip-declaration' then
+      oc(coCreateDeclaration,false)
+    else if s='--skip-implementation' then
+      oc(coImplementation,false)
+    else if s='--skip-fail' then
+      oc(coDefaultFail,false)
+    else if s='--skip-unit' then
+      oc(coCreateUnit,false)
+    else if s='--skip-setup' then
+      oc(coSetup,false)
+    else if s='--skip-teardown' then
+      oc(coTeardown,false)
+    else if s='--skip-functions' then
+      oc(coFunctions,false)
+    else if s='--skip-classes' then
+      oc(coClasses,false)
+    else if s='--skip-register' then
+      oc(coRegisterTests,false)
+    else if s='--singletestclass' then
+      oc(coSingleClass,true)
+    else if s='--skip-methods' then
+      om(tmtMethods,false)
+    else if s='--skip-fields' then
+      om(tmtMethods,false)
+    else if s='--skip-properties' then
+      om(tmtMethods,false)
+    else if (s='--testparentname') then
+      FCodeGen.TestClassParent:=o
+    else if (s='--testunitname') then
+      FCodeGen.DestUnitname:=o
+    else if (s='--failmessage') then
+      FCodeGen.Failmessage:=o
+    else if (s='--unittestclassname') then
+      FCodeGen.UnitTestClassName:=O
+    else if (s='--prefix') then
+      FCodeGen.TestNamePrefix:=O
+    else if (s='--limit') then
+      AddValues(O,FCodeGen.LimitIdentifiers)
+    else if (s='--defaultclasstest') then
+      AddValues(O,FCodeGen.DefaultClassTests)
+    else
+      begin
+      if (FInputFile='') then
+        FInputFile:=s
+      else if (FoutputFile<>'') then
+        begin
+        WriteHelp;
+        Exit;
+        end
+      else
+        FoutputFile:=s;
+      end;
+    Inc(I);
+    end;
+  Result:=FInputFile<>'';
+  If Not Result then
+    begin
+    Writeln(SErrNoInput);
+    WriteHelp;
+    end;
+  If (FOutputFile='') then
+    FOutputFile:='tc'+FInputFile;
+end;
+
+procedure TPasToUnitTestApplication.DoRun;
+var
+  ErrorMsg: String;
+begin
+  Terminate;
+  // parse parameters
+  if HasOption('h','help') then
+    begin
+    WriteHelp;
+    Exit;
+    end;
+  if CheckOptions then
+    FCodeGen.Execute(FInputfile,FOutputFile);
+end;
+
+constructor TPasToUnitTestApplication.Create(TheOwner: TComponent);
+begin
+  inherited Create(TheOwner);
+  StopOnException:=True;
+  FCodeGen :=TFPTestCodeCreator.Create(Self)
+end;
+
+destructor TPasToUnitTestApplication.Destroy;
+begin
+  FreeAndNil(FCodeGen);
+  inherited Destroy;
+end;
+
+procedure TPasToUnitTestApplication.WriteHelp;
+begin
+  Writeln(SHelp0);
+  Writeln(SHelp1);
+  Writeln(SHelp10 );
+  Writeln(SHelp20 );
+  Writeln(SHelp30 );
+  Writeln(SHelp40 );
+  Writeln(SHelp50 );
+  Writeln(SHelp60 );
+  Writeln(SHelp70 );
+  Writeln(SHelp80 );
+  Writeln(SHelp90 );
+  Writeln(SHelp100);
+  Writeln(SHelp105);
+  Writeln(SHelp110);
+  Writeln(SHelp120);
+  Writeln(SHelp130);
+  Writeln(SHelp140);
+  Writeln(SHelp150);
+  Writeln(SHelp160);
+  Writeln(SHelp170);
+  Writeln(SHelp180);
+  Writeln(SHelp190);
+  Writeln(SHelp200);
+  Writeln(SHelp210);
+  Writeln(SHelp220);
+  Writeln(SHelp230);
+  Writeln(SHelp240);
+  Writeln(SHelp250);
+  Writeln(SHelp260);
+  Writeln(SHelp270);
+  Writeln(SHelp280);
+  Writeln(SHelp290);
+  Writeln(SHelp400);
+end;
+
+var
+  Application: TPasToUnitTestApplication;
+
+begin
+  Application:=TPasToUnitTestApplication.Create(nil);
+  Application.Title:='Pascal code to Unit Tests';
+  Application.Run;
+  Application.Free;
+end.
+

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