Pārlūkot izejas kodu

* 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 gadi atpakaļ
vecāks
revīzija
de82339f4a
64 mainītis faili ar 21128 papildinājumiem un 1169 dzēšanām
  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/testunit1.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/paswrite.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/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/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.lpr 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.fpc 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/dw_dxml.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.lpi 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/fpdocstripper.lpi svneol=native#text/plain
+utils/fpdoc/fpdocstripper.pp 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/dglobals.de.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.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/mkfpdocproj.lpi 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/sh_pas.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/projectparser.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/ppdep.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_VERSION=2.6.3
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_UNITS+=pastree pscanner pparser paswrite
+override TARGET_UNITS+=pastree pscanner pparser paswrite pastounittest passrcutil
 endif
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_RSTS+=pscanner pparser pastree
+override TARGET_RSTS+=pscanner pparser pastree pastounittest
 endif
 override INSTALL_FPCPACKAGE=y
 ifeq ($(FULL_TARGET),i386-linux)

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

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

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

@@ -488,8 +488,8 @@ begin
       begin
        write(s);
        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 assigned(lics.Body) and (TPasImplBlock(lics.Body).Elements.Count >0) then
        //  GetTPasImplBlock(TPasImplBlock(lics.Body),lindent+1,0,false,true)
@@ -509,8 +509,8 @@ begin
      if liwd.Expressions.Count>0 then
       begin
        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;
      writeln(' do');
      //if TPasImplBlock(liwd.Body).Elements.Count >0  then
@@ -1157,7 +1157,7 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
           begin
            pv:=TPasVariant(prct.Variants[i]);
            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(': (');
            if GetVariantRecord(TPasElement(pv.Members),j+1) then
              writeln(s1,');')
@@ -1245,7 +1245,7 @@ procedure GetTypes(pe:TPasElement; lindent:integer);
           begin
            pv:=TPasVariant(prct.Variants[i]);
            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(': (');
            if GetVariantRecord(TPasElement(pv.Members),j+2) then
              writeln(s2,');')

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

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

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

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

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

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

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 314 - 267
packages/fcl-passrc/src/pparser.pp


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

@@ -76,6 +76,10 @@ type
     tkGreaterEqualThan,      // '>='
     tkPower,                 // '**'
     tkSymmetricalDifference, // '><'
+    tkAssignPlus,            // +=
+    tkAssignMinus,           // -=
+    tkAssignMul,             // *=
+    tkAssignDivision,        // /=
     // Reserved words
     tkabsolute,
     tkand,
@@ -105,6 +109,7 @@ type
     tkfunction,
     tkgeneric,
     tkgoto,
+    tkHelper,
     tkif,
     tkimplementation,
     tkin,
@@ -185,6 +190,7 @@ type
   private
     FTextFile: Text;
     FileOpened: Boolean;
+    FBuffer : Array[0..4096-1] of byte;
   public
     constructor Create(const AFilename: string); override;
     destructor Destroy; override;
@@ -215,7 +221,7 @@ type
 
   TStringStreamLineReader = class(TStreamLineReader)
   Public
-    constructor Create(const AFilename: string; Const ASource: String);
+    constructor Create( const AFilename: string; Const ASource: String);
   end;
 
   { TMacroReader }
@@ -288,7 +294,7 @@ type
 
   TPascalScannerPPSkipMode = (ppSkipNone, ppSkipIfBranch, ppSkipElseBranch, ppSkipAll);
 
-  TPOption = (po_delphi);
+  TPOption = (po_delphi,po_cassignments);
   TPOptions = set of TPOption;
 
   { TPascalScanner }
@@ -402,6 +408,10 @@ const
     '>=',
     '**',
     '><',
+    '+=',
+    '-=',
+    '*=',
+    '/=',
     // Reserved words
     'absolute',
     'and',
@@ -431,6 +441,7 @@ const
     'function',
     'generic',
     'goto',
+    'helper',
     'if',
     'implementation',
     'in',
@@ -483,7 +494,7 @@ const
 function FilenameIsAbsolute(const TheFilename: string):boolean;
 function FilenameIsWinAbsolute(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
 
@@ -551,7 +562,7 @@ begin
   Result:=-1;
 end;
 
-function IsNamedToken(Const AToken : String; Var T : TToken) : Boolean;
+function IsNamedToken(Const AToken : String; Out T : TToken) : Boolean;
 
 Var
   I : Integer;
@@ -787,10 +798,12 @@ end;
   ---------------------------------------------------------------------}
 
 constructor TFileLineReader.Create(const AFilename: string);
+
 begin
   inherited Create(AFileName);
   Assign(FTextFile, AFilename);
   Reset(FTextFile);
+  SetTextBuf(FTextFile,FBuffer,SizeOf(FBuffer));
   FileOpened := true;
 end;
 
@@ -895,7 +908,10 @@ end;
 
 procedure TBaseFileResolver.AddIncludePath(const APath: string);
 begin
-  FIncludePaths.Add(IncludeTrailingPathDelimiter(ExpandFileName(APath)));
+  if (APath='') then
+    FIncludePaths.Add('./')
+  else
+    FIncludePaths.Add(IncludeTrailingPathDelimiter(ExpandFileName(APath)));
 end;
 
 { ---------------------------------------------------------------------
@@ -1249,7 +1265,7 @@ var
   TokenStart, CurPos: PChar;
   i: TToken;
   OldLength, SectionLength, NestingLevel, Index: Integer;
-  Directive, Param, MN, MV: string;
+  Directive, Param : string;
 begin
   if TokenStr = nil then
     if not FetchLine then
@@ -1368,13 +1384,30 @@ begin
         begin
           Inc(TokenStr);
           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;
     '+':
       begin
         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;
     ',':
       begin
@@ -1384,7 +1417,16 @@ begin
     '-':
       begin
         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;
     '.':
       begin
@@ -1412,8 +1454,16 @@ begin
             Move(TokenStart^, FCurTokenString[1], SectionLength);
           Result := tkComment;
           //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;
     '0'..'9':
       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
 
 uses
-  Classes, SysUtils, typinfo, fpcunit, testutils, testregistry, pscanner, pparser;
+  Classes, SysUtils, typinfo, fpcunit, testregistry, pscanner;
 
 type
 
@@ -99,6 +99,10 @@ type
     procedure TestBackslash;
     procedure TestDotDot;
     procedure TestAssign;
+    procedure TestAssignPlus;
+    procedure TestAssignMinus;
+    procedure TestAssignMul;
+    procedure TestAssignDivision;
     procedure TestNotEqual;
     procedure TestLessEqualThan;
     procedure TestGreaterEqualThan;
@@ -131,6 +135,7 @@ type
     procedure TestFunction;
     procedure TestGeneric;
     procedure TestGoto;
+    Procedure TestHelper;
     procedure TestIf;
     procedure TestImplementation;
     procedure TestIn;
@@ -636,6 +641,34 @@ begin
   TestToken(tkAssign,':=');
 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;
 
@@ -860,6 +893,11 @@ begin
   TestToken(tkgoto,'goto');
 end;
 
+procedure TTestScanner.TestHelper;
+begin
+  TestToken(tkHelper,'helper');
+end;
+
 
 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>
       <local>
         <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>
     </RunParams>
     <RequiredPackages Count="2">
@@ -36,7 +37,7 @@
         <PackageName Value="FCL"/>
       </Item2>
     </RequiredPackages>
-    <Units Count="2">
+    <Units Count="12">
       <Unit0>
         <Filename Value="testpassrc.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -47,6 +48,56 @@
         <IsPartOfProject Value="True"/>
         <UnitName Value="tcscanner"/>
       </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>
   </ProjectOptions>
   <CompilerOptions>

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

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

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

@@ -250,12 +250,8 @@ type
     procedure SetCount(NewCount: Integer);
     Procedure RaiseIndexError(Index: Integer);
   public
-{$IFNDEF VER2_4}
-{$ifndef fpdocsystem}
     Type
       TDirection = (FromBeginning, FromEnd);
-{$endif}
-{$ENDIF}
     destructor Destroy; override;
     Procedure AddList(AList : TFPList);
     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_VERSION=2.6.3
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 ifeq ($(FULL_TARGET),i386-linux)
 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_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -2863,6 +2865,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_RMWAIT=1
 endif
 ifeq ($(FULL_TARGET),i386-win32)
@@ -2874,6 +2878,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
@@ -2889,6 +2895,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
@@ -2902,6 +2910,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -2914,6 +2924,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 TARGET_DIRS_FPPKG=1
@@ -2924,6 +2936,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -2936,6 +2950,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -2948,6 +2964,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -2960,6 +2978,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 TARGET_DIRS_FPPKG=1
@@ -2970,6 +2990,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 TARGET_DIRS_FPPKG=1
@@ -2980,6 +3002,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -2992,6 +3016,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 TARGET_DIRS_FPPKG=1
@@ -3002,6 +3028,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3015,6 +3043,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
@@ -3028,6 +3058,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 TARGET_DIRS_FPPKG=1
@@ -3038,6 +3070,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 TARGET_DIRS_FPPKG=1
@@ -3048,6 +3082,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3061,6 +3097,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 TARGET_DIRS_FPPKG=1
@@ -3071,6 +3109,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 TARGET_DIRS_FPPKG=1
@@ -3081,6 +3121,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 TARGET_DIRS_FPPKG=1
@@ -3091,6 +3133,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3104,6 +3148,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3116,6 +3162,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3128,6 +3176,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3140,6 +3190,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 TARGET_DIRS_FPPKG=1
@@ -3150,6 +3202,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 TARGET_DIRS_FPPKG=1
@@ -3160,6 +3214,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3172,6 +3228,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 TARGET_DIRS_FPPKG=1
@@ -3182,6 +3240,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 TARGET_DIRS_FPPKG=1
@@ -3192,6 +3252,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3204,6 +3266,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3216,6 +3280,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 TARGET_DIRS_FPPKG=1
@@ -3226,6 +3292,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 TARGET_DIRS_FPPKG=1
@@ -3236,6 +3304,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3249,6 +3319,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 TARGET_DIRS_FPPKG=1
@@ -3259,6 +3331,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 TARGET_DIRS_FPPKG=1
@@ -3269,6 +3343,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 TARGET_DIRS_FPPKG=1
@@ -3279,6 +3355,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3291,6 +3369,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3303,6 +3383,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3315,6 +3397,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 TARGET_DIRS_FPPKG=1
@@ -3325,6 +3409,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3337,6 +3423,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3349,6 +3437,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3361,6 +3451,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3373,6 +3465,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3385,6 +3479,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3398,6 +3494,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPMC=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
@@ -3413,6 +3511,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 TARGET_DIRS_FPPKG=1
@@ -3423,6 +3523,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3435,6 +3537,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 TARGET_DIRS_FPPKG=1
@@ -3445,6 +3549,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3458,6 +3564,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_RMWAIT=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3471,6 +3579,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 TARGET_DIRS_FPPKG=1
@@ -3481,6 +3591,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 TARGET_DIRS_FPPKG=1
@@ -3491,6 +3603,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 TARGET_DIRS_FPPKG=1
@@ -3501,6 +3615,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 TARGET_DIRS_FPPKG=1
@@ -3511,6 +3627,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3523,6 +3641,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_FPCRESLIPO=1
 TARGET_DIRS_INSTANTFPC=1
@@ -3536,6 +3656,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 TARGET_DIRS_FPPKG=1
@@ -3546,6 +3668,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 TARGET_DIRS_FPPKG=1
@@ -3556,6 +3680,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3568,6 +3694,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 TARGET_DIRS_FPPKG=1
@@ -3578,6 +3706,8 @@ TARGET_DIRS_FPRCP=1
 TARGET_DIRS_DXEGEN=1
 TARGET_DIRS_FPDOC=1
 TARGET_DIRS_FPCMKCFG=1
+TARGET_DIRS_PAS2UT=1
+TARGET_DIRS_PAS2FPM=1
 TARGET_DIRS_FPCRES=1
 TARGET_DIRS_INSTANTFPC=1
 endif
@@ -3941,6 +4071,96 @@ fpcmkcfg:
 	$(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
 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
 fpcres_all:
 	$(MAKE) -C fpcres all

+ 1 - 1
utils/Makefile.fpc

@@ -7,7 +7,7 @@ name=utils
 version=2.6.3
 
 [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_linux=grab_vcsa
 dirs_win32=fpmc fpcres rmwait instantfpc importtl

+ 113 - 2
utils/fpdoc/Makefile

@@ -1693,13 +1693,14 @@ else
 TAROPT=vz
 TAREXT=.tar.gz
 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)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
@@ -1707,6 +1708,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-win32)
@@ -1714,6 +1716,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-os2)
@@ -1721,6 +1724,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
@@ -1729,6 +1733,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-beos)
@@ -1737,6 +1742,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
@@ -1745,6 +1751,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
@@ -1752,6 +1759,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
@@ -1759,6 +1767,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
@@ -1766,6 +1775,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-netware)
@@ -1773,6 +1783,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
@@ -1780,6 +1791,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
@@ -1787,6 +1799,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
@@ -1796,6 +1809,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-emx)
@@ -1803,6 +1817,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
@@ -1810,6 +1825,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
@@ -1817,6 +1833,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-wince)
@@ -1824,6 +1841,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
@@ -1831,6 +1849,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
@@ -1838,6 +1857,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
@@ -1845,6 +1865,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
@@ -1854,6 +1875,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
@@ -1862,6 +1884,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
@@ -1870,6 +1893,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
@@ -1877,6 +1901,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
@@ -1884,6 +1909,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
@@ -1891,6 +1917,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
@@ -1898,6 +1925,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
@@ -1905,6 +1933,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
@@ -1912,6 +1941,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
@@ -1920,6 +1950,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
@@ -1927,6 +1958,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
@@ -1934,6 +1966,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
@@ -1941,6 +1974,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
@@ -1950,6 +1984,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
@@ -1957,6 +1992,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
@@ -1964,6 +2000,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
@@ -1971,6 +2008,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
@@ -1979,6 +2017,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
@@ -1986,6 +2025,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
@@ -1993,6 +2033,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
@@ -2000,6 +2041,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
@@ -2008,6 +2050,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
@@ -2016,6 +2059,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
@@ -2023,6 +2067,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
@@ -2030,6 +2075,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
@@ -2037,6 +2083,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
@@ -2046,6 +2093,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
@@ -2053,6 +2101,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
@@ -2060,6 +2109,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),arm-linux)
@@ -2068,6 +2118,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
@@ -2075,6 +2126,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
@@ -2084,6 +2136,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),arm-wince)
@@ -2091,6 +2144,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),arm-gba)
@@ -2098,6 +2152,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),arm-nds)
@@ -2105,6 +2160,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
@@ -2112,6 +2168,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
@@ -2119,6 +2176,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
@@ -2127,6 +2185,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
@@ -2136,6 +2195,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
@@ -2143,6 +2203,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
@@ -2150,6 +2211,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
@@ -2158,6 +2220,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
@@ -2165,6 +2228,7 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
@@ -2173,6 +2237,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_ICONVENC=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_CHM=1
 endif
 ifdef REQUIRE_PACKAGES_RTL
@@ -2365,6 +2430,44 @@ ifdef UNITDIR_FPMAKE_FCL-PASSRC
 override COMPILER_FPMAKE_UNITDIR+=$(UNITDIR_FPMAKE_FCL-PASSRC)
 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
 PACKAGEDIR_CHM:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /chm/Makefile.fpc,$(PACKAGESDIR))))))
 ifneq ($(PACKAGEDIR_CHM),)
@@ -3066,5 +3169,13 @@ include fpcmake.loc
 endif
 .NOTPARALLEL:
 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
+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
 
 [require]
-packages=fcl-base fcl-xml fcl-passrc chm
+packages=fcl-base fcl-xml fcl-passrc fcl-process chm
 packages_darwin=univint
 
 [target]
@@ -33,6 +33,18 @@ files=dwriter.rst fpdoc.rst dglobals.rst makeskel.rst fpdocopts.rst
 [rules]
 .NOTPARALLEL:
 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
+
+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
   * 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
   * Skeleton XML description file generator
 
@@ -66,3 +73,4 @@ Contributors
 ------------
 Initial French output strings by Pierre Muller
 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;
 
+Const
+  CacheSize = 20;
+  ContentBufSize = 4096 * 8;
+
 Var
   LEOL : Integer;
   modir : string;
@@ -35,6 +39,7 @@ resourcestring
   SDocPrograms               = 'Programs';
   SDocUnits                  = 'Units';
   SDocUnitTitle              = 'Reference for unit ''%s''';
+  SDocInheritanceHierarchy   = 'Inheritance Hierarchy';
   SDocInterfaceSection       = 'Interface section';
   SDocImplementationSection  = 'Implementation section';
   SDocUsedUnits              = 'Used units';
@@ -47,6 +52,7 @@ resourcestring
   SDocProceduresAndFunctions = 'Procedures and functions';
   SDocVariables              = 'Variables';
   SDocIdentifierIndex        = 'Index';
+  SDocPackageClassHierarchy  = 'Class hierarchy';
   SDocModuleIndex            = 'Index of all identifiers in unit ''%s''';
   SDocPackageIndex           = 'Index of all identifiers in package ''%s''';
   SDocUnitOverview           = 'Overview of unit ''%s''';
@@ -82,6 +88,8 @@ resourcestring
   SDocVisibility             = 'Visibility';
   SDocOpaque                 = 'Opaque type';
   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';
   
   // Topics
@@ -129,37 +137,43 @@ resourcestring
 
   STitle           = 'FPDoc - Free Pascal Documentation Tool';
   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]';
   SUsageOption010  = '--content         Create content file for package cross-references';
   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';
-  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:';
   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>';
   SWritingPages               = 'Writing %d pages...';
   SNeedPackageName            = 'No package name specified. Please specify one using the --package option.';
+  SAvailablePackages          = 'Available packages: ';
   SDone                       = 'Done.';
   SErrCouldNotCreateOutputDir = 'Could not create output directory "%s"';
   SErrCouldNotCreateFile      = 'Could not create file "%s": %s';
@@ -190,6 +205,8 @@ type
     destructor Destroy; override;
   end;
 
+  TPasExternalClassType = Class(TPasClassType);
+  TPasExternalModule = Class(TPasModule);
 
   { Link entry tree
     TFPDocEngine stores the root of the entry tree in its property
@@ -284,6 +301,8 @@ type
   private
     FDocLogLevels: TFPDocLogLevels;
     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
     DescrDocs: TObjectList;             // List of XML documents
     DescrDocNames: TStringList;         // Names of the XML documents
@@ -319,7 +338,7 @@ type
     // Link tree support
     procedure AddLink(const APathName, ALinkTo: 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;
 
     // Documentation file support
@@ -453,7 +472,6 @@ begin
     end;
     { No child found, let's create one if we are at the end of the path }
     if DotPos > 0 then
-      // !!!: better throw an exception
       Raise Exception.CreateFmt('Link path does not exist: %s',[APathName]);
     Result := TLinkNode.Create(ChildName, ALinkTo);
     if Assigned(LastChild) then
@@ -603,7 +621,6 @@ var
 begin
   for i := 0 to FPackages.Count - 1 do
     TPasPackage(FPackages[i]).Release;
-  FPackages.Free;
   FRootDocNode.Free;
   FRootLinkNode.Free;
   DescrDocNames.Free;
@@ -675,6 +692,8 @@ var
         Inc(i);
       NewNode := TLinkNode.Create(Copy(s, ThisSpaces + 1, i - ThisSpaces - 1),
         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
         PrevSibling.FNextSibling := NewNode
       else
@@ -728,7 +747,7 @@ var
       begin
         if not CreateNew then
           exit;
-        Module := TPasModule.Create(s, HPackage);
+        Module := TPasExternalModule.Create(s, HPackage);
         Module.InterfaceSection := TInterfaceSection.Create('', Module);
         HPackage.Modules.Add(Module);
       end;
@@ -789,7 +808,7 @@ var
     begin
       s:= ResolvePackageModule(AName,HPackage,Module,True);
       // Create node for class
-      Result := TPasClassType.Create(s, Module.InterfaceSection);
+      Result := TPasExternalClassType.Create(s, Module.InterfaceSection);
       Result.ObjKind := okClass;
       Module.InterfaceSection.Declarations.Add(Result);
       Module.InterfaceSection.Classes.Add(Result);
@@ -965,11 +984,14 @@ end;
 
 var
   s: String;
+  buf : Array[1..ContentBufSize-1] of byte;
+
 begin
   if not FileExists(AFileName) then
     raise EInOutError.Create('File not found: ' + AFileName);
   Assign(f, AFilename);
   Reset(f);
+  SetTextBuf(F,Buf,SizeOf(Buf));
   while not EOF(f) do
   begin
     ReadLn(f, s);
@@ -1019,9 +1041,11 @@ var
   ClassDecl: TPasClassType;
   Member: TPasElement;
   s: String;
+  Buf : Array[0..ContentBufSize-1] of byte;
 begin
   Assign(ContentFile, AFilename);
   Rewrite(ContentFile);
+  SetTextBuf(ContentFile,Buf,SizeOf(Buf));
   try
     WriteLn(ContentFile, '# FPDoc Content File');
     WriteLn(ContentFile, ':link tree');
@@ -1042,6 +1066,8 @@ begin
     for i := 0 to Package.Modules.Count - 1 do
     begin
       Module := TPasModule(Package.Modules[i]);
+      if not assigned(Module.InterfaceSection) then
+        continue;
       for j := 0 to Module.InterfaceSection.Classes.Count - 1 do
       begin
         ClassDecl := TPasClassType(Module.InterfaceSection.Classes[j]);
@@ -1147,11 +1173,11 @@ var
   Module: TPasElement;
 begin
   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
     begin
       Module := TPasElement(CurModule.InterfaceSection.UsesList[i]);
-      if Module.ClassType = TPasModule then
+      if Module.ClassType.InheritsFrom(TPasModule) then
       begin
         Result := FindInModule(TPasModule(Module), AName);
         if Assigned(Result) then
@@ -1231,84 +1257,77 @@ begin
     SetLength(Result, 0);
 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
-  // 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
-      Result := ResolveLink(AModule, AModule.PathName + '.' + ALinkDest);
-      if CanWeExit(Result) then
-        Exit;
+    Result:=ResolveLink(AModule, ThisPackage.Name + '.' + ALinkDest, Strict);
+    ThisPackage := ThisPackage.NextSibling;
     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
-      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;
+
+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
-      { 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
-        { 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;
-
-  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
       if ALinkDest[i] = '.' then
-      begin
-        Result := ResolveLink(AModule, Copy(ALinkDest, 1, i - 1));
+        begin
+        Result := ResolveLink(AModule, Copy(ALinkDest, 1, i - 1), Strict);
         exit;
-      end;
+        end;
 end;
 
 procedure ReadXMLFileALT(OUT ADoc:TXMLDocument;const AFileName:ansistring);
@@ -1503,7 +1522,7 @@ begin
           break;
         CurPackage := CurPackage.NextSibling;
       end;
-      if not Assigned(Result) then
+      if not Assigned(Result) and assigned(CurModule.InterfaceSection) then
       begin
         { Okay, then we have to try all imported units of the current module }
         UnitList := CurModule.InterfaceSection.UsesList;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 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 Function FileNameExtension : String; override;
-    
+    Class procedure SplitImport(var AFilename, ALinkPrefix: String); override;
   end;
 {$ELSE} // implementation
 
@@ -175,6 +175,8 @@ begin
     for i := 0 to Package.Modules.Count - 1 do
     begin
       AModule := TPasModule(Package.Modules[i]);
+      If not assigned(AModule.InterfaceSection) Then
+         Continue;
       ObjUnitItem := ObjByUnitItem.Children.NewItem;
       ObjUnitItem.Text := AModule.Name;
       RoutinesUnitItem := RoutinesByUnitItem.Children.NewItem;
@@ -292,6 +294,8 @@ begin
     for i := 0 to Package.Modules.Count - 1 do
     begin
       AModule := TPasModule(Package.Modules[i]);
+      if not assigned(AModule.InterfaceSection) then
+        continue;
       ParentItem := Index.Items.NewItem;
       ParentItem.Text := AModule.Name;
       ParentItem.Local := FixHTMLpath(Allocator.GetFilename(AModule, 0));
@@ -341,7 +345,7 @@ begin
       begin
         ParentElement := TPasProcedureType(AModule.InterfaceSection.Functions[j]);
         TmpItem := Index.Items.NewItem;
-        TmpItem.Text := ParentElement.Name + ' ' + TPasFunction(ParentElement).ElementTypeName;
+        TmpItem.Text := ParentElement.Name + ' ' + ParentElement.ElementTypeName;
         TmpItem.Local := FixHTMLpath(Allocator.GetFilename(ParentElement, 0));
       end;
       // consts
@@ -565,4 +569,21 @@ begin
   result:='.chm';
 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}

+ 119 - 10
utils/fpdoc/dw_ipflin.pas

@@ -141,6 +141,7 @@ type
   public
     constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
     class function FileNameExtension: string; override;
+    procedure WriteClassInheritanceOverview(ClassDecl: TPasClassType); override;
   end;
 
 
@@ -148,7 +149,7 @@ type
 implementation
 
 uses
-  SysUtils, dwriter;
+  SysUtils, dwriter, dbugintf;
 
 
 { TFPDocWriter overrides }
@@ -195,7 +196,6 @@ const
   cMax = 100;
 var
   sl: TStringlist;
-  ns: string;
   i: integer;
   lText: string;
 begin
@@ -500,6 +500,117 @@ begin
   InTypesDeclaration := False;
 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}
 
 class function TIPFNewWriter.FileNameExtension: String;
@@ -509,17 +620,15 @@ end;
 
 procedure TIPFNewWriter.DescrBeginURL(const AURL: DOMString);
 begin
-  //Write(EscapeText(AURL));
+  Write(':link reftype=launch object=''netscape'' data=''' + AURL + '''.');
 end;
 
 procedure TIPFNewWriter.DescrEndURL;
 begin
-  // do nothing
+  Write(':elink.');
 end;
 
 function TIPFNewWriter.GetLabel(AElement: TPasElement): String;
-var
-  i: Integer;
 begin
   if AElement.ClassType = TPasUnresolvedTypeRef then
     Result := Engine.ResolveLink(Module, AElement.Name)
@@ -590,7 +699,7 @@ end;
 
 Function TIPFNewWriter.StripText(S : String) : String;
 var
-  I,L: Integer;
+  I: Integer;
 begin
   //Result := S;
   SetLength(Result, 0);
@@ -611,7 +720,7 @@ begin
   fColCount := 0;
   Writeln(':userdoc.');
   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(':docprof toc=12345.');
   WriteLn(':title.' + PackageName);
@@ -735,9 +844,9 @@ begin
     DescrEndBold;
 //    writeln(':lm margin=3.');
     writeln('.br');
-  end;
+  end
 
-  if InPackageOverview then
+  else if InPackageOverview then
   begin
     FInHeadingText := ':h2%s. ' + SectionName;
 //    Writeln(':h2.' + SectionName);

+ 1 - 1
utils/fpdoc/dw_latex.pp

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

+ 4 - 2
utils/fpdoc/dw_xml.pp

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

+ 15 - 4
utils/fpdoc/dwlinear.pp

@@ -86,6 +86,8 @@ Type
     procedure WriteUnitEntry(UnitRef : TPasType);virtual; Abstract;
     procedure EndUnitOverview; virtual; Abstract;
     Property LastURL : DomString Read FLastURL Write FLastURL;
+    // Overriden from fpdocwriter;
+    procedure DescrWriteText(const AText: DOMString); override;
   Public
     Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
     function InterpretOption(const Cmd, Arg: String): Boolean; override;
@@ -107,13 +109,12 @@ Type
     procedure WriteClassDecl(ClassDecl: TPasClassType);
     procedure WriteClassMethodOverview(ClassDecl: TPasClassType);
     procedure WriteClassPropertyOverview(ClassDecl: TPasClassType);
-    procedure WriteClassInterfacesOverView(ClassDecl: TPasClassType);
+    procedure WriteClassInterfacesOverview(ClassDecl: TPasClassType);
+    procedure WriteClassInheritanceOverview(ClassDecl: TPasClassType); virtual;
     procedure WriteProperty(PropDecl: TPasProperty);
     procedure WriteExample(ADocNode: TDocNode);
     procedure WriteSeeAlso(ADocNode: TDocNode);
     Procedure WriteTopicNode(Node : TDocNode; Level : Integer);
-    // Overriden from fpdocwriter;
-    procedure DescrWriteText(const AText: DOMString); override;
   end;
 
 implementation
@@ -415,6 +416,10 @@ begin
     ConvertNotes(ClassDecl,DocNode.Notes);
   end;
 
+  // graemeg: this must move above SeeAlso, Version and Notes written above.
+  // Write Class Hierarchy (Inheritance) Overview;
+  WriteClassInheritanceOverView(ClassDecl);
+
   // Write Interfaces Overview;
   WriteClassInterfacesOverView(ClassDecl);
   // Write method overview
@@ -517,7 +522,7 @@ begin
 end;
 
 
-procedure TLinearWriter.WriteClassInterfacesOverView(ClassDecl: TPasClassType);
+procedure TLinearWriter.WriteClassInterfacesOverview(ClassDecl: TPasClassType);
 var
   lInterface: TPasElement;
   i: Integer;
@@ -571,6 +576,12 @@ begin
   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;
 begin

+ 89 - 56
utils/fpdoc/dwriter.pp

@@ -3,6 +3,8 @@
     FPDoc  -  Free Pascal Documentation Tool
     Copyright (C) 2000 - 2003 by
       Areca Systems GmbH / Sebastian Guenther, [email protected]
+    2005-2012 by
+      various FPC contributors
 
     * Output string definitions
     * Basic writer (output generator) class
@@ -45,7 +47,7 @@ resourcestring
 
   SErrDescrTagUnknown = 'Warning: Unknown tag "%s" in description';
   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"';
   SErrUnknownLink = 'Could not resolve link to "%s"';
   SErralreadyRegistered = 'Class for output format "%s" already registered';
@@ -73,6 +75,7 @@ type
     FEmitNotes: Boolean;
     FEngine  : TFPDocEngine;
     FPackage : TPasPackage;
+    FContext : TPasElement;
     FTopics  : TList;
     FImgExt : String;
     FBeforeEmitNote : TWriterNoteEvent;
@@ -157,6 +160,7 @@ type
     procedure DescrEndTableRow; virtual; abstract;
     procedure DescrBeginTableCell; virtual; abstract;
     procedure DescrEndTableCell; virtual; abstract;
+    Property CurrentContext : TPasElement Read FContext ;
   public
     Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); virtual;
     destructor Destroy;  override;
@@ -168,6 +172,7 @@ type
     Function InterpretOption(Const Cmd,Arg : String) : Boolean; Virtual;
     Class Function FileNameExtension : String; virtual;
     Class Procedure Usage(List : TStrings); virtual;
+    Class procedure SplitImport(var AFilename, ALinkPrefix: String); virtual;
     procedure WriteDoc; virtual; Abstract;
     Function WriteDescr(Element: TPasElement) : TDocNode;
     procedure WriteDescr(Element: TPasElement; DocNode: TDocNode);
@@ -370,6 +375,19 @@ begin
   // Do nothing.
 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;
 
 Var
@@ -475,20 +493,24 @@ begin
   Result := False;
   if not Assigned(El) then
     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;
-  Result := True;
 end;
 
 function TFPDocWriter.ConvertNotes(AContext: TPasElement; El: TDOMElement
@@ -594,6 +616,7 @@ function TFPDocWriter.ConvertBaseShort(AContext: TPasElement;
 var
   El, DescrEl: TDOMElement;
   FPEl: TPasElement;
+  hlp : TPasElement;
 begin
   Result := True;
   if Node.NodeType = ELEMENT_NODE then
@@ -622,7 +645,12 @@ begin
     else if Node.NodeName = 'printshort' then
     begin
       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
         ConvertShort(AContext, DescrEl)
       else
@@ -716,53 +744,58 @@ var
   Node, Child: TDOMNode;
   ParaCreated: Boolean;
 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
-      if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'section') then
+      while Assigned(Node) do
       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
-          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;
 
 procedure TFPDocWriter.ConvertExtShortOrNonSectionBlocks(AContext: TPasElement;

+ 18 - 6
utils/fpdoc/fpclasschart.lpi

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

+ 11 - 108
utils/fpdoc/fpclasschart.pp

@@ -19,7 +19,7 @@ program fpclasschart;
 
 uses
   SysUtils, Classes, Typinfo, Gettext, dom, xmlread,
-  dGlobals, PasTree, PParser,PScanner, xmlwrite;
+  dGlobals, PasTree, PParser,PScanner, xmlwrite, fpdocclasstree;
 
 resourcestring
   STitle = 'fpClassTree - Create class tree from pascal sources';
@@ -33,28 +33,18 @@ resourcestring
   SMergedFile = 'Merged %d classes from file %s.';
   SClassesAdded = 'Added %d classes from %d files.';
 
-Const
-  RootNames : Array[TPasObjKind] of string
-            = ('Objects', 'Classes', 'Interfaces','Generics','Specializations');
-
 type
 
   { TClassTreeEngine }
 
+
   TClassTreeEngine = class(TFPDocEngine)
   Private
-    FClassTree : TXMLDocument;
-    FTreeStart : TDomElement;
+    FTree : TClassTreeBuilder;
     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
     Constructor Create(AClassTree : TXMLDocument; AObjectKind : TPasObjKind);
     Destructor Destroy; override;
-    Function BuildTree : Integer;
     function CreateElement(AClass: TPTreeElement; const AName: String;
       AParent: TPasElement; AVisibility :TPasMemberVisibility;
       const ASourceFilename: String; ASourceLinenumber: Integer): TPasElement; override;
@@ -99,6 +89,11 @@ type
     Property MaxObjectsPerColumn : Integer Read FMaxObjectsPerColumn Write FMaxObjectsPerColumn;
   end;
 
+{ TClassTreeBuilder }
+
+
+
+
 { TChartFormatter }
 
 constructor TClassChartFormatter.Create(AXML: TXMLDocument);
@@ -454,21 +449,11 @@ end;
 
 Constructor TClassTreeEngine.Create(AClassTree : TXMLDocument; AObjectKind : TPasObjKind);
 
-Var
-  N : TDomNode;
 
 begin
-  FClassTree:=AClassTree;
-  FTreeStart:=FClassTree.DocumentElement;
   FPackage:=TPasPackage.Create('dummy',Nil);
-  FObjectKind:=AObjectKind;
+  FTree:=TClassTreeBuilder.Create(FPackage,AObjectKind);
   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;
 end;
 
@@ -478,89 +463,7 @@ begin
   inherited Destroy;
 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.    
   ---------------------------------------------------------------------}
@@ -622,7 +525,7 @@ begin
   XML:=TXMLDocument.Create;
   Try
     //XML.
-    XML.AppendChild(XML.CreateElement(RootNames[AObjectKind]));
+    XML.AppendChild(XML.CreateElement(ObjKindNames[AObjectKind]));
     For I:=0 to MergeFiles.Count-1 do
       begin
       XMl2:=TXMLDocument.Create;
@@ -640,7 +543,7 @@ begin
       Engine := TClassTreeEngine.Create(XML,AObjectKind);
       Try
         ParseSource(Engine,InputFiles[I],OSTarget,CPUTarget);
-        ACount:=ACount+Engine.BuildTree;
+        ACount:=ACount+Engine.Ftree.BuildTree(Engine.FObjects);
       Finally
         Engine.Free;
       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
   by Sebastian Guenther, [email protected]
@@ -62,6 +62,10 @@ span.code {
 span.sym {
   color: darkred
 }
+/* No wordwrap in code fragments */
+span.code {
+   white-space: nowrap
+}
 
 /* keywords in source fragments */
 span.kw {
@@ -127,40 +131,30 @@ table.bar {
   background-color: #a0c0ff;
 }
 
+td p {
+ margin: 0;
+}
+
 span.bartitle {
   font-weight: bold;
   font-style: italic;
   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>
       <local>
         <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)"/>
       </local>
     </RunParams>
@@ -40,7 +40,7 @@
         <PackageName Value="FCL"/>
       </Item1>
     </RequiredPackages>
-    <Units Count="15">
+    <Units Count="16">
       <Unit0>
         <Filename Value="fpdoc.pp"/>
         <IsPartOfProject Value="True"/>
@@ -116,6 +116,11 @@
         <IsPartOfProject Value="True"/>
         <UnitName Value="mkfpdoc"/>
       </Unit14>
+      <Unit15>
+        <Filename Value="fpdocclasstree.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="fpdocclasstree"/>
+      </Unit15>
     </Units>
   </ProjectOptions>
   <CompilerOptions>

+ 41 - 19
utils/fpdoc/fpdoc.pp

@@ -3,6 +3,8 @@
     FPDoc  -  Free Pascal Documentation Tool
     Copyright (C) 2000 - 2003 by
       Areca Systems GmbH / Sebastian Guenther, [email protected]
+    2005-2012 by
+      various FPC contributors
 
     See the file COPYING, included in this distribution,
     for details about the copyright.
@@ -20,7 +22,8 @@ uses
   cwstring,
 {$endif}
   SysUtils, Classes, Gettext, custapp,
-  dGlobals,  // GLobal definitions, constants.
+  dGlobals,  // Global definitions, constants.
+  fpdocclasstree, // Class tree builder
   dwriter,   // TFPDocWriter definition.
   dwlinear,  // Linear (abstract) writer
   dw_LaTeX,  // TLaTex writer
@@ -30,14 +33,15 @@ uses
   dw_ipflin, // IPF writer (new linear output)
   dw_man,    // Man page writer
   dw_linrtf, // linear RTF writer
-  dw_txt, fpdocproj, mkfpdoc;    // TXT writer
+  dw_txt,    // TXT writer
+  fpdocproj, mkfpdoc;
 
 
 Type
 
-  { TFPDocAplication }
+  { TFPDocApplication }
 
-  TFPDocAplication = Class(TCustomApplication)
+  TFPDocApplication = Class(TCustomApplication)
   private
     FCreator : TFPDocCreator;
     FPackage : TFPDocPackage;
@@ -47,7 +51,7 @@ Type
   Protected
     procedure OutputLog(Sender: TObject; const Msg: String);
     procedure ParseCommandLine;
-    procedure Parseoption(const S: String);
+    procedure ParseOption(const S: String);
     Procedure Usage(AnExitCode : Byte);
     Procedure DoRun; override;
   Public
@@ -57,7 +61,7 @@ Type
   end;
 
 
-Procedure TFPDocAplication.Usage(AnExitCode : Byte);
+Procedure TFPDocApplication.Usage(AnExitCode : Byte);
 
 Var
   I,P : Integer;
@@ -71,6 +75,7 @@ begin
   Writeln(SUsageOption010);
   Writeln(SUsageOption020);
   Writeln(SUsageOption030);
+  Writeln(SUsageOption035);
   Writeln(SUsageOption040);
   Writeln(SUsageOption050);
   Writeln(SUsageOption060);
@@ -83,7 +88,6 @@ begin
   Writeln(SUsageOption130);
   Writeln(SUsageOption140);
   Writeln(SUsageOption150);
-  Writeln(SUsageOption155);
   Writeln(SUsageOption160);
   Writeln(SUsageOption170);
   Writeln(SUsageOption180);
@@ -95,6 +99,12 @@ begin
   Writeln(SUsageOption240);
   Writeln(SUsageOption250);
   Writeln(SUsageOption260);
+  Writeln(SUsageOption270);
+  Writeln(SUsageOption280);
+  Writeln(SUsageOption290);
+  Writeln(SUsageOption300);
+  Writeln(SUsageOption310);
+  Writeln(SUsageOption320);
   L:=TStringList.Create;
   Try
     Backend:=FCreator.OPtions.Backend;
@@ -130,29 +140,40 @@ begin
   Halt(AnExitCode);
 end;
 
-destructor TFPDocAplication.Destroy;
+destructor TFPDocApplication.Destroy;
 
 begin
   FreeAndNil(FCreator);
   Inherited;
 end;
 
-function TFPDocAplication.SelectedPackage: TFPDocPackage;
+function TFPDocApplication.SelectedPackage: TFPDocPackage;
+var
+  i:integer;
 begin
   Result:=FPackage;
   if (FPackage=Nil) or (FPackage.Name='') then
     begin
     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);
     end;
 end;
 
-procedure TFPDocAplication.OutputLog(Sender: TObject; const Msg: String);
+procedure TFPDocApplication.OutputLog(Sender: TObject; const Msg: String);
 begin
   Writeln(StdErr,Msg);
 end;
 
-procedure TFPDocAplication.ParseCommandLine;
+procedure TFPDocApplication.ParseCommandLine;
 
   Function ProjectOpt(Const s : string) : boolean;
 
@@ -183,8 +204,8 @@ begin
       Fpackage:=FCreator.Packages.FindPackage(FCreator.Options.DefaultPackageName);
     end;
   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;
   // Check package
   for i := 1 to ParamCount do
@@ -202,7 +223,7 @@ begin
   SelectedPackage; // Will print error if none available.
 end;
 
-procedure TFPDocAplication.Parseoption(Const S : String);
+procedure TFPDocApplication.ParseOption(Const S : String);
 
   procedure AddDirToFileList(List: TStrings; const ADirName, AMask: String);
 
@@ -266,7 +287,7 @@ begin
   else if s = '--stop-on-parser-error' then
     FCreator.Options.StopOnParseError := True
   else if s = '--dont-trim' then
-    FCreator.Options.donttrim := True
+    FCreator.Options.DontTrim := True
   else
     begin
     i := Pos('=', s);
@@ -343,7 +364,7 @@ begin
     end;
 end;
 
-Procedure TFPDocAplication.DoRun;
+Procedure TFPDocApplication.DoRun;
 
 begin
 {$IFDEF Unix}
@@ -353,7 +374,8 @@ begin
 {$ENDIF}
   WriteLn(STitle);
   WriteLn(Format(SVersion, [DefFPCVersion, DefFPCDate]));
-  WriteLn(SCopyright);
+  WriteLn(SCopyright1);
+  WriteLn(SCopyright2);
   WriteLn;
   ParseCommandLine;
   if (FWriteProjectFile<>'') then
@@ -364,7 +386,7 @@ begin
   Terminate;
 end;
 
-constructor TFPDocAplication.Create(AOwner: TComponent);
+constructor TFPDocApplication.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
   StopOnException:=true;
@@ -373,7 +395,7 @@ begin
 end;
 
 begin
-  With TFPDocAplication.Create(Nil) do
+  With TFPDocApplication.Create(Nil) do
     try
       Run;
     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
     FContent: String;
     FDescriptions: TStrings;
-    FIMports: TStrings;
-    FinPuts: TStrings;
+    FImports: TStrings;
+    FInputs: TStrings;
     FName: String;
     FOutput: String;
   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
     Copyright (C) 2000 - 2003 by
       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,
     for details about the copyright.
@@ -28,7 +33,6 @@ uses
 resourcestring
   STitle = 'MakeSkel - FPDoc skeleton XML description file generator';
   SVersion = 'Version %s [%s]';
-  SCopyright = '(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, [email protected]';
   SCmdLineHelp = 'See documentation for usage.';
   SCmdLineInvalidOption = 'Ignoring unknown option "%s"';
   SNoPackageNameProvided = 'Please specify a package name with --package=<name>';
@@ -188,6 +192,14 @@ Var
 begin
   Result := AClass.Create(AName, AParent);
   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
     CurModule := TPasModule(Result);
   // Track this element
@@ -344,6 +356,8 @@ Var
   N : TDocNode;
      
 begin
+  if not(FileExists(AFileName)) then
+    raise Exception.CreateFmt('Cannot find source file %s to document.',[AFileName]);
   FNodeList:=TStringList.Create;
   Try
     FEmittedList:=TStringList.Create;
@@ -614,7 +628,8 @@ var
 begin
   WriteLn(STitle);
   WriteLn(Format(SVersion, [FPCVersion, FPCDate]));
-  WriteLn(SCopyright);
+  WriteLn(SCopyright1);
+  WriteLn(SCopyright2);
   InitOptions;
   Try
     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
     Constructor Create(AOwner : TComponent); 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);
     Property Project : TFPDocProject Read FProject;
     Property ScannerLogEvents : TPScannerLogEvents Read FScannerLogEvents Write FScannerLogEvents;
@@ -186,16 +186,19 @@ var
   i,j: Integer;
   Engine : TFPDocEngine;
   Cmd,Arg : String;
+  WriterClass: TFPDocWriterClass;
 
 begin
+  Cmd:='';
   FCurPackage:=APackage;
   Engine:=TFPDocEngine.Create;
   try
+    WriterClass:=GetWriterClass(Options.Backend);
     For J:=0 to Apackage.Imports.Count-1 do
       begin
       Arg:=Apackage.Imports[j];
-      i := Pos(',', Arg);
-      Engine.ReadContentFile(Copy(Arg,1,i-1),Copy(Arg,i+1,Length(Arg)));
+      WriterClass.SplitImport(Arg,Cmd);
+      Engine.ReadContentFile(Arg, Cmd);
       end;
     for i := 0 to APackage.Descriptions.Count - 1 do
       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>
 </element>
 
+<element name="AStringConst" link="ABooleanConst"/>
+
 <!-- constant Visibility: default -->
 <element name="AStringConst">
 <short></short>
@@ -488,7 +490,7 @@ Appears in 2.0
 
 <!-- function result Visibility: default -->
 <element name="OverloadedFunc.Result">
-<short></short>
+<short>Soso</short>
 </element>
 
 <!-- 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.
+

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels