浏览代码

Merged revisions 13218-13347 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

git-svn-id: branches/objc@13350 -

Jonas Maebe 16 年之前
父节点
当前提交
92de010fe1
共有 100 个文件被更改,包括 3780 次插入1399 次删除
  1. 35 13
      .gitattributes
  2. 4 3
      compiler/aggas.pas
  3. 4 4
      compiler/aoptda.pas
  4. 19 4
      compiler/arm/cpuinfo.pas
  5. 1 1
      compiler/avr/cgcpu.pas
  6. 27 0
      compiler/avr/cpuinfo.pas
  7. 1 1
      compiler/avr/navrmat.pas
  8. 123 0
      compiler/cclasses.pas
  9. 10 18
      compiler/cfileutl.pas
  10. 42 37
      compiler/dbgdwarf.pas
  11. 46 9
      compiler/dbgstabs.pas
  12. 2 2
      compiler/fpcdefs.inc
  13. 28 19
      compiler/globals.pas
  14. 32 9
      compiler/htypechk.pas
  15. 7 7
      compiler/i386/daopt386.pas
  16. 1 1
      compiler/link.pas
  17. 48 19
      compiler/msg/errord.msg
  18. 49 20
      compiler/msg/errordu.msg
  19. 32 24
      compiler/msg/errore.msg
  20. 8 7
      compiler/msgidx.inc
  21. 303 299
      compiler/msgtxt.inc
  22. 9 22
      compiler/ncal.pas
  23. 21 8
      compiler/ncgcal.pas
  24. 4 4
      compiler/ncgflw.pas
  25. 20 1
      compiler/ncgld.pas
  26. 8 1
      compiler/ncgrtti.pas
  27. 10 1
      compiler/ncnv.pas
  28. 4 3
      compiler/nmem.pas
  29. 10 1
      compiler/node.pas
  30. 5 0
      compiler/options.pas
  31. 147 33
      compiler/optvirt.pas
  32. 19 5
      compiler/parser.pas
  33. 18 0
      compiler/pdecobj.pas
  34. 16 2
      compiler/pdecsub.pas
  35. 4 1
      compiler/pinline.pas
  36. 3 3
      compiler/pmodules.pas
  37. 3 2
      compiler/powerpc/agppcmpw.pas
  38. 2 1
      compiler/powerpc/cpupi.pas
  39. 3 2
      compiler/powerpc64/cpupi.pas
  40. 1 1
      compiler/ppu.pas
  41. 7 1
      compiler/ptconst.pas
  42. 20 17
      compiler/scandir.pas
  43. 13 4
      compiler/symdef.pas
  44. 2 1
      compiler/symsym.pas
  45. 1 2
      compiler/symtable.pas
  46. 2 1
      compiler/systems.pas
  47. 2 2
      compiler/systems/i_embed.pas
  48. 2 0
      compiler/systems/i_gba.pas
  49. 2 0
      compiler/systems/i_nds.pas
  50. 55 25
      compiler/systems/t_embed.pas
  51. 1 1
      compiler/systems/t_gba.pas
  52. 1 1
      compiler/systems/t_nds.pas
  53. 128 1
      compiler/wpobase.pas
  54. 72 20
      compiler/wpoinfo.pas
  55. 2 2
      ide/fpdebug.pas
  56. 3 3
      ide/fpkeys.pas
  57. 1 1
      ide/fpmingw.pas
  58. 2 2
      ide/fpviews.pas
  59. 1 0
      packages/chm/src/chmreader.pas
  60. 6 0
      packages/fcl-base/src/daemonapp.pp
  61. 5 1
      packages/fcl-base/src/win/daemonapp.inc
  62. 123 3
      packages/fcl-db/src/codegen/fpcgtiopf.pp
  63. 99 13
      packages/fcl-db/src/datadict/fpdatadict.pp
  64. 2 0
      packages/fcl-db/src/datadict/fpddsqldb.pp
  65. 8 1
      packages/fcl-db/src/sqldb/sqldb.pp
  66. 40 9
      packages/fcl-db/src/sqlite/customsqliteds.pas
  67. 2 2
      packages/fcl-image/src/fpcolhash.pas
  68. 1 1
      packages/fcl-image/src/fpreadbmp.pp
  69. 46 1
      packages/fcl-json/Makefile
  70. 2 2
      packages/fcl-net/src/mkxmlrpc.pp
  71. 2 2
      packages/fcl-net/src/ssockets.pp
  72. 18 18
      packages/fcl-web/Makefile
  73. 14 2
      packages/fcl-web/Makefile.fpc
  74. 13 4
      packages/fcl-web/src/custfcgi.pp
  75. 2 2
      packages/fcl-web/src/fpweb.pp
  76. 7 1
      packages/fcl-web/src/httpdefs.pp
  77. 352 69
      packages/fcl-xml/src/dom.pp
  78. 6 1
      packages/fcl-xml/src/htmwrite.pp
  79. 15 5
      packages/fcl-xml/src/sax_html.pp
  80. 180 115
      packages/fcl-xml/src/xmlread.pp
  81. 6 1
      packages/fcl-xml/src/xmlwrite.pp
  82. 365 321
      packages/fcl-xml/src/xpath.pp
  83. 7 3
      packages/fcl-xml/tests/api.xml
  84. 147 30
      packages/fcl-xml/tests/xpathts.pp
  85. 5 5
      packages/fpgtk/src/fpgtk.pp
  86. 186 22
      packages/fpmkunit/src/fpmkunit.pp
  87. 3 2
      packages/gdbint/src/gdbint.pp
  88. 4 2
      packages/graph/src/inc/fills.inc
  89. 18 15
      packages/graph/src/inc/graph.inc
  90. 7 5
      packages/gtk2/src/gtk+/gdk/gdkevents.inc
  91. 9 1
      packages/iconvenc/src/iconvert.inc
  92. 3 2
      packages/libxml/src/xml2.pas
  93. 25 0
      packages/mysql/src/mysql.inc
  94. 11 3
      packages/objcrtl/src/objcrtlutils.pas
  95. 59 59
      packages/winunits-base/Makefile
  96. 1 1
      packages/winunits-base/Makefile.fpc
  97. 6 0
      packages/winunits-base/fpmake.pp
  98. 2 2
      packages/winunits-base/src/activex.pp
  99. 2 1
      packages/winunits-base/src/buildwinutilsbase.pp
  100. 525 0
      packages/winunits-base/src/dwmapi.pp

+ 35 - 13
.gitattributes

@@ -5031,9 +5031,12 @@ packages/winunits-base/src/comconst.pp svneol=native#text/plain
 packages/winunits-base/src/commctrl.pp svneol=native#text/plain
 packages/winunits-base/src/commctrl.pp svneol=native#text/plain
 packages/winunits-base/src/commdlg.pp svneol=native#text/plain
 packages/winunits-base/src/commdlg.pp svneol=native#text/plain
 packages/winunits-base/src/comobj.pp svneol=native#text/plain
 packages/winunits-base/src/comobj.pp svneol=native#text/plain
+packages/winunits-base/src/dwmapi.pp svneol=native#text/plain
 packages/winunits-base/src/flatsb.pp svneol=native#text/plain
 packages/winunits-base/src/flatsb.pp svneol=native#text/plain
+packages/winunits-base/src/htmlhelp.pp svneol=native#text/plain
 packages/winunits-base/src/imagehlp.pp svneol=native#text/plain
 packages/winunits-base/src/imagehlp.pp svneol=native#text/plain
 packages/winunits-base/src/mmsystem.pp svneol=native#text/plain
 packages/winunits-base/src/mmsystem.pp svneol=native#text/plain
+packages/winunits-base/src/multimon.pp svneol=native#text/plain
 packages/winunits-base/src/ole2.pp svneol=native#text/plain
 packages/winunits-base/src/ole2.pp svneol=native#text/plain
 packages/winunits-base/src/oleserver.pp svneol=native#text/plain
 packages/winunits-base/src/oleserver.pp svneol=native#text/plain
 packages/winunits-base/src/richedit.pp svneol=native#text/plain
 packages/winunits-base/src/richedit.pp svneol=native#text/plain
@@ -5525,6 +5528,7 @@ rtl/darwin/x86_64/sig_cpu.inc svneol=native#text/plain
 rtl/darwin/x86_64/sighnd.inc svneol=native#text/plain
 rtl/darwin/x86_64/sighnd.inc svneol=native#text/plain
 rtl/embedded/Makefile svneol=native#text/plain
 rtl/embedded/Makefile svneol=native#text/plain
 rtl/embedded/Makefile.fpc svneol=native#text/plain
 rtl/embedded/Makefile.fpc svneol=native#text/plain
+rtl/embedded/arm/at91sam7x256.pp svneol=native#text/plain
 rtl/embedded/arm/lpc21x4.pp svneol=native#text/plain
 rtl/embedded/arm/lpc21x4.pp svneol=native#text/plain
 rtl/embedded/check.inc svneol=native#text/plain
 rtl/embedded/check.inc svneol=native#text/plain
 rtl/embedded/empty.cfg -text
 rtl/embedded/empty.cfg -text
@@ -6017,26 +6021,27 @@ rtl/morphos/varutils.pp svneol=native#text/plain
 rtl/morphos/video.pp svneol=native#text/plain
 rtl/morphos/video.pp svneol=native#text/plain
 rtl/morphos/videodata.inc svneol=native#text/plain
 rtl/morphos/videodata.inc svneol=native#text/plain
 rtl/nds/Makefile svneol=native#text/plain
 rtl/nds/Makefile svneol=native#text/plain
-rtl/nds/Makefile.fpc -text
-rtl/nds/classes.pp -text
+rtl/nds/Makefile.fpc svneol=native#text/plain
+rtl/nds/classes.pp svneol=native#text/plain
 rtl/nds/cprt07.as svneol=native#text/plain
 rtl/nds/cprt07.as svneol=native#text/plain
 rtl/nds/cprt09.as svneol=native#text/plain
 rtl/nds/cprt09.as svneol=native#text/plain
-rtl/nds/dos.pp -text
+rtl/nds/dos.pp svneol=native#text/plain
 rtl/nds/nds.inc svneol=native#text/plain
 rtl/nds/nds.inc svneol=native#text/plain
-rtl/nds/ndsbios.inc -text
-rtl/nds/ndsbiosh.inc -text
+rtl/nds/ndsbios.inc svneol=native#text/plain
+rtl/nds/ndsbiosh.inc svneol=native#text/plain
 rtl/nds/ndsh.inc svneol=native#text/plain
 rtl/nds/ndsh.inc svneol=native#text/plain
 rtl/nds/prt07.as svneol=native#text/plain
 rtl/nds/prt07.as svneol=native#text/plain
 rtl/nds/prt09.as svneol=native#text/plain
 rtl/nds/prt09.as svneol=native#text/plain
-rtl/nds/sysdir.inc -text
-rtl/nds/sysfile.inc -text
+rtl/nds/sysdir.inc svneol=native#text/plain
+rtl/nds/sysfile.inc svneol=native#text/plain
 rtl/nds/sysheap.inc svneol=native#text/x-pascal
 rtl/nds/sysheap.inc svneol=native#text/x-pascal
-rtl/nds/sysos.inc -text
-rtl/nds/sysosh.inc -text
+rtl/nds/sysos.inc svneol=native#text/plain
+rtl/nds/sysosh.inc svneol=native#text/plain
+rtl/nds/system.pp svneol=native#text/plain
 rtl/nds/systhrd.inc svneol=native#text/plain
 rtl/nds/systhrd.inc svneol=native#text/plain
-rtl/nds/sysutils.pp -text
-rtl/nds/tthread.inc -text
-rtl/nds/varutils.pp -text
+rtl/nds/sysutils.pp svneol=native#text/plain
+rtl/nds/tthread.inc svneol=native#text/plain
+rtl/nds/varutils.pp svneol=native#text/plain
 rtl/netbsd/Makefile svneol=native#text/plain
 rtl/netbsd/Makefile svneol=native#text/plain
 rtl/netbsd/Makefile.fpc svneol=native#text/plain
 rtl/netbsd/Makefile.fpc svneol=native#text/plain
 rtl/netbsd/errno.inc svneol=native#text/plain
 rtl/netbsd/errno.inc svneol=native#text/plain
@@ -6974,12 +6979,14 @@ tests/tbf/tb0211a.pp svneol=native#text/plain
 tests/tbf/tb0212.pp svneol=native#text/plain
 tests/tbf/tb0212.pp svneol=native#text/plain
 tests/tbf/tb0213.pp svneol=native#text/plain
 tests/tbf/tb0213.pp svneol=native#text/plain
 tests/tbf/tb0214.pp svneol=native#text/plain
 tests/tbf/tb0214.pp svneol=native#text/plain
+tests/tbf/tb0214a.pp svneol=native#text/plain
 tests/tbf/tb0215.pp svneol=native#text/plain
 tests/tbf/tb0215.pp svneol=native#text/plain
 tests/tbf/tb0215a.pp svneol=native#text/plain
 tests/tbf/tb0215a.pp svneol=native#text/plain
 tests/tbf/tb0215b.pp svneol=native#text/plain
 tests/tbf/tb0215b.pp svneol=native#text/plain
 tests/tbf/tb0215c.pp svneol=native#text/plain
 tests/tbf/tb0215c.pp svneol=native#text/plain
 tests/tbf/tb0215d.pp svneol=native#text/plain
 tests/tbf/tb0215d.pp svneol=native#text/plain
 tests/tbf/tb0215e.pp svneol=native#text/plain
 tests/tbf/tb0215e.pp svneol=native#text/plain
+tests/tbf/tb0216.pp svneol=native#text/plain
 tests/tbf/ub0115.pp svneol=native#text/plain
 tests/tbf/ub0115.pp svneol=native#text/plain
 tests/tbf/ub0149.pp svneol=native#text/plain
 tests/tbf/ub0149.pp svneol=native#text/plain
 tests/tbf/ub0158a.pp svneol=native#text/plain
 tests/tbf/ub0158a.pp svneol=native#text/plain
@@ -7095,7 +7102,6 @@ tests/tbs/tb0110.pp svneol=native#text/plain
 tests/tbs/tb0111.pp svneol=native#text/plain
 tests/tbs/tb0111.pp svneol=native#text/plain
 tests/tbs/tb0112.pp svneol=native#text/plain
 tests/tbs/tb0112.pp svneol=native#text/plain
 tests/tbs/tb0113.pp svneol=native#text/plain
 tests/tbs/tb0113.pp svneol=native#text/plain
-tests/tbs/tb0114.pp svneol=native#text/plain
 tests/tbs/tb0115.pp svneol=native#text/plain
 tests/tbs/tb0115.pp svneol=native#text/plain
 tests/tbs/tb0116.pp svneol=native#text/plain
 tests/tbs/tb0116.pp svneol=native#text/plain
 tests/tbs/tb0117.pp svneol=native#text/plain
 tests/tbs/tb0117.pp svneol=native#text/plain
@@ -8009,6 +8015,8 @@ tests/test/opt/twpo2.pp svneol=native#text/plain
 tests/test/opt/twpo3.pp svneol=native#text/plain
 tests/test/opt/twpo3.pp svneol=native#text/plain
 tests/test/opt/twpo4.pp svneol=native#text/plain
 tests/test/opt/twpo4.pp svneol=native#text/plain
 tests/test/opt/twpo5.pp svneol=native#text/plain
 tests/test/opt/twpo5.pp svneol=native#text/plain
+tests/test/opt/twpo6.pp svneol=native#text/plain
+tests/test/opt/twpo7.pp svneol=native#text/plain
 tests/test/opt/uwpo2.pp svneol=native#text/plain
 tests/test/opt/uwpo2.pp svneol=native#text/plain
 tests/test/packages/fcl-base/tascii85.pp svneol=native#text/plain
 tests/test/packages/fcl-base/tascii85.pp svneol=native#text/plain
 tests/test/packages/fcl-base/tgettext1.pp svneol=native#text/plain
 tests/test/packages/fcl-base/tgettext1.pp svneol=native#text/plain
@@ -8232,6 +8240,7 @@ tests/test/tparray22.pp svneol=native#text/plain
 tests/test/tparray23.pp svneol=native#text/plain
 tests/test/tparray23.pp svneol=native#text/plain
 tests/test/tparray24.pp svneol=native#text/plain
 tests/test/tparray24.pp svneol=native#text/plain
 tests/test/tparray25.pp svneol=native#text/plain
 tests/test/tparray25.pp svneol=native#text/plain
+tests/test/tparray26.pp svneol=native#text/plain
 tests/test/tparray3.pp svneol=native#text/plain
 tests/test/tparray3.pp svneol=native#text/plain
 tests/test/tparray4.pp svneol=native#text/plain
 tests/test/tparray4.pp svneol=native#text/plain
 tests/test/tparray5.pp svneol=native#text/plain
 tests/test/tparray5.pp svneol=native#text/plain
@@ -8603,6 +8612,8 @@ tests/webtbf/tw13563a.pp svneol=native#text/plain
 tests/webtbf/tw1365.pp svneol=native#text/plain
 tests/webtbf/tw1365.pp svneol=native#text/plain
 tests/webtbf/tw13815.pp svneol=native#text/plain
 tests/webtbf/tw13815.pp svneol=native#text/plain
 tests/webtbf/tw1395.pp svneol=native#text/plain
 tests/webtbf/tw1395.pp svneol=native#text/plain
+tests/webtbf/tw13956.pp svneol=native#text/plain
+tests/webtbf/tw13992.pp svneol=native#text/plain
 tests/webtbf/tw1407.pp svneol=native#text/plain
 tests/webtbf/tw1407.pp svneol=native#text/plain
 tests/webtbf/tw1432.pp svneol=native#text/plain
 tests/webtbf/tw1432.pp svneol=native#text/plain
 tests/webtbf/tw1467.pp svneol=native#text/plain
 tests/webtbf/tw1467.pp svneol=native#text/plain
@@ -8965,6 +8976,7 @@ tests/webtbs/tw1068.pp svneol=native#text/plain
 tests/webtbs/tw10681.pp svneol=native#text/plain
 tests/webtbs/tw10681.pp svneol=native#text/plain
 tests/webtbs/tw10684.pp svneol=native#text/plain
 tests/webtbs/tw10684.pp svneol=native#text/plain
 tests/webtbs/tw1071.pp svneol=native#text/plain
 tests/webtbs/tw1071.pp svneol=native#text/plain
+tests/webtbs/tw10717.pp svneol=native#text/plain
 tests/webtbs/tw10727.pp svneol=native#text/plain
 tests/webtbs/tw10727.pp svneol=native#text/plain
 tests/webtbs/tw1073.pp svneol=native#text/plain
 tests/webtbs/tw1073.pp svneol=native#text/plain
 tests/webtbs/tw10736.pp svneol=native#text/plain
 tests/webtbs/tw10736.pp svneol=native#text/plain
@@ -9157,9 +9169,19 @@ tests/webtbs/tw1374.pp svneol=native#text/plain
 tests/webtbs/tw1375.pp svneol=native#text/plain
 tests/webtbs/tw1375.pp svneol=native#text/plain
 tests/webtbs/tw1376.pp svneol=native#text/plain
 tests/webtbs/tw1376.pp svneol=native#text/plain
 tests/webtbs/tw13763.pp svneol=native#text/plain
 tests/webtbs/tw13763.pp svneol=native#text/plain
+tests/webtbs/tw13813.pp svneol=native#text/plain
 tests/webtbs/tw13820.pp svneol=native#text/plain
 tests/webtbs/tw13820.pp svneol=native#text/plain
+tests/webtbs/tw13872.pp svneol=native#text/plain
+tests/webtbs/tw13890.pp svneol=native#text/plain
+tests/webtbs/tw13948.pp svneol=native#text/plain
 tests/webtbs/tw1398.pp svneol=native#text/plain
 tests/webtbs/tw1398.pp svneol=native#text/plain
+tests/webtbs/tw13984.pp svneol=native#text/plain
+tests/webtbs/tw13992a.pp svneol=native#text/plain
 tests/webtbs/tw1401.pp svneol=native#text/plain
 tests/webtbs/tw1401.pp svneol=native#text/plain
+tests/webtbs/tw14019.pp svneol=native#text/plain
+tests/webtbs/tw14020.pp svneol=native#text/plain
+tests/webtbs/tw14020a.pp svneol=native#text/plain
+tests/webtbs/tw14040.pp svneol=native#text/plain
 tests/webtbs/tw1407.pp svneol=native#text/plain
 tests/webtbs/tw1407.pp svneol=native#text/plain
 tests/webtbs/tw1408.pp svneol=native#text/plain
 tests/webtbs/tw1408.pp svneol=native#text/plain
 tests/webtbs/tw1409.pp svneol=native#text/plain
 tests/webtbs/tw1409.pp svneol=native#text/plain

+ 4 - 3
compiler/aggas.pas

@@ -375,7 +375,7 @@ implementation
           secname:='.tls';
           secname:='.tls';
 
 
         { go32v2 stub only loads .text and .data sections, and allocates space for .bss.
         { go32v2 stub only loads .text and .data sections, and allocates space for .bss.
-          Thus, data which normally goes into .rodata and .rodata_norel sections must 
+          Thus, data which normally goes into .rodata and .rodata_norel sections must
           end up in .data section }
           end up in .data section }
         if (atype in [sec_rodata,sec_rodata_norel]) and
         if (atype in [sec_rodata,sec_rodata_norel]) and
           (target_info.system=system_i386_go32v2) then
           (target_info.system=system_i386_go32v2) then
@@ -387,8 +387,9 @@ implementation
         if not(target_info.system in systems_darwin) and
         if not(target_info.system in systems_darwin) and
            create_smartlink_sections and
            create_smartlink_sections and
            (aname<>'') and
            (aname<>'') and
-           (atype <> sec_toc) and
-           (atype<>sec_bss) then
+           (atype<>sec_toc) and
+           { on embedded systems every byte counts, so smartlink bss too }
+           ((atype<>sec_bss) or (target_info.system in system_embedded)) then
           begin
           begin
             case aorder of
             case aorder of
               secorder_begin :
               secorder_begin :

+ 4 - 4
compiler/aoptda.pas

@@ -36,6 +36,10 @@ Unit aoptda;
       TAOptDFA = class
       TAOptDFA = class
         { uses the same constructor as TAoptCpu = constructor from TAoptObj }
         { uses the same constructor as TAoptCpu = constructor from TAoptObj }
 
 
+        { How many instructions are between the current instruction and the }
+        { last one that modified the register                               }
+        InstrSinceLastMod: TInstrSinceLastMod;
+
         { gathers the information regarding the contents of every register }
         { gathers the information regarding the contents of every register }
         { at the end of every instruction                                  }
         { at the end of every instruction                                  }
         Procedure DoDFA;
         Procedure DoDFA;
@@ -43,10 +47,6 @@ Unit aoptda;
         { handles the processor dependent dataflow analizing               }
         { handles the processor dependent dataflow analizing               }
         Procedure CpuDFA(p: PInstr); Virtual; Abstract;
         Procedure CpuDFA(p: PInstr); Virtual; Abstract;
 
 
-        { How many instructions are between the current instruction and the }
-        { last one that modified the register                               }
-        InstrSinceLastMod: TInstrSinceLastMod;
-
         { convert a TInsChange value into the corresponding register }
         { convert a TInsChange value into the corresponding register }
         //!!!!!!!!!! Function TCh2Reg(Ch: TInsChange): TRegister; Virtual;
         //!!!!!!!!!! Function TCh2Reg(Ch: TInsChange): TRegister; Virtual;
         { returns whether the instruction P reads from register Reg }
         { returns whether the instruction P reads from register Reg }

+ 19 - 4
compiler/arm/cpuinfo.pas

@@ -49,9 +49,17 @@ Type
 
 
    tcontrollertype =
    tcontrollertype =
      (ct_none,
      (ct_none,
+
+      { Phillips }
       ct_lpc2114,
       ct_lpc2114,
       ct_lpc2124,
       ct_lpc2124,
-      ct_lpc2194
+      ct_lpc2194,
+
+      { ATMEL }
+      ct_at91sam7s256,
+      ct_at91sam7se256,
+      ct_at91sam7x256,
+      ct_at91sam7xc256
      );
      );
 
 
 Const
 Const
@@ -94,17 +102,24 @@ Const
      ('',
      ('',
       'LPC2114',
       'LPC2114',
       'LPC2124',
       'LPC2124',
-      'LPC2194'
+      'LPC2194',
+      'AT91SAM7S256',
+      'AT91SAM7SE256',
+      'AT91SAM7X256',
+      'AT91SAM7XC256'
      );
      );
 
 
    controllerunitstr : array[tcontrollertype] of string[20] =
    controllerunitstr : array[tcontrollertype] of string[20] =
      ('',
      ('',
       'LPC21x4',
       'LPC21x4',
       'LPC21x4',
       'LPC21x4',
-      'LPC21x4'
+      'LPC21x4',
+      'AT91SAM7x256',
+      'AT91SAM7x256',
+      'AT91SAM7x256',
+      'AT91SAM7x256'
      );
      );
 
 
-
    { Supported optimizations, only used for information }
    { Supported optimizations, only used for information }
    supported_optimizerswitches = genericlevel1optimizerswitches+
    supported_optimizerswitches = genericlevel1optimizerswitches+
                                  genericlevel2optimizerswitches+
                                  genericlevel2optimizerswitches+

+ 1 - 1
compiler/avr/cgcpu.pas

@@ -181,7 +181,7 @@ unit cgcpu;
                 a_load_ref_reg(list,location^.size,location^.size,tmpref,location^.register);
                 a_load_ref_reg(list,location^.size,location^.size,tmpref,location^.register);
               LOC_REFERENCE:
               LOC_REFERENCE:
                 begin
                 begin
-                  reference_reset_base(ref,location^.reference.index,location^.reference.offset,araloc.alignment);
+                  reference_reset_base(ref,location^.reference.index,location^.reference.offset,paraloc.alignment);
                   { doubles in softemu mode have a strange order of registers and references }
                   { doubles in softemu mode have a strange order of registers and references }
                   if location^.size=OS_32 then
                   if location^.size=OS_32 then
                     g_concatcopy(list,tmpref,ref,4)
                     g_concatcopy(list,tmpref,ref,4)

+ 27 - 0
compiler/avr/cpuinfo.pas

@@ -40,6 +40,16 @@ Type
       fp_libgcc
       fp_libgcc
      );
      );
 
 
+   tcontrollertype =
+     (ct_none,
+
+      ct_atmega16,
+      ct_atmega32,
+      ct_atmega48,
+      ct_atmega64,
+      ct_atmega128
+     );
+
 Const
 Const
    {# Size of native extended floating point type }
    {# Size of native extended floating point type }
    extended_size = 12;
    extended_size = 12;
@@ -71,6 +81,23 @@ Const
      'LIBGCC'
      'LIBGCC'
    );
    );
 
 
+   controllertypestr : array[tcontrollertype] of string[20] =
+     ('',
+      'ATMEGA16',
+      'ATMEGA32',
+      'ATMEGA48',
+      'ATMEGA64',
+      'ATMEGA128'
+     );
+
+   controllerunitstr : array[tcontrollertype] of string[20] =
+     ('',
+      'ATMEGA16',
+      'ATMEGA32',
+      'ATMEGA48',
+      'ATMEGA64',
+      'ATMEGA128'
+     );
    { Supported optimizations, only used for information }
    { Supported optimizations, only used for information }
    supported_optimizerswitches = genericlevel1optimizerswitches+
    supported_optimizerswitches = genericlevel1optimizerswitches+
                                  genericlevel2optimizerswitches+
                                  genericlevel2optimizerswitches+

+ 1 - 1
compiler/avr/navrmat.pas

@@ -123,8 +123,8 @@ implementation
        procedure genOrdConstNodeMod;
        procedure genOrdConstNodeMod;
          var
          var
              modreg, maskreg, tempreg : tregister;
              modreg, maskreg, tempreg : tregister;
-{
          begin
          begin
+{
              if (tordconstnode(right).value = 0) then begin
              if (tordconstnode(right).value = 0) then begin
                  internalerror(2005061702);
                  internalerror(2005061702);
              end
              end

+ 123 - 0
compiler/cclasses.pas

@@ -504,6 +504,35 @@ type
       end;
       end;
 
 
 
 
+{******************************************************************
+                             tbitset
+*******************************************************************}
+
+       tbitset = class
+       private
+         fdata: pbyte;
+         fdatasize: longint;
+       public
+         constructor create(initsize: longint);
+         constructor create_bytesize(bytesize: longint);
+         destructor destroy; override;
+         procedure clear;
+         procedure grow(nsize: longint);
+         { sets a bit }
+         procedure include(index: longint);
+         { clears a bit }
+         procedure exclude(index: longint);
+         { finds an entry, creates one if not exists }
+         function isset(index: longint): boolean;
+
+         procedure addset(aset: tbitset);
+         procedure subset(aset: tbitset);
+
+         property data: pbyte read fdata;
+         property datasize: longint read fdatasize;
+      end;
+
+
     function FPHash(const s:shortstring):LongWord;
     function FPHash(const s:shortstring):LongWord;
     function FPHash(P: PChar; Len: Integer): LongWord;
     function FPHash(P: PChar; Len: Integer): LongWord;
 
 
@@ -2757,4 +2786,98 @@ end;
         Result := False;
         Result := False;
       end;
       end;
 
 
+
+{****************************************************************************
+                                tbitset
+****************************************************************************}
+
+    constructor tbitset.create(initsize: longint);
+      begin
+        create_bytesize((initsize+7) div 8);
+      end;
+
+
+    constructor tbitset.create_bytesize(bytesize: longint);
+      begin
+        fdatasize:=bytesize;
+        getmem(fdata,fdataSize);
+        clear;
+      end;
+
+
+    destructor tbitset.destroy;
+      begin
+        freemem(fdata,fdatasize);
+        inherited destroy;
+      end;
+
+
+    procedure tbitset.clear;
+      begin
+        fillchar(fdata^,fdatasize,0);
+      end;
+
+
+    procedure tbitset.grow(nsize: longint);
+      begin
+        reallocmem(fdata,nsize);
+        fillchar(fdata[fdatasize],nsize-fdatasize,0);
+        fdatasize:=nsize;
+      end;
+
+
+    procedure tbitset.include(index: longint);
+      var
+        dataindex: longint;
+      begin
+        { don't use bitpacked array, not endian-safe }
+        dataindex:=index shr 3;
+        if (dataindex>=datasize) then
+          grow(dataindex);
+        fdata[dataindex]:=fdata[dataindex] or (1 shl (index and 7));
+      end;
+
+
+    procedure tbitset.exclude(index: longint);
+      var
+        dataindex: longint;
+      begin
+        dataindex:=index shr 3;
+        if (dataindex>=datasize) then
+          exit;
+        fdata[dataindex]:=fdata[dataindex] and not(1 shl (index and 7));
+      end;
+
+
+    function tbitset.isset(index: longint): boolean;
+      var
+        dataindex: longint;
+      begin
+        dataindex:=index shr 3;
+        result:=
+          (dataindex<datasize) and
+          (((fdata[index shr 3] shr (index and 7)) and 1)<>0);
+      end;
+
+
+    procedure tbitset.addset(aset: tbitset);
+      var
+        i: longint;
+      begin
+        if (aset.datasize>datasize) then
+          grow(aset.datasize);
+        for i:=0 to aset.datasize-1 do
+          fdata[i]:=fdata[i] or aset.data[i];
+      end;
+
+
+    procedure tbitset.subset(aset: tbitset);
+      var
+        i: longint;
+      begin
+        for i:=0 to min(datasize,aset.datasize)-1 do
+          fdata[i]:=fdata[i] and not(aset.data[i]);
+      end;
+
+
 end.
 end.

+ 10 - 18
compiler/cfileutl.pas

@@ -46,16 +46,11 @@ interface
       CUtils,CClasses,
       CUtils,CClasses,
       Systems;
       Systems;
 
 
-    const
-      { On case sensitive file systems, you have 9 lookups per used unit, }
-      { including the system unit, in the current directory               }
-      MinSearchesBeforeCache = 20;
-
     type
     type
       TCachedDirectory = class(TFPHashObject)
       TCachedDirectory = class(TFPHashObject)
       private
       private
         FDirectoryEntries : TFPHashList;
         FDirectoryEntries : TFPHashList;
-        FSearchCount: longint;
+        FCached : Boolean;
         procedure FreeDirectoryEntries;
         procedure FreeDirectoryEntries;
         function GetItemAttr(const AName: TCmdStr): byte;
         function GetItemAttr(const AName: TCmdStr): byte;
         function TryUseCache: boolean;
         function TryUseCache: boolean;
@@ -196,6 +191,7 @@ end;
       begin
       begin
         inherited create(AList,AName);
         inherited create(AList,AName);
         FDirectoryEntries:=TFPHashList.Create;
         FDirectoryEntries:=TFPHashList.Create;
+        FCached:=False;
       end;
       end;
 
 
 
 
@@ -209,25 +205,21 @@ end;
 
 
     function TCachedDirectory.TryUseCache:boolean;
     function TCachedDirectory.TryUseCache:boolean;
       begin
       begin
-        Result:=true;
-        if (FSearchCount > MinSearchesBeforeCache) then
+        Result:=True;
+        if FCached then
           exit;
           exit;
-        if (FSearchCount = MinSearchesBeforeCache) then
-          begin
-            inc(FSearchCount);
-            Reload;
-            exit;
-          end;
-        inc(FSearchCount);
-        Result:=false;
+        if not current_settings.disabledircache then
+          ForceUseCache
+        else
+          Result:=False;
       end;
       end;
 
 
 
 
     procedure TCachedDirectory.ForceUseCache;
     procedure TCachedDirectory.ForceUseCache;
       begin
       begin
-        if (FSearchCount<=MinSearchesBeforeCache) then
+        if not FCached then
           begin
           begin
-            FSearchCount:=MinSearchesBeforeCache+1;
+            FCached:=True;
             Reload;
             Reload;
           end;
           end;
       end;
       end;

+ 42 - 37
compiler/dbgdwarf.pas

@@ -137,7 +137,7 @@ interface
 
 
         { DWARF 3 values.   }
         { DWARF 3 values.   }
         DW_AT_allocated := $4e,DW_AT_associated := $4f,
         DW_AT_allocated := $4e,DW_AT_associated := $4f,
-        DW_AT_data_location := $50,DW_AT_stride := $51,
+        DW_AT_data_location := $50,DW_AT_byte_stride := $51,
         DW_AT_entry_pc := $52,DW_AT_use_UTF8 := $53,
         DW_AT_entry_pc := $52,DW_AT_use_UTF8 := $53,
         DW_AT_extension := $54,DW_AT_ranges := $55,
         DW_AT_extension := $54,DW_AT_ranges := $55,
         DW_AT_trampoline := $56,DW_AT_call_column := $57,
         DW_AT_trampoline := $56,DW_AT_call_column := $57,
@@ -308,6 +308,8 @@ interface
       TDebugInfoDwarf2 = class(TDebugInfoDwarf)
       TDebugInfoDwarf2 = class(TDebugInfoDwarf)
       private
       private
       protected
       protected
+        procedure appenddef_set_intern(list:TAsmList;def:tsetdef; force_tag_set: boolean);
+
         procedure appenddef_file(list:TAsmList;def:tfiledef); override;
         procedure appenddef_file(list:TAsmList;def:tfiledef); override;
         procedure appenddef_formal(list:TAsmList;def:tformaldef); override;
         procedure appenddef_formal(list:TAsmList;def:tformaldef); override;
         procedure appenddef_object(list:TAsmList;def:tobjectdef); override;
         procedure appenddef_object(list:TAsmList;def:tobjectdef); override;
@@ -320,7 +322,7 @@ interface
 
 
       { TDebugInfoDwarf3 }
       { TDebugInfoDwarf3 }
 
 
-      TDebugInfoDwarf3 = class(TDebugInfoDwarf)
+      TDebugInfoDwarf3 = class(TDebugInfoDwarf2)
       private
       private
       protected
       protected
         procedure appenddef_array(list:TAsmList;def:tarraydef); override;
         procedure appenddef_array(list:TAsmList;def:tarraydef); override;
@@ -1327,6 +1329,7 @@ implementation
       var
       var
         size : aint;
         size : aint;
         elesize : aint;
         elesize : aint;
+        elestrideattr : tdwarf_attribute;
         labsym: tasmlabel;
         labsym: tasmlabel;
       begin
       begin
         if is_dynamic_array(def) then
         if is_dynamic_array(def) then
@@ -1340,9 +1343,15 @@ implementation
           end;
           end;
 
 
         if not is_packed_array(def) then
         if not is_packed_array(def) then
-          elesize := def.elesize*8
+          begin
+          elestrideattr := DW_AT_byte_stride;
+          elesize := def.elesize;
+          end
         else
         else
+          begin
+          elestrideattr := DW_AT_stride_size;
           elesize := def.elepackedbitsize;
           elesize := def.elepackedbitsize;
+          end;
 
 
         if is_special_array(def) then
         if is_special_array(def) then
           begin
           begin
@@ -1350,11 +1359,11 @@ implementation
             if assigned(def.typesym) then
             if assigned(def.typesym) then
               append_entry(DW_TAG_array_type,true,[
               append_entry(DW_TAG_array_type,true,[
                 DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
                 DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
-                DW_AT_stride_size,DW_FORM_udata,elesize
+                elestrideattr,DW_FORM_udata,elesize
                 ])
                 ])
             else
             else
               append_entry(DW_TAG_array_type,true,[
               append_entry(DW_TAG_array_type,true,[
-                DW_AT_stride_size,DW_FORM_udata,elesize
+                elestrideattr,DW_FORM_udata,elesize
                 ]);
                 ]);
             append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef));
             append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef));
             finish_entry;
             finish_entry;
@@ -1370,12 +1379,12 @@ implementation
               append_entry(DW_TAG_array_type,true,[
               append_entry(DW_TAG_array_type,true,[
                 DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
                 DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
                 DW_AT_byte_size,DW_FORM_udata,size,
                 DW_AT_byte_size,DW_FORM_udata,size,
-                DW_AT_stride_size,DW_FORM_udata,elesize
+                elestrideattr,DW_FORM_udata,elesize
                 ])
                 ])
             else
             else
               append_entry(DW_TAG_array_type,true,[
               append_entry(DW_TAG_array_type,true,[
                 DW_AT_byte_size,DW_FORM_udata,size,
                 DW_AT_byte_size,DW_FORM_udata,size,
-                DW_AT_stride_size,DW_FORM_udata,elesize
+                elestrideattr,DW_FORM_udata,elesize
                 ]);
                 ]);
             append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef));
             append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef));
             finish_entry;
             finish_entry;
@@ -1467,7 +1476,7 @@ implementation
           current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(arr,0));
           current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(arr,0));
           append_entry(DW_TAG_array_type,true,[
           append_entry(DW_TAG_array_type,true,[
             DW_AT_byte_size,DW_FORM_udata,def.size,
             DW_AT_byte_size,DW_FORM_udata,def.size,
-            DW_AT_stride_size,DW_FORM_udata,1*8
+            DW_AT_byte_stride,DW_FORM_udata,1
             ]);
             ]);
           append_labelentry_ref(DW_AT_type,def_dwarf_lab(cchartype));
           append_labelentry_ref(DW_AT_type,def_dwarf_lab(cchartype));
           finish_entry;
           finish_entry;
@@ -3026,11 +3035,12 @@ implementation
         end;
         end;
       end;
       end;
 
 
-    procedure TDebugInfoDwarf2.appenddef_set(list:TAsmList;def: tsetdef);
+    procedure TDebugInfoDwarf2.appenddef_set_intern(list:TAsmList;def: tsetdef; force_tag_set: boolean);
       var
       var
         lab: tasmlabel;
         lab: tasmlabel;
       begin
       begin
-        if (ds_dwarf_sets in current_settings.debugswitches) then
+        if force_tag_set or
+           (ds_dwarf_sets in current_settings.debugswitches) then
           begin
           begin
             { current (20070704 -- patch was committed on 20060513) gdb cvs supports set types }
             { current (20070704 -- patch was committed on 20060513) gdb cvs supports set types }
 
 
@@ -3045,21 +3055,21 @@ implementation
                 ]);
                 ]);
             if assigned(def.elementdef) then
             if assigned(def.elementdef) then
               begin
               begin
-                if (def.elementdef.typ=enumdef) then
-                  begin
-                    { gdb 6.7 - 6.8 is broken for regular enum sets }
-                    if not(tf_dwarf_only_local_labels in target_info.flags) then
-                      current_asmdata.getdatalabel(lab)
-                    else
-                      current_asmdata.getaddrlabel(lab);
-                    append_labelentry_ref(DW_AT_type,lab);
-                    finish_entry;
-                    current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(lab,0));
-                    append_entry(DW_TAG_subrange_type,false,[
-                      DW_AT_lower_bound,DW_FORM_sdata,tenumdef(def.elementdef).minval,
-                      DW_AT_upper_bound,DW_FORM_sdata,tenumdef(def.elementdef).maxval
-                      ]);
-                  end;
+                if not(tf_dwarf_only_local_labels in target_info.flags) then
+                  current_asmdata.getdatalabel(lab)
+                else
+                  current_asmdata.getaddrlabel(lab);
+                append_labelentry_ref(DW_AT_type,lab);
+                finish_entry;
+                current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(lab,0));
+                { Sets of e.g. [1..5] are actually stored as a set of [0..7],
+                  so write the exact boundaries of the set here. Let's hope no
+                  debugger ever rejects this because this "subrange" type can
+                  actually have a larger range than the original one.  }
+                append_entry(DW_TAG_subrange_type,false,[
+                  DW_AT_lower_bound,DW_FORM_sdata,def.setbase,
+                  DW_AT_upper_bound,DW_FORM_sdata,get_max_value(def.elementdef).svalue
+                  ]);
                 append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef))
                 append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef))
               end
               end
           end
           end
@@ -3082,6 +3092,11 @@ implementation
         finish_entry;
         finish_entry;
       end;
       end;
 
 
+    procedure TDebugInfoDwarf2.appenddef_set(list:TAsmList;def: tsetdef);
+      begin
+        appenddef_set_intern(list,def,false);
+      end;
+
     procedure TDebugInfoDwarf2.appenddef_undefined(list:TAsmList;def: tundefineddef);
     procedure TDebugInfoDwarf2.appenddef_undefined(list:TAsmList;def: tundefineddef);
       begin
       begin
         { gdb 6.4 doesn't support DW_TAG_unspecified_type so we
         { gdb 6.4 doesn't support DW_TAG_unspecified_type so we
@@ -3137,6 +3152,7 @@ implementation
         finish_entry;
         finish_entry;
         { to simplify things, we don't write a multidimensional array here }
         { to simplify things, we don't write a multidimensional array here }
         append_entry(DW_TAG_subrange_type,false,[
         append_entry(DW_TAG_subrange_type,false,[
+          DW_AT_byte_stride,DW_FORM_udata,def.elesize,
           DW_AT_lower_bound,DW_FORM_udata,0,
           DW_AT_lower_bound,DW_FORM_udata,0,
           DW_AT_upper_bound,DW_FORM_block1,5
           DW_AT_upper_bound,DW_FORM_block1,5
           ]);
           ]);
@@ -3400,18 +3416,7 @@ implementation
 
 
     procedure TDebugInfoDwarf3.appenddef_set(list:TAsmList;def: tsetdef);
     procedure TDebugInfoDwarf3.appenddef_set(list:TAsmList;def: tsetdef);
       begin
       begin
-        if assigned(def.typesym) then
-          append_entry(DW_TAG_set_type,false,[
-            DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
-            DW_AT_byte_size,DW_FORM_data2,def.size
-            ])
-        else
-          append_entry(DW_TAG_set_type,false,[
-            DW_AT_byte_size,DW_FORM_data2,def.size
-            ]);
-        if assigned(tsetdef(def).elementdef) then
-          append_labelentry_ref(DW_AT_type,def_dwarf_lab(tsetdef(def).elementdef));
-        finish_entry;
+        appenddef_set_intern(list,def,true);
       end;
       end;
 
 
     procedure TDebugInfoDwarf3.appenddef_undefined(list:TAsmList;def: tundefineddef);
     procedure TDebugInfoDwarf3.appenddef_undefined(list:TAsmList;def: tundefineddef);

+ 46 - 9
compiler/dbgstabs.pas

@@ -73,6 +73,7 @@ interface
         procedure field_add_stabstr(p:TObject;arg:pointer);
         procedure field_add_stabstr(p:TObject;arg:pointer);
         procedure method_add_stabstr(p:TObject;arg:pointer);
         procedure method_add_stabstr(p:TObject;arg:pointer);
         procedure field_write_defs(p:TObject;arg:pointer);
         procedure field_write_defs(p:TObject;arg:pointer);
+        function  get_enum_defstr(def: tenumdef; lowerbound: longint): ansistring;
       protected
       protected
         procedure appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);override;
         procedure appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);override;
         procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
         procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
@@ -561,25 +562,36 @@ implementation
       end;
       end;
 
 
 
 
-    procedure TDebugInfoStabs.appenddef_enum(list:TAsmList;def:tenumdef);
+    function TDebugInfoStabs.get_enum_defstr(def: tenumdef; lowerbound: longint): ansistring;
       var
       var
-        st : ansistring;
-        p  : Tenumsym;
+        i: longint;
+        p: tenumsym;
       begin
       begin
         { we can specify the size with @s<size>; prefix PM }
         { we can specify the size with @s<size>; prefix PM }
         if def.size <> std_param_align then
         if def.size <> std_param_align then
-          st:='@s'+tostr(def.size*8)+';e'
+          result:='@s'+tostr(def.size*8)+';e'
         else
         else
-          st:='e';
+          result:='e';
         p := tenumsym(def.firstenum);
         p := tenumsym(def.firstenum);
+        { the if-test is required because pred(def.minval) might overflow;
+          the longint() typecast should be safe because stabs is not
+          supported for 64 bit targets }
+        if (def.minval<>lowerbound) then
+          for i:=lowerbound to pred(longint(def.minval)) do
+            result:=result+'<invalid>:'+tostr(i)+',';
+
         while assigned(p) do
         while assigned(p) do
           begin
           begin
-            st:=st+GetSymName(p)+':'+tostr(p.value)+',';
+            result:=result+GetSymName(p)+':'+tostr(p.value)+',';
             p:=p.nextenum;
             p:=p.nextenum;
           end;
           end;
         { the final ',' is required to have a valid stabs }
         { the final ',' is required to have a valid stabs }
-        st:=st+';';
-        write_def_stabstr(list,def,st);
+        result:=result+';';
+      end;
+
+    procedure TDebugInfoStabs.appenddef_enum(list:TAsmList;def:tenumdef);
+      begin
+        write_def_stabstr(list,def,get_enum_defstr(def,def.minval));
       end;
       end;
 
 
 
 
@@ -787,9 +799,34 @@ implementation
 
 
     procedure TDebugInfoStabs.appenddef_set(list:TAsmList;def:tsetdef);
     procedure TDebugInfoStabs.appenddef_set(list:TAsmList;def:tsetdef);
       var
       var
+        st,
         ss : ansistring;
         ss : ansistring;
+        p: pchar;
+        elementdefstabnr: string;
       begin
       begin
-        ss:=def_stabstr_evaluate(def,'@s$1;S$2',[tostr(def.size*8),def_stab_number(tsetdef(def).elementdef)]);
+        { ugly hack: create a temporary subrange type if the lower bound of
+          the set's element type is not a multiple of 8 (because we store them
+          as if the lower bound is a multiple of 8) }
+        if (def.setbase<>get_min_value(def.elementdef)) then
+          begin
+            { allocate a def number }
+            inc(global_stab_number);
+            elementdefstabnr:=tostr(global_stab_number);
+            { anonymous subrange def }
+            st:='":t'+elementdefstabnr+'=';
+            if (def.elementdef.typ = enumdef) then
+              st:=st+get_enum_defstr(tenumdef(def.elementdef),def.setbase)
+            else
+              st:=st+def_stabstr_evaluate(def.elementdef,'r'+elementdefstabnr+';$1;$2;',[tostr(longint(def.setbase)),tostr(longint(get_max_value(def.elementdef).svalue))]);
+            st:=st+'",'+tostr(N_LSYM)+',0,0,0';
+            { add to list }
+            getmem(p,length(st)+1);
+            move(pchar(st)^,p^,length(st)+1);
+            list.concat(Tai_stab.create(stab_stabs,p));
+          end
+        else
+          elementdefstabnr:=def_stab_number(def.elementdef);
+        ss:=def_stabstr_evaluate(def,'@s$1;S$2',[tostr(def.size*8),elementdefstabnr]);
         write_def_stabstr(list,def,ss);
         write_def_stabstr(list,def,ss);
       end;
       end;
 
 

+ 2 - 2
compiler/fpcdefs.inc

@@ -126,6 +126,6 @@
 
 
 {$define SUPPORT_UNALIGNED}
 {$define SUPPORT_UNALIGNED}
 
 
-{$if not defined(cpui386) and defined(i386)}
-{$error Cross-compiling from non-i386 to i386 is not yet supported at this time }
+{$if not defined(FPC_HAS_TYPE_EXTENDED) and defined(i386)}
+{$error Cross-compiling from systems without support for an 80 bit extended floating point type to i386 is not yet supported at this time }
 {$endif}
 {$endif}

+ 28 - 19
compiler/globals.pas

@@ -104,7 +104,9 @@ interface
     type
     type
        tcodepagestring = string[20];
        tcodepagestring = string[20];
 
 
-       tsettings = record
+       { this is written to ppus during token recording for generics so it must be packed }
+       tsettings = packed record
+         alignment       : talignmentinfo;
          globalswitches  : tglobalswitches;
          globalswitches  : tglobalswitches;
          moduleswitches  : tmoduleswitches;
          moduleswitches  : tmoduleswitches;
          localswitches   : tlocalswitches;
          localswitches   : tlocalswitches;
@@ -119,7 +121,10 @@ interface
            >0: round to this size }
            >0: round to this size }
          setalloc,
          setalloc,
          packenum        : shortint;
          packenum        : shortint;
-         alignment       : talignmentinfo;
+
+         packrecords     : shortint;
+         maxfpuregisters : shortint;
+
          cputype,
          cputype,
          optimizecputype : tcputype;
          optimizecputype : tcputype;
          fputype         : tfputype;
          fputype         : tfputype;
@@ -128,15 +133,14 @@ interface
          defproccall     : tproccalloption;
          defproccall     : tproccalloption;
          sourcecodepage  : tcodepagestring;
          sourcecodepage  : tcodepagestring;
 
 
-         packrecords     : shortint;
-         maxfpuregisters : shortint;
-
          minfpconstprec  : tfloattype;
          minfpconstprec  : tfloattype;
 
 
+         disabledircache : boolean;
+
         { CPU targets with microcontroller support can add a controller specific unit }
         { CPU targets with microcontroller support can add a controller specific unit }
-{$if defined(ARM)}
+{$if defined(ARM) or defined(AVR)}
         controllertype   : tcontrollertype;
         controllertype   : tcontrollertype;
-{$endif defined(ARM)}
+{$endif defined(ARM) or defined(AVR)}
        end;
        end;
 
 
     const
     const
@@ -328,16 +332,6 @@ interface
 
 
     const
     const
       default_settings : TSettings = (
       default_settings : TSettings = (
-        globalswitches : [cs_check_unit_name,cs_link_static];
-        moduleswitches : [cs_extsyntax,cs_implicit_exceptions];
-        localswitches : [cs_check_io,cs_typed_const_writable];
-        modeswitches : fpcmodeswitches;
-        optimizerswitches : [];
-        genwpoptimizerswitches : [];
-        dowpoptimizerswitches : [];
-        debugswitches : [];
-        setalloc : 0;
-        packenum : 4;
         alignment : (
         alignment : (
           procalign : 0;
           procalign : 0;
           loopalign : 0;
           loopalign : 0;
@@ -352,6 +346,21 @@ interface
           recordalignmax : 0;
           recordalignmax : 0;
           maxCrecordalign : 0;
           maxCrecordalign : 0;
         );
         );
+        globalswitches : [cs_check_unit_name,cs_link_static];
+        moduleswitches : [cs_extsyntax,cs_implicit_exceptions];
+        localswitches : [cs_check_io,cs_typed_const_writable];
+        modeswitches : fpcmodeswitches;
+        optimizerswitches : [];
+        genwpoptimizerswitches : [];
+        dowpoptimizerswitches : [];
+        debugswitches : [];
+
+        setalloc : 0;
+        packenum : 4;
+
+        packrecords     : 0;
+        maxfpuregisters : 0;
+
 {$ifdef i386}
 {$ifdef i386}
         cputype : cpu_Pentium;
         cputype : cpu_Pentium;
         optimizecputype : cpu_Pentium3;
         optimizecputype : cpu_Pentium3;
@@ -396,9 +405,9 @@ interface
         interfacetype : it_interfacecom;
         interfacetype : it_interfacecom;
         defproccall : pocall_default;
         defproccall : pocall_default;
         sourcecodepage : '8859-1';
         sourcecodepage : '8859-1';
-        packrecords     : 0;
-        maxfpuregisters : 0;
         minfpconstprec : s32real;
         minfpconstprec : s32real;
+
+        disabledircache : false;
 {$if defined(ARM)}
 {$if defined(ARM)}
         controllertype : ct_none;
         controllertype : ct_none;
 {$endif defined(ARM)}
 {$endif defined(ARM)}

+ 32 - 9
compiler/htypechk.pas

@@ -68,10 +68,10 @@ interface
         FAllowVariant : boolean;
         FAllowVariant : boolean;
         procedure collect_overloads_in_class(ProcdefOverloadList:TFPObjectList);
         procedure collect_overloads_in_class(ProcdefOverloadList:TFPObjectList);
         procedure collect_overloads_in_units(ProcdefOverloadList:TFPObjectList);
         procedure collect_overloads_in_units(ProcdefOverloadList:TFPObjectList);
-        procedure create_candidate_list(ignorevisibility:boolean);
+        procedure create_candidate_list(ignorevisibility,allowdefaultparas:boolean);
         function  proc_add(ps:tprocsym;pd:tprocdef):pcandidate;
         function  proc_add(ps:tprocsym;pd:tprocdef):pcandidate;
       public
       public
-        constructor create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility:boolean);
+        constructor create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility,allowdefaultparas:boolean);
         constructor create_operator(op:ttoken;ppn:tnode);
         constructor create_operator(op:ttoken;ppn:tnode);
         destructor destroy;override;
         destructor destroy;override;
         procedure list(all:boolean);
         procedure list(all:boolean);
@@ -955,7 +955,8 @@ implementation
         gotvec,
         gotvec,
         gotclass,
         gotclass,
         gotdynarray,
         gotdynarray,
-        gotderef : boolean;
+        gotderef,
+        gottypeconv : boolean;
         fromdef,
         fromdef,
         todef    : tdef;
         todef    : tdef;
         errmsg,
         errmsg,
@@ -976,6 +977,7 @@ implementation
         gotpointer:=false;
         gotpointer:=false;
         gotdynarray:=false;
         gotdynarray:=false;
         gotstring:=false;
         gotstring:=false;
+        gottypeconv:=false;
         hp:=p;
         hp:=p;
         if not(valid_void in opts) and
         if not(valid_void in opts) and
            is_void(hp.resultdef) then
            is_void(hp.resultdef) then
@@ -1013,6 +1015,17 @@ implementation
                       { same when we got a class and subscript (= deref) }
                       { same when we got a class and subscript (= deref) }
                       (gotclass and gotsubscript) or
                       (gotclass and gotsubscript) or
                       (
                       (
+                       { allowing assignments to typecasted properties
+                           a) is Delphi-incompatible
+                           b) causes problems in case the getter is a function
+                              (because then the result of the getter is
+                               typecasted to this type, and then we "assign" to
+                               this typecasted function result) -> always
+                               disallow, since property accessors should be
+                               transparantly changeable to functions at all
+                               times
+                       }
+                       not(gottypeconv) and
                        not(gotsubscript and gotrecord) and
                        not(gotsubscript and gotrecord) and
                        not(gotstring and gotvec)
                        not(gotstring and gotvec)
                       ) then
                       ) then
@@ -1059,6 +1072,7 @@ implementation
                end;
                end;
              typeconvn :
              typeconvn :
                begin
                begin
+                 gottypeconv:=true;
                  { typecast sizes must match, exceptions:
                  { typecast sizes must match, exceptions:
                    - implicit typecast made by absolute
                    - implicit typecast made by absolute
                    - from formaldef
                    - from formaldef
@@ -1599,7 +1613,7 @@ implementation
                            TCallCandidates
                            TCallCandidates
 ****************************************************************************}
 ****************************************************************************}
 
 
-    constructor tcallcandidates.create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility:boolean);
+    constructor tcallcandidates.create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility,allowdefaultparas:boolean);
       begin
       begin
         if not assigned(sym) then
         if not assigned(sym) then
           internalerror(200411015);
           internalerror(200411015);
@@ -1607,7 +1621,7 @@ implementation
         FProcsym:=sym;
         FProcsym:=sym;
         FProcsymtable:=st;
         FProcsymtable:=st;
         FParanode:=ppn;
         FParanode:=ppn;
-        create_candidate_list(ignorevisibility);
+        create_candidate_list(ignorevisibility,allowdefaultparas);
       end;
       end;
 
 
 
 
@@ -1617,7 +1631,7 @@ implementation
         FProcsym:=nil;
         FProcsym:=nil;
         FProcsymtable:=nil;
         FProcsymtable:=nil;
         FParanode:=ppn;
         FParanode:=ppn;
-        create_candidate_list(false);
+        create_candidate_list(false,false);
       end;
       end;
 
 
 
 
@@ -1730,7 +1744,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcallcandidates.create_candidate_list(ignorevisibility:boolean);
+    procedure tcallcandidates.create_candidate_list(ignorevisibility,allowdefaultparas:boolean);
       var
       var
         j     : integer;
         j     : integer;
         pd    : tprocdef;
         pd    : tprocdef;
@@ -1789,8 +1803,17 @@ implementation
               it is visible }
               it is visible }
             if (FParalength>=pd.minparacount) and
             if (FParalength>=pd.minparacount) and
                (
                (
-                (FParalength<=pd.maxparacount) or
-                (po_varargs in pd.procoptions)
+                (
+                 allowdefaultparas and
+                 (
+                  (FParalength<=pd.maxparacount) or
+                  (po_varargs in pd.procoptions)
+                 )
+                ) or
+                (
+                 not allowdefaultparas and
+                 (FParalength=pd.maxparacount)
+                )
                ) and
                ) and
                (
                (
                 ignorevisibility or
                 ignorevisibility or

+ 7 - 7
compiler/i386/daopt386.pas

@@ -218,13 +218,6 @@ type
     function getlabelwithsym(sym: tasmlabel): tai;
     function getlabelwithsym(sym: tasmlabel): tai;
 
 
    private
    private
-    { Walks through the list to find the lowest and highest label number, inits the }
-    { labeltable and fixes/optimizes some regallocs                                 }
-     procedure initlabeltable;
-
-    function initdfapass2: boolean;
-    procedure dodfapass2;
-
     { asm list we're working on }
     { asm list we're working on }
     list: TAsmList;
     list: TAsmList;
 
 
@@ -240,6 +233,13 @@ type
     { all labels in the current block: their value mapped to their location }
     { all labels in the current block: their value mapped to their location }
     lolab, hilab, labdif: longint;
     lolab, hilab, labdif: longint;
     labeltable: plabeltable;
     labeltable: plabeltable;
+
+    { Walks through the list to find the lowest and highest label number, inits the }
+    { labeltable and fixes/optimizes some regallocs                                 }
+     procedure initlabeltable;
+
+    function initdfapass2: boolean;
+    procedure dodfapass2;
   end;
   end;
 
 
 
 

+ 1 - 1
compiler/link.pas

@@ -100,12 +100,12 @@ interface
          procedure PrintLinkerScript;
          procedure PrintLinkerScript;
          function  RunLinkScript(const outputname:TCmdStr):boolean;
          function  RunLinkScript(const outputname:TCmdStr):boolean;
       protected
       protected
+         linkscript : TCmdStrList;
          property CObjInput:TObjInputClass read FCObjInput write FCObjInput;
          property CObjInput:TObjInputClass read FCObjInput write FCObjInput;
          property CExeOutput:TExeOutputClass read FCExeOutput write FCExeOutput;
          property CExeOutput:TExeOutputClass read FCExeOutput write FCExeOutput;
          property StaticLibraryList:TFPHashObjectList read FStaticLibraryList;
          property StaticLibraryList:TFPHashObjectList read FStaticLibraryList;
          property ImportLibraryList:TFPHashObjectList read FImportLibraryList;
          property ImportLibraryList:TFPHashObjectList read FImportLibraryList;
          procedure DefaultLinkScript;virtual;abstract;
          procedure DefaultLinkScript;virtual;abstract;
-         linkscript : TCmdStrList;
       public
       public
          IsSharedLibrary : boolean;
          IsSharedLibrary : boolean;
          Constructor Create;override;
          Constructor Create;override;

+ 48 - 19
compiler/msg/errord.msg

@@ -1,9 +1,9 @@
 #
 #
 #   German (alternative, LATIN-US DOS) Language File for Free Pascal
 #   German (alternative, LATIN-US DOS) Language File for Free Pascal
 #   Latest updates contributed by Karl-Michael Schindler aka mischi
 #   Latest updates contributed by Karl-Michael Schindler aka mischi
-#   <karl-michael.schindler at physik.uni-halle.de>
+#   <karl-michael.schindler at web.de>
 #
 #
-#   Based on errore.msg of SVN revision 12528
+#   Based on errore.msg of SVN revision 13257 + one
 #
 #
 #   This file is part of the Free Pascal Compiler
 #   This file is part of the Free Pascal Compiler
 #   Copyright (c) 1998-2009 by the Free Pascal Development team
 #   Copyright (c) 1998-2009 by the Free Pascal Development team
@@ -1185,7 +1185,7 @@ parser_n_ignore_lower_visibility=03250_N_Die virtuelle Methode "$1" hat eine nie
 #
 #
 # Type Checking
 # Type Checking
 #
 #
-# 04083 is the last used one
+# 04087 is the last used one
 #
 #
 % \section{Type checking errors}
 % \section{Type checking errors}
 % This section lists all errors that can occur when type checking is
 % This section lists all errors that can occur when type checking is
@@ -1469,6 +1469,20 @@ type_w_pointer_to_signed=04082_W_Die Konvertierung von Pointern in einen Integer
 type_interface_has_no_guid=04083_E_Interface Typ $1 hat keine g�ltige GUID
 type_interface_has_no_guid=04083_E_Interface Typ $1 hat keine g�ltige GUID
 % When applying the as-operator to an interface or class, the desired interface (i.e. the right operand of the
 % When applying the as-operator to an interface or class, the desired interface (i.e. the right operand of the
 % as-operator) must have a valid GUID.
 % as-operator) must have a valid GUID.
+type_e_invalid_objc_selector_name=04084_E_Ung�ltiger Objective-C-Selector-Name
+% An Objective-C selector cannot be empty, must be a valid identifier or a single colon,
+% and if it contains at least one colon it must also end in one.
+type_e_expected_objc_method_but_got=04085_E_Erwartete eine Objective-C-Methode, erhielt aber $1
+% A selector can only be created for Objective-C methods, not for any other kind
+% of procedure/function/method.
+type_e_expected_objc_method=04086_E_Erwartete eine Objective-C-Methode, oder den Namen einer konstanten Methode
+% A selector can only be created for Objective-C methods, either by specifying
+% the name using a string constant, or by using an Objective-C method identifier
+% that is visible in the current scope.
+type_e_no_type_info=04087_E_F�r diesen Typ steht keine Typ-Information zu Verf�gung
+% Type information is not generated for some types, such as enumerations with gaps
+% in their value range (this includes enumerations whose lower bound is different
+% from zero).
 % \end{description}
 % \end{description}
 #
 #
 # Symtable
 # Symtable
@@ -1574,12 +1588,12 @@ sym_w_uninitialized_local_variable=05036_W_Lokale Variable "$1" wird verwendet,
 % This message is displayed if the compiler thinks that a variable will
 % This message is displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % was not initialized first (i.e. appeared in the left-hand side of an
 % was not initialized first (i.e. appeared in the left-hand side of an
-% assigment).
+% assignment).
 sym_w_uninitialized_variable=05037_W_Variable "$1" scheint nicht initialisiert worden zu sein
 sym_w_uninitialized_variable=05037_W_Variable "$1" scheint nicht initialisiert worden zu sein
 % These messages are displayed if the compiler thinks that a variable will
 % These messages are displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % wasn't initialized first (i.e. appeared in the left-hand side of an
 % wasn't initialized first (i.e. appeared in the left-hand side of an
-% assigment).
+% assignassignmentment).
 sym_e_id_no_member=05038_E_Bezeichener verweist nicht auf ein Element: $1
 sym_e_id_no_member=05038_E_Bezeichener verweist nicht auf ein Element: $1
 % This error is generated when an identifier of a record,
 % This error is generated when an identifier of a record,
 % field or method is accessed while it is not defined.
 % field or method is accessed while it is not defined.
@@ -1614,22 +1628,22 @@ sym_h_uninitialized_local_variable=05057_H_Die Variable "$1" scheint nicht initi
 % This message is displayed if the compiler thinks that a variable will
 % This message is displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % was not initialized first (i.e. it did not appear in the left-hand side of an
 % was not initialized first (i.e. it did not appear in the left-hand side of an
-% assigment).
+% assignment).
 sym_h_uninitialized_variable=05058_H_Die Variable "$1" scheint nicht initialisiert zu sein
 sym_h_uninitialized_variable=05058_H_Die Variable "$1" scheint nicht initialisiert zu sein
 % This message is displayed if the compiler thinks that a variable will
 % This message is displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % was not initialized first (i.e. t did not appear in the left-hand side of an
 % was not initialized first (i.e. t did not appear in the left-hand side of an
-% assigment).
+% assignment).
 sym_w_function_result_uninitialized=05059_W_Die Ergebnisvariable der Funktion scheint nicht initialisiert zu sein
 sym_w_function_result_uninitialized=05059_W_Die Ergebnisvariable der Funktion scheint nicht initialisiert zu sein
 % This message is displayed if the compiler thinks that the function result
 % This message is displayed if the compiler thinks that the function result
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % before it is initialized (i.e. before it appeared in the left-hand side of an
 % before it is initialized (i.e. before it appeared in the left-hand side of an
-% assigment).
+% assignment).
 sym_h_function_result_uninitialized=05060_H_Die Ergebnisvariable der Funktion scheint nicht initialisiert zu sein
 sym_h_function_result_uninitialized=05060_H_Die Ergebnisvariable der Funktion scheint nicht initialisiert zu sein
 % This message is displayed if the compiler thinks that the function result
 % This message is displayed if the compiler thinks that the function result
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % before it is initialized (i.e. it appears in the left-hand side of an
 % before it is initialized (i.e. it appears in the left-hand side of an
-% assigment)
+% assignment)
 sym_w_identifier_only_read=05061_W_Die Variable "$1" wird gelesen, obwohl ihr aber noch kein Wert zugewiesen wurde
 sym_w_identifier_only_read=05061_W_Die Variable "$1" wird gelesen, obwohl ihr aber noch kein Wert zugewiesen wurde
 % You have read the value of a variable, but nowhere assigned a value to
 % You have read the value of a variable, but nowhere assigned a value to
 % it.
 % it.
@@ -2192,6 +2206,10 @@ execinfo_x_stackcommit=09134_X_Stack Bereich "committed": $1 Bytes
 % \begin{description}
 % \begin{description}
 link_f_executable_too_big=09200_F_Das Programm - Image ist f�r das Target $1 zu groá
 link_f_executable_too_big=09200_F_Das Programm - Image ist f�r das Target $1 zu groá
 % Fatal error when resulting executable is too big.
 % Fatal error when resulting executable is too big.
+link_w_32bit_absolute_reloc=09201_W_Object Daei "$1" enth„lt eine 32-bit absolute Relocation auf Symbol "$2".
+% Warning when 64-bit object file contains 32-bit absolute relocations.
+% In such case an executable image can be loaded into lower 4Gb of
+% address space only.
 %\end{description}
 %\end{description}
 # EndOfTeX
 # EndOfTeX
 
 
@@ -2401,7 +2419,7 @@ unit_e_different_wpo_file=10061_E_Unit $1 wurde mit einer anderen Feedback-Einga
 #
 #
 #  Options
 #  Options
 #
 #
-# 11044 is the last used one
+# 11046 is the last used one
 #
 #
 option_usage=11000_O_$1 [Optionen] <Eingabedatei> [Optionen]
 option_usage=11000_O_$1 [Optionen] <Eingabedatei> [Optionen]
 # BeginOfTeX
 # BeginOfTeX
@@ -2516,6 +2534,13 @@ option_unsupported_target=11044_F_Die Option "$1" wird auf der Zielplattform nic
 % Not all options are supported or implemented for all target platforms. This message informs you that a chosen
 % Not all options are supported or implemented for all target platforms. This message informs you that a chosen
 % option is incompatible with the currently selected target platform.
 % option is incompatible with the currently selected target platform.
 %\end{description}
 %\end{description}
+option_unsupported_target_for_feature=11045_F_Das Feature "$1" wird f�r die ausgew„hlte Zielplattform nicht oder noch nicht unterst�tzt
+% Not all features are supported or implemented for all target platforms. This message informs you that a chosen
+% feature is incompatible with the currently selected target platform.
+option_dwarf_smart_linking=11046_N_DWARF Debug-Information kann auf dieser Zielplattform nicht zusammen mit Smartlinking benutzt werden, es wird auf statisches Linken umgeschaltet
+% Smart linking is currently incompatble with DWARF debug information on most
+% platforms, so smart linking is disabled in such cases.
+
 # EndOfTeX
 # EndOfTeX
 
 
 #
 #
@@ -2529,11 +2554,11 @@ option_unsupported_target=11044_F_Die Option "$1" wird auf der Zielplattform nic
 % This section lists errors that occur when the compiler is performing
 % This section lists errors that occur when the compiler is performing
 % whole program optimization.
 % whole program optimization.
 % \begin{description}
 % \begin{description}
-wpo_cant_find_file=12000_F_Feedback-Datei $1 f�r die Gesamtprogramm-Optimierung kann nicht ge”ffnet werden
+wpo_cant_find_file=12000_F_Feedback-Datei "$1" f�r die Gesamtprogramm-Optimierung kann nicht ge”ffnet werden
 % The compiler cannot open the specified feedback file with whole program optimization information.
 % The compiler cannot open the specified feedback file with whole program optimization information.
-wpo_begin_processing=12001_D_Bearbeite die Informationen zur Gesamtprogramm-Optimierung aus der wpo-Feedback-Datei $1
+wpo_begin_processing=12001_D_Bearbeite die Informationen zur Gesamtprogramm-Optimierung aus der wpo-Feedback-Datei "$1"
 % The compiler starts processing whole program optimization information found in the named file.
 % The compiler starts processing whole program optimization information found in the named file.
-wpo_end_processing=12002_D_Bearbeitung der Informationen zur Gesamtprogramm-Optimierung aus der wpo-Feedback-Datei $1 beendet
+wpo_end_processing=12002_D_Bearbeitung der Informationen zur Gesamtprogramm-Optimierung aus der wpo-Feedback-Datei "$1" beendet
 % The compiler has finished processing the whole program optimization information found in the named file.
 % The compiler has finished processing the whole program optimization information found in the named file.
 wpo_expected_section=12003_E_Erwarte einen Sektions-Header, statt dessen "$2" in Zeile $1 der wpo-Feedback-Datei erhalten
 wpo_expected_section=12003_E_Erwarte einen Sektions-Header, statt dessen "$2" in Zeile $1 der wpo-Feedback-Datei erhalten
 % The compiler expected a section header in the whole program optimization file (starting with \%),
 % The compiler expected a section header in the whole program optimization file (starting with \%),
@@ -2631,6 +2656,9 @@ Unterst
   All
   All
   $WPOPTIMIZATIONS
   $WPOPTIMIZATIONS
 
 
+Unterst�tzte Microcontroller:
+  $CONTROLLERTYPES
+
 Dieses Programm unterliegt der GNU General Public Licence
 Dieses Programm unterliegt der GNU General Public Licence
 Weitere Informationen sind in COPYING.FPC zu finden
 Weitere Informationen sind in COPYING.FPC zu finden
 
 
@@ -2850,19 +2878,20 @@ S*2Tlinux_Linux
 **1u<x>_Entferne die Definition f�r das Symbol <x>
 **1u<x>_Entferne die Definition f�r das Symbol <x>
 **1U<x>_Unit-Optionen:
 **1U<x>_Unit-Optionen:
 **2Un_Pr�fe den Unitnamen nicht
 **2Un_Pr�fe den Unitnamen nicht
-**2Ur_Erzeuge release unit Dateien
+**2Ur_Erzeuge "release unit"-Dateien
 **2Us_Erzeuge eine Systemunit
 **2Us_Erzeuge eine Systemunit
 **1v<x>_Meldungen, <x> ist eine Kombination der folgenden Zeichen:
 **1v<x>_Meldungen, <x> ist eine Kombination der folgenden Zeichen:
 **2*_e : Fehler (Standard)             0 : Nichts (ausser Fehlern)
 **2*_e : Fehler (Standard)             0 : Nichts (ausser Fehlern)
 **2*_w : Warnungen                     u : Unit Informationen
 **2*_w : Warnungen                     u : Unit Informationen
 **2*_n : Anmerkungen                   t : Angesprochene/benutzte Dateien
 **2*_n : Anmerkungen                   t : Angesprochene/benutzte Dateien
-**2*_h : Hinweise                      c : Preprozessordirektive
+**2*_h : Hinweise                      c : Preprozessordirektiven
 **2*_i : Allgemeine Informationen      d : Debug Informationen
 **2*_i : Allgemeine Informationen      d : Debug Informationen
 **2*_l : Zeilennummern                 r : Rhide/GCC kompatibler Modus
 **2*_l : Zeilennummern                 r : Rhide/GCC kompatibler Modus
+**2*_s : Zeitstempel                   q : Nummer der Meldung
 **2*_a : Alles                         x : Exe-Datei Informationen (nur Win32)
 **2*_a : Alles                         x : Exe-Datei Informationen (nur Win32)
-**2*_b : Schreibe bei Meldungen mit Dateinamen den vollst„ndigem Pfad
-**2*_v : Schreibe fpcdebug.txt mit     p : Schreibe tree.log mit Analysenbaum (parse tree)
-**2*_   ganz viel Information          q : Zeige die Nummer der Meldung
+**2*_b : Schreibe bei Meldungen mit    p : Schreibe tree.log mit Analysenbaum (parse tree)
+**2*_    Dateinamen den vollst„ndigen  v : Schreibe fpcdebug.txt mit 
+**2*_    Pfad                              ganz viel Information
 **2*_m<x>,<y> : Zeige die Meldungen mit den Nummern <x> und <y> nicht
 **2*_m<x>,<y> : Zeige die Meldungen mit den Nummern <x> und <y> nicht
 3*1W<x>_Ziel-spezifische Optionen (Ziele)
 3*1W<x>_Ziel-spezifische Optionen (Ziele)
 A*1W<x>_Ziel-spezifische Optionen (Ziele)
 A*1W<x>_Ziel-spezifische Optionen (Ziele)
@@ -2909,7 +2938,7 @@ P*2WX_Erm
 **2XP<x>_Stelle den Namen der Compiler-Hilfsprogrammen den Prefix <x> voran
 **2XP<x>_Stelle den Namen der Compiler-Hilfsprogrammen den Prefix <x> voran
 **2Xr<x>_Setze den Bibliotheks-Suchpfad zu <x>       (ben”tigt f�r cross compile)
 **2Xr<x>_Setze den Bibliotheks-Suchpfad zu <x>       (ben”tigt f�r cross compile)
 **2XR<x>_Stelle allen Linker-Suchpfaden den Namen <x> voran (BeOS, Darwin, FreeBSD, Linux, Mac OS, Solaris)
 **2XR<x>_Stelle allen Linker-Suchpfaden den Namen <x> voran (BeOS, Darwin, FreeBSD, Linux, Mac OS, Solaris)
-**2Xs_Entferne alle Symbole von ausf�hrbarer Datei
+**2Xs_Entferne alle Symbole aus der ausf�hrbaren Datei
 **2XS_Versuche Units statisch zu linken (default)    (definiert FPC_LINK_STATIC)
 **2XS_Versuche Units statisch zu linken (default)    (definiert FPC_LINK_STATIC)
 **2Xt_Linke mit statischen Bibliotheken              (-static wird an den Linker �bergeben)
 **2Xt_Linke mit statischen Bibliotheken              (-static wird an den Linker �bergeben)
 **2XX_Versuche Units smart zu linken                 (definiert FPC_LINK_SMART)
 **2XX_Versuche Units smart zu linken                 (definiert FPC_LINK_SMART)

+ 49 - 20
compiler/msg/errordu.msg

@@ -1,9 +1,9 @@
-#
+#
 #   German (UTF-8) Language File for Free Pascal
 #   German (UTF-8) Language File for Free Pascal
 #   Latest updates contributed by Karl-Michael Schindler aka mischi
 #   Latest updates contributed by Karl-Michael Schindler aka mischi
-#   <karl-michael.schindler at physik.uni-halle.de>
+#   <karl-michael.schindler at web.de>
 #
 #
-#   Based on errore.msg of SVN revision 12528
+#   Based on errore.msg of SVN revision 13257 + one
 #
 #
 #   This file is part of the Free Pascal Compiler
 #   This file is part of the Free Pascal Compiler
 #   Copyright (c) 1998-2009 by the Free Pascal Development team
 #   Copyright (c) 1998-2009 by the Free Pascal Development team
@@ -1184,7 +1184,7 @@ parser_n_ignore_lower_visibility=03250_N_Die virtuelle Methode "$1" hat eine nie
 #
 #
 # Type Checking
 # Type Checking
 #
 #
-# 04083 is the last used one
+# 04087 is the last used one
 #
 #
 % \section{Type checking errors}
 % \section{Type checking errors}
 % This section lists all errors that can occur when type checking is
 % This section lists all errors that can occur when type checking is
@@ -1468,6 +1468,20 @@ type_w_pointer_to_signed=04082_W_Die Konvertierung von Pointern in einen Integer
 type_interface_has_no_guid=04083_E_Interface Typ $1 hat keine gültige GUID
 type_interface_has_no_guid=04083_E_Interface Typ $1 hat keine gültige GUID
 % When applying the as-operator to an interface or class, the desired interface (i.e. the right operand of the
 % When applying the as-operator to an interface or class, the desired interface (i.e. the right operand of the
 % as-operator) must have a valid GUID.
 % as-operator) must have a valid GUID.
+type_e_invalid_objc_selector_name=04084_E_Ungültiger Objective-C-Selector-Name
+% An Objective-C selector cannot be empty, must be a valid identifier or a single colon,
+% and if it contains at least one colon it must also end in one.
+type_e_expected_objc_method_but_got=04085_E_Erwartete eine Objective-C-Methode, erhielt aber $1
+% A selector can only be created for Objective-C methods, not for any other kind
+% of procedure/function/method.
+type_e_expected_objc_method=04086_E_Erwartete eine Objective-C-Methode, oder den Namen einer konstanten Methode
+% A selector can only be created for Objective-C methods, either by specifying
+% the name using a string constant, or by using an Objective-C method identifier
+% that is visible in the current scope.
+type_e_no_type_info=04087_E_Für diesen Typ steht keine Typ-Information zu Verfügung
+% Type information is not generated for some types, such as enumerations with gaps
+% in their value range (this includes enumerations whose lower bound is different
+% from zero).
 % \end{description}
 % \end{description}
 #
 #
 # Symtable
 # Symtable
@@ -1573,12 +1587,12 @@ sym_w_uninitialized_local_variable=05036_W_Lokale Variable "$1" wird verwendet,
 % This message is displayed if the compiler thinks that a variable will
 % This message is displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % was not initialized first (i.e. appeared in the left-hand side of an
 % was not initialized first (i.e. appeared in the left-hand side of an
-% assigment).
+% assignment).
 sym_w_uninitialized_variable=05037_W_Variable "$1" scheint nicht initialisiert worden zu sein
 sym_w_uninitialized_variable=05037_W_Variable "$1" scheint nicht initialisiert worden zu sein
 % These messages are displayed if the compiler thinks that a variable will
 % These messages are displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % wasn't initialized first (i.e. appeared in the left-hand side of an
 % wasn't initialized first (i.e. appeared in the left-hand side of an
-% assigment).
+% assignment).
 sym_e_id_no_member=05038_E_Bezeichener verweist nicht auf ein Element: $1
 sym_e_id_no_member=05038_E_Bezeichener verweist nicht auf ein Element: $1
 % This error is generated when an identifier of a record,
 % This error is generated when an identifier of a record,
 % field or method is accessed while it is not defined.
 % field or method is accessed while it is not defined.
@@ -1613,22 +1627,22 @@ sym_h_uninitialized_local_variable=05057_H_Die Variable "$1" scheint nicht initi
 % This message is displayed if the compiler thinks that a variable will
 % This message is displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % was not initialized first (i.e. it did not appear in the left-hand side of an
 % was not initialized first (i.e. it did not appear in the left-hand side of an
-% assigment).
+% assignment).
 sym_h_uninitialized_variable=05058_H_Die Variable "$1" scheint nicht initialisiert zu sein
 sym_h_uninitialized_variable=05058_H_Die Variable "$1" scheint nicht initialisiert zu sein
 % This message is displayed if the compiler thinks that a variable will
 % This message is displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % was not initialized first (i.e. t did not appear in the left-hand side of an
 % was not initialized first (i.e. t did not appear in the left-hand side of an
-% assigment).
+% assignment).
 sym_w_function_result_uninitialized=05059_W_Die Ergebnisvariable der Funktion scheint nicht initialisiert zu sein
 sym_w_function_result_uninitialized=05059_W_Die Ergebnisvariable der Funktion scheint nicht initialisiert zu sein
 % This message is displayed if the compiler thinks that the function result
 % This message is displayed if the compiler thinks that the function result
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % before it is initialized (i.e. before it appeared in the left-hand side of an
 % before it is initialized (i.e. before it appeared in the left-hand side of an
-% assigment).
+% assignment).
 sym_h_function_result_uninitialized=05060_H_Die Ergebnisvariable der Funktion scheint nicht initialisiert zu sein
 sym_h_function_result_uninitialized=05060_H_Die Ergebnisvariable der Funktion scheint nicht initialisiert zu sein
 % This message is displayed if the compiler thinks that the function result
 % This message is displayed if the compiler thinks that the function result
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % before it is initialized (i.e. it appears in the left-hand side of an
 % before it is initialized (i.e. it appears in the left-hand side of an
-% assigment)
+% assignment)
 sym_w_identifier_only_read=05061_W_Die Variable "$1" wird gelesen, obwohl ihr aber noch kein Wert zugewiesen wurde
 sym_w_identifier_only_read=05061_W_Die Variable "$1" wird gelesen, obwohl ihr aber noch kein Wert zugewiesen wurde
 % You have read the value of a variable, but nowhere assigned a value to
 % You have read the value of a variable, but nowhere assigned a value to
 % it.
 % it.
@@ -2191,6 +2205,10 @@ execinfo_x_stackcommit=09134_X_Stack Bereich "committed": $1 Bytes
 % \begin{description}
 % \begin{description}
 link_f_executable_too_big=09200_F_Das Programm - Image ist für das Target $1 zu groß
 link_f_executable_too_big=09200_F_Das Programm - Image ist für das Target $1 zu groß
 % Fatal error when resulting executable is too big.
 % Fatal error when resulting executable is too big.
+link_w_32bit_absolute_reloc=09201_W_Object Daei "$1" enthält eine 32-bit absolute Relocation auf Symbol "$2".
+% Warning when 64-bit object file contains 32-bit absolute relocations.
+% In such case an executable image can be loaded into lower 4Gb of
+% address space only.
 %\end{description}
 %\end{description}
 # EndOfTeX
 # EndOfTeX
 
 
@@ -2400,7 +2418,7 @@ unit_e_different_wpo_file=10061_E_Unit $1 wurde mit einer anderen Feedback-Einga
 #
 #
 #  Options
 #  Options
 #
 #
-# 11044 is the last used one
+# 11046 is the last used one
 #
 #
 option_usage=11000_O_$1 [Optionen] <Eingabedatei> [Optionen]
 option_usage=11000_O_$1 [Optionen] <Eingabedatei> [Optionen]
 # BeginOfTeX
 # BeginOfTeX
@@ -2514,6 +2532,13 @@ option_else_without_if=11043_F_Zur \var{\#ELSE} Direktive in Zeile $2 der Option
 option_unsupported_target=11044_F_Die Option "$1" wird auf der Zielplattform nicht oder noch nicht unterstützt
 option_unsupported_target=11044_F_Die Option "$1" wird auf der Zielplattform nicht oder noch nicht unterstützt
 % Not all options are supported or implemented for all target platforms. This message informs you that a chosen
 % Not all options are supported or implemented for all target platforms. This message informs you that a chosen
 % option is incompatible with the currently selected target platform.
 % option is incompatible with the currently selected target platform.
+option_unsupported_target_for_feature=11045_F_Das Feature "$1" wird für die ausgewählte Zielplattform nicht oder noch nicht unterstützt
+% Not all features are supported or implemented for all target platforms. This message informs you that a chosen
+% feature is incompatible with the currently selected target platform.
+option_dwarf_smart_linking=11046_N_DWARF Debug-Information kann auf dieser Zielplattform nicht zusammen mit Smartlinking benutzt werden, es wird auf statisches Linken umgeschaltet
+% Smart linking is currently incompatble with DWARF debug information on most
+% platforms, so smart linking is disabled in such cases.
+
 %\end{description}
 %\end{description}
 # EndOfTeX
 # EndOfTeX
 
 
@@ -2528,11 +2553,11 @@ option_unsupported_target=11044_F_Die Option "$1" wird auf der Zielplattform nic
 % This section lists errors that occur when the compiler is performing
 % This section lists errors that occur when the compiler is performing
 % whole program optimization.
 % whole program optimization.
 % \begin{description}
 % \begin{description}
-wpo_cant_find_file=12000_F_Feedback-Datei $1 für die Gesamtprogramm-Optimierung kann nicht geöffnet werden
+wpo_cant_find_file=12000_F_Feedback-Datei "$1" für die Gesamtprogramm-Optimierung kann nicht geöffnet werden
 % The compiler cannot open the specified feedback file with whole program optimization information.
 % The compiler cannot open the specified feedback file with whole program optimization information.
-wpo_begin_processing=12001_D_Bearbeite die Informationen zur Gesamtprogramm-Optimierung aus der wpo-Feedback-Datei $1
+wpo_begin_processing=12001_D_Bearbeite die Informationen zur Gesamtprogramm-Optimierung aus der wpo-Feedback-Datei "$1"
 % The compiler starts processing whole program optimization information found in the named file.
 % The compiler starts processing whole program optimization information found in the named file.
-wpo_end_processing=12002_D_Bearbeitung der Informationen zur Gesamtprogramm-Optimierung aus der wpo-Feedback-Datei $1 beendet
+wpo_end_processing=12002_D_Bearbeitung der Informationen zur Gesamtprogramm-Optimierung aus der wpo-Feedback-Datei "$1" beendet
 % The compiler has finished processing the whole program optimization information found in the named file.
 % The compiler has finished processing the whole program optimization information found in the named file.
 wpo_expected_section=12003_E_Erwarte einen Sektions-Header, statt dessen "$2" in Zeile $1 der wpo-Feedback-Datei erhalten
 wpo_expected_section=12003_E_Erwarte einen Sektions-Header, statt dessen "$2" in Zeile $1 der wpo-Feedback-Datei erhalten
 % The compiler expected a section header in the whole program optimization file (starting with \%),
 % The compiler expected a section header in the whole program optimization file (starting with \%),
@@ -2630,6 +2655,9 @@ Unterstützte Gesamtprogramm-Optimierungen:
   All
   All
   $WPOPTIMIZATIONS
   $WPOPTIMIZATIONS
 
 
+Unterstützte Microcontroller:
+  $CONTROLLERTYPES
+
 Dieses Programm unterliegt der GNU General Public Licence
 Dieses Programm unterliegt der GNU General Public Licence
 Weitere Informationen sind in COPYING.FPC zu finden
 Weitere Informationen sind in COPYING.FPC zu finden
 
 
@@ -2849,19 +2877,20 @@ S*2Tlinux_Linux
 **1u<x>_Entferne die Definition für das Symbol <x>
 **1u<x>_Entferne die Definition für das Symbol <x>
 **1U<x>_Unit-Optionen:
 **1U<x>_Unit-Optionen:
 **2Un_Prüfe den Unitnamen nicht
 **2Un_Prüfe den Unitnamen nicht
-**2Ur_Erzeuge release unit Dateien
+**2Ur_Erzeuge "release unit"-Dateien
 **2Us_Erzeuge eine Systemunit
 **2Us_Erzeuge eine Systemunit
 **1v<x>_Meldungen, <x> ist eine Kombination der folgenden Zeichen:
 **1v<x>_Meldungen, <x> ist eine Kombination der folgenden Zeichen:
 **2*_e : Fehler (Standard)             0 : Nichts (ausser Fehlern)
 **2*_e : Fehler (Standard)             0 : Nichts (ausser Fehlern)
 **2*_w : Warnungen                     u : Unit Informationen
 **2*_w : Warnungen                     u : Unit Informationen
 **2*_n : Anmerkungen                   t : Angesprochene/benutzte Dateien
 **2*_n : Anmerkungen                   t : Angesprochene/benutzte Dateien
-**2*_h : Hinweise                      c : Preprozessordirektive
+**2*_h : Hinweise                      c : Preprozessordirektiven
 **2*_i : Allgemeine Informationen      d : Debug Informationen
 **2*_i : Allgemeine Informationen      d : Debug Informationen
 **2*_l : Zeilennummern                 r : Rhide/GCC kompatibler Modus
 **2*_l : Zeilennummern                 r : Rhide/GCC kompatibler Modus
+**2*_s : Zeitstempel                   q : Nummer der Meldung
 **2*_a : Alles                         x : Exe-Datei Informationen (nur Win32)
 **2*_a : Alles                         x : Exe-Datei Informationen (nur Win32)
-**2*_b : Schreibe bei Meldungen mit Dateinamen den vollständigem Pfad
-**2*_v : Schreibe fpcdebug.txt mit     p : Schreibe tree.log mit Analysenbaum (parse tree)
-**2*_   ganz viel Information          q : Zeige die Nummer der Meldung
+**2*_b : Schreibe bei Meldungen mit    p : Schreibe tree.log mit Analysenbaum (parse tree)
+**2*_    Dateinamen den vollständigen  v : Schreibe fpcdebug.txt mit 
+**2*_    Pfad                              ganz viel Information
 **2*_m<x>,<y> : Zeige die Meldungen mit den Nummern <x> und <y> nicht
 **2*_m<x>,<y> : Zeige die Meldungen mit den Nummern <x> und <y> nicht
 3*1W<x>_Ziel-spezifische Optionen (Ziele)
 3*1W<x>_Ziel-spezifische Optionen (Ziele)
 A*1W<x>_Ziel-spezifische Optionen (Ziele)
 A*1W<x>_Ziel-spezifische Optionen (Ziele)
@@ -2908,7 +2937,7 @@ P*2WX_Ermögliche den executable stack (Linux)
 **2XP<x>_Stelle den Namen der Compiler-Hilfsprogrammen den Prefix <x> voran
 **2XP<x>_Stelle den Namen der Compiler-Hilfsprogrammen den Prefix <x> voran
 **2Xr<x>_Setze den Bibliotheks-Suchpfad zu <x>       (benötigt für cross compile)
 **2Xr<x>_Setze den Bibliotheks-Suchpfad zu <x>       (benötigt für cross compile)
 **2XR<x>_Stelle allen Linker-Suchpfaden den Namen <x> voran (BeOS, Darwin, FreeBSD, Linux, Mac OS, Solaris)
 **2XR<x>_Stelle allen Linker-Suchpfaden den Namen <x> voran (BeOS, Darwin, FreeBSD, Linux, Mac OS, Solaris)
-**2Xs_Entferne alle Symbole von ausführbarer Datei
+**2Xs_Entferne alle Symbole aus der ausführbaren Datei
 **2XS_Versuche Units statisch zu linken (default)    (definiert FPC_LINK_STATIC)
 **2XS_Versuche Units statisch zu linken (default)    (definiert FPC_LINK_STATIC)
 **2Xt_Linke mit statischen Bibliotheken              (-static wird an den Linker übergeben)
 **2Xt_Linke mit statischen Bibliotheken              (-static wird an den Linker übergeben)
 **2XX_Versuche Units smart zu linken                 (definiert FPC_LINK_SMART)
 **2XX_Versuche Units smart zu linken                 (definiert FPC_LINK_SMART)

+ 32 - 24
compiler/msg/errore.msg

@@ -366,7 +366,7 @@ scan_w_multiple_main_name_overrides=02086_W_Overriding name of "main" procedure
 #
 #
 # Parser
 # Parser
 #
 #
-# 03255 is the last used one
+# 03256 is the last used one
 #
 #
 % \section{Parser messages}
 % \section{Parser messages}
 % This section lists all parser messages. The parser takes care of the
 % This section lists all parser messages. The parser takes care of the
@@ -1176,23 +1176,28 @@ parser_n_ignore_lower_visibility=03250_N_Virtual method "$1" has a lower visibil
 % The virtual method overrides an method that is declared with a higher visibility. This might give
 % The virtual method overrides an method that is declared with a higher visibility. This might give
 % unexpected results. In case the new visibility is private than it might be that a call to inherited in a
 % unexpected results. In case the new visibility is private than it might be that a call to inherited in a
 % new child class will call the higher visible method in a parent class and ignores the private method.
 % new child class will call the higher visible method in a parent class and ignores the private method.
-parser_e_objc_requires_msgstr=03251_E_Objective-C messages require their Objective-C selector name to be specified using the "message" directive.
+parser_e_field_not_allowed_here=03251_E_Fields cannot appear after a method or property definition, start a new visibility section first
+% Once a method or property has been defined in a class or object, you cannot define any fields afterwards
+% without starting a new visibility section (such as \var{public}, \var{private}, etc.). The reason is
+% that otherwise the source code can appear ambiguous to the compiler, since it is possible to use modifiers
+% such as \var{default} and \var{register} also as field names.
+parser_e_objc_requires_msgstr=03252_E_Objective-C messages require their Objective-C selector name to be specified using the "message" directive.
 % Objective-C messages require their Objective-C name (selector name) to be specified using the \var{message `someName:'} procedure directive.
 % Objective-C messages require their Objective-C name (selector name) to be specified using the \var{message `someName:'} procedure directive.
 % While bindings to other languages automatically generate such names based on the identifier you use (by replacing
 % While bindings to other languages automatically generate such names based on the identifier you use (by replacing
 % all underscores with colons), this is unsafe since nothing prevents an Objective-C method name to contain actual
 % all underscores with colons), this is unsafe since nothing prevents an Objective-C method name to contain actual
 % colons.
 % colons.
-parser_e_objc_no_constructor_destructor=03252_E_Objective-C does not have formal constructors nor destructors. Use the alloc, initXXX and dealloc messages.
+parser_e_objc_no_constructor_destructor=03253_E_Objective-C does not have formal constructors nor destructors. Use the alloc, initXXX and dealloc messages.
 % The Objective-C language does not have any constructors or destructors. While there are some messages with a similar
 % The Objective-C language does not have any constructors or destructors. While there are some messages with a similar
 % purpose (such as \var{init} and \var{dealloc}), these cannot be identified using automatic parsers and do not
 % purpose (such as \var{init} and \var{dealloc}), these cannot be identified using automatic parsers and do not
 % guarantee anything like Pascal constructors/destructors (e.g., you have to take care of only calling ``designated''
 % guarantee anything like Pascal constructors/destructors (e.g., you have to take care of only calling ``designated''
 % inherited ``constructors''). For these reasons, we have opted to follow the standard Objective-C patterns for
 % inherited ``constructors''). For these reasons, we have opted to follow the standard Objective-C patterns for
 % instance creation/destruction.
 % instance creation/destruction.
-parser_e_message_string_too_long=03253_E_Message name is too long (max. 255 characters)
+parser_e_message_string_too_long=03254_E_Message name is too long (max. 255 characters)
 % Due to compiler implementation reasons, message names are currently limited to 255 characters.
 % Due to compiler implementation reasons, message names are currently limited to 255 characters.
-parser_e_objc_message_name_too_long=03254_E_Objective-C message symbol name for "$1" is too long
+parser_e_objc_message_name_too_long=03255_E_Objective-C message symbol name for "$1" is too long
 % Due to compiler implementation reasons, mangled message names (i.e., the symbol names used in the assembler
 % Due to compiler implementation reasons, mangled message names (i.e., the symbol names used in the assembler
 % code) are currently limited to 255 characters.
 % code) are currently limited to 255 characters.
-parser_h_no_objc_parent=03255_H_Defining a new Objective-C root class. To derive from another root class (e.g., NSObject), specify it as the parent class.
+parser_h_no_objc_parent=03256_H_Defining a new Objective-C root class. To derive from another root class (e.g., NSObject), specify it as the parent class.
 % If no parent class is specified for an Object Pascal class, then it automatically derives from TObject.
 % If no parent class is specified for an Object Pascal class, then it automatically derives from TObject.
 % Objective-C classes however do not automatically derive from NSObject, because one can have multiple
 % Objective-C classes however do not automatically derive from NSObject, because one can have multiple
 % root classes in Objective-C. For example, in the Cocoa framework both NSObject and NSProxy are root classes.
 % root classes in Objective-C. For example, in the Cocoa framework both NSObject and NSProxy are root classes.
@@ -1611,7 +1616,7 @@ sym_w_uninitialized_variable=05037_W_Variable "$1" does not seem to be initializ
 % This message is displayed if the compiler thinks that a variable will
 % This message is displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % was not initialized first (i.e. appeared in the left-hand side of an
 % was not initialized first (i.e. appeared in the left-hand side of an
-% assigment).
+% assignment).
 sym_e_id_no_member=05038_E_identifier idents no member "$1"
 sym_e_id_no_member=05038_E_identifier idents no member "$1"
 % This error is generated when an identifier of a record,
 % This error is generated when an identifier of a record,
 % field or method is accessed while it is not defined.
 % field or method is accessed while it is not defined.
@@ -1646,22 +1651,22 @@ sym_h_uninitialized_local_variable=05057_H_Local variable "$1" does not seem to
 % This message is displayed if the compiler thinks that a variable will
 % This message is displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % was not initialized first (i.e. it did not appear in the left-hand side of an
 % was not initialized first (i.e. it did not appear in the left-hand side of an
-% assigment).
+% assignment).
 sym_h_uninitialized_variable=05058_H_Variable "$1" does not seem to be initialized
 sym_h_uninitialized_variable=05058_H_Variable "$1" does not seem to be initialized
 % This message is displayed if the compiler thinks that a variable will
 % This message is displayed if the compiler thinks that a variable will
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % be used (i.e. it appears in the right-hand side of an expression) when it
 % was not initialized first (i.e. t did not appear in the left-hand side of an
 % was not initialized first (i.e. t did not appear in the left-hand side of an
-% assigment).
+% assignment).
 sym_w_function_result_uninitialized=05059_W_Function result variable does not seem to initialized
 sym_w_function_result_uninitialized=05059_W_Function result variable does not seem to initialized
 % This message is displayed if the compiler thinks that the function result
 % This message is displayed if the compiler thinks that the function result
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % before it is initialized (i.e. before it appeared in the left-hand side of an
 % before it is initialized (i.e. before it appeared in the left-hand side of an
-% assigment).
+% assignment).
 sym_h_function_result_uninitialized=05060_H_Function result variable does not seem to be initialized
 sym_h_function_result_uninitialized=05060_H_Function result variable does not seem to be initialized
 % This message is displayed if the compiler thinks that the function result
 % This message is displayed if the compiler thinks that the function result
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % variable will be used (i.e. it appears in the right-hand side of an expression)
 % before it is initialized (i.e. it appears in the left-hand side of an
 % before it is initialized (i.e. it appears in the left-hand side of an
-% assigment)
+% assignment)
 sym_w_identifier_only_read=05061_W_Variable "$1" read but nowhere assigned
 sym_w_identifier_only_read=05061_W_Variable "$1" read but nowhere assigned
 % You have read the value of a variable, but nowhere assigned a value to
 % You have read the value of a variable, but nowhere assigned a value to
 % it.
 % it.
@@ -2231,7 +2236,7 @@ link_f_executable_too_big=09200_F_Executable image size is too big for $1 target
 % Fatal error when resulting executable is too big.
 % Fatal error when resulting executable is too big.
 link_w_32bit_absolute_reloc=09201_W_Object file "$1" contains 32-bit absolute relocation to symbol "$2".
 link_w_32bit_absolute_reloc=09201_W_Object file "$1" contains 32-bit absolute relocation to symbol "$2".
 % Warning when 64-bit object file contains 32-bit absolute relocations.
 % Warning when 64-bit object file contains 32-bit absolute relocations.
-% In such case an executable image can be loaded into lower 4Gb of 
+% In such case an executable image can be loaded into lower 4Gb of
 % address space only.
 % address space only.
 %\end{description}
 %\end{description}
 # EndOfTeX
 # EndOfTeX
@@ -2577,11 +2582,11 @@ option_dwarf_smart_linking=11046_N_DWARF debug information cannot be used with s
 % This section lists errors that occur when the compiler is performing
 % This section lists errors that occur when the compiler is performing
 % whole program optimization.
 % whole program optimization.
 % \begin{description}
 % \begin{description}
-wpo_cant_find_file=12000_F_Cannot open whole program optimization feedback file $1
+wpo_cant_find_file=12000_F_Cannot open whole program optimization feedback file "$1"
 % The compiler cannot open the specified feedback file with whole program optimization information.
 % The compiler cannot open the specified feedback file with whole program optimization information.
-wpo_begin_processing=12001_D_Processing whole program optimization information in wpo feedback file $1
+wpo_begin_processing=12001_D_Processing whole program optimization information in wpo feedback file "$1"
 % The compiler starts processing whole program optimization information found in the named file.
 % The compiler starts processing whole program optimization information found in the named file.
-wpo_end_processing=12002_D_Finished processing the whole program optimization information in wpo feedback file $1
+wpo_end_processing=12002_D_Finished processing the whole program optimization information in wpo feedback file "$1"
 % The compiler has finished processing the whole program optimization information found in the named file.
 % The compiler has finished processing the whole program optimization information found in the named file.
 wpo_expected_section=12003_E_Expected section header, but got "$2" at line $1 of wpo feedback file
 wpo_expected_section=12003_E_Expected section header, but got "$2" at line $1 of wpo feedback file
 % The compiler expected a section header in the whole program optimization file (starting with \%),
 % The compiler expected a section header in the whole program optimization file (starting with \%),
@@ -2778,6 +2783,7 @@ S*2Aas_Assemble using GNU AS
 **2Fa<x>[,y]_(for a program) load units <x> and [y] before uses is parsed
 **2Fa<x>[,y]_(for a program) load units <x> and [y] before uses is parsed
 **2Fc<x>_Set input codepage to <x>
 **2Fc<x>_Set input codepage to <x>
 **2FC<x>_Set RC compiler binary name to <x>
 **2FC<x>_Set RC compiler binary name to <x>
+**2Fd_Disable the compiler's internal directory cache
 **2FD<x>_Set the directory where to search for compiler utilities
 **2FD<x>_Set the directory where to search for compiler utilities
 **2Fe<x>_Redirect error output to <x>
 **2Fe<x>_Redirect error output to <x>
 **2Ff<x>_Add <x> to framework path (Darwin only)
 **2Ff<x>_Add <x> to framework path (Darwin only)
@@ -2798,14 +2804,15 @@ S*2Aas_Assemble using GNU AS
 *g2gh_Use heaptrace unit (for memory leak/corruption debugging)
 *g2gh_Use heaptrace unit (for memory leak/corruption debugging)
 *g2gl_Use line info unit (show more info with backtraces)
 *g2gl_Use line info unit (show more info with backtraces)
 *g2go<x>_Set debug information options
 *g2go<x>_Set debug information options
-*g3godwarfsets_ Enable Dwarf set debug information (breaks gdb < 6.5)
+*g3godwarfsets_ Enable DWARF set debug information (breaks gdb < 6.5)
+*g3gostabsabsincludes_ Store absolute/full include file paths in Stabs
 *g2gp_Preserve case in stabs symbol names
 *g2gp_Preserve case in stabs symbol names
-*g2gs_Generate stabs debug information
+*g2gs_Generate Stabs debug information
 *g2gt_Trash local variables (to detect uninitialized uses)
 *g2gt_Trash local variables (to detect uninitialized uses)
-*g2gv_Generates programs traceable with valgrind
-*g2gw_Generate dwarf-2 debug information (same as -gw2)
-*g2gw2_Generate dwarf-2 debug information
-*g2gw3_Generate dwarf-3 debug information
+*g2gv_Generates programs traceable with Valgrind
+*g2gw_Generate DWARFv2 debug information (same as -gw2)
+*g2gw2_Generate DWARFv2 debug information
+*g2gw3_Generate DWARFv3 debug information
 **1i_Information
 **1i_Information
 **2iD_Return compiler date
 **2iD_Return compiler date
 **2iV_Return short compiler version
 **2iV_Return short compiler version
@@ -2912,10 +2919,11 @@ S*2Tlinux_Linux
 **2*_h : Show hints                  c : Show conditionals
 **2*_h : Show hints                  c : Show conditionals
 **2*_i : Show general info           d : Show debug info
 **2*_i : Show general info           d : Show debug info
 **2*_l : Show linenumbers            r : Rhide/GCC compatibility mode
 **2*_l : Show linenumbers            r : Rhide/GCC compatibility mode
+**2*_s : Show time stamps            q : Show message numbers
 **2*_a : Show everything             x : Executable info (Win32 only)
 **2*_a : Show everything             x : Executable info (Win32 only)
-**2*_b : Write file names messages with full path
-**2*_v : Write fpcdebug.txt with     p : Write tree.log with parse tree
-**2*_    lots of debugging info      q : Show message numbers
+**2*_b : Write file names messages   p : Write tree.log with parse tree
+**2*_    with full path              v : Write fpcdebug.txt with
+**2*_                                    lots of debugging info
 **2*_m<x>,<y> : Don't show messages numbered <x> and <y>
 **2*_m<x>,<y> : Don't show messages numbered <x> and <y>
 3*1W<x>_Target-specific options (targets)
 3*1W<x>_Target-specific options (targets)
 A*1W<x>_Target-specific options (targets)
 A*1W<x>_Target-specific options (targets)

+ 8 - 7
compiler/msgidx.inc

@@ -338,11 +338,12 @@ const
   parser_e_weak_external_not_supported=03248;
   parser_e_weak_external_not_supported=03248;
   parser_e_forward_mismatch=03249;
   parser_e_forward_mismatch=03249;
   parser_n_ignore_lower_visibility=03250;
   parser_n_ignore_lower_visibility=03250;
-  parser_e_objc_requires_msgstr=03251;
-  parser_e_objc_no_constructor_destructor=03252;
-  parser_e_message_string_too_long=03253;
-  parser_e_objc_message_name_too_long=03254;
-  parser_h_no_objc_parent=03255;
+  parser_e_field_not_allowed_here=03251;
+  parser_e_objc_requires_msgstr=03252;
+  parser_e_objc_no_constructor_destructor=03253;
+  parser_e_message_string_too_long=03254;
+  parser_e_objc_message_name_too_long=03255;
+  parser_h_no_objc_parent=03256;
   type_e_mismatch=04000;
   type_e_mismatch=04000;
   type_e_incompatible_types=04001;
   type_e_incompatible_types=04001;
   type_e_not_equal_types=04002;
   type_e_not_equal_types=04002;
@@ -793,9 +794,9 @@ const
   option_info=11024;
   option_info=11024;
   option_help_pages=11025;
   option_help_pages=11025;
 
 
-  MsgTxtSize = 51640;
+  MsgTxtSize = 51955;
 
 
   MsgIdxMax : array[1..20] of longint=(
   MsgIdxMax : array[1..20] of longint=(
-    24,87,256,88,65,51,108,22,202,62,
+    24,87,257,88,65,51,108,22,202,62,
     47,20,1,1,1,1,1,1,1,1
     47,20,1,1,1,1,1,1,1,1
   );
   );

文件差异内容过多而无法显示
+ 303 - 299
compiler/msgtxt.inc


+ 9 - 22
compiler/ncal.pas

@@ -75,6 +75,7 @@ interface
           procedure register_created_object_types;
           procedure register_created_object_types;
 
 
 
 
+       private
           { inlining support }
           { inlining support }
           inlinelocals            : TFPObjectList;
           inlinelocals            : TFPObjectList;
           inlineinitstatement,
           inlineinitstatement,
@@ -1276,7 +1277,6 @@ implementation
         hdef : tdef;
         hdef : tdef;
         ptemp : ttempcreatenode;
         ptemp : ttempcreatenode;
         usederef : boolean;
         usederef : boolean;
-        usevoidpointer : boolean;
       begin
       begin
         { Load all complex loads into a temp to prevent
         { Load all complex loads into a temp to prevent
           double calls to a function. We can't simply check for a hp.nodetype=calln }
           double calls to a function. We can't simply check for a hp.nodetype=calln }
@@ -1287,33 +1287,22 @@ implementation
             usederef:=(p.resultdef.typ in [arraydef,recorddef]) or
             usederef:=(p.resultdef.typ in [arraydef,recorddef]) or
                       is_shortstring(p.resultdef) or
                       is_shortstring(p.resultdef) or
                       is_object(p.resultdef);
                       is_object(p.resultdef);
-            { avoid refcount increase }
-            usevoidpointer:=is_interface(p.resultdef);
 
 
             if usederef then
             if usederef then
               hdef:=tpointerdef.create(p.resultdef)
               hdef:=tpointerdef.create(p.resultdef)
             else
             else
               hdef:=p.resultdef;
               hdef:=p.resultdef;
 
 
-            if usevoidpointer then
+            ptemp:=ctempcreatenode.create(hdef,hdef.size,tt_persistent,true);
+            if usederef then
               begin
               begin
-                ptemp:=ctempcreatenode.create(voidpointertype,voidpointertype.size,tt_persistent,true);
-                loadp:=ctypeconvnode.create_internal(p,voidpointertype);
-                refp:=ctypeconvnode.create_internal(ctemprefnode.create(ptemp),hdef);
+                loadp:=caddrnode.create_internal(p);
+                refp:=cderefnode.create(ctemprefnode.create(ptemp));
               end
               end
             else
             else
               begin
               begin
-                ptemp:=ctempcreatenode.create(hdef,hdef.size,tt_persistent,true);
-                if usederef then
-                  begin
-                    loadp:=caddrnode.create_internal(p);
-                    refp:=cderefnode.create(ctemprefnode.create(ptemp));
-                  end
-                else
-                  begin
-                    loadp:=p;
-                    refp:=ctemprefnode.create(ptemp)
-                  end
+                loadp:=p;
+                refp:=ctemprefnode.create(ptemp)
               end;
               end;
             add_init_statement(ptemp);
             add_init_statement(ptemp);
             add_init_statement(cassignmentnode.create(
             add_init_statement(cassignmentnode.create(
@@ -2372,7 +2361,7 @@ implementation
                   { ignore possible private for properties or in delphi mode for anon. inherited (FK) }
                   { ignore possible private for properties or in delphi mode for anon. inherited (FK) }
                   ignorevisibility:=(nf_isproperty in flags) or
                   ignorevisibility:=(nf_isproperty in flags) or
                                     ((m_delphi in current_settings.modeswitches) and (cnf_anon_inherited in callnodeflags));
                                     ((m_delphi in current_settings.modeswitches) and (cnf_anon_inherited in callnodeflags));
-                  candidates:=tcallcandidates.create(symtableprocentry,symtableproc,left,ignorevisibility);
+                  candidates:=tcallcandidates.create(symtableprocentry,symtableproc,left,ignorevisibility,not(nf_isproperty in flags));
 
 
                    { no procedures found? then there is something wrong
                    { no procedures found? then there is something wrong
                      with the parameter size or the procedures are
                      with the parameter size or the procedures are
@@ -2411,9 +2400,7 @@ implementation
                             end
                             end
                           else
                           else
                             begin
                             begin
-                              if assigned(left) then
-                               current_filepos:=left.fileinfo;
-                              CGMessage1(parser_e_wrong_parameter_size,symtableprocentry.realname);
+                              CGMessagePos1(fileinfo,parser_e_wrong_parameter_size,symtableprocentry.realname);
                               symtableprocentry.write_parameter_lists(nil);
                               symtableprocentry.write_parameter_lists(nil);
                             end;
                             end;
                         end;
                         end;

+ 21 - 8
compiler/ncgcal.pas

@@ -974,6 +974,23 @@ implementation
          { procedure variable or normal function call ? }
          { procedure variable or normal function call ? }
          if (right=nil) then
          if (right=nil) then
            begin
            begin
+             { register call for WPO (must be done before wpo test below,
+               otherwise optimised called methods are no longer registered)
+             }
+             if (po_virtualmethod in procdefinition.procoptions) and
+                assigned(methodpointer) and
+                (methodpointer.nodetype<>typen) and
+                (not assigned(current_procinfo) or
+                 wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
+               tprocdef(procdefinition)._class.register_vmt_call(tprocdef(procdefinition).extnumber);
+{$ifdef vtentry}
+             if not is_interface(tprocdef(procdefinition)._class) then
+               begin
+                 inc(current_asmdata.NextVTEntryNr);
+                 current_asmdata.CurrAsmList.Concat(tai_symbol.CreateName('VTREF'+tostr(current_asmdata.NextVTEntryNr)+'_'+tprocdef(procdefinition)._class.vmt_mangledname+'$$'+tostr(vmtoffset div sizeof(pint)),AT_FUNCTION,0));
+               end;
+{$endif vtentry}
+
              name_to_call:='';
              name_to_call:='';
              { When methodpointer is typen we don't need (and can't) load
              { When methodpointer is typen we don't need (and can't) load
                a pointer. We can directly call the correct procdef (PFV) }
                a pointer. We can directly call the correct procdef (PFV) }
@@ -1005,14 +1022,10 @@ implementation
 
 
                  { Call through VMT, generate a VTREF symbol to notify the linker }
                  { Call through VMT, generate a VTREF symbol to notify the linker }
                  vmtoffset:=tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber);
                  vmtoffset:=tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber);
-{$ifdef vtentry}
-                 if not is_interface(tprocdef(procdefinition)._class) then
-                   begin
-                     inc(current_asmdata.NextVTEntryNr);
-                     current_asmdata.CurrAsmList.Concat(tai_symbol.CreateName('VTREF'+tostr(current_asmdata.NextVTEntryNr)+'_'+tprocdef(procdefinition)._class.vmt_mangledname+'$$'+tostr(vmtoffset div sizeof(pint)),AT_FUNCTION,0));
-                   end;
-{$endif vtentry}
-
+                 { register call for WPO }
+                 if (not assigned(current_procinfo) or
+                     wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
+                   tprocdef(procdefinition)._class.register_vmt_call(tprocdef(procdefinition).extnumber);
 {$ifndef x86}
 {$ifndef x86}
                  pvreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_ADDR);
                  pvreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_ADDR);
 {$endif not x86}
 {$endif not x86}

+ 4 - 4
compiler/ncgflw.pas

@@ -31,10 +31,10 @@ interface
 
 
     type
     type
        tcgwhilerepeatnode = class(twhilerepeatnode)
        tcgwhilerepeatnode = class(twhilerepeatnode)
+          usedregvars: tusedregvars;
+
           procedure pass_generate_code;override;
           procedure pass_generate_code;override;
           procedure sync_regvars(checkusedregvars: boolean);
           procedure sync_regvars(checkusedregvars: boolean);
-
-          usedregvars: tusedregvars;
        end;
        end;
 
 
        tcgifnode = class(tifnode)
        tcgifnode = class(tifnode)
@@ -42,10 +42,10 @@ interface
        end;
        end;
 
 
        tcgfornode = class(tfornode)
        tcgfornode = class(tfornode)
+          usedregvars: tusedregvars;
+
           procedure pass_generate_code;override;
           procedure pass_generate_code;override;
           procedure sync_regvars(checkusedregvars: boolean);
           procedure sync_regvars(checkusedregvars: boolean);
-
-          usedregvars: tusedregvars;
        end;
        end;
 
 
        tcgexitnode = class(texitnode)
        tcgexitnode = class(texitnode)

+ 20 - 1
compiler/ncgld.pas

@@ -64,7 +64,8 @@ implementation
       cpubase,parabase,
       cpubase,parabase,
       tgobj,ncgutil,
       tgobj,ncgutil,
       cgobj,
       cgobj,
-      ncgbas,ncgflw;
+      ncgbas,ncgflw,
+      wpobase;
 
 
 {*****************************************************************************
 {*****************************************************************************
                    SSA (for memory temps) support
                    SSA (for memory temps) support
@@ -115,6 +116,14 @@ implementation
                   result := fen_norecurse_true;
                   result := fen_norecurse_true;
                 end;
                 end;
             end;
             end;
+          { Subscriptn must be rejected, otherwise we may replace an
+            an entire record with a temp for its first field, mantis #13948)
+            Exception: the field's size is the same as the entire record
+          }
+          subscriptn:
+            if not(tsubscriptnode(n).left.resultdef.typ in [recorddef,objectdef]) or
+               (tsubscriptnode(n).left.resultdef.size <> tsubscriptnode(n).resultdef.size) then
+              result := fen_norecurse_false;
           { optimize the searching a bit }
           { optimize the searching a bit }
           derefn,addrn,
           derefn,addrn,
           calln,inlinen,casen,
           calln,inlinen,casen,
@@ -481,6 +490,16 @@ implementation
                      if (po_virtualmethod in procdef.procoptions) and
                      if (po_virtualmethod in procdef.procoptions) and
                         not(nf_inherited in flags) then
                         not(nf_inherited in flags) then
                        begin
                        begin
+                         if (not assigned(current_procinfo) or
+                             wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
+                           procdef._class.register_vmt_call(procdef.extnumber);
+            {$ifdef vtentry}
+                         if not is_interface(procdef._class) then
+                           begin
+                             inc(current_asmdata.NextVTEntryNr);
+                             current_asmdata.CurrAsmList.Concat(tai_symbol.CreateName('VTREF'+tostr(current_asmdata.NextVTEntryNr)+'_'+procdef._class.vmt_mangledname+'$$'+tostr(vmtoffset div sizeof(pint)),AT_FUNCTION,0));
+                           end;
+            {$endif vtentry}
                          { a classrefdef already points to the VMT }
                          { a classrefdef already points to the VMT }
                          if (left.resultdef.typ<>classrefdef) then
                          if (left.resultdef.typ<>classrefdef) then
                            begin
                            begin

+ 8 - 1
compiler/ncgrtti.pas

@@ -67,7 +67,8 @@ implementation
        fmodule,
        fmodule,
        symsym,
        symsym,
        aasmtai,aasmdata,
        aasmtai,aasmdata,
-       defutil
+       defutil,
+       wpobase
        ;
        ;
 
 
 
 
@@ -311,6 +312,12 @@ implementation
                      { virtual method, write vmt offset }
                      { virtual method, write vmt offset }
                      current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,
                      current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,
                        tprocdef(propaccesslist.procdef)._class.vmtmethodoffset(tprocdef(propaccesslist.procdef).extnumber)));
                        tprocdef(propaccesslist.procdef)._class.vmtmethodoffset(tprocdef(propaccesslist.procdef).extnumber)));
+                     { register for wpo }
+                     tprocdef(propaccesslist.procdef)._class.register_vmt_call(tprocdef(propaccesslist.procdef).extnumber);
+                     {$ifdef vtentry}
+                     { not sure if we can insert those vtentry symbols safely here }
+                     {$error register methods used for published properties}
+                     {$endif vtentry}
                      typvalue:=2;
                      typvalue:=2;
                   end;
                   end;
              end;
              end;

+ 10 - 1
compiler/ncnv.pas

@@ -189,13 +189,13 @@ interface
        ttypeconvnodeclass = class of ttypeconvnode;
        ttypeconvnodeclass = class of ttypeconvnode;
 
 
        tasnode = class(tbinarynode)
        tasnode = class(tbinarynode)
+          call: tnode;
           constructor create(l,r : tnode);virtual;
           constructor create(l,r : tnode);virtual;
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
           function pass_typecheck:tnode;override;
           function pass_typecheck:tnode;override;
           function dogetcopy: tnode;override;
           function dogetcopy: tnode;override;
           function docompare(p: tnode): boolean; override;
           function docompare(p: tnode): boolean; override;
           destructor destroy; override;
           destructor destroy; override;
-          call: tnode;
        end;
        end;
        tasnodeclass = class of tasnode;
        tasnodeclass = class of tasnode;
 
 
@@ -3202,6 +3202,11 @@ implementation
          if codegenerror then
          if codegenerror then
            exit;
            exit;
 
 
+         { Passing a class type to an "is" expression cannot result in a class
+           of that type to be constructed.
+         }
+         include(right.flags,nf_ignore_for_wpo);
+
          if (right.resultdef.typ=classrefdef) then
          if (right.resultdef.typ=classrefdef) then
           begin
           begin
             { left must be a class }
             { left must be a class }
@@ -3399,6 +3404,10 @@ implementation
         procname: string;
         procname: string;
       begin
       begin
         result:=nil;
         result:=nil;
+        { Passing a class type to an "as" expression cannot result in a class
+          of that type to be constructed.
+        }
+        include(right.flags,nf_ignore_for_wpo);
         if not assigned(call) then
         if not assigned(call) then
           begin
           begin
             if is_class(left.resultdef) and
             if is_class(left.resultdef) and

+ 4 - 3
compiler/nmem.pas

@@ -175,9 +175,10 @@ implementation
          else if not is_objcclass(left.resultdef) and
          else if not is_objcclass(left.resultdef) and
                  not is_objcclassref(left.resultdef) then
                  not is_objcclassref(left.resultdef) then
            begin
            begin
-             if not assigned(current_procinfo) or
-               (po_inline in current_procinfo.procdef.procoptions) or
-               wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname) then
+             if not(nf_ignore_for_wpo in flags) and
+                (not assigned(current_procinfo) or
+                 (po_inline in current_procinfo.procdef.procoptions) or
+                  wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
              begin
              begin
                { keep track of which classes might be instantiated via a classrefdef }
                { keep track of which classes might be instantiated via a classrefdef }
                if (left.resultdef.typ=classrefdef) then
                if (left.resultdef.typ=classrefdef) then

+ 10 - 1
compiler/node.pas

@@ -257,7 +257,16 @@ interface
          nf_get_asm_position,
          nf_get_asm_position,
 
 
          { tblocknode }
          { tblocknode }
-         nf_block_with_exit
+         nf_block_with_exit,
+
+         { tloadvmtaddrnode }
+         nf_ignore_for_wpo  { we know that this loadvmtaddrnode cannot be used to construct a class instance }
+
+         { WARNING: there are now 32 elements in this type, and a set of this
+             type is written to the PPU. So before adding any more elements,
+             either move some flags to specific nodes, or stream a normalset
+             to the ppu
+         }
 
 
        );
        );
 
 

+ 5 - 0
compiler/options.pas

@@ -852,6 +852,11 @@ begin
                    end;
                    end;
                  'C' :
                  'C' :
                    RCCompiler := More;
                    RCCompiler := More;
+                 'd' :
+                   if UnsetBool(more, 0) then
+                     init_settings.disabledircache:=false
+                   else
+                     init_settings.disabledircache:=true;
                  'D' :
                  'D' :
                    utilsdirectory:=FixPath(More,true);
                    utilsdirectory:=FixPath(More,true);
                  'e' :
                  'e' :

+ 147 - 33
compiler/optvirt.pas

@@ -40,6 +40,7 @@ unit optvirt;
         fdef: tobjectdef;
         fdef: tobjectdef;
         fparent: tinheritancetreenode;
         fparent: tinheritancetreenode;
         fchilds: tfpobjectlist;
         fchilds: tfpobjectlist;
+        fcalledvmtmethods: tbitset;
         finstantiated: boolean;
         finstantiated: boolean;
 
 
         function getchild(index: longint): tinheritancetreenode;
         function getchild(index: longint): tinheritancetreenode;
@@ -57,6 +58,7 @@ unit optvirt;
           this def (either new or existing one
           this def (either new or existing one
         }
         }
         function  maybeaddchild(_def: tobjectdef; _instantiated: boolean): tinheritancetreenode;
         function  maybeaddchild(_def: tobjectdef; _instantiated: boolean): tinheritancetreenode;
+        function  findchild(_def: tobjectdef): tinheritancetreenode;
       end;
       end;
 
 
 
 
@@ -73,6 +75,9 @@ unit optvirt;
         function registerinstantiatedobjectdefrecursive(def: tobjectdef; instantiated: boolean): tinheritancetreenode;
         function registerinstantiatedobjectdefrecursive(def: tobjectdef; instantiated: boolean): tinheritancetreenode;
         procedure markvmethods(node: tinheritancetreenode; p: pointer);
         procedure markvmethods(node: tinheritancetreenode; p: pointer);
         procedure printobjectvmtinfo(node: tinheritancetreenode; arg: pointer);
         procedure printobjectvmtinfo(node: tinheritancetreenode; arg: pointer);
+        procedure addcalledvmtentries(node: tinheritancetreenode; arg: pointer);
+
+        function  getnodefordef(def: tobjectdef): tinheritancetreenode;
        public
        public
         constructor create;
         constructor create;
         destructor destroy; override;
         destructor destroy; override;
@@ -81,6 +86,7 @@ unit optvirt;
         }
         }
         procedure registerinstantiatedobjdef(def: tdef);
         procedure registerinstantiatedobjdef(def: tdef);
         procedure registerinstantiatedclassrefdef(def: tdef);
         procedure registerinstantiatedclassrefdef(def: tdef);
+        procedure registercalledvmtentries(entries: tcalledvmtentries);
         procedure checkforclassrefinheritance(def: tdef);
         procedure checkforclassrefinheritance(def: tdef);
         procedure foreachnode(proctocall: tinheritancetreecallback; arg: pointer);
         procedure foreachnode(proctocall: tinheritancetreecallback; arg: pointer);
         procedure foreachleafnode(proctocall: tinheritancetreecallback; arg: pointer);
         procedure foreachleafnode(proctocall: tinheritancetreecallback; arg: pointer);
@@ -178,6 +184,8 @@ unit optvirt;
         fparent:=_parent;
         fparent:=_parent;
         fdef:=_def;
         fdef:=_def;
         finstantiated:=_instantiated;
         finstantiated:=_instantiated;
+        if assigned(_def) then
+          fcalledvmtmethods:=tbitset.create(_def.vmtentries.count);
       end;
       end;
 
 
 
 
@@ -185,6 +193,7 @@ unit optvirt;
       begin
       begin
         { fchilds owns its members, so it will free them too }
         { fchilds owns its members, so it will free them too }
         fchilds.free;
         fchilds.free;
+        fcalledvmtmethods.free;
         inherited destroy;
         inherited destroy;
       end;
       end;
 
 
@@ -211,8 +220,6 @@ unit optvirt;
 
 
 
 
     function tinheritancetreenode.maybeaddchild(_def: tobjectdef; _instantiated: boolean): tinheritancetreenode;
     function tinheritancetreenode.maybeaddchild(_def: tobjectdef; _instantiated: boolean): tinheritancetreenode;
-      var
-        i: longint;
       begin
       begin
         { sanity check }
         { sanity check }
         if assigned(_def.childof) then 
         if assigned(_def.childof) then 
@@ -226,19 +233,32 @@ unit optvirt;
         if not assigned(fchilds) then
         if not assigned(fchilds) then
           fchilds:=tfpobjectlist.create(true);
           fchilds:=tfpobjectlist.create(true);
         { def already a child -> return }
         { def already a child -> return }
-        for i := 0 to fchilds.count-1 do
-          if (tinheritancetreenode(fchilds[i]).def=_def) then
-            begin
-              result:=tinheritancetreenode(fchilds[i]);
-              result.finstantiated:=result.finstantiated or _instantiated;
-              exit;
-            end;
-        { not found, add new child }
-        result:=tinheritancetreenode.create(self,_def,_instantiated);
-        fchilds.add(result);
+        result:=findchild(_def);
+        if assigned(result) then
+          result.finstantiated:=result.finstantiated or _instantiated
+        else
+          begin
+            { not found, add new child }
+            result:=tinheritancetreenode.create(self,_def,_instantiated);
+            fchilds.add(result);
+          end;
       end;
       end;
 
 
 
 
+    function tinheritancetreenode.findchild(_def: tobjectdef): tinheritancetreenode;
+      var
+        i: longint;
+      begin
+        result:=nil;
+        if assigned(fchilds) then
+          for i := 0 to fchilds.count-1 do
+            if (tinheritancetreenode(fchilds[i]).def=_def) then
+              begin
+                result:=tinheritancetreenode(fchilds[i]);
+                break;
+              end;
+      end;
+
     { *************************** tinheritancetree ************************* }
     { *************************** tinheritancetree ************************* }
 
 
     constructor tinheritancetree.create;
     constructor tinheritancetree.create;
@@ -296,6 +316,37 @@ unit optvirt;
       end;
       end;
 
 
 
 
+    function tinheritancetree.getnodefordef(def: tobjectdef): tinheritancetreenode;
+      begin
+        if assigned(def.childof) then
+          begin
+            result:=getnodefordef(def.childof);
+            if assigned(result) then
+              result:=result.findchild(def);
+          end
+        else
+          result:=froots.findchild(def);
+      end;
+
+
+    procedure tinheritancetree.registercalledvmtentries(entries: tcalledvmtentries);
+      var
+        node: tinheritancetreenode;
+      begin
+        node:=getnodefordef(tobjectdef(entries.objdef));
+        { it's possible that no instance of this class or its descendants are
+          instantiated
+        }
+        if not assigned(node) then
+          exit;
+        { now mark these methods as (potentially) called for this type and for
+          all of its descendants
+        }
+        addcalledvmtentries(node,entries.calledentries);
+        foreachnodefromroot(node,@addcalledvmtentries,entries.calledentries);
+      end;
+
+
    procedure tinheritancetree.checkforclassrefinheritance(def: tdef);
    procedure tinheritancetree.checkforclassrefinheritance(def: tdef);
      var
      var
        i: longint;
        i: longint;
@@ -408,8 +459,19 @@ unit optvirt;
               
               
               if not assigned(currnode.def.vmcallstaticinfo) then
               if not assigned(currnode.def.vmcallstaticinfo) then
                 currnode.def.vmcallstaticinfo:=allocmem(currnode.def.vmtentries.count*sizeof(tvmcallstatic));
                 currnode.def.vmcallstaticinfo:=allocmem(currnode.def.vmtentries.count*sizeof(tvmcallstatic));
+              { if this method cannot be called, we can just mark it as
+                unreachable. This will cause its static name to be set to
+                FPC_ABSTRACTERROR later on. Exception: published methods are
+                always reachable (via RTTI).
+              }
+              if (pd.visibility<>vis_published) and
+                 not(currnode.fcalledvmtmethods.isset(i)) then
+                begin
+                  currnode.def.vmcallstaticinfo^[i]:=vmcs_unreachable;
+                  currnode:=currnode.parent;
+                end
               { same procdef as in all instantiated childs? (yes or don't know) }
               { same procdef as in all instantiated childs? (yes or don't know) }
-              if (currnode.def.vmcallstaticinfo^[i] in [vmcs_default,vmcs_yes]) then
+              else if (currnode.def.vmcallstaticinfo^[i] in [vmcs_default,vmcs_yes]) then
                 begin
                 begin
                   { methods in uninstantiated classes can be made static if
                   { methods in uninstantiated classes can be made static if
                     they are the same in all instantiated derived classes
                     they are the same in all instantiated derived classes
@@ -439,14 +501,16 @@ unit optvirt;
                     end;
                     end;
                   currnode:=currnode.parent;
                   currnode:=currnode.parent;
                 end
                 end
-              else
+              else if (currnode.def.vmcallstaticinfo^[i]=vmcs_no) then
                 begin
                 begin
                   {$IFDEF DEBUG_DEVIRT}
                   {$IFDEF DEBUG_DEVIRT}
                   writeln('    not processing parents, already non-static for ',currnode.def.typename);
                   writeln('    not processing parents, already non-static for ',currnode.def.typename);
                   {$ENDIF}
                   {$ENDIF}
                   { parents are already set to vmcs_no, so no need to continue }
                   { parents are already set to vmcs_no, so no need to continue }
                   currnode:=nil;
                   currnode:=nil;
-                end;
+                end
+              else
+                currnode:=currnode.parent;
             until not assigned(currnode) or
             until not assigned(currnode) or
                   not assigned(currnode.def);
                   not assigned(currnode.def);
           end;
           end;
@@ -463,10 +527,12 @@ unit optvirt;
       var
       var
         i,
         i,
         totaldevirtualised,
         totaldevirtualised,
-        totalvirtual: ptrint;
+        totalvirtual,
+        totalunreachable: ptrint;
       begin
       begin
         totaldevirtualised:=0;
         totaldevirtualised:=0;
         totalvirtual:=0;
         totalvirtual:=0;
+        totalunreachable:=0;
         writeln(node.def.typename);
         writeln(node.def.typename);
         if (node.def.vmtentries.count=0) then
         if (node.def.vmtentries.count=0) then
           begin
           begin
@@ -481,13 +547,26 @@ unit optvirt;
                 begin
                 begin
                   inc(totaldevirtualised);
                   inc(totaldevirtualised);
                   writeln('  Devirtualised: ',pvmtentry(node.def.vmtentries[i])^.procdef.typename);
                   writeln('  Devirtualised: ',pvmtentry(node.def.vmtentries[i])^.procdef.typename);
+                end
+              else if (node.def.vmcallstaticinfo^[i]=vmcs_unreachable) then
+                begin
+                  inc(totalunreachable);
+                  writeln('   Unreachable: ',pvmtentry(node.def.vmtentries[i])^.procdef.typename);
                 end;
                 end;
             end;
             end;
-        writeln('Total devirtualised: ',totaldevirtualised,'/',totalvirtual);
+        writeln('Total devirtualised/unreachable/all: ',totaldevirtualised,'/',totalunreachable,'/',totalvirtual);
         writeln;
         writeln;
       end;
       end;
 
 
 
 
+    procedure tinheritancetree.addcalledvmtentries(node: tinheritancetreenode; arg: pointer);
+      var
+        vmtentries: tbitset absolute arg;
+      begin
+        node.fcalledvmtmethods.addset(vmtentries);
+      end;
+
+
     procedure tinheritancetree.printvmtinfo;
     procedure tinheritancetree.printvmtinfo;
       begin
       begin
         foreachnode(@printobjectvmtinfo,nil);
         foreachnode(@printobjectvmtinfo,nil);
@@ -622,11 +701,18 @@ unit optvirt;
         if (node.def.vmtentries.count=0) then
         if (node.def.vmtentries.count=0) then
           exit;
           exit;
         for i:=0 to node.def.vmtentries.count-1 do
         for i:=0 to node.def.vmtentries.count-1 do
-          if (po_virtualmethod in pvmtentry(node.def.vmtentries[i])^.procdef.procoptions) and
-             (node.def.vmcallstaticinfo^[i]=vmcs_yes) then
-            begin
-              { add info about devirtualised vmt entry }
-              classdevirtinfo.addstaticmethod(i,pvmtentry(node.def.vmtentries[i])^.procdef.mangledname);
+          if (po_virtualmethod in pvmtentry(node.def.vmtentries[i])^.procdef.procoptions) then
+            case node.def.vmcallstaticinfo^[i] of
+              vmcs_yes:
+                begin
+                  { add info about devirtualised vmt entry }
+                  classdevirtinfo.addstaticmethod(i,pvmtentry(node.def.vmtentries[i])^.procdef.mangledname);
+                end;
+              vmcs_unreachable:
+                begin
+                  { static reference to FPC_ABSTRACTERROR }
+                  classdevirtinfo.addstaticmethod(i,'FPC_ABSTRACTERROR');
+                end;
             end;
             end;
       end;
       end;
 
 
@@ -809,6 +895,17 @@ unit optvirt;
              end;
              end;
            end;
            end;
 
 
+         { add info about called virtual methods }
+         hp:=tmodule(loaded_units.first);
+         while assigned(hp) do
+          begin
+            if assigned(hp.wpoinfo.calledvmtentries) then
+              for i:=0 to hp.wpoinfo.calledvmtentries.count-1 do
+                inheritancetree.registercalledvmtentries(tcalledvmtentries(hp.wpoinfo.calledvmtentries[i]));
+            hp:=tmodule(hp.next);
+          end;
+
+
          inheritancetree.optimizevirtualmethods;
          inheritancetree.optimizevirtualmethods;
 {$ifdef DEBUG_DEVIRT}
 {$ifdef DEBUG_DEVIRT}
          inheritancetree.printvmtinfo;
          inheritancetree.printvmtinfo;
@@ -1054,34 +1151,51 @@ unit optvirt;
              exit;
              exit;
            end;
            end;
 
 
+         { if it's for a vmtentry of an objdef and the objdef is
+           not instantiated, then we can fill the vmt with pointers
+           to FPC_ABSTRACTERROR, except for published methods
+           (these can be called via rtti, so always have to point
+            to the original method)
+         }
+         if forvmtentry and
+            (tprocdef(procdef).visibility=vis_published) then
+           begin
+             result:=false;
+             exit;
+           end;
+
          { get the component names for the class/procdef combo }
          { get the component names for the class/procdef combo }
          defsdecompose(realobjdef,tprocdef(procdef),unitid,classid,vmtentry);
          defsdecompose(realobjdef,tprocdef(procdef),unitid,classid,vmtentry);
 
 
+         { If we don't have information about a particular unit/class/method,
+           it means that such class cannot be instantiated. So if we are
+           looking up information for a vmt entry, we can always safely return
+           FPC_ABSTRACTERROR if we do not find anything, unless it's a
+           published method (but those are handled already above) or a
+           class method (can be called even if the class is not instantiated).
+         }
+         result:=
+           forvmtentry and
+           not(po_classmethod in tprocdef(procdef).procoptions);
+         staticname:='FPC_ABSTRACTERROR';
+
          { do we have any info for this unit? }
          { do we have any info for this unit? }
          unitdevirtinfo:=findunit(unitid^);
          unitdevirtinfo:=findunit(unitid^);
-         result:=false;
          if not assigned(unitdevirtinfo) then
          if not assigned(unitdevirtinfo) then
            exit;
            exit;
          { and for this class? }
          { and for this class? }
          classdevirtinfo:=unitdevirtinfo.findclass(classid^);
          classdevirtinfo:=unitdevirtinfo.findclass(classid^);
          if not assigned(classdevirtinfo) then
          if not assigned(classdevirtinfo) then
            exit;
            exit;
-         { if it's for a vmtentry of an objdef and the objdef is
-           not instantiated, then we can fill the vmt with pointers
-           to FPC_ABSTRACTERROR, except for published methods
-           (these can be called via rtti, so always have to point
-            to the original method)
-         }
-         if forvmtentry and
-            (tprocdef(procdef).procsym.visibility=vis_published) then
-           exit;
          if forvmtentry and
          if forvmtentry and
             (objdef.typ=objectdef) and
             (objdef.typ=objectdef) and
             not classdevirtinfo.instantiated and
             not classdevirtinfo.instantiated and
             { virtual class methods can be called even if the class is not instantiated }
             { virtual class methods can be called even if the class is not instantiated }
             not(po_classmethod in tprocdef(procdef).procoptions) then
             not(po_classmethod in tprocdef(procdef).procoptions) then
            begin
            begin
-             staticname:='FPC_ABSTRACTERROR';
+             { already set above
+               staticname:='FPC_ABSTRACTERROR';
+             }
              result:=true;
              result:=true;
            end
            end
          else
          else

+ 19 - 5
compiler/parser.pas

@@ -86,6 +86,7 @@ implementation
          pattern:='';
          pattern:='';
          orgpattern:='';
          orgpattern:='';
          current_scanner:=nil;
          current_scanner:=nil;
+         switchesstatestackpos:=0;
 
 
          { register all nodes and tais }
          { register all nodes and tais }
          registernodes;
          registernodes;
@@ -280,6 +281,8 @@ implementation
           oldcurrent_procinfo : tprocinfo;
           oldcurrent_procinfo : tprocinfo;
           old_settings : tsettings;
           old_settings : tsettings;
           oldsourcecodepage : tcodepagestring;
           oldsourcecodepage : tcodepagestring;
+          old_switchesstatestack : tswitchesstatestack;
+          old_switchesstatestackpos : Integer;
         end;
         end;
 
 
       var
       var
@@ -300,11 +303,13 @@ implementation
          with olddata^ do
          with olddata^ do
           begin
           begin
             old_current_module:=current_module;
             old_current_module:=current_module;
-          { save symtable state }
+
+            { save symtable state }
             oldsymtablestack:=symtablestack;
             oldsymtablestack:=symtablestack;
             oldmacrosymtablestack:=macrosymtablestack;
             oldmacrosymtablestack:=macrosymtablestack;
             oldcurrent_procinfo:=current_procinfo;
             oldcurrent_procinfo:=current_procinfo;
-          { save scanner state }
+
+            { save scanner state }
             oldc:=c;
             oldc:=c;
             oldpattern:=pattern;
             oldpattern:=pattern;
             oldorgpattern:=orgpattern;
             oldorgpattern:=orgpattern;
@@ -312,14 +317,19 @@ implementation
             oldidtoken:=idtoken;
             oldidtoken:=idtoken;
             old_block_type:=block_type;
             old_block_type:=block_type;
             oldtokenpos:=current_tokenpos;
             oldtokenpos:=current_tokenpos;
-          { save cg }
+            old_switchesstatestack:=switchesstatestack;
+            old_switchesstatestackpos:=switchesstatestackpos;
+
+            { save cg }
             oldparse_only:=parse_only;
             oldparse_only:=parse_only;
-          { save akt... state }
-          { handle the postponed case first }
+
+            { save akt... state }
+            { handle the postponed case first }
             flushpendingswitchesstate;
             flushpendingswitchesstate;
             oldcurrent_filepos:=current_filepos;
             oldcurrent_filepos:=current_filepos;
             old_settings:=current_settings;
             old_settings:=current_settings;
           end;
           end;
+
        { reset parser, a previous fatal error could have left these variables in an unreliable state, this is
        { reset parser, a previous fatal error could have left these variables in an unreliable state, this is
          important for the IDE }
          important for the IDE }
          afterassignment:=false;
          afterassignment:=false;
@@ -457,8 +467,12 @@ implementation
                 idtoken:=oldidtoken;
                 idtoken:=oldidtoken;
                 current_tokenpos:=oldtokenpos;
                 current_tokenpos:=oldtokenpos;
                 block_type:=old_block_type;
                 block_type:=old_block_type;
+                switchesstatestack:=old_switchesstatestack;
+                switchesstatestackpos:=old_switchesstatestackpos;
+
                 { restore cg }
                 { restore cg }
                 parse_only:=oldparse_only;
                 parse_only:=oldparse_only;
+
                 { restore symtable state }
                 { restore symtable state }
                 symtablestack:=oldsymtablestack;
                 symtablestack:=oldsymtablestack;
                 macrosymtablestack:=oldmacrosymtablestack;
                 macrosymtablestack:=oldmacrosymtablestack;

+ 18 - 0
compiler/pdecobj.pas

@@ -101,6 +101,11 @@ implementation
             include(p.propoptions,ppo_defaultproperty);
             include(p.propoptions,ppo_defaultproperty);
             if not(ppo_hasparameters in p.propoptions) then
             if not(ppo_hasparameters in p.propoptions) then
               message(parser_e_property_need_paras);
               message(parser_e_property_need_paras);
+            if (token=_COLON) then
+              begin
+                Message(parser_e_field_not_allowed_here);
+                consume_all_until(_SEMICOLON);
+              end;
             consume(_SEMICOLON);
             consume(_SEMICOLON);
           end;
           end;
         { hint directives, these can be separated by semicolons here,
         { hint directives, these can be separated by semicolons here,
@@ -408,6 +413,7 @@ implementation
         oldparse_only,
         oldparse_only,
         old_parse_generic : boolean;
         old_parse_generic : boolean;
         object_member_blocktype : tblock_type;
         object_member_blocktype : tblock_type;
+        fields_allowed: boolean;
       begin
       begin
         { empty class declaration ? }
         { empty class declaration ? }
         if (current_objectdef.objecttype in [odt_class,odt_objcclass]) and
         if (current_objectdef.objecttype in [odt_class,odt_objcclass]) and
@@ -424,6 +430,7 @@ implementation
           current_objectdef.symtable.currentvisibility:=vis_public;
           current_objectdef.symtable.currentvisibility:=vis_public;
         testcurobject:=1;
         testcurobject:=1;
         has_destructor:=false;
         has_destructor:=false;
+        fields_allowed:=true;
         object_member_blocktype:=bt_general;
         object_member_blocktype:=bt_general;
         repeat
         repeat
           case token of
           case token of
@@ -451,6 +458,7 @@ implementation
                        consume(_PRIVATE);
                        consume(_PRIVATE);
                        current_objectdef.symtable.currentvisibility:=vis_private;
                        current_objectdef.symtable.currentvisibility:=vis_private;
                        include(current_objectdef.objectoptions,oo_has_private);
                        include(current_objectdef.objectoptions,oo_has_private);
+                       fields_allowed:=true;
                      end;
                      end;
                    _PROTECTED :
                    _PROTECTED :
                      begin
                      begin
@@ -459,6 +467,7 @@ implementation
                        consume(_PROTECTED);
                        consume(_PROTECTED);
                        current_objectdef.symtable.currentvisibility:=vis_protected;
                        current_objectdef.symtable.currentvisibility:=vis_protected;
                        include(current_objectdef.objectoptions,oo_has_protected);
                        include(current_objectdef.objectoptions,oo_has_protected);
+                       fields_allowed:=true;
                      end;
                      end;
                    _PUBLIC :
                    _PUBLIC :
                      begin
                      begin
@@ -466,6 +475,7 @@ implementation
                          Message(parser_e_no_access_specifier_in_interfaces);
                          Message(parser_e_no_access_specifier_in_interfaces);
                        consume(_PUBLIC);
                        consume(_PUBLIC);
                        current_objectdef.symtable.currentvisibility:=vis_public;
                        current_objectdef.symtable.currentvisibility:=vis_public;
+                       fields_allowed:=true;
                      end;
                      end;
                    _PUBLISHED :
                    _PUBLISHED :
                      begin
                      begin
@@ -476,6 +486,7 @@ implementation
                          Message(parser_e_no_access_specifier_in_interfaces);
                          Message(parser_e_no_access_specifier_in_interfaces);
                        consume(_PUBLISHED);
                        consume(_PUBLISHED);
                        current_objectdef.symtable.currentvisibility:=vis_published;
                        current_objectdef.symtable.currentvisibility:=vis_published;
+                       fields_allowed:=true;
                      end;
                      end;
                    _STRICT :
                    _STRICT :
                      begin
                      begin
@@ -503,6 +514,7 @@ implementation
                           end
                           end
                         else
                         else
                           message(parser_e_protected_or_private_expected);
                           message(parser_e_protected_or_private_expected);
+                        fields_allowed:=true;
                       end;
                       end;
                     else
                     else
                       begin
                       begin
@@ -514,6 +526,8 @@ implementation
                             if (current_objectdef.symtable.currentvisibility=vis_published) and
                             if (current_objectdef.symtable.currentvisibility=vis_published) and
                                not(oo_can_have_published in current_objectdef.objectoptions) then
                                not(oo_can_have_published in current_objectdef.objectoptions) then
                               Message(parser_e_cant_have_published);
                               Message(parser_e_cant_have_published);
+                            if (not fields_allowed) then
+                              Message(parser_e_field_not_allowed_here);
 
 
                             read_record_fields([vd_object])
                             read_record_fields([vd_object])
                           end
                           end
@@ -525,6 +539,7 @@ implementation
             _PROPERTY :
             _PROPERTY :
               begin
               begin
                 property_dec;
                 property_dec;
+                fields_allowed:=false;
               end;
               end;
             _PROCEDURE,
             _PROCEDURE,
             _FUNCTION,
             _FUNCTION,
@@ -571,6 +586,7 @@ implementation
                 maybe_parse_hint_directives(pd);
                 maybe_parse_hint_directives(pd);
 
 
                 parse_only:=oldparse_only;
                 parse_only:=oldparse_only;
+                fields_allowed:=false;
               end;
               end;
             _CONSTRUCTOR :
             _CONSTRUCTOR :
               begin
               begin
@@ -604,6 +620,7 @@ implementation
                 maybe_parse_hint_directives(pd);
                 maybe_parse_hint_directives(pd);
 
 
                 parse_only:=oldparse_only;
                 parse_only:=oldparse_only;
+                fields_allowed:=false;
               end;
               end;
             _DESTRUCTOR :
             _DESTRUCTOR :
               begin
               begin
@@ -642,6 +659,7 @@ implementation
                 maybe_parse_hint_directives(pd);
                 maybe_parse_hint_directives(pd);
 
 
                 parse_only:=oldparse_only;
                 parse_only:=oldparse_only;
+                fields_allowed:=false;
               end;
               end;
             _END :
             _END :
               begin
               begin

+ 16 - 2
compiler/pdecsub.pas

@@ -1128,7 +1128,14 @@ implementation
           message(parser_e_illegal_function_result);
           message(parser_e_illegal_function_result);
         { support procedure proc stdcall export; }
         { support procedure proc stdcall export; }
         if not(check_proc_directive(false)) then
         if not(check_proc_directive(false)) then
-          consume(_SEMICOLON);
+          begin
+            if (token=_COLON) then
+              begin
+                message(parser_e_field_not_allowed_here);
+                consume_all_until(_SEMICOLON);
+              end;
+            consume(_SEMICOLON);
+          end;
         result:=pd;
         result:=pd;
 
 
         if locationstr<>'' then
         if locationstr<>'' then
@@ -2487,7 +2494,14 @@ const
                      (token in [_END,_RKLAMMER,_EQUAL]) then
                      (token in [_END,_RKLAMMER,_EQUAL]) then
                     break
                     break
                   else
                   else
-                    consume(_SEMICOLON);
+                    begin
+                      if (token=_COLON) then
+                        begin
+                          Message(parser_e_field_not_allowed_here);
+                          consume_all_until(_SEMICOLON);
+                        end;
+                      consume(_SEMICOLON)
+                    end;
                 end;
                 end;
             end
             end
            else
            else

+ 4 - 1
compiler/pinline.pas

@@ -79,7 +79,10 @@ implementation
         p:=comp_expr(true);
         p:=comp_expr(true);
         { calc return type }
         { calc return type }
         if is_new then
         if is_new then
-          set_varstate(p,vs_written,[])
+          begin
+            set_varstate(p,vs_written,[]);
+            valid_for_var(p,true);
+          end
         else
         else
           set_varstate(p,vs_readwritten,[vsf_must_be_valid]);
           set_varstate(p,vs_readwritten,[vsf_must_be_valid]);
         if (m_mac in current_settings.modeswitches) and
         if (m_mac in current_settings.modeswitches) and

+ 3 - 3
compiler/pmodules.pas

@@ -1042,6 +1042,9 @@ implementation
            needs to be added implicitly }
            needs to be added implicitly }
          current_module.updatemaps;
          current_module.updatemaps;
 
 
+         { create whole program optimisation information }
+         current_module.wpoinfo:=tunitwpoinfo.create;
+
          { ... parse the declarations }
          { ... parse the declarations }
          Message1(parser_u_parsing_interface,current_module.realmodulename^);
          Message1(parser_u_parsing_interface,current_module.realmodulename^);
          symtablestack.push(current_module.globalsymtable);
          symtablestack.push(current_module.globalsymtable);
@@ -1120,9 +1123,6 @@ implementation
          symtablestack.push(current_module.globalsymtable);
          symtablestack.push(current_module.globalsymtable);
          symtablestack.push(current_module.localsymtable);
          symtablestack.push(current_module.localsymtable);
 
 
-         { create whole program optimisation information }
-         current_module.wpoinfo:=tunitwpoinfo.create;
-
          if not current_module.interface_only then
          if not current_module.interface_only then
            begin
            begin
              Message1(parser_u_parsing_implementation,current_module.modulename^);
              Message1(parser_u_parsing_implementation,current_module.modulename^);

+ 3 - 2
compiler/powerpc/agppcmpw.pas

@@ -41,11 +41,12 @@ interface
         procedure WriteExternals;
         procedure WriteExternals;
         procedure WriteAsmFileHeader;
         procedure WriteAsmFileHeader;
       private
       private
+        cur_CSECT_name: String;
+        cur_CSECT_class: String;
+
         procedure WriteInstruction(hp : tai);
         procedure WriteInstruction(hp : tai);
         procedure WriteProcedureHeader(var hp:tai);
         procedure WriteProcedureHeader(var hp:tai);
         procedure WriteDataHeader(var s:string; isExported, isConst:boolean);
         procedure WriteDataHeader(var s:string; isExported, isConst:boolean);
-        cur_CSECT_name: String;
-        cur_CSECT_class: String;
       end;
       end;
 
 
 
 

+ 2 - 1
compiler/powerpc/cpupi.pas

@@ -47,10 +47,11 @@ unit cpupi;
          private
          private
           first_save_int_reg, first_save_fpu_reg: tsuperregister;
           first_save_int_reg, first_save_fpu_reg: tsuperregister;
          public
          public
+          needs_frame_pointer: boolean;
+
           property get_first_save_int_reg: tsuperregister read first_save_int_reg;
           property get_first_save_int_reg: tsuperregister read first_save_int_reg;
           property get_first_save_fpu_reg: tsuperregister read first_save_fpu_reg;
           property get_first_save_fpu_reg: tsuperregister read first_save_fpu_reg;
 
 
-          needs_frame_pointer: boolean;
        end;
        end;
 
 
 
 

+ 3 - 2
compiler/powerpc64/cpupi.pas

@@ -37,13 +37,14 @@ type
 
 
     { offset where the frame pointer from the outer procedure is stored. }
     { offset where the frame pointer from the outer procedure is stored. }
     parent_framepointer_offset: longint;
     parent_framepointer_offset: longint;
+
+    needs_frame_pointer : boolean;
+
     constructor create(aparent: tprocinfo); override;
     constructor create(aparent: tprocinfo); override;
     procedure set_first_temp_offset; override;
     procedure set_first_temp_offset; override;
     function calc_stackframe_size: longint; override;
     function calc_stackframe_size: longint; override;
     function calc_stackframe_size(numgpr, numfpr : longint): longint;
     function calc_stackframe_size(numgpr, numfpr : longint): longint;
 
 
-    needs_frame_pointer : boolean;
-
     procedure allocate_got_register(list: TAsmList); override;
     procedure allocate_got_register(list: TAsmList); override;
   end;
   end;
 
 

+ 1 - 1
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 {$endif Test_Double_checksum}
 
 
 const
 const
-  CurrentPPUVersion = 97;
+  CurrentPPUVersion = 100;
 
 
 { buffer sizes }
 { buffer sizes }
   maxentrysize = 1024;
   maxentrysize = 1024;

+ 7 - 1
compiler/ptconst.pas

@@ -44,7 +44,8 @@ implementation
        { parser specific stuff }
        { parser specific stuff }
        pbase,pexpr,pdecvar,
        pbase,pexpr,pdecvar,
        { codegen }
        { codegen }
-       cpuinfo,cgbase,dbgbase
+       cpuinfo,cgbase,dbgbase,
+       wpobase
        ;
        ;
 
 
 {$maxfpuregisters 0}
 {$maxfpuregisters 0}
@@ -329,6 +330,11 @@ implementation
                 if not Tobjectdef(tclassrefdef(n.resultdef).pointeddef).is_related(tobjectdef(def.pointeddef)) then
                 if not Tobjectdef(tclassrefdef(n.resultdef).pointeddef).is_related(tobjectdef(def.pointeddef)) then
                   IncompatibleTypes(n.resultdef, def);
                   IncompatibleTypes(n.resultdef, def);
                 list.concat(Tai_const.Create_sym(current_asmdata.RefAsmSymbol(Tobjectdef(tclassrefdef(n.resultdef).pointeddef).vmt_mangledname)));
                 list.concat(Tai_const.Create_sym(current_asmdata.RefAsmSymbol(Tobjectdef(tclassrefdef(n.resultdef).pointeddef).vmt_mangledname)));
+                { update wpo info }
+                if not assigned(current_procinfo) or
+                   (po_inline in current_procinfo.procdef.procoptions) or
+                   wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname) then
+                  tobjectdef(tclassrefdef(n.resultdef).pointeddef).register_maybe_created_object_type;
               end;
               end;
              niln:
              niln:
                list.concat(Tai_const.Create_sym(nil));
                list.concat(Tai_const.Create_sym(nil));

+ 20 - 17
compiler/scandir.pas

@@ -23,22 +23,10 @@ unit scandir;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
-interface
-
-
-    procedure InitScannerDirectives;
-
-implementation
+  interface
 
 
     uses
     uses
-      SysUtils,
-      cutils,cfileutl,
-      globtype,globals,systems,widestr,cpuinfo,
-      verbose,comphook,ppu,
-      scanner,switches,
-      fmodule,
-      symconst,symtable,
-      rabase;
+      globtype;
 
 
     const
     const
       switchesstatestackmax = 20;
       switchesstatestackmax = 20;
@@ -49,10 +37,27 @@ implementation
         verbosity: longint;
         verbosity: longint;
       end;
       end;
 
 
+    type
+      tswitchesstatestack = array[0..switchesstatestackmax] of tsavedswitchesstate;
+
     var
     var
-      switchesstatestack: array[0..switchesstatestackmax] of tsavedswitchesstate;
+      switchesstatestack:tswitchesstatestack;
       switchesstatestackpos: Integer;
       switchesstatestackpos: Integer;
 
 
+    procedure InitScannerDirectives;
+
+  implementation
+
+    uses
+      SysUtils,
+      cutils,cfileutl,
+      globals,systems,widestr,cpuinfo,
+      verbose,comphook,ppu,
+      scanner,switches,
+      fmodule,
+      symconst,symtable,
+      rabase;
+
 {*****************************************************************************
 {*****************************************************************************
                                     Helpers
                                     Helpers
 *****************************************************************************}
 *****************************************************************************}
@@ -1405,6 +1410,4 @@ implementation
         AddDirective('Z4',directive_all, @dir_z4);
         AddDirective('Z4',directive_all, @dir_z4);
       end;
       end;
 
 
-begin
-  switchesstatestackpos:= 0;
 end.
 end.

+ 13 - 4
compiler/symdef.pas

@@ -231,7 +231,7 @@ interface
 
 
        { tobjectdef }
        { tobjectdef }
 
 
-       tvmcallstatic = (vmcs_default, vmcs_yes, vmcs_no);
+       tvmcallstatic = (vmcs_default, vmcs_yes, vmcs_no, vmcs_unreachable);
        pmvcallstaticinfo = ^tmvcallstaticinfo;
        pmvcallstaticinfo = ^tmvcallstaticinfo;
        tmvcallstaticinfo = array[0..1024*1024-1] of tvmcallstatic;
        tmvcallstaticinfo = array[0..1024*1024-1] of tvmcallstatic;
        tobjectdef = class(tabstractrecorddef)
        tobjectdef = class(tabstractrecorddef)
@@ -296,9 +296,11 @@ interface
           function FindDestructor : tprocdef;
           function FindDestructor : tprocdef;
           function implements_any_interfaces: boolean;
           function implements_any_interfaces: boolean;
           procedure reset; override;
           procedure reset; override;
+          { WPO }
           procedure register_created_object_type;override;
           procedure register_created_object_type;override;
           procedure register_maybe_created_object_type;
           procedure register_maybe_created_object_type;
           procedure register_created_classref_type;
           procedure register_created_classref_type;
+          procedure register_vmt_call(index:longint);
           procedure make_all_methods_external;
           procedure make_all_methods_external;
        end;
        end;
 
 
@@ -2385,10 +2387,10 @@ implementation
             exit;
             exit;
           end;
           end;
 
 
+        result:=cachedelesize*aint(cachedelecount);
         if (ado_IsBitPacked in arrayoptions) then
         if (ado_IsBitPacked in arrayoptions) then
-          size:=(cachedelesize * aint(cachedelecount) + 7) div 8
-        else
-          result:=cachedelesize*aint(cachedelecount);
+          { can't just add 7 and divide by 8, because that may overflow }
+          result:=result div 8 + ord((result mod 8)<>0);
       end;
       end;
 
 
 
 
@@ -4319,6 +4321,13 @@ implementation
       end;
       end;
 
 
 
 
+    procedure tobjectdef.register_vmt_call(index: longint);
+      begin
+        if (is_object(self) or is_class(self)) then
+          current_module.wpoinfo.addcalledvmtentry(self,index);
+      end;
+
+
     procedure make_procdef_external(data: tobject; arg: pointer);
     procedure make_procdef_external(data: tobject; arg: pointer);
       var
       var
         def: tdef absolute data;
         def: tdef absolute data;

+ 2 - 1
compiler/symsym.pas

@@ -137,9 +137,10 @@ interface
                                          callback:Tnotification_callback):cardinal;
                                          callback:Tnotification_callback):cardinal;
           procedure unregister_notification(id:cardinal);
           procedure unregister_notification(id:cardinal);
         private
         private
-          procedure setvardef(def:tdef);
           _vardef     : tdef;
           _vardef     : tdef;
           vardefderef : tderef;
           vardefderef : tderef;
+
+          procedure setvardef(def:tdef);
         public
         public
           property vardef: tdef read _vardef write setvardef;
           property vardef: tdef read _vardef write setvardef;
       end;
       end;

+ 1 - 2
compiler/symtable.pas

@@ -91,12 +91,11 @@ interface
           procedure insertdef(def:TDefEntry);override;
           procedure insertdef(def:TDefEntry);override;
           function is_packed: boolean;
           function is_packed: boolean;
         protected
         protected
-          procedure setdatasize(val: aint);
           _datasize       : aint;
           _datasize       : aint;
           { size in bits of the data in case of bitpacked record. Only important during construction, }
           { size in bits of the data in case of bitpacked record. Only important during construction, }
           { no need to save in/restore from ppu file. datasize is always (databitsize+7) div 8.       }
           { no need to save in/restore from ppu file. datasize is always (databitsize+7) div 8.       }
           databitsize    : aint;
           databitsize    : aint;
-          { bitpacked? -> all fieldvarsym offsets are in bits instead of bytes }
+          procedure setdatasize(val: aint);
         public
         public
           property datasize : aint read _datasize write setdatasize;
           property datasize : aint read _datasize write setdatasize;
        end;
        end;

+ 2 - 1
compiler/systems.pas

@@ -236,7 +236,8 @@ interface
 
 
 
 
        palignmentinfo = ^talignmentinfo;
        palignmentinfo = ^talignmentinfo;
-       talignmentinfo = record
+       { this is written to ppus during token recording for generics so it must be packed }
+       talignmentinfo = packed record
          procalign,
          procalign,
          loopalign,
          loopalign,
          jumpalign,
          jumpalign,

+ 2 - 2
compiler/systems/i_embed.pas

@@ -33,8 +33,8 @@ unit i_embed;
             system       : system_arm_embedded;
             system       : system_arm_embedded;
             name         : 'Embedded';
             name         : 'Embedded';
             shortname    : 'embedded';
             shortname    : 'embedded';
-            flags        : [tf_needs_symbol_size,tf_files_case_sensitive,tf_use_function_relative_addresses
-	                          ,tf_smartlink_sections];
+            flags        : [tf_needs_symbol_size,tf_files_case_sensitive,
+                            tf_use_function_relative_addresses,tf_smartlink_sections];
             cpu          : cpu_arm;
             cpu          : cpu_arm;
             unit_env     : '';
             unit_env     : '';
             extradefines : '';
             extradefines : '';

+ 2 - 0
compiler/systems/i_gba.pas

@@ -57,6 +57,8 @@ unit i_gba;
             staticClibext : '.a';
             staticClibext : '.a';
             staticClibprefix : 'lib';
             staticClibprefix : 'lib';
             sharedClibprefix : 'lib';
             sharedClibprefix : 'lib';
+            importlibprefix : 'libimp';
+            importlibext : '.a';
             Cprefix      : '';
             Cprefix      : '';
             newline      : #10;
             newline      : #10;
             dirsep       : '/';
             dirsep       : '/';

+ 2 - 0
compiler/systems/i_nds.pas

@@ -57,6 +57,8 @@ unit i_nds;
             staticClibext : '.a';
             staticClibext : '.a';
             staticClibprefix : 'lib';
             staticClibprefix : 'lib';
             sharedClibprefix : 'lib';
             sharedClibprefix : 'lib';
+            importlibprefix : 'libimp';
+            importlibext : '.a';
             Cprefix      : '';
             Cprefix      : '';
             newline      : #10;
             newline      : #10;
             dirsep       : '/';
             dirsep       : '/';

+ 55 - 25
compiler/systems/t_embed.pas

@@ -224,32 +224,63 @@ begin
       with linkres do
       with linkres do
         begin
         begin
           Add('ENTRY(_START)');
           Add('ENTRY(_START)');
-          Add('SECTIONS');
+          Add('MEMORY');
           Add('{');
           Add('{');
-          Add('     . = 0x0;  /* start of flash */');
-          Add('    /* code and constants */');
-          Add('    .text :');
-          Add('    {');
-          Add('    *(.init, .init.*)');
-          Add('    *(.text, .text.*)');
-          Add('    *(.strings)');
-          Add('    *(.rodata.*)');
-          Add('    *(.comment)');
-          Add('    }');
-          Add('    /* uninitialized data */');
-          Add('    . = 0x40000000;  /* start of ram */');
-          Add('    .bss :');
-          Add('    {');
-          Add('    *(.bss, .bss.*)');
-          Add('    *(COMMON)');
-          Add('    *(.data, .data.*)');
-          Add('    KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
-          Add('    }');
+          Add('    flash : ORIGIN = 0, LENGTH = 256K');
+          Add('    ram : ORIGIN = 0x40000000, LENGTH = 16K');
           Add('}');
           Add('}');
+          Add('_stack_top = 0x40003FFC;');
         end;
         end;
+      ct_at91sam7s256,
+      ct_at91sam7se256,
+      ct_at91sam7x256,
+      ct_at91sam7xc256:
+      with linkres do
+        begin
+          Add('ENTRY(_START)');
+          Add('MEMORY');
+          Add('{');
+          Add('    flash : ORIGIN = 0, LENGTH = 256K');
+          Add('    ram : ORIGIN = 0x200000, LENGTH = 64K');
+          Add('}');
+          Add('_stack_top = 0x20FFFC;');
+        end;
+
     else
     else
       internalerror(200902011);
       internalerror(200902011);
   end;
   end;
+
+  with linkres do
+    begin
+      Add('SECTIONS');
+      Add('{');
+      Add('     .text :');
+      Add('    {');
+      Add('    *(.init, .init.*)');
+      Add('    *(.text, .text.*)');
+      Add('    *(.strings)');
+      Add('    *(.rodata, .rodata.*)');
+      Add('    *(.comment)');
+      Add('    _etext = .;');
+      Add('    } >flash');
+      Add('    .data :');
+      Add('    {');
+      Add('    _data = .;');
+      Add('    *(.data, .data.*)');
+      Add('    KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
+      Add('    _edata = .;');
+      Add('    } >ram AT >flash');
+      Add('    .bss :');
+      Add('    {');
+      Add('    _bss_start = .;');
+      Add('    *(.bss, .bss.*)');
+      Add('    *(COMMON)');
+      Add('    } >ram');
+      Add('. = ALIGN(4);');
+      Add('_bss_end = . ;');
+      Add('}');
+      Add('_end = .;');
+    end;
 {$endif ARM}
 {$endif ARM}
 
 
   { Write and Close response }
   { Write and Close response }
@@ -308,17 +339,16 @@ begin
   success:=DoExec(FindUtil(utilsprefix+BinStr),cmdstr,true,false);
   success:=DoExec(FindUtil(utilsprefix+BinStr),cmdstr,true,false);
 
 
 { Remove ReponseFile }
 { Remove ReponseFile }
-  if (success) and not(cs_link_nolink in current_settings.globalswitches) then
+  if success and not(cs_link_nolink in current_settings.globalswitches) then
    DeleteFile(outputexedir+Info.ResName);
    DeleteFile(outputexedir+Info.ResName);
 
 
-{ Post process
+{ Post process }
   if success then
   if success then
     begin
     begin
-      success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+
+      success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O ihex '+
         ChangeFileExt(current_module.exefilename^,'.elf')+' '+
         ChangeFileExt(current_module.exefilename^,'.elf')+' '+
-        current_module.exefilename^,true,false);
+        ChangeFileExt(current_module.exefilename^,'.hex'),true,false);
     end;
     end;
-}
 
 
   MakeExecutable:=success;   { otherwise a recursive call to link method }
   MakeExecutable:=success;   { otherwise a recursive call to link method }
 end;
 end;

+ 1 - 1
compiler/systems/t_gba.pas

@@ -31,7 +31,7 @@ implementation
 
 
     uses
     uses
        SysUtils,
        SysUtils,
-       cutils,cfileutils,cclasses,
+       cutils,cfileutl,cclasses,
        globtype,globals,systems,verbose,script,fmodule,i_gba,link;
        globtype,globals,systems,verbose,script,fmodule,i_gba,link;
 
 
     type
     type

+ 1 - 1
compiler/systems/t_nds.pas

@@ -31,7 +31,7 @@ implementation
 
 
     uses
     uses
        SysUtils,
        SysUtils,
-       cutils,cfileutils,cclasses,
+       cutils,cfileutl,cclasses,
        globtype,globals,systems,verbose,script,fmodule,i_nds,link;
        globtype,globals,systems,verbose,script,fmodule,i_nds,link;
 
 
     type
     type

+ 128 - 1
compiler/wpobase.pas

@@ -110,6 +110,31 @@ type
   { ** Information created per unit for use during subsequent compilation *** }
   { ** Information created per unit for use during subsequent compilation *** }
   { ************************************************************************* }
   { ************************************************************************* }
 
 
+  { information about called vmt entries for a class }
+  tcalledvmtentries = class
+   protected
+    { the class }
+    fobjdef: tdef;
+    fobjdefderef: tderef;
+    { the vmt entries }
+    fcalledentries: tbitset;
+   public
+    constructor create(_objdef: tdef; nentries: longint);
+    constructor ppuload(ppufile: tcompilerppufile);
+    destructor destroy; override;
+    procedure ppuwrite(ppufile: tcompilerppufile);
+
+    procedure buildderef;
+    procedure buildderefimpl;
+    procedure deref;
+    procedure derefimpl;
+
+    property objdef: tdef read fobjdef write fobjdef;
+    property objdefderef: tderef read fobjdefderef write fobjdefderef;
+    property calledentries: tbitset read fcalledentries write fcalledentries;
+  end;
+
+
   { base class of information collected per unit. Still needs to be
   { base class of information collected per unit. Still needs to be
     generalised for different kinds of wpo information, currently specific
     generalised for different kinds of wpo information, currently specific
     to devirtualization.
     to devirtualization.
@@ -127,6 +152,12 @@ type
        so they can end up in a classrefdef var and be instantiated)
        so they can end up in a classrefdef var and be instantiated)
     }
     }
     fmaybecreatedbyclassrefdeftypes: tfpobjectlist;
     fmaybecreatedbyclassrefdeftypes: tfpobjectlist;
+
+    { called virtual methods for all classes (hashed by mangled classname,
+      entries bitmaps indicating which vmt entries per class are called --
+      tcalledvmtentries)
+    }
+    fcalledvmtentries: tfphashlist;
    public
    public
     constructor create; reintroduce; virtual;
     constructor create; reintroduce; virtual;
     destructor destroy; override;
     destructor destroy; override;
@@ -134,10 +165,12 @@ type
     property createdobjtypes: tfpobjectlist read fcreatedobjtypes;
     property createdobjtypes: tfpobjectlist read fcreatedobjtypes;
     property createdclassrefobjtypes: tfpobjectlist read fcreatedclassrefobjtypes;
     property createdclassrefobjtypes: tfpobjectlist read fcreatedclassrefobjtypes;
     property maybecreatedbyclassrefdeftypes: tfpobjectlist read fmaybecreatedbyclassrefdeftypes;
     property maybecreatedbyclassrefdeftypes: tfpobjectlist read fmaybecreatedbyclassrefdeftypes;
+    property calledvmtentries: tfphashlist read fcalledvmtentries;
 
 
     procedure addcreatedobjtype(def: tdef);
     procedure addcreatedobjtype(def: tdef);
     procedure addcreatedobjtypeforclassref(def: tdef);
     procedure addcreatedobjtypeforclassref(def: tdef);
     procedure addmaybecreatedbyclassref(def: tdef);
     procedure addmaybecreatedbyclassref(def: tdef);
+    procedure addcalledvmtentry(def: tdef; index: longint);
   end;
   end;
 
 
   { ************************************************************************* }
   { ************************************************************************* }
@@ -321,10 +354,13 @@ implementation
       fcreatedobjtypes:=tfpobjectlist.create(false);
       fcreatedobjtypes:=tfpobjectlist.create(false);
       fcreatedclassrefobjtypes:=tfpobjectlist.create(false);
       fcreatedclassrefobjtypes:=tfpobjectlist.create(false);
       fmaybecreatedbyclassrefdeftypes:=tfpobjectlist.create(false);
       fmaybecreatedbyclassrefdeftypes:=tfpobjectlist.create(false);
+      fcalledvmtentries:=tfphashlist.create;
     end;
     end;
 
 
 
 
   destructor tunitwpoinfobase.destroy;
   destructor tunitwpoinfobase.destroy;
+    var
+      i: longint;
     begin
     begin
       fcreatedobjtypes.free;
       fcreatedobjtypes.free;
       fcreatedobjtypes:=nil;
       fcreatedobjtypes:=nil;
@@ -332,6 +368,18 @@ implementation
       fcreatedclassrefobjtypes:=nil;
       fcreatedclassrefobjtypes:=nil;
       fmaybecreatedbyclassrefdeftypes.free;
       fmaybecreatedbyclassrefdeftypes.free;
       fmaybecreatedbyclassrefdeftypes:=nil;
       fmaybecreatedbyclassrefdeftypes:=nil;
+
+      { may not be assigned in case the info was loaded from a ppu and we
+        are not generating a wpo feedback file (see tunitwpoinfo.ppuload)
+      }
+      if assigned(fcalledvmtentries) then
+        begin
+          for i:=0 to fcalledvmtentries.count-1 do
+            tcalledvmtentries(fcalledvmtentries[i]).free;
+          fcalledvmtentries.free;
+          fcalledvmtentries:=nil;
+        end;
+
       inherited destroy;
       inherited destroy;
     end;
     end;
     
     
@@ -341,16 +389,35 @@ implementation
       fcreatedobjtypes.add(def);
       fcreatedobjtypes.add(def);
     end;
     end;
 
 
+
   procedure tunitwpoinfobase.addcreatedobjtypeforclassref(def: tdef);
   procedure tunitwpoinfobase.addcreatedobjtypeforclassref(def: tdef);
     begin
     begin
       fcreatedclassrefobjtypes.add(def);
       fcreatedclassrefobjtypes.add(def);
     end;
     end;
 
 
+
   procedure tunitwpoinfobase.addmaybecreatedbyclassref(def: tdef);
   procedure tunitwpoinfobase.addmaybecreatedbyclassref(def: tdef);
     begin
     begin
       fmaybecreatedbyclassrefdeftypes.add(def);
       fmaybecreatedbyclassrefdeftypes.add(def);
     end;
     end;
 
 
+
+  procedure tunitwpoinfobase.addcalledvmtentry(def: tdef; index: longint);
+    var
+      entries: tcalledvmtentries;
+      key: shortstring;
+    begin
+      key:=tobjectdef(def).vmt_mangledname;
+      entries:=tcalledvmtentries(fcalledvmtentries.find(key));
+      if not assigned(entries) then
+        begin
+          entries:=tcalledvmtentries.create(def,tobjectdef(def).vmtentries.count);
+          fcalledvmtentries.add(key,entries);
+        end;
+      entries.calledentries.include(index);
+    end;
+
+
   { twpofilereader }
   { twpofilereader }
 
 
   function twpofilereader.getnextnoncommentline(out s: string):
   function twpofilereader.getnextnoncommentline(out s: string):
@@ -379,7 +446,9 @@ implementation
 
 
   constructor twpofilereader.create(const fn: tcmdstr; dest: twpoinfomanagerbase);
   constructor twpofilereader.create(const fn: tcmdstr; dest: twpoinfomanagerbase);
     begin
     begin
-      if not FileExists(fn) then
+      if not FileExists(fn) or
+         { FileExists also returns true for directories }
+         DirectoryExists(fn) then
         begin
         begin
           cgmessage1(wpo_cant_find_file,fn);
           cgmessage1(wpo_cant_find_file,fn);
           exit;
           exit;
@@ -677,4 +746,62 @@ implementation
       inherited destroy;
       inherited destroy;
     end;
     end;
 
 
+  { tcalledvmtentries }
+
+  constructor tcalledvmtentries.create(_objdef: tdef; nentries: longint);
+    begin
+      objdef:=_objdef;
+      calledentries:=tbitset.create(nentries);
+    end;
+
+
+  constructor tcalledvmtentries.ppuload(ppufile: tcompilerppufile);
+    var
+      len: longint;
+    begin
+      ppufile.getderef(fobjdefderef);
+      len:=ppufile.getlongint;
+      calledentries:=tbitset.create_bytesize(len);
+      if (len <> calledentries.datasize) then
+        internalerror(2009060301);
+      ppufile.readdata(calledentries.data^,len);
+    end;
+
+
+  destructor tcalledvmtentries.destroy;
+    begin
+      fcalledentries.free;
+      inherited destroy;
+    end;
+
+
+  procedure tcalledvmtentries.ppuwrite(ppufile: tcompilerppufile);
+    begin
+      ppufile.putderef(objdefderef);
+      ppufile.putlongint(calledentries.datasize);
+      ppufile.putdata(calledentries.data^,calledentries.datasize);
+    end;
+
+
+  procedure tcalledvmtentries.buildderef;
+    begin
+      objdefderef.build(objdef);
+    end;
+
+
+  procedure tcalledvmtentries.buildderefimpl;
+    begin
+    end;
+
+
+  procedure tcalledvmtentries.deref;
+    begin
+      objdef:=tdef(objdefderef.resolve);
+    end;
+
+
+  procedure tcalledvmtentries.derefimpl;
+    begin
+    end;
+
 end.
 end.

+ 72 - 20
compiler/wpoinfo.pas

@@ -41,6 +41,7 @@ type
     fcreatedobjtypesderefs: pderefarray;
     fcreatedobjtypesderefs: pderefarray;
     fcreatedclassrefobjtypesderefs: pderefarray;
     fcreatedclassrefobjtypesderefs: pderefarray;
     fmaybecreatedbyclassrefdeftypesderefs: pderefarray;
     fmaybecreatedbyclassrefdeftypesderefs: pderefarray;
+    fcalledvmtentriestemplist: tfpobjectlist;
    { devirtualisation information -- end }
    { devirtualisation information -- end }
 
 
    public
    public
@@ -92,6 +93,13 @@ implementation
           freemem(fmaybecreatedbyclassrefdeftypesderefs);
           freemem(fmaybecreatedbyclassrefdeftypesderefs);
           fmaybecreatedbyclassrefdeftypesderefs:=nil;
           fmaybecreatedbyclassrefdeftypesderefs:=nil;
         end;
         end;
+
+      if assigned(fcalledvmtentriestemplist) then
+        begin
+          fcalledvmtentriestemplist.free;
+          fcalledvmtentriestemplist:=nil;
+        end;
+
       inherited destroy;
       inherited destroy;
     end;
     end;
     
     
@@ -113,6 +121,10 @@ implementation
       for i:=0 to fmaybecreatedbyclassrefdeftypes.count-1 do
       for i:=0 to fmaybecreatedbyclassrefdeftypes.count-1 do
         ppufile.putderef(fmaybecreatedbyclassrefdeftypesderefs^[i]);
         ppufile.putderef(fmaybecreatedbyclassrefdeftypesderefs^[i]);
 
 
+      ppufile.putlongint(fcalledvmtentries.count);
+      for i:=0 to fcalledvmtentries.count-1 do
+        tcalledvmtentries(fcalledvmtentries[i]).ppuwrite(ppufile);
+
       ppufile.writeentry(ibcreatedobjtypes);
       ppufile.writeentry(ibcreatedobjtypes);
 
 
       { don't free deref arrays immediately after use, as the types may need
       { don't free deref arrays immediately after use, as the types may need
@@ -129,26 +141,41 @@ implementation
       if ppufile.readentry<>ibcreatedobjtypes then
       if ppufile.readentry<>ibcreatedobjtypes then
         cgmessage(unit_f_ppu_read_error);
         cgmessage(unit_f_ppu_read_error);
 
 
-      len:=ppufile.getlongint;
-      fcreatedobjtypes:=tfpobjectlist.create(false);
-      fcreatedobjtypes.count:=len;
-      getmem(fcreatedobjtypesderefs,len*sizeof(tderef));
-      for i:=0 to len-1 do
-        ppufile.getderef(fcreatedobjtypesderefs^[i]);
-
-      len:=ppufile.getlongint;
-      fcreatedclassrefobjtypes:=tfpobjectlist.create(false);
-      fcreatedclassrefobjtypes.count:=len;
-      getmem(fcreatedclassrefobjtypesderefs,len*sizeof(tderef));
-      for i:=0 to len-1 do
-        ppufile.getderef(fcreatedclassrefobjtypesderefs^[i]);
-
-      len:=ppufile.getlongint;
-      fmaybecreatedbyclassrefdeftypes:=tfpobjectlist.create(false);
-      fmaybecreatedbyclassrefdeftypes.count:=len;
-      getmem(fmaybecreatedbyclassrefdeftypesderefs,len*sizeof(tderef));
-      for i:=0 to len-1 do
-        ppufile.getderef(fmaybecreatedbyclassrefdeftypesderefs^[i]);
+      { don't load the wpo info from the units if we are not generating
+        a wpo feedback file (that would just take time and memory)
+      }
+      if (init_settings.genwpoptimizerswitches=[]) then
+        ppufile.skipdata(ppufile.entrysize)
+      else
+        begin
+          len:=ppufile.getlongint;
+          fcreatedobjtypes:=tfpobjectlist.create(false);
+          fcreatedobjtypes.count:=len;
+          getmem(fcreatedobjtypesderefs,len*sizeof(tderef));
+          for i:=0 to len-1 do
+            ppufile.getderef(fcreatedobjtypesderefs^[i]);
+
+          len:=ppufile.getlongint;
+          fcreatedclassrefobjtypes:=tfpobjectlist.create(false);
+          fcreatedclassrefobjtypes.count:=len;
+          getmem(fcreatedclassrefobjtypesderefs,len*sizeof(tderef));
+          for i:=0 to len-1 do
+            ppufile.getderef(fcreatedclassrefobjtypesderefs^[i]);
+
+          len:=ppufile.getlongint;
+          fmaybecreatedbyclassrefdeftypes:=tfpobjectlist.create(false);
+          fmaybecreatedbyclassrefdeftypes.count:=len;
+          getmem(fmaybecreatedbyclassrefdeftypesderefs,len*sizeof(tderef));
+          for i:=0 to len-1 do
+            ppufile.getderef(fmaybecreatedbyclassrefdeftypesderefs^[i]);
+
+          len:=ppufile.getlongint;
+          fcalledvmtentriestemplist:=tfpobjectlist.create(false);
+          fcalledvmtentriestemplist.count:=len;
+          fcalledvmtentries:=tfphashlist.create;
+          for i:=0 to len-1 do
+            fcalledvmtentriestemplist[i]:=tcalledvmtentries.ppuload(ppufile);
+        end;
     end;
     end;
 
 
 
 
@@ -167,6 +194,9 @@ implementation
       getmem(fmaybecreatedbyclassrefdeftypesderefs,fmaybecreatedbyclassrefdeftypes.count*sizeof(tderef));
       getmem(fmaybecreatedbyclassrefdeftypesderefs,fmaybecreatedbyclassrefdeftypes.count*sizeof(tderef));
       for i:=0 to fmaybecreatedbyclassrefdeftypes.count-1 do
       for i:=0 to fmaybecreatedbyclassrefdeftypes.count-1 do
         fmaybecreatedbyclassrefdeftypesderefs^[i].build(fmaybecreatedbyclassrefdeftypes[i]);
         fmaybecreatedbyclassrefdeftypesderefs^[i].build(fmaybecreatedbyclassrefdeftypes[i]);
+
+      for i:=0 to fcalledvmtentries.count-1 do
+        tcalledvmtentries(fcalledvmtentries[i]).objdefderef.build(tcalledvmtentries(fcalledvmtentries[i]).objdef);
     end;
     end;
 
 
 
 
@@ -178,7 +208,12 @@ implementation
   procedure tunitwpoinfo.deref;
   procedure tunitwpoinfo.deref;
     var
     var
       i: longint;
       i: longint;
+      len: longint;
+
     begin
     begin
+      if (init_settings.genwpoptimizerswitches=[]) then
+        exit;
+
       { don't free deref arrays immediately after use, as the types may need
       { don't free deref arrays immediately after use, as the types may need
         re-resolving in case a unit needs to be reloaded
         re-resolving in case a unit needs to be reloaded
       }
       }
@@ -190,6 +225,23 @@ implementation
 
 
       for i:=0 to fmaybecreatedbyclassrefdeftypes.count-1 do
       for i:=0 to fmaybecreatedbyclassrefdeftypes.count-1 do
         fmaybecreatedbyclassrefdeftypes[i]:=fmaybecreatedbyclassrefdeftypesderefs^[i].resolve;
         fmaybecreatedbyclassrefdeftypes[i]:=fmaybecreatedbyclassrefdeftypesderefs^[i].resolve;
+
+      { in case we are re-resolving, free previous batch }
+      if (fcalledvmtentries.count<>0) then
+        { don't just re-deref, in case the name might have changed (?) }
+        fcalledvmtentries.clear;
+      { allocate enough internal memory in one go }
+      fcalledvmtentries.capacity:=fcalledvmtentriestemplist.count;
+      { now resolve all items in the list and add them to the hash table }
+      for i:=0 to fcalledvmtentriestemplist.count-1 do
+        begin
+          with tcalledvmtentries(fcalledvmtentriestemplist[i]) do
+            begin
+              objdef:=tdef(objdefderef.resolve);
+              fcalledvmtentries.add(tobjectdef(objdef).vmt_mangledname,
+                fcalledvmtentriestemplist[i]);
+            end;
+        end;
     end;
     end;
 
 
 
 

+ 2 - 2
ide/fpdebug.pas

@@ -201,6 +201,8 @@ type
 
 
     PWatch = ^TWatch;
     PWatch = ^TWatch;
     TWatch =  Object(TObject)
     TWatch =  Object(TObject)
+      expr : pstring;
+      last_value,current_value : pchar;
       constructor Init(s : string);
       constructor Init(s : string);
       constructor Load(var S: TStream);
       constructor Load(var S: TStream);
       procedure   Store(var S: TStream);
       procedure   Store(var S: TStream);
@@ -208,8 +210,6 @@ type
       procedure Get_new_value;
       procedure Get_new_value;
       procedure Force_new_value;
       procedure Force_new_value;
       destructor done;virtual;
       destructor done;virtual;
-      expr : pstring;
-      last_value,current_value : pchar;
     private
     private
       GDBRunCount : longint;
       GDBRunCount : longint;
     end;
     end;

+ 3 - 3
ide/fpkeys.pas

@@ -36,13 +36,13 @@ Const
 type
 type
    PKeyDialog = ^TKeyDialog;
    PKeyDialog = ^TKeyDialog;
    TKeyDialog = object(TCenterDialog)
    TKeyDialog = object(TCenterDialog)
-     Constructor Init(Const ATitle : String);
-     {Procedure HandleEvent(var E : TEvent);virtual;}
-     function Execute : Word;Virtual;
       PSTL : Array [1..NumWantedKeys] of PLabel;
       PSTL : Array [1..NumWantedKeys] of PLabel;
       PL : Array [1..NumWantedKeys] of PInputLine;
       PL : Array [1..NumWantedKeys] of PInputLine;
       KeyOK : Array [1..NumWantedKeys] of boolean;
       KeyOK : Array [1..NumWantedKeys] of boolean;
       PST,PST2 : PAdvancedStaticText;
       PST,PST2 : PAdvancedStaticText;
+      Constructor Init(Const ATitle : String);
+     {Procedure HandleEvent(var E : TEvent);virtual;}
+     function Execute : Word;Virtual;
    end;
    end;
 
 
 Procedure LoadKeys(var S : TStream);
 Procedure LoadKeys(var S : TStream);

+ 1 - 1
ide/fpmingw.pas

@@ -34,7 +34,7 @@ uses gdbint; // force dependancies that hopefully make it execute at the right m
 Type
 Type
   TAtexitFunction = function(p:TCFUnction):longint cdecl;
   TAtexitFunction = function(p:TCFUnction):longint cdecl;
 
 
-var _imp__atexit : TAtExitFunction; Cvar;  // "true" atexit in mingw libs.
+var _imp__atexit : TAtExitFunction; Cvar; external;  // "true" atexit in mingw libs.
 
 
 function atexit(p:TCFunction):longint;cdecl; [public, alias : '_atexit'];
 function atexit(p:TCFunction):longint;cdecl; [public, alias : '_atexit'];
 
 

+ 2 - 2
ide/fpviews.pas

@@ -124,10 +124,10 @@ type
 
 
     PSourceEditor = ^TSourceEditor;
     PSourceEditor = ^TSourceEditor;
     TSourceEditor = object(TFileEditor)
     TSourceEditor = object(TFileEditor)
-      constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
-          PScrollBar; AIndicator: PIndicator;const AFileName: string);
       CompileStamp : longint;
       CompileStamp : longint;
       CodeCompleteTip: PFPToolTip;
       CodeCompleteTip: PFPToolTip;
+      constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
+          PScrollBar; AIndicator: PIndicator;const AFileName: string);
 {$ifndef NODEBUG}
 {$ifndef NODEBUG}
     private
     private
       ShouldHandleBreakpoints : boolean;
       ShouldHandleBreakpoints : boolean;

+ 1 - 0
packages/chm/src/chmreader.pas

@@ -241,6 +241,7 @@ begin
   {$IFDEF CHM_DEBUG}
   {$IFDEF CHM_DEBUG}
   WriteLn('PMGI depth = ', fDirectoryHeader.IndexTreeDepth);
   WriteLn('PMGI depth = ', fDirectoryHeader.IndexTreeDepth);
   WriteLn('PMGI Root =  ', fDirectoryHeader.IndexOfRootChunk);
   WriteLn('PMGI Root =  ', fDirectoryHeader.IndexOfRootChunk);
+  Writeln('DirCount  =  ', fDirectoryHeader.DirectoryChunkCount);
   {$ENDIF}
   {$ENDIF}
   fDirectoryEntriesStartPos := fStream.Position;
   fDirectoryEntriesStartPos := fStream.Position;
   fDirectoryHeaderLength := LEtoN(fHeaderEntries[1].Length);
   fDirectoryHeaderLength := LEtoN(fHeaderEntries[1].Length);

+ 6 - 0
packages/fcl-base/src/daemonapp.pp

@@ -236,6 +236,7 @@ Type
   Published
   Published
     Property DaemonClassName : String Read FDaemonClassName Write FDaemonClassName;
     Property DaemonClassName : String Read FDaemonClassName Write FDaemonClassName;
     Property Name : String Read FName Write SetName;
     Property Name : String Read FName Write SetName;
+    Property Description : String Read FDescription Write FDescription;
     Property DisplayName : String Read FDisplayName Write FDisplayName;
     Property DisplayName : String Read FDisplayName Write FDisplayName;
     Property RunArguments : String Read FRunArgs Write FRunArgs;
     Property RunArguments : String Read FRunArgs Write FRunArgs;
     Property Options : TDaemonOptions Read FOptions Write FOptions;
     Property Options : TDaemonOptions Read FOptions Write FOptions;
@@ -1141,6 +1142,11 @@ begin
         CheckControlMessage(True);
         CheckControlMessage(True);
       CheckControlMessage(False);
       CheckControlMessage(False);
       end;
       end;
+    end
+  else
+    begin
+    FDaemon.Status:=csStopped;
+    Application.Terminate;
     end;
     end;
 end;
 end;
 
 

+ 5 - 1
packages/fcl-base/src/win/daemonapp.inc

@@ -185,12 +185,13 @@ Procedure TCustomDaemonApplication.SysInstallDaemon(Daemon : TCustomDaemon);
 
 
 Var
 Var
   SM,SV: SC_HANDLE;
   SM,SV: SC_HANDLE;
-  N,DN,E,LG,UN,UP : String;
+  SD,N,DN,E,LG,UN,UP : String;
   DD : TDaemonDef;
   DD : TDaemonDef;
   ST,STT,ES: Integer;
   ST,STT,ES: Integer;
   IDTag : DWord;
   IDTag : DWord;
   PIDTag : LPDWord;
   PIDTag : LPDWord;
   PDeps,PN,PP : PChar;
   PDeps,PN,PP : PChar;
+  D : TServiceDescriptionA;
   
   
 begin
 begin
   SM:=TSMData(FSysData).FHandle;
   SM:=TSMData(FSysData).FHandle;
@@ -243,6 +244,9 @@ begin
     If (SV=0) then
     If (SV=0) then
       RaiseLastOSError;
       RaiseLastOSError;
     Try
     Try
+      SD:=DD.Description;
+      D.lpDescription:=Pchar(SD);
+      ChangeServiceConfig2(SV,SERVICE_CONFIG_DESCRIPTION,@D);
       If (PIDTag<>Nil) then
       If (PIDTag<>Nil) then
         DD.WinBindings.IDTag:=IDTag;
         DD.WinBindings.IDTag:=IDTag;
     finally
     finally

+ 123 - 3
packages/fcl-db/src/codegen/fpcgtiopf.pp

@@ -23,10 +23,12 @@ uses
   Classes, SysUtils, db, fpddcodegen;
   Classes, SysUtils, db, fpddcodegen;
   
   
 TYpe
 TYpe
-  TClassOption = (caCreateClass,caConstructor,caDestructor,caCreateList,caListAddMethod,caListItemsProperty);
+  TClassOption = (caCreateClass,caConstructor,caDestructor,caCreateList,
+                  caListAddMethod,caListItemsProperty,caOverrideRead,
+                  caOverrideReadThis,caOverrideSave);
   TClassOptions = Set of TClassOption;
   TClassOptions = Set of TClassOption;
   TVisitorOption = (voRead,voReadList,voCreate,voDelete,voUpdate,
   TVisitorOption = (voRead,voReadList,voCreate,voDelete,voUpdate,
-                    voCommonSetupParams,voSingleSaveVisitor);
+                    voCommonSetupParams,voSingleSaveVisitor,voRegisterVisitors);
   TVisitorOptions = set of TVisitorOption;
   TVisitorOptions = set of TVisitorOption;
   
   
   { TTiOPFCodeOptions }
   { TTiOPFCodeOptions }
@@ -76,6 +78,9 @@ TYpe
     // Auxiliary routines
     // Auxiliary routines
     procedure WriteFieldAssign(Strings: TStrings; F: TFieldPropDef);
     procedure WriteFieldAssign(Strings: TStrings; F: TFieldPropDef);
     procedure WriteAssignToParam(Strings: TStrings; F: TFieldPropDef);
     procedure WriteAssignToParam(Strings: TStrings; F: TFieldPropDef);
+    procedure WriteReadWriteOverride(Strings: TStrings; const AAMethod, AVisitorGroup: String);
+    procedure WriteRegisterVisitorLine(Strings: TStrings;
+      const V: TVisitorOption; const ObjectClassName: String);
     procedure WriteSetSQL(Strings: TStrings; const ASQL: String);
     procedure WriteSetSQL(Strings: TStrings; const ASQL: String);
     procedure WriteSQLConstants(Strings: TStrings);
     procedure WriteSQLConstants(Strings: TStrings);
     Procedure WriteTerminateVisitor(Strings : TStrings; V : TVisitorOption; const ObjectClassName: String);
     Procedure WriteTerminateVisitor(Strings : TStrings; V : TVisitorOption; const ObjectClassName: String);
@@ -90,14 +95,17 @@ TYpe
     procedure WriteReadVisitor(Strings: TStrings; const ObjectClassName: String );
     procedure WriteReadVisitor(Strings: TStrings; const ObjectClassName: String );
     procedure WriteVisitorDeclaration(Strings: TStrings; V: TVisitorOption; const ObjectClassName: String);
     procedure WriteVisitorDeclaration(Strings: TStrings; V: TVisitorOption; const ObjectClassName: String);
     procedure WriteVisitorImplementation(Strings: TStrings; V: TVisitorOption; const ObjectClassName: String);
     procedure WriteVisitorImplementation(Strings: TStrings; V: TVisitorOption; const ObjectClassName: String);
+    procedure WriteVisitorRegistration(Strings: TStrings; const ObjectClassName: String);
   Protected
   Protected
     // Not to be overridden.
     // Not to be overridden.
     procedure WriteListAddObject(Strings: TStrings; const ListClassName, ObjectClassName: String);
     procedure WriteListAddObject(Strings: TStrings; const ListClassName, ObjectClassName: String);
     // Overrides of parent objects
     // Overrides of parent objects
     function AllowPropertyDeclaration(F: TFieldPropDef; AVisibility: TVisibilities): Boolean; override;
     function AllowPropertyDeclaration(F: TFieldPropDef; AVisibility: TVisibilities): Boolean; override;
     Function GetInterfaceUsesClause : string; override;
     Function GetInterfaceUsesClause : string; override;
+    procedure WriteVisibilityStart(V: TVisibility; Strings: TStrings); override;
     Procedure DoGenerateInterface(Strings: TStrings); override;
     Procedure DoGenerateInterface(Strings: TStrings); override;
     Procedure DoGenerateImplementation(Strings: TStrings); override;
     Procedure DoGenerateImplementation(Strings: TStrings); override;
+    procedure CreateImplementation(Strings: TStrings); override;
     Function NeedsConstructor : Boolean; override;
     Function NeedsConstructor : Boolean; override;
     Function NeedsDestructor : Boolean; override;
     Function NeedsDestructor : Boolean; override;
     Class Function NeedsFieldDefs : Boolean; override;
     Class Function NeedsFieldDefs : Boolean; override;
@@ -370,8 +378,12 @@ begin
   If (Result<>'') then
   If (Result<>'') then
     Result:=Result+', ';
     Result:=Result+', ';
   Result:=Result+'tiVisitor, tiVisitorDB, tiObject';
   Result:=Result+'tiVisitor, tiVisitorDB, tiObject';
+  If (voRegisterVisitors in tiOPFoptions.VisitorOptions)
+     or ([caOverrideRead,caOverrideReadThis,caOverrideSave]*tiOPFOptions.ClassOptions<>[]) then
+    Result:=Result+', tiOPFManager';
 end;
 end;
 
 
+
 procedure TTiOPFCodeGenerator.DoGenerateInterface(Strings: TStrings);
 procedure TTiOPFCodeGenerator.DoGenerateInterface(Strings: TStrings);
 
 
 Var
 Var
@@ -400,6 +412,12 @@ begin
       DecIndent;
       DecIndent;
     end;
     end;
     end;
     end;
+  If voRegisterVisitors in tiOPFoptions.VisitorOptions then
+    begin
+    AddLn(Strings);
+    AddLn(Strings,'Procedure Register'+tiOPFoptions.ObjectClassName+'Visitors;');
+    AddLn(Strings);
+    end;
 end;
 end;
 
 
 
 
@@ -526,7 +544,7 @@ procedure TTiOPFCodeGenerator.WriteSQLConstants(Strings : TStrings);
 
 
 Const
 Const
   VisSQL : Array [TVisitorOption] of string
   VisSQL : Array [TVisitorOption] of string
-         = ('Read','ReadList','Create','Delete','Update','','');
+         = ('Read','ReadList','Create','Delete','Update','','','');
 
 
 Var
 Var
   OCN,S : String;
   OCN,S : String;
@@ -596,9 +614,62 @@ begin
     For V:=Low(TVisitorOption) to High(TVisitorOption) do
     For V:=Low(TVisitorOption) to High(TVisitorOption) do
       If V in VisitorOptions then
       If V in VisitorOptions then
         WriteVisitorImplementation(Strings,V,ObjectClassName);
         WriteVisitorImplementation(Strings,V,ObjectClassName);
+    If (voRegisterVisitors in TiOPFOptions.VisitorOptions) then
+      WriteVisitorRegistration(Strings,ObjectClassName);
     end;
     end;
 end;
 end;
 
 
+{ ---------------------------------------------------------------------
+  Override read/write/readthis
+  ---------------------------------------------------------------------}
+
+procedure TTiOPFCodeGenerator.WriteVisibilityStart(V: TVisibility;
+  Strings: TStrings);
+begin
+  Inherited;
+  If (V=vPublic) then
+    begin
+    if (caOverrideSave in TiOPFOptions.ClassOptions) then
+      AddLn(Strings,'Procedure Save; override;');
+    If (caOverrideRead in TiOPFOptions.ClassOptions) then
+      AddLn(Strings,'Procedure Read; override;');
+    If (caOverrideReadThis in TiOPFOptions.ClassOptions) then
+      AddLn(Strings,'Procedure ReadThis; override;');
+    end;
+end;
+
+procedure TTiOPFCodeGenerator.CreateImplementation(Strings: TStrings);
+
+begin
+  inherited CreateImplementation(Strings);
+  if (caOverrideSave in TiOPFOptions.ClassOptions) then
+    WriteReadWriteOverride(Strings,'Save','Save');
+  If (caOverrideRead in TiOPFOptions.ClassOptions) then
+    WriteReadWriteOverride(Strings,'Read','Read');
+  If (caOverrideReadThis in TiOPFOptions.ClassOptions) then
+    WriteReadWriteOverride(Strings,'ReadThis','Read');
+end;
+
+procedure TTiOPFCodeGenerator.WriteReadWriteOverride(Strings : TStrings; Const AAMethod,AVisitorGroup : String);
+
+Const
+  SExecVisitor = 'GTIOPFManager.VisitorManager.Execute(''%s_%s'',Self);';
+
+Var
+  OCN,S: String;
+
+begin
+  OCN:=TiOPFOptions.ObjectClassName;
+  S:=Format('Procedure %s.%s;',[OCN,AAMethod]);
+  BeginMethod(Strings,S);
+  AddLn(Strings,'begin');
+  IncIndent;
+  S:=Format(SExecVisitor,[OCN,AVisitorGroup]);
+  AddLn(Strings,S);
+  DecIndent;
+  EndMethod(Strings,S);
+end;
+
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
   Visitor helper routines
   Visitor helper routines
   ---------------------------------------------------------------------}
   ---------------------------------------------------------------------}
@@ -619,6 +690,7 @@ begin
     WriteTerminateVisitor(Strings,V,ObjectClassName);
     WriteTerminateVisitor(Strings,V,ObjectClassName);
 end;
 end;
 
 
+
 Function TTiOPFCodeGenerator.BeginInit(Strings : TStrings; const AClass : String) : String;
 Function TTiOPFCodeGenerator.BeginInit(Strings : TStrings; const AClass : String) : String;
 
 
 begin
 begin
@@ -674,6 +746,54 @@ begin
   IncIndent;
   IncIndent;
 end;
 end;
 
 
+{ ---------------------------------------------------------------------
+  Visitor registration
+  ---------------------------------------------------------------------}
+
+procedure TTiOPFCodeGenerator.WriteRegisterVisitorLine(Strings : TStrings; Const V: TVisitorOption; Const ObjectClassName : String);
+
+Var
+  C : String;
+  S : String;
+
+begin
+  C:=VisitorClassName(v,ObjectClassName);
+  Case V of
+    voRead        : S:='Read';
+    voReadList    : S:='ReadList';
+    voCreate      : S:='Save';
+    voDelete      : S:='Save';
+    voUpdate      : S:='Save';
+  end;
+  S:=ObjectClassName+'_'+S;
+  S:=Format('GTIOPFManager.RegisterVisitor(''%s'',%s);',[S,C]);
+  AddLn(Strings,S);
+end;
+
+procedure TTiOPFCodeGenerator.WriteVisitorRegistration(Strings : TStrings; Const ObjectClassName : String);
+
+Const
+  RealVis = [voRead,voReadList,voCreate,voDelete,voUpdate];
+
+Var
+  v : TVisitorOption;
+  S : String;
+
+begin
+  Addln(Strings);
+  S:='Procedure Register'+ObjectClassName+'Visitors;';
+  BeginMethod(Strings,S);
+  AddLn(Strings,'begin');
+  IncIndent;
+  For v:=Low(TVisitorOption) to High(TVisitorOption) do
+    begin
+    If (V in RealVis) and (V in TiOPFOptions.VisitorOptions) then
+      WriteRegisterVisitorLine(Strings,V,ObjectClassName);
+    end;
+  DecIndent;
+  EndMethod(Strings,S);
+end;
+
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
   Read Visitor
   Read Visitor
   ---------------------------------------------------------------------}
   ---------------------------------------------------------------------}

+ 99 - 13
packages/fcl-db/src/datadict/fpdatadict.pp

@@ -24,8 +24,15 @@ uses
 
 
 Type
 Type
   // Supported objects in this data dictionary
   // Supported objects in this data dictionary
-  TObjectType = (otUnknown,otDictionary,otTables,otTable,otFields,otField,
-                 otConnection,otTableData,otIndexDefs,otIndexDef);
+  TObjectType = (otUnknown,otDictionary,
+                 otTables,otTable,
+                 otFields,otField,
+                 otConnection,otTableData,
+                 otIndexDefs,otIndexDef,
+                 otSequenceDefs,otSequenceDef,
+                 otForeignKeyDefs,otForeignKeyDef,
+                 otDomainDefs,otDomainDef);
+
   TDDProgressEvent = Procedure(Sender : TObject; Const Msg : String) of Object;
   TDDProgressEvent = Procedure(Sender : TObject; Const Msg : String) of Object;
 
 
   TFPDDFieldList = Class;
   TFPDDFieldList = Class;
@@ -450,7 +457,9 @@ Type
   end;
   end;
 
 
   { TFPDDSQLEngine }
   { TFPDDSQLEngine }
-  TSQLEngineOption = (eoLineFeedAfterField,eoUseOldInWhereParams,eoAndTermsInBrackets,eoQuoteFieldNames,eoLineFeedAfterAndTerm,eoAddTerminator);
+  TSQLEngineOption = (eoLineFeedAfterField,eoUseOldInWhereParams,eoAndTermsInBrackets,
+                      eoQuoteFieldNames,eoLineFeedAfterAndTerm,eoAddTerminator,
+                      eoSkipForeignkeys);
   TSQLEngineOptions = Set of TSQLEngineOption;
   TSQLEngineOptions = Set of TSQLEngineOption;
   
   
 
 
@@ -470,7 +479,8 @@ Type
     Procedure ResetLine;
     Procedure ResetLine;
     Procedure AddToStringLN(Var Res : String; S : String);
     Procedure AddToStringLN(Var Res : String; S : String);
     Procedure AddToString(Var Res : String; S : String);
     Procedure AddToString(Var Res : String; S : String);
-    Procedure FixUpStatement(var Res : String);
+    Procedure FixUpStatement(var Res : String; ForceTerminator : Boolean = False);
+    Procedure FixUpStatement(SQL : TStrings; ForceTerminator : Boolean = False);
     Procedure AddWhereClause(Var Res : String; FieldList: TFPDDFieldList; UseOldParam:Boolean);
     Procedure AddWhereClause(Var Res : String; FieldList: TFPDDFieldList; UseOldParam:Boolean);
     Function CreateAndTerm(FD : TDDFieldDef; UseOldParam : Boolean): string;
     Function CreateAndTerm(FD : TDDFieldDef; UseOldParam : Boolean): string;
     // Primitives. Override for engine-specifics
     // Primitives. Override for engine-specifics
@@ -488,6 +498,7 @@ Type
   Public
   Public
     Constructor Create; virtual;
     Constructor Create; virtual;
     function  CreateWhereSQL(Var Res : String; FieldList: TFPDDFieldList; UseOldParam:Boolean): String;
     function  CreateWhereSQL(Var Res : String; FieldList: TFPDDFieldList; UseOldParam:Boolean): String;
+    // Methods that fill a stringlist
     Procedure CreateSelectSQLStrings(FieldList,KeyFields : TFPDDFieldList; SQL : TStrings);
     Procedure CreateSelectSQLStrings(FieldList,KeyFields : TFPDDFieldList; SQL : TStrings);
     Procedure CreateInsertSQLStrings(FieldList : TFPDDFieldList; SQL : TStrings);
     Procedure CreateInsertSQLStrings(FieldList : TFPDDFieldList; SQL : TStrings);
     Procedure CreateUpdateSQLStrings(FieldList,KeyFields : TFPDDFieldList; SQL : TStrings);
     Procedure CreateUpdateSQLStrings(FieldList,KeyFields : TFPDDFieldList; SQL : TStrings);
@@ -495,23 +506,29 @@ Type
     Procedure CreateCreateSQLStrings(Fields,KeyFields : TFPDDFieldList; SQL : TStrings);
     Procedure CreateCreateSQLStrings(Fields,KeyFields : TFPDDFieldList; SQL : TStrings);
     Procedure CreateCreateSQLStrings(KeyFields : TFPDDFieldList; SQL : TStrings);
     Procedure CreateCreateSQLStrings(KeyFields : TFPDDFieldList; SQL : TStrings);
     Procedure CreateIndexesSQLStrings(Indexes : TFPDDIndexList; SQL : TStrings);
     Procedure CreateIndexesSQLStrings(Indexes : TFPDDIndexList; SQL : TStrings);
+    Procedure CreateForeignKeysSQLStrings(ForeignKeys: TDDForeignKeyDefs; SQL : TStrings);
     Procedure CreateSequencesSQLStrings(Sequences : TFPDDSequenceList; SQL : TStrings);
     Procedure CreateSequencesSQLStrings(Sequences : TFPDDSequenceList; SQL : TStrings);
     Procedure CreateDomainsSQLStrings(Domains : TFPDDDomainList; SQL : TStrings);
     Procedure CreateDomainsSQLStrings(Domains : TFPDDDomainList; SQL : TStrings);
+    // Insert/Update/Delete statements.
     Function  CreateSelectSQL(FieldList,KeyFields : TFPDDFieldList) : String; virtual;
     Function  CreateSelectSQL(FieldList,KeyFields : TFPDDFieldList) : String; virtual;
     Function  CreateInsertSQL(FieldList : TFPDDFieldList) : String; virtual;
     Function  CreateInsertSQL(FieldList : TFPDDFieldList) : String; virtual;
     Function  CreateUpdateSQL(FieldList,KeyFields : TFPDDFieldList) : String; virtual;
     Function  CreateUpdateSQL(FieldList,KeyFields : TFPDDFieldList) : String; virtual;
     Function  CreateDeleteSQL(KeyFields : TFPDDFieldList) : String; virtual;
     Function  CreateDeleteSQL(KeyFields : TFPDDFieldList) : String; virtual;
+    // CREATE TABLE statement
     Function  CreateCreateSQL(Fields,KeyFields : TFPDDFieldList) : String; virtual;
     Function  CreateCreateSQL(Fields,KeyFields : TFPDDFieldList) : String; virtual;
     Function  CreateCreateSQL(KeyFields : TFPDDFieldList) : String; virtual;
     Function  CreateCreateSQL(KeyFields : TFPDDFieldList) : String; virtual;
-    // Indexes
+    // CREATE INDEX
     Function  CreateIndexSQL(Index : TDDIndexDef) : String; virtual;
     Function  CreateIndexSQL(Index : TDDIndexDef) : String; virtual;
     Function  CreateIndexesSQL(Indexes : TFPDDIndexList) : String;
     Function  CreateIndexesSQL(Indexes : TFPDDIndexList) : String;
     Function  CreateIndexesSQL(Indexes : TDDIndexDefs) : String;
     Function  CreateIndexesSQL(Indexes : TDDIndexDefs) : String;
-    // Sequences
+    // CONSTRAINT: Foreign keys
+    Function  CreateForeignKeySQL(ForeignKey: TDDForeignKeyDef) : String;virtual;
+    Function  CreateForeignKeysSQL(ForeignKeys: TDDForeignKeyDefs) : String;
+    // CREATE SEQUENCE
     Function  CreateSequenceSQL(Sequence : TDDSequenceDef) : String; virtual;
     Function  CreateSequenceSQL(Sequence : TDDSequenceDef) : String; virtual;
     Function  CreateSequencesSQL(Sequences : TFPDDSequenceList) : String;
     Function  CreateSequencesSQL(Sequences : TFPDDSequenceList) : String;
     Function  CreateSequencesSQL(Sequences : TDDSequenceDefs) : String;
     Function  CreateSequencesSQL(Sequences : TDDSequenceDefs) : String;
-    // Domains
+    // CREATE DOMAIN
     Function  CreateDomainSQL(Domain : TDDDomainDef) : String; virtual;
     Function  CreateDomainSQL(Domain : TDDDomainDef) : String; virtual;
     Function  CreateDomainsSQL(Domains : TFPDDDomainList) : String;
     Function  CreateDomainsSQL(Domains : TFPDDDomainList) : String;
     Function  CreateDomainsSQL(Domains : TDDDomainDefs) : String;
     Function  CreateDomainsSQL(Domains : TDDDomainDefs) : String;
@@ -1317,6 +1334,7 @@ begin
   FTableName:=AValue;
   FTableName:=AValue;
   FFieldDefs.TableName:=AValue;
   FFieldDefs.TableName:=AValue;
   FIndexDefs.TableName:=AValue;
   FIndexDefs.TableName:=AValue;
+  FKeyDefs.TableName:=AValue;
 end;
 end;
 
 
 function TDDTableDef.GetPrimaryKeyName: String;
 function TDDTableDef.GetPrimaryKeyName: String;
@@ -1461,6 +1479,7 @@ begin
     OnProgress(Self,Format(SSavingFieldsFrom,[TableName]));
     OnProgress(Self,Format(SSavingFieldsFrom,[TableName]));
   FFieldDefs.SaveToIni(Ini,ASection+SFieldSuffix);
   FFieldDefs.SaveToIni(Ini,ASection+SFieldSuffix);
   FIndexDefs.SaveToIni(Ini,ASection+SIndexSuffix);
   FIndexDefs.SaveToIni(Ini,ASection+SIndexSuffix);
+  FKeyDefs.SaveToIni(Ini,ASection+SKeySuffix);
 end;
 end;
 
 
 procedure TDDTableDef.LoadFromIni(Ini: TCustomInifile; ASection: String);
 procedure TDDTableDef.LoadFromIni(Ini: TCustomInifile; ASection: String);
@@ -1474,6 +1493,7 @@ begin
     OnProgress(Self,Format(SLoadingFieldsFrom,[TableName]));
     OnProgress(Self,Format(SLoadingFieldsFrom,[TableName]));
   FFieldDefs.LoadFromIni(Ini,ASection+SFieldSuffix);
   FFieldDefs.LoadFromIni(Ini,ASection+SFieldSuffix);
   FIndexDefs.LoadFromIni(Ini,ASection+SIndexSuffix);
   FIndexDefs.LoadFromIni(Ini,ASection+SIndexSuffix);
+  FKeyDefs.LoadFromIni(Ini,ASection+SKeySuffix);
 end;
 end;
 
 
 procedure TDDTableDef.PrimaryIndexToFields;
 procedure TDDTableDef.PrimaryIndexToFields;
@@ -1935,7 +1955,6 @@ end;
 function TFPDDEngine.ImportDomains(Domains: TDDDomainDefs; List : TStrings; UpdateExisting : boolean) : Integer;
 function TFPDDEngine.ImportDomains(Domains: TDDDomainDefs; List : TStrings; UpdateExisting : boolean) : Integer;
 begin
 begin
   result := 0;
   result := 0;
-  writeln ('importing no domains');
 end;
 end;
 
 
 function TFPDDEngine.GetSequenceList(List: TStrings): integer;
 function TFPDDEngine.GetSequenceList(List: TStrings): integer;
@@ -1947,7 +1966,6 @@ end;
 function TFPDDEngine.ImportSequences(Sequences: TDDSequenceDefs; List : TStrings; UpdateExisting : boolean) : Integer;
 function TFPDDEngine.ImportSequences(Sequences: TDDSequenceDefs; List : TStrings; UpdateExisting : boolean) : Integer;
 begin
 begin
   result := 0;
   result := 0;
-  writeln ('importing no sequences');
 end;
 end;
 
 
 procedure TFPDDEngine.CreateTable(Table: TDDTableDef);
 procedure TFPDDEngine.CreateTable(Table: TDDTableDef);
@@ -2015,11 +2033,33 @@ begin
   NoIndent;
   NoIndent;
 end;
 end;
 
 
-procedure TFPDDSQLEngine.FixUpStatement(var Res: String);
+procedure TFPDDSQLEngine.FixUpStatement(var Res: String; ForceTerminator : Boolean = False);
+
+Var
+  L : Integer;
+
 begin
 begin
   Res:=Trim(Res);
   Res:=Trim(Res);
-  if (eoAddTerminator in Options) then
-    Res:=Res+FTerminatorChar;
+  if (eoAddTerminator in Options) or ForceTerminator then
+    begin
+    L:=Length(Res);
+    If (L=0) or (Res[L]<>FTerminatorChar) then
+      Res:=Res+FTerminatorChar;
+    end;
+end;
+
+procedure TFPDDSQLEngine.FixUpStatement(SQL: TStrings; ForceTerminator: Boolean = False);
+
+Var
+  S : String;
+
+begin
+  If (SQL.Count>0) then
+    begin
+    S:=SQL[SQL.Count-1];
+    FixupStatement(S,ForceTerminator);
+    SQL[SQL.Count-1]:=S;
+    end;
 end;
 end;
 
 
 Procedure TFPDDSQLEngine.AddToStringLN(Var Res : String;S : String);
 Procedure TFPDDSQLEngine.AddToStringLN(Var Res : String;S : String);
@@ -2428,6 +2468,31 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TFPDDSQLEngine.CreateForeignKeySQL(ForeignKey: TDDForeignKeyDef
+  ): String;
+
+begin
+  Result:=Format('ALTER TABLE %s ADD CONSTRAINT %s',[TableDef.TableName,ForeignKey.KeyName]);
+  Result:=Result+Format(' FOREIGN KEY (%s)',[ForeignKey.KeyFields]);
+  Result:=Result+Format(' REFERENCES %s(%s)',[ForeignKey.ReferencesTable,ForeignKey.ReferencedFields])
+end;
+
+function TFPDDSQLEngine.CreateForeignKeysSQL(ForeignKeys: TDDForeignKeyDefs
+  ): String;
+
+Var
+  SQL : TStrings;
+
+begin
+  SQL:=TStringList.Create;
+  try
+    CreateForeignKeysSQLStrings(ForeignKeys,SQL);
+    Result:=SQL.Text;
+  finally
+    SQL.Free;
+  end;
+end;
+
 function TFPDDSQLEngine.CreateSequenceSQL(Sequence: TDDSequenceDef): String;
 function TFPDDSQLEngine.CreateSequenceSQL(Sequence: TDDSequenceDef): String;
 begin
 begin
   Result:='CREATE SEQUENCE '+Sequence.SequenceName;
   Result:='CREATE SEQUENCE '+Sequence.SequenceName;
@@ -2529,7 +2594,8 @@ Var
   KF : TFPDDFieldlist;
   KF : TFPDDFieldlist;
   ID : TDDIndexDef;
   ID : TDDIndexDef;
   FD : TDDFieldDef;
   FD : TDDFieldDef;
-  
+  S : String;
+
 begin
 begin
   CheckTableDef;
   CheckTableDef;
   L:=TStringList.Create;
   L:=TStringList.Create;
@@ -2547,7 +2613,16 @@ begin
             KF.Add(FD);
             KF.Add(FD);
           end;
           end;
       CreateCreateSQLStrings(KF,SQL);
       CreateCreateSQLStrings(KF,SQL);
+      FixupStatement(SQL,True);
       L.Text:=CreateIndexesSQL(TableDef.Indexes);
       L.Text:=CreateIndexesSQL(TableDef.Indexes);
+      If (L.Count>0) then
+        begin
+        SQL.AddStrings(L);
+        FixupStatement(SQL,True);
+        end;
+      L.Clear;
+      If Not (eoSkipForeignKeys in Options) then
+        L.Text:=CreateForeignKeysSQL(TableDef.ForeignKeys);
       SQL.AddStrings(L);
       SQL.AddStrings(L);
     finally
     finally
       KF.Free;
       KF.Free;
@@ -2605,6 +2680,17 @@ begin
       SQL.Add(CreateIndexSQL(Indexes[i])+TerminatorChar);
       SQL.Add(CreateIndexSQL(Indexes[i])+TerminatorChar);
 end;
 end;
 
 
+procedure TFPDDSQLEngine.CreateForeignKeysSQLStrings(
+  ForeignKeys: TDDForeignKeyDefs; SQL: TStrings);
+
+Var
+  I : integer;
+
+begin
+  For I:=0 to ForeignKeys.Count-1 do
+    SQL.Add(CreateForeignKeySQL(ForeignKeys[i])+TerminatorChar);
+end;
+
 procedure TFPDDSQLEngine.CreateSequencesSQLStrings(Sequences: TFPDDSequenceList;
 procedure TFPDDSQLEngine.CreateSequencesSQLStrings(Sequences: TFPDDSequenceList;
   SQL: TStrings);
   SQL: TStrings);
 
 

+ 2 - 0
packages/fcl-db/src/datadict/fpddsqldb.pp

@@ -57,6 +57,7 @@ Const
   KeyUserName     = 'User';
   KeyUserName     = 'User';
   KeyPassword     = 'Password';
   KeyPassword     = 'Password';
   KeyEncode       = 'Trivial';
   KeyEncode       = 'Trivial';
+  KeyCharset      = 'Charset';
 
 
 implementation
 implementation
 
 
@@ -105,6 +106,7 @@ begin
     FConn.Password:=XorDecode(KeyEncode,L.Values[KeyPassword]);
     FConn.Password:=XorDecode(KeyEncode,L.Values[KeyPassword]);
     FConn.LoginPrompt:=False;
     FConn.LoginPrompt:=False;
     FConn.Connected:=True;
     FConn.Connected:=True;
+    FConn.CharSet:=L.Values[KeyCharset];
     FConnected:=True;
     FConnected:=True;
     FConnectString:=AConnectString;
     FConnectString:=AConnectString;
     Result:=True;
     Result:=True;

+ 8 - 1
packages/fcl-db/src/sqldb/sqldb.pp

@@ -1214,7 +1214,14 @@ var tel, fieldc : integer;
     ReadFromFile: Boolean;
     ReadFromFile: Boolean;
 begin
 begin
   ReadFromFile:=IsReadFromPacket;
   ReadFromFile:=IsReadFromPacket;
-  Prepare;
+  if ReadFromFile then
+    begin
+    FCursor:=TSQLCursor.Create;
+    FCursor.FStatementType:=stSelect;
+    FUpdateable:=True;
+    end
+  else
+    Prepare;
   if FCursor.FStatementType in [stSelect,stExecProcedure] then
   if FCursor.FStatementType in [stSelect,stExecProcedure] then
     begin
     begin
     if not ReadFromFile then
     if not ReadFromFile then

+ 40 - 9
packages/fcl-db/src/sqlite/customsqliteds.pas

@@ -45,6 +45,8 @@ const
   DefaultStringSize = 255;
   DefaultStringSize = 255;
 
 
 type
 type
+  TCustomSqliteDataset = class;
+
   PDataRecord = ^DataRecord;
   PDataRecord = ^DataRecord;
   PPDataRecord = ^PDataRecord;
   PPDataRecord = ^PDataRecord;
   DataRecord = record
   DataRecord = record
@@ -57,12 +59,14 @@ type
   TDSStream = class(TStream)
   TDSStream = class(TStream)
   private
   private
     FActiveItem: PDataRecord;
     FActiveItem: PDataRecord;
+    FDataset: TCustomSqliteDataset;
     FFieldRow: PChar;
     FFieldRow: PChar;
-    FFieldIndex: Integer;
+    FField: TField;
+    FFieldOffset: Integer;
     FRowSize: Integer;
     FRowSize: Integer;
     FPosition: LongInt;
     FPosition: LongInt;
   public
   public
-    constructor Create(const ActiveItem: PDataRecord; FieldIndex: Integer);
+    constructor Create(Dataset: TCustomSqliteDataset; Field: TField);
     function Write(const Buffer; Count: LongInt): LongInt; override;
     function Write(const Buffer; Count: LongInt): LongInt; override;
     function Read(var Buffer; Count: LongInt): LongInt; override;
     function Read(var Buffer; Count: LongInt): LongInt; override;
     function Seek(Offset: LongInt; Origin: Word): LongInt; override;
     function Seek(Offset: LongInt; Origin: Word): LongInt; override;
@@ -202,6 +206,7 @@ type
     function Lookup(const KeyFields: String; const KeyValues: Variant; const ResultFields: String): Variant; override;
     function Lookup(const KeyFields: String; const KeyValues: Variant; const ResultFields: String): Variant; override;
     // Additional procedures
     // Additional procedures
     function ApplyUpdates: Boolean;
     function ApplyUpdates: Boolean;
+    procedure ClearUpdates(RecordStates: TRecordStateSet = [rsAdded, rsDeleted, rsUpdated]);
     function CreateTable: Boolean;
     function CreateTable: Boolean;
     function CreateTable(const ATableName: String): Boolean;
     function CreateTable(const ATableName: String): Boolean;
     procedure ExecCallback(const ASql: String; UserData: Pointer = nil);
     procedure ExecCallback(const ASql: String; UserData: Pointer = nil);
@@ -209,6 +214,7 @@ type
     procedure ExecSQL(const ASql: String);
     procedure ExecSQL(const ASql: String);
     procedure ExecSQLList;
     procedure ExecSQLList;
     procedure ExecuteDirect(const ASql: String); virtual; abstract;
     procedure ExecuteDirect(const ASql: String); virtual; abstract;
+    function GetSQLValue(Values: PPChar; FieldIndex: Integer): String;
     procedure QueryUpdates(RecordStates: TRecordStateSet; Callback: TQueryUpdatesCallback; UserData: Pointer = nil);
     procedure QueryUpdates(RecordStates: TRecordStateSet; Callback: TQueryUpdatesCallback; UserData: Pointer = nil);
     function QuickQuery(const ASql: String):String;overload;
     function QuickQuery(const ASql: String):String;overload;
     function QuickQuery(const ASql: String; const AStrList: TStrings): String; overload;
     function QuickQuery(const ASql: String; const AStrList: TStrings): String; overload;
@@ -323,13 +329,18 @@ end;
 
 
 // TDSStream
 // TDSStream
 
 
-constructor TDSStream.Create(const ActiveItem: PDataRecord; FieldIndex: Integer);
+constructor TDSStream.Create(Dataset: TCustomSqliteDataset; Field: TField);
 begin
 begin
   inherited Create;
   inherited Create;
   //FPosition := 0;
   //FPosition := 0;
-  FActiveItem := ActiveItem;
-  FFieldIndex := FieldIndex;
-  FFieldRow := ActiveItem^.Row[FieldIndex];
+  FDataset := Dataset;
+  FField := Field;
+  if Field.FieldNo >= 0 then
+    FFieldOffset := Field.FieldNo - 1
+  else
+    FFieldOffset := Dataset.FieldDefs.Count + Dataset.FCalcFieldList.IndexOf(Field);
+  FActiveItem := PPDataRecord(Dataset.ActiveBuffer)^;
+  FFieldRow := FActiveItem^.Row[FFieldOffset];
   if FFieldRow <> nil then
   if FFieldRow <> nil then
     FRowSize := StrLen(FFieldRow);
     FRowSize := StrLen(FFieldRow);
   //else
   //else
@@ -360,7 +371,7 @@ begin
   if FRowSize > 0 then
   if FRowSize > 0 then
     Move(FFieldRow^, NewRow^, FRowSize);
     Move(FFieldRow^, NewRow^, FRowSize);
   Move(Buffer, (NewRow + FRowSize)^, Count);
   Move(Buffer, (NewRow + FRowSize)^, Count);
-  FActiveItem^.Row[FFieldIndex] := NewRow;
+  FActiveItem^.Row[FFieldOffset] := NewRow;
   StrDispose(FFieldRow);
   StrDispose(FFieldRow);
   {$ifdef DEBUG_SQLITEDS}
   {$ifdef DEBUG_SQLITEDS}
   WriteLn('##TDSStream.Write##');
   WriteLn('##TDSStream.Write##');
@@ -373,6 +384,8 @@ begin
   FFieldRow := NewRow;
   FFieldRow := NewRow;
   FRowSize := StrLen(NewRow);
   FRowSize := StrLen(NewRow);
   Inc(FPosition, Count);
   Inc(FPosition, Count);
+  if not (FDataset.State in [dsCalcFields, dsFilter, dsNewValue]) then
+    FDataset.DataEvent(deFieldChange, PtrInt(FField));
 end; 
 end; 
  
  
 function TDSStream.Read(var Buffer; Count: Longint): LongInt;
 function TDSStream.Read(var Buffer; Count: Longint): LongInt;
@@ -454,7 +467,7 @@ begin
     StrDispose(FCacheItem^.Row[Field.FieldNo - 1]);
     StrDispose(FCacheItem^.Row[Field.FieldNo - 1]);
     FCacheItem^.Row[Field.FieldNo - 1] := nil;
     FCacheItem^.Row[Field.FieldNo - 1] := nil;
   end;
   end;
-  Result:= TDSStream.Create(PPDataRecord(ActiveBuffer)^, Field.FieldNo - 1);
+  Result := TDSStream.Create(Self, Field);
 end;
 end;
 
 
 procedure TCustomSqliteDataset.DoBeforeClose;
 procedure TCustomSqliteDataset.DoBeforeClose;
@@ -1446,6 +1459,14 @@ begin
     DatabaseError(ReturnString, Self);
     DatabaseError(ReturnString, Self);
 end;
 end;
 
 
+function TCustomSqliteDataset.GetSQLValue(Values: PPChar; FieldIndex: Integer
+  ): String;
+begin
+  if (State = dsInactive) or (FieldIndex < 0) or (FieldIndex >= FieldDefs.Count) then
+    DatabaseError('Error retrieving SQL value: dataset inactive or field out of range', Self);
+  Result := FGetSqlStr[FieldIndex](Values[FieldIndex]);
+end;
+
 procedure TCustomSqliteDataset.ExecSQL;
 procedure TCustomSqliteDataset.ExecSQL;
 begin
 begin
   ExecSQL(FSQL);
   ExecSQL(FSQL);
@@ -1590,7 +1611,17 @@ begin
   {$ifdef DEBUG_SQLITEDS}
   {$ifdef DEBUG_SQLITEDS}
   WriteLn('  Result: ', Result);
   WriteLn('  Result: ', Result);
   {$endif}   
   {$endif}   
-end;    
+end;
+
+procedure TCustomSqliteDataset.ClearUpdates(RecordStates: TRecordStateSet);
+begin
+  if rsUpdated in RecordStates then
+    FUpdatedItems.Clear;
+  if rsDeleted in RecordStates then
+    FDeletedItems.Clear;
+  if rsAdded in RecordStates then
+    FAddedItems.Clear;
+end;
 
 
 function TCustomSqliteDataset.CreateTable: Boolean;
 function TCustomSqliteDataset.CreateTable: Boolean;
 begin
 begin

+ 2 - 2
packages/fcl-image/src/fpcolhash.pas

@@ -71,8 +71,8 @@ type
   private
   private
     Root : PColHashMainNode;
     Root : PColHashMainNode;
     AllIntegers : boolean;
     AllIntegers : boolean;
-    procedure FreeAllData;
     FCount : longword;
     FCount : longword;
+    procedure FreeAllData;
     function AllocateMainNode : PColHashMainNode;
     function AllocateMainNode : PColHashMainNode;
     function AllocateSubNode : PColHashSubNode;
     function AllocateSubNode : PColHashSubNode;
     procedure DeallocateLinkedList(node : PColHashSubNode);
     procedure DeallocateLinkedList(node : PColHashSubNode);
@@ -409,4 +409,4 @@ begin
   end;
   end;
 end;
 end;
 
 
-end.
+end.

+ 1 - 1
packages/fcl-image/src/fpreadbmp.pp

@@ -32,7 +32,6 @@ uses FPImage, classes, sysutils, BMPcomn;
 type
 type
   TFPReaderBMP = class (TFPCustomImageReader)
   TFPReaderBMP = class (TFPCustomImageReader)
     Private
     Private
-      Procedure FreeBufs;       // Free (and nil) buffers.
       DeltaX, DeltaY : integer; // Used for the never-used delta option in RLE
       DeltaX, DeltaY : integer; // Used for the never-used delta option in RLE
       TopDown : boolean;        // If set, bitmap is stored top down instead of bottom up
       TopDown : boolean;        // If set, bitmap is stored top down instead of bottom up
       continue : boolean;       // needed for onprogress event
       continue : boolean;       // needed for onprogress event
@@ -40,6 +39,7 @@ type
       percentinterval : longword;
       percentinterval : longword;
       percentacc : longword;
       percentacc : longword;
       Rect : TRect;
       Rect : TRect;
+      Procedure FreeBufs;       // Free (and nil) buffers.
     protected
     protected
       ReadSize : Integer;       // Size (in bytes) of 1 scanline.
       ReadSize : Integer;       // Size (in bytes) of 1 scanline.
       BFI : TBitMapInfoHeader;  // The header as read from the stream.
       BFI : TBitMapInfoHeader;  // The header as read from the stream.

+ 46 - 1
packages/fcl-json/Makefile

@@ -1,5 +1,5 @@
 #
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2008/10/22]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2009/03/15]
 #
 #
 default: all
 default: all
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian 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 sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded
 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 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 sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded
@@ -1179,6 +1179,7 @@ endif
 ifeq ($(OS_TARGET),go32v2)
 ifeq ($(OS_TARGET),go32v2)
 STATICLIBPREFIX=
 STATICLIBPREFIX=
 SHORTSUFFIX=dos
 SHORTSUFFIX=dos
+IMPORTLIBPREFIX=
 endif
 endif
 ifeq ($(OS_TARGET),watcom)
 ifeq ($(OS_TARGET),watcom)
 STATICLIBPREFIX=
 STATICLIBPREFIX=
@@ -1186,6 +1187,7 @@ OEXT=.obj
 ASMEXT=.asm
 ASMEXT=.asm
 SHAREDLIBEXT=.dll
 SHAREDLIBEXT=.dll
 SHORTSUFFIX=wat
 SHORTSUFFIX=wat
+IMPORTLIBPREFIX=
 endif
 endif
 ifeq ($(OS_TARGET),linux)
 ifeq ($(OS_TARGET),linux)
 BATCHEXT=.sh
 BATCHEXT=.sh
@@ -1222,6 +1224,7 @@ STATICLIBPREFIX=
 SHAREDLIBEXT=.dll
 SHAREDLIBEXT=.dll
 SHORTSUFFIX=os2
 SHORTSUFFIX=os2
 ECHO=echo
 ECHO=echo
+IMPORTLIBPREFIX=
 endif
 endif
 ifeq ($(OS_TARGET),emx)
 ifeq ($(OS_TARGET),emx)
 BATCHEXT=.cmd
 BATCHEXT=.cmd
@@ -1230,6 +1233,7 @@ STATICLIBPREFIX=
 SHAREDLIBEXT=.dll
 SHAREDLIBEXT=.dll
 SHORTSUFFIX=emx
 SHORTSUFFIX=emx
 ECHO=echo
 ECHO=echo
+IMPORTLIBPREFIX=
 endif
 endif
 ifeq ($(OS_TARGET),amiga)
 ifeq ($(OS_TARGET),amiga)
 EXEEXT=
 EXEEXT=
@@ -1269,17 +1273,20 @@ ifeq ($(OS_TARGET),netware)
 EXEEXT=.nlm
 EXEEXT=.nlm
 STATICLIBPREFIX=
 STATICLIBPREFIX=
 SHORTSUFFIX=nw
 SHORTSUFFIX=nw
+IMPORTLIBPREFIX=imp
 endif
 endif
 ifeq ($(OS_TARGET),netwlibc)
 ifeq ($(OS_TARGET),netwlibc)
 EXEEXT=.nlm
 EXEEXT=.nlm
 STATICLIBPREFIX=
 STATICLIBPREFIX=
 SHORTSUFFIX=nwl
 SHORTSUFFIX=nwl
+IMPORTLIBPREFIX=imp
 endif
 endif
 ifeq ($(OS_TARGET),macos)
 ifeq ($(OS_TARGET),macos)
 BATCHEXT=
 BATCHEXT=
 EXEEXT=
 EXEEXT=
 DEBUGSYMEXT=.xcoff
 DEBUGSYMEXT=.xcoff
 SHORTSUFFIX=mac
 SHORTSUFFIX=mac
+IMPORTLIBPREFIX=imp
 endif
 endif
 ifeq ($(OS_TARGET),darwin)
 ifeq ($(OS_TARGET),darwin)
 BATCHEXT=.sh
 BATCHEXT=.sh
@@ -1306,14 +1313,17 @@ STATICLIBEXT=.a1
 SHAREDLIBEXT=.so1
 SHAREDLIBEXT=.so1
 STATICLIBPREFIX=
 STATICLIBPREFIX=
 SHORTSUFFIX=v1
 SHORTSUFFIX=v1
+IMPORTLIBPREFIX=
 endif
 endif
 ifeq ($(OS_TARGET),go32v2)
 ifeq ($(OS_TARGET),go32v2)
 STATICLIBPREFIX=
 STATICLIBPREFIX=
 SHORTSUFFIX=dos
 SHORTSUFFIX=dos
+IMPORTLIBPREFIX=
 endif
 endif
 ifeq ($(OS_TARGET),watcom)
 ifeq ($(OS_TARGET),watcom)
 STATICLIBPREFIX=
 STATICLIBPREFIX=
 SHORTSUFFIX=wat
 SHORTSUFFIX=wat
+IMPORTLIBPREFIX=
 endif
 endif
 ifeq ($(OS_TARGET),linux)
 ifeq ($(OS_TARGET),linux)
 BATCHEXT=.sh
 BATCHEXT=.sh
@@ -1360,6 +1370,7 @@ STATICLIBEXT=.ao2
 SHAREDLIBEXT=.dll
 SHAREDLIBEXT=.dll
 SHORTSUFFIX=os2
 SHORTSUFFIX=os2
 ECHO=echo
 ECHO=echo
+IMPORTLIBPREFIX=
 endif
 endif
 ifeq ($(OS_TARGET),amiga)
 ifeq ($(OS_TARGET),amiga)
 EXEEXT=
 EXEEXT=
@@ -1420,6 +1431,7 @@ STATICLIBEXT=.a
 SHAREDLIBEXT=.nlm
 SHAREDLIBEXT=.nlm
 EXEEXT=.nlm
 EXEEXT=.nlm
 SHORTSUFFIX=nw
 SHORTSUFFIX=nw
+IMPORTLIBPREFIX=imp
 endif
 endif
 ifeq ($(OS_TARGET),netwlibc)
 ifeq ($(OS_TARGET),netwlibc)
 STATICLIBPREFIX=
 STATICLIBPREFIX=
@@ -1431,6 +1443,7 @@ STATICLIBEXT=.a
 SHAREDLIBEXT=.nlm
 SHAREDLIBEXT=.nlm
 EXEEXT=.nlm
 EXEEXT=.nlm
 SHORTSUFFIX=nwl
 SHORTSUFFIX=nwl
+IMPORTLIBPREFIX=imp
 endif
 endif
 ifeq ($(OS_TARGET),macos)
 ifeq ($(OS_TARGET),macos)
 BATCHEXT=
 BATCHEXT=
@@ -1442,6 +1455,7 @@ STATICLIBEXT=.a
 EXEEXT=
 EXEEXT=
 DEBUGSYMEXT=.xcoff
 DEBUGSYMEXT=.xcoff
 SHORTSUFFIX=mac
 SHORTSUFFIX=mac
+IMPORTLIBPREFIX=imp
 endif
 endif
 endif
 endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
@@ -1770,6 +1784,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_UNIVINT=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
@@ -1846,6 +1861,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_UNIVINT=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
@@ -1882,6 +1898,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_UNIVINT=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
@@ -1904,6 +1921,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_UNIVINT=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
@@ -1932,6 +1950,7 @@ REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_UNIVINT=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
@@ -2054,6 +2073,32 @@ ifdef UNITDIR_WINUNITS-JEDI
 override COMPILER_UNITDIR+=$(UNITDIR_WINUNITS-JEDI)
 override COMPILER_UNITDIR+=$(UNITDIR_WINUNITS-JEDI)
 endif
 endif
 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
+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
+endif
 ifndef NOCPUDEF
 ifndef NOCPUDEF
 override FPCOPTDEF=$(ARCH)
 override FPCOPTDEF=$(ARCH)
 endif
 endif

+ 2 - 2
packages/fcl-net/src/mkxmlrpc.pp

@@ -47,11 +47,11 @@ type
   end;
   end;
 
 
   TRPCList = class
   TRPCList = class
+    ServerClasses: TList;
+    UsedModules: TStringList;
     constructor Create;
     constructor Create;
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddServerClass(const AClassName: String);
     procedure AddServerClass(const AClassName: String);
-    ServerClasses: TList;
-    UsedModules: TStringList;
   end;
   end;
 
 
 var
 var

+ 2 - 2
packages/fcl-net/src/ssockets.pp

@@ -109,10 +109,10 @@ type
   TInetServer = Class(TSocketServer)
   TInetServer = Class(TSocketServer)
   Protected
   Protected
     FAddr : TINetSockAddr;
     FAddr : TINetSockAddr;
-    Function  SockToStream (ASocket : Longint) : TSocketStream;Override;
-    Function Accept : Longint;override;
     FPort : Word;
     FPort : Word;
     FHost: string;
     FHost: string;
+    Function  SockToStream (ASocket : Longint) : TSocketStream;Override;
+    Function Accept : Longint;override;
   Public
   Public
     Procedure Bind; Override;
     Procedure Bind; Override;
     Constructor Create(APort: Word);
     Constructor Create(APort: Word);

+ 18 - 18
packages/fcl-web/Makefile

@@ -1,5 +1,5 @@
 #
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2009/03/29]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2009/06/23]
 #
 #
 default: all
 default: all
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian 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 sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded
 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 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 sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded
@@ -271,25 +271,25 @@ ifeq ($(FULL_TARGET),i386-go32v2)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
@@ -298,7 +298,7 @@ ifeq ($(FULL_TARGET),i386-netware)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
@@ -316,7 +316,7 @@ ifeq ($(FULL_TARGET),i386-netwlibc)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
@@ -328,10 +328,10 @@ ifeq ($(FULL_TARGET),m68k-linux)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
@@ -340,7 +340,7 @@ ifeq ($(FULL_TARGET),m68k-atari)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
@@ -352,7 +352,7 @@ ifeq ($(FULL_TARGET),powerpc-linux)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
@@ -373,10 +373,10 @@ ifeq ($(FULL_TARGET),sparc-linux)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
@@ -385,13 +385,13 @@ ifeq ($(FULL_TARGET),x86_64-linux)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
@@ -406,7 +406,7 @@ ifeq ($(FULL_TARGET),arm-darwin)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
+override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache  fastcgi custfcgi fpfcgi
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache
 override TARGET_UNITS+=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb webutil fpdatasetform cgiapp ezcgi fpapache

+ 14 - 2
packages/fcl-web/Makefile.fpc

@@ -8,10 +8,22 @@ version=2.2.2
 
 
 [target]
 [target]
 units=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb \
 units=httpdefs fphttp custweb custcgi fpcgi fptemplate fphtml websession fpweb \
-      webutil fpdatasetform cgiapp ezcgi fpapache 
-units_linux=fastcgi custfcgi fpfcgi
+      webutil fpdatasetform cgiapp ezcgi fpapache
 rsts=fpcgi fphtml fpweb websession cgiapp
 rsts=fpcgi fphtml fpweb websession cgiapp
 
 
+# these units are listed separately because they don't work for
+# darwin (which does support the rest of fcl-web)
+units_beos=fastcgi custfcgi fpfcgi
+units_haiku=fastcgi custfcgi fpfcgi
+units_freebsd=fastcgi custfcgi fpfcgi
+units_solaris=fastcgi custfcgi fpfcgi
+units_netbsd=fastcgi custfcgi fpfcgi
+units_openbsd=fastcgi custfcgi fpfcgi
+units_linux=fastcgi custfcgi fpfcgi
+units_win32=fastcgi custfcgi fpfcgi
+units_win64=fastcgi custfcgi fpfcgi
+units_wince=fastcgi custfcgi fpfcgi
+
 [require]
 [require]
 packages=fcl-base fcl-xml fcl-db fcl-process httpd22
 packages=fcl-base fcl-xml fcl-db fcl-process httpd22
 packages_darwin=univint
 packages_darwin=univint

+ 13 - 4
packages/fcl-web/src/custfcgi.pp

@@ -85,7 +85,16 @@ uses
 {$ifdef CGIDEBUG}
 {$ifdef CGIDEBUG}
   dbugintf,
   dbugintf,
 {$endif}
 {$endif}
-  BaseUnix, Sockets;
+  Sockets;
+
+{$undef nosignal}
+
+{$if defined(FreeBSD) or defined(Linux)}
+  {$define nosignal}
+{$ifend}
+
+Const 
+   NoSignalAttr =  {$ifdef nosignal} MSG_NOSIGNAL{$else}0{$endif};
 
 
 { TFCGIHTTPRequest }
 { TFCGIHTTPRequest }
 
 
@@ -243,7 +252,7 @@ var BytesToWrite : word;
     BytesWritten  : Integer;
     BytesWritten  : Integer;
 begin
 begin
   BytesToWrite := BEtoN(ARecord^.contentLength) + ARecord^.paddingLength+sizeof(FCGI_Header);
   BytesToWrite := BEtoN(ARecord^.contentLength) + ARecord^.paddingLength+sizeof(FCGI_Header);
-  BytesWritten := sockets.fpsend(TFCGIRequest(Request).Handle, ARecord, BytesToWrite, MSG_NOSIGNAL);
+  BytesWritten := sockets.fpsend(TFCGIRequest(Request).Handle, ARecord, BytesToWrite, NoSignalAttr);
   Assert(BytesWritten=BytesToWrite);
   Assert(BytesWritten=BytesToWrite);
 end;
 end;
 
 
@@ -336,7 +345,7 @@ begin
     if not TFCGIRequest(ARequest).KeepConnectionAfterRequest then
     if not TFCGIRequest(ARequest).KeepConnectionAfterRequest then
       begin
       begin
       fpshutdown(FHandle,SHUT_RDWR);
       fpshutdown(FHandle,SHUT_RDWR);
-      FpClose(FHandle);
+      CloseSocket(FHandle);
       FHandle := -1;
       FHandle := -1;
       end;
       end;
     Request := Nil;
     Request := Nil;
@@ -359,7 +368,7 @@ var Header : FCGI_Header;
    result := False;
    result := False;
     if ByteAmount>0 then
     if ByteAmount>0 then
       begin
       begin
-      BytesRead := sockets.fpRecv(FHandle, ReadBuf, ByteAmount, MSG_NOSIGNAL);
+      BytesRead := sockets.fpRecv(FHandle, ReadBuf, ByteAmount, NoSignalAttr);
       if BytesRead<>ByteAmount then
       if BytesRead<>ByteAmount then
         begin
         begin
 //        SendDebug('FCGIRecord incomplete');
 //        SendDebug('FCGIRecord incomplete');

+ 2 - 2
packages/fcl-web/src/fpweb.pp

@@ -38,10 +38,10 @@ Type
     Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); override;
     Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); override;
     Procedure DoGetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); virtual;
     Procedure DoGetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); virtual;
     Procedure GetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean);
     Procedure GetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean);
-    Procedure Assign(Source : TPersistent); override;
   Public
   Public
     Constructor create(ACollection : TCollection); override;
     Constructor create(ACollection : TCollection); override;
     Destructor destroy; override;
     Destructor destroy; override;
+    Procedure Assign(Source : TPersistent); override;
   published
   published
     Property Content : String Read GetStringContent Write SetContent;
     Property Content : String Read GetStringContent Write SetContent;
     Property Contents : TStrings Read GetContents Write SetContents;
     Property Contents : TStrings Read GetContents Write SetContents;
@@ -332,7 +332,7 @@ end;
 
 
 procedure TCustomFPWebModule.SetActions(const AValue: TFPWebActions);
 procedure TCustomFPWebModule.SetActions(const AValue: TFPWebActions);
 begin
 begin
-  if (FActions<>AValue) then;
+  if (FActions<>AValue) then
     FActions.Assign(AValue);
     FActions.Assign(AValue);
 end;
 end;
 
 

+ 7 - 1
packages/fcl-web/src/httpdefs.pp

@@ -1113,6 +1113,9 @@ var
   R : String;
   R : String;
 
 
 begin
 begin
+{$ifdef CGIDEBUG}
+  SendMethodEnter('TRequest.InitRequestVars');
+{$endif}
   R:=Method;
   R:=Method;
   if (R='') then
   if (R='') then
     Raise Exception.Create(SErrNoRequestMethod);
     Raise Exception.Create(SErrNoRequestMethod);
@@ -1126,6 +1129,9 @@ begin
     InitGetVars
     InitGetVars
   else
   else
     Raise Exception.CreateFmt(SErrInvalidRequestMethod,[R]);
     Raise Exception.CreateFmt(SErrInvalidRequestMethod,[R]);
+{$ifdef CGIDEBUG}
+  SendMethodExit('TRequest.InitRequestVars');
+{$endif}
 end;
 end;
 
 
 Type
 Type
@@ -1158,7 +1164,7 @@ begin
     CT:=ContentType;
     CT:=ContentType;
     if Pos('MULTIPART/FORM-DATA',Uppercase(CT))<>0 then
     if Pos('MULTIPART/FORM-DATA',Uppercase(CT))<>0 then
       ProcessMultiPart(M,CT, ContentFields)
       ProcessMultiPart(M,CT, ContentFields)
-    else if CompareText('APPLICATION/X-WWW-FORM-URLENCODED',CT)=0 then
+    else if Pos('APPLICATION/X-WWW-FORM-URLENCODED',Uppercase(CT))<>0 then
       ProcessUrlEncoded(M, ContentFields)
       ProcessUrlEncoded(M, ContentFields)
     else
     else
       begin
       begin

+ 352 - 69
packages/fcl-xml/src/dom.pp

@@ -251,6 +251,7 @@ type
     property Prefix: DOMString read GetPrefix write SetPrefix;
     property Prefix: DOMString read GetPrefix write SetPrefix;
     // DOM level 3
     // DOM level 3
     property TextContent: DOMString read GetTextContent write SetTextContent;
     property TextContent: DOMString read GetTextContent write SetTextContent;
+    function LookupNamespaceURI(const APrefix: DOMString): DOMString;
     // Extensions to DOM interface:
     // Extensions to DOM interface:
     function CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode; overload; virtual;
     function CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode; overload; virtual;
     function FindNode(const ANodeName: DOMString): TDOMNode; virtual;
     function FindNode(const ANodeName: DOMString): TDOMNode; virtual;
@@ -290,6 +291,8 @@ type
 //   NodeList
 //   NodeList
 // -------------------------------------------------------
 // -------------------------------------------------------
 
 
+  TFilterResult = (frFalse, frNorecurseFalse, frTrue, frNorecurseTrue);
+
   TDOMNodeList = class(TObject)
   TDOMNodeList = class(TObject)
   protected
   protected
     FNode: TDOMNode;
     FNode: TDOMNode;
@@ -297,6 +300,8 @@ type
     FList: TFPList;
     FList: TFPList;
     function GetCount: LongWord;
     function GetCount: LongWord;
     function GetItem(index: LongWord): TDOMNode;
     function GetItem(index: LongWord): TDOMNode;
+    function NodeFilter(aNode: TDOMNode): TFilterResult; virtual;
+    // now deprecated in favor of NodeFilter
     procedure BuildList; virtual;
     procedure BuildList; virtual;
   public
   public
     constructor Create(ANode: TDOMNode);
     constructor Create(ANode: TDOMNode);
@@ -311,9 +316,12 @@ type
   TDOMElementList = class(TDOMNodeList)
   TDOMElementList = class(TDOMNodeList)
   protected
   protected
     filter: DOMString;
     filter: DOMString;
-    FNamespaceFilter: DOMString;
+    FNSIndexFilter: Integer;
+    localNameFilter: DOMString;
+    FMatchNS: Boolean;
+    FMatchAnyNS: Boolean;
     UseFilter: Boolean;
     UseFilter: Boolean;
-    procedure BuildList; override;
+    function NodeFilter(aNode: TDOMNode): TFilterResult; override;
   public
   public
     constructor Create(ANode: TDOMNode; const AFilter: DOMString); overload;
     constructor Create(ANode: TDOMNode; const AFilter: DOMString); overload;
     constructor Create(ANode: TDOMNode; const nsURI, localName: DOMString); overload;
     constructor Create(ANode: TDOMNode; const nsURI, localName: DOMString); overload;
@@ -344,11 +352,10 @@ type
     function SetNamedItem(arg: TDOMNode): TDOMNode;
     function SetNamedItem(arg: TDOMNode): TDOMNode;
     function RemoveNamedItem(const name: DOMString): TDOMNode;
     function RemoveNamedItem(const name: DOMString): TDOMNode;
     // Introduced in DOM Level 2:
     // Introduced in DOM Level 2:
-    function getNamedItemNS(const namespaceURI, localName: DOMString): TDOMNode;
-    function setNamedItemNS(arg: TDOMNode): TDOMNode;
-    function removeNamedItemNS(const namespaceURI,localName: DOMString): TDOMNode;
+    function getNamedItemNS(const namespaceURI, localName: DOMString): TDOMNode; virtual;
+    function setNamedItemNS(arg: TDOMNode): TDOMNode; virtual;
+    function removeNamedItemNS(const namespaceURI,localName: DOMString): TDOMNode; virtual;
 
 
-    // FIX: made readonly. Reason: Anyone was allowed to insert any node without any checking.
     property Item[index: LongWord]: TDOMNode read GetItem; default;
     property Item[index: LongWord]: TDOMNode read GetItem; default;
     property Length: LongWord read GetLength;
     property Length: LongWord read GetLength;
   end;
   end;
@@ -424,6 +431,7 @@ type
     FNodeLists: THashTable;
     FNodeLists: THashTable;
     FMaxPoolSize: Integer;
     FMaxPoolSize: Integer;
     FPools: PNodePool;
     FPools: PNodePool;
+    FDocumentURI: DOMString;
     function GetDocumentElement: TDOMElement;
     function GetDocumentElement: TDOMElement;
     function GetDocType: TDOMDocumentType;
     function GetDocType: TDOMDocumentType;
     function GetNodeType: Integer; override;
     function GetNodeType: Integer; override;
@@ -466,6 +474,8 @@ type
     function CreateAttributeNS(const nsURI, QualifiedName: DOMString): TDOMAttr;
     function CreateAttributeNS(const nsURI, QualifiedName: DOMString): TDOMAttr;
     function GetElementsByTagNameNS(const nsURI, alocalName: DOMString): TDOMNodeList;
     function GetElementsByTagNameNS(const nsURI, alocalName: DOMString): TDOMNodeList;
     function GetElementById(const ElementID: DOMString): TDOMElement;
     function GetElementById(const ElementID: DOMString): TDOMElement;
+    // DOM level 3:
+    property documentURI: DOMString read FDocumentURI write FDocumentURI;
     // Extensions to DOM interface:
     // Extensions to DOM interface:
     constructor Create;
     constructor Create;
     destructor Destroy; override;
     destructor Destroy; override;
@@ -535,6 +545,7 @@ type
     function  GetNodeValue: DOMString; override;
     function  GetNodeValue: DOMString; override;
     function GetNodeType: Integer; override;
     function GetNodeType: Integer; override;
     function GetSpecified: Boolean;
     function GetSpecified: Boolean;
+    function GetIsID: Boolean;
     procedure SetNodeValue(const AValue: DOMString); override;
     procedure SetNodeValue(const AValue: DOMString); override;
   public
   public
     destructor Destroy; override;
     destructor Destroy; override;
@@ -543,6 +554,7 @@ type
     property Specified: Boolean read GetSpecified;
     property Specified: Boolean read GetSpecified;
     property Value: DOMString read GetNodeValue write SetNodeValue;
     property Value: DOMString read GetNodeValue write SetNodeValue;
     property OwnerElement: TDOMElement read FOwnerElement;
     property OwnerElement: TDOMElement read FOwnerElement;
+    property IsID: Boolean read GetIsID;
     // extensions
     // extensions
     // TODO: this is to be replaced with DOM 3 TypeInfo
     // TODO: this is to be replaced with DOM 3 TypeInfo
     property DataType: TAttrDataType read FDataType write FDataType;
     property DataType: TAttrDataType read FDataType write FDataType;
@@ -788,6 +800,19 @@ const
 
 
 implementation
 implementation
 
 
+{ a namespace-enabled NamedNodeMap }
+type
+  TAttributeMap = class(TDOMNamedNodeMap)
+  private
+    function FindNS(nsIndex: Integer; const aLocalName: DOMString;
+      out Index: LongWord): Boolean;
+    function InternalRemoveNS(const nsURI, aLocalName: DOMString): TDOMNode;
+  public
+    function getNamedItemNS(const namespaceURI, localName: DOMString): TDOMNode; override;
+    function setNamedItemNS(arg: TDOMNode): TDOMNode; override;
+    function removeNamedItemNS(const namespaceURI,localName: DOMString): TDOMNode; override;
+  end;
+
 // -------------------------------------------------------
 // -------------------------------------------------------
 //   DOM Exception
 //   DOM Exception
 // -------------------------------------------------------
 // -------------------------------------------------------
@@ -1072,9 +1097,9 @@ begin
     child.SetReadOnly(Value);
     child.SetReadOnly(Value);
     child := child.NextSibling;
     child := child.NextSibling;
   end;
   end;
-  attrs := Attributes;
-  if Assigned(attrs) then
+  if HasAttributes then
   begin
   begin
+    attrs := Attributes;
     for I := 0 to attrs.Length-1 do
     for I := 0 to attrs.Length-1 do
       attrs[I].SetReadOnly(Value);
       attrs[I].SetReadOnly(Value);
   end;
   end;
@@ -1106,6 +1131,64 @@ begin
   Result := CompareDOMStrings(DOMPChar(name), DOMPChar(SelfName), Length(name), Length(SelfName));
   Result := CompareDOMStrings(DOMPChar(name), DOMPChar(SelfName), Length(name), Length(SelfName));
 end;
 end;
 
 
+// This will return nil for Entity, Notation, DocType and DocFragment's
+function GetAncestorElement(n: TDOMNode): TDOMElement;
+var
+  parent: TDOMNode;
+begin
+  parent := n.ParentNode;
+  while Assigned(parent) and (parent.NodeType <> ELEMENT_NODE) do
+    parent := parent.ParentNode;
+  Result := TDOMElement(parent);
+end;
+
+// TODO: specs prescribe to return default namespace if APrefix=null,
+// but we aren't able to distinguish null from an empty string.
+// This breaks level3/nodelookupnamespaceuri08 which passes an empty string.
+function TDOMNode.LookupNamespaceURI(const APrefix: DOMString): DOMString;
+var
+  Attr: TDOMAttr;
+  Map: TDOMNamedNodeMap;
+  I: Integer;
+begin
+  Result := '';
+  if Self = nil then
+    Exit;
+  case NodeType of
+    ELEMENT_NODE:
+    begin
+      if (nfLevel2 in FFlags) and (TDOMElement(Self).Prefix = APrefix) then
+      begin
+        result := Self.NamespaceURI;
+        Exit;
+      end;
+      if HasAttributes then
+      begin
+        Map := Attributes;
+        for I := 0 to Map.Length-1 do
+        begin
+          Attr := TDOMAttr(Map[I]);
+          // should ignore level 1 atts here
+          if ((Attr.Prefix = 'xmlns') and (Attr.localName = APrefix)) or
+             ((Attr.localName = 'xmlns') and (APrefix = '')) then
+          begin
+            result := Attr.NodeValue;
+            Exit;
+          end;
+        end
+      end;
+      result := GetAncestorElement(Self).LookupNamespaceURI(APrefix);
+    end;
+    DOCUMENT_NODE:
+      result := TDOMDocument(Self).documentElement.LookupNamespaceURI(APrefix);
+
+    ATTRIBUTE_NODE:
+      result := TDOMAttr(Self).OwnerElement.LookupNamespaceURI(APrefix);
+
+  else
+    Result := GetAncestorElement(Self).LookupNamespaceURI(APrefix);
+  end;
+end;
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 
 
@@ -1400,18 +1483,43 @@ begin
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
+function TDOMNodeList.NodeFilter(aNode: TDOMNode): TFilterResult;
+begin
+// accept all nodes but don't allow recursion
+  Result := frNorecurseTrue;
+end;
+
 procedure TDOMNodeList.BuildList;
 procedure TDOMNodeList.BuildList;
 var
 var
-  Child: TDOMNode;
+  current, next: TDOMNode;
+  res: TFilterResult;
 begin
 begin
   FList.Clear;
   FList.Clear;
   FRevision := FNode.GetRevision; // refresh
   FRevision := FNode.GetRevision; // refresh
 
 
-  Child := FNode.FirstChild;
-  while Assigned(Child) do
+  current := FNode.FirstChild;
+
+  while Assigned(current) do
   begin
   begin
-    FList.Add(Child);
-    Child := Child.NextSibling;
+    res := NodeFilter(current);
+    if res in [frTrue, frNorecurseTrue] then
+      FList.Add(current);
+
+    next := nil;
+    if res in [frTrue, frFalse] then
+      next := current.FirstChild;
+
+    if next = nil then
+    begin
+      while current <> FNode do
+      begin
+        next := current.NextSibling;
+        if Assigned(next) then
+          Break;
+        current := current.ParentNode;
+      end;
+    end;
+    current := next;
   end;
   end;
 end;
 end;
 
 
@@ -1446,38 +1554,34 @@ end;
 constructor TDOMElementList.Create(ANode: TDOMNode; const nsURI, localName: DOMString);
 constructor TDOMElementList.Create(ANode: TDOMNode; const nsURI, localName: DOMString);
 begin
 begin
   inherited Create(ANode);
   inherited Create(ANode);
-  filter := localName;
-  FNamespaceFilter := nsURI;
-  UseFilter := (filter <> '*') and (FNamespaceFilter <> '*');
+  localNameFilter := localName;
+  FMatchNS := True;
+  FMatchAnyNS := (nsURI = '*');
+  if not FMatchAnyNS then
+    FNSIndexFilter := ANode.FOwnerDocument.IndexOfNS(nsURI);
+  UseFilter := (localName <> '*');
 end;
 end;
 
 
-// TODO: namespace support here
-procedure TDOMElementList.BuildList;
+function TDOMElementList.NodeFilter(aNode: TDOMNode): TFilterResult;
 var
 var
-  Child: TDOMNode;
+  I, L: Integer;
 begin
 begin
-  FList.Clear;
-  FRevision := FNode.GetRevision; // refresh
-
-  Child := FNode.FirstChild;
-  while Assigned(Child) and (Child <> FNode) do
+  Result := frFalse;
+  if aNode.NodeType = ELEMENT_NODE then with TDOMElement(aNode) do
   begin
   begin
-    if (Child.NodeType = ELEMENT_NODE) and (not UseFilter or (TDOMElement(Child).TagName = filter)) then
-          FList.Add(Child);
-    // recursive track node hierarchy  
-    if Assigned(Child.FirstChild) then
-      Child := Child.FirstChild
-    else
-      if Assigned(Child.NextSibling) then
-        Child := Child.NextSibling
-      else
+    if FMatchNS then
+    begin
+      if (FMatchAnyNS or (FNSI.NSIndex = Word(FNSIndexFilter))) then
       begin
       begin
-         Child := Child.ParentNode;
-         while Assigned(Child) and (Child <> FNode) and not Assigned(Child.NextSibling) do
-           Child := Child.ParentNode;
-         if Assigned(Child) and (Child <> FNode) then
-            Child := Child.NextSibling;
+        I := FNSI.PrefixLen;
+        L := system.Length(FNSI.QName^.Key);
+        if (not UseFilter or ((L-I = system.Length(localNameFilter)) and
+          CompareMem(@FNSI.QName^.Key[I+1], DOMPChar(localNameFilter), system.Length(localNameFilter)*sizeof(WideChar)))) then
+          Result := frTrue;
       end;
       end;
+    end
+    else if (not UseFilter or (TagName = Filter)) then
+      Result := frTrue;
   end;
   end;
 end;
 end;
 
 
@@ -1551,11 +1655,11 @@ begin
     Result := nil;
     Result := nil;
 end;
 end;
 
 
+// Note: this *may* raise NOT_SUPPORTED_ERR if the document is e.g. HTML.
+// This isn't checked now.
 function TDOMNamedNodeMap.GetNamedItemNS(const namespaceURI, localName: DOMString): TDOMNode;
 function TDOMNamedNodeMap.GetNamedItemNS(const namespaceURI, localName: DOMString): TDOMNode;
 begin
 begin
-  // TODO: implement TDOMNamedNodeMap.GetNamedItemNS
-  raise EDOMNotSupported.Create('TDOMNamedNodeMap.GetNamedItemNS');
-    Result := nil;
+  Result := nil;
 end;
 end;
 
 
 function TDOMNamedNodeMap.ValidateInsert(arg: TDOMNode): Integer;
 function TDOMNamedNodeMap.ValidateInsert(arg: TDOMNode): Integer;
@@ -1608,15 +1712,13 @@ begin
 end;
 end;
 
 
 function TDOMNamedNodeMap.SetNamedItemNS(arg: TDOMNode): TDOMNode;
 function TDOMNamedNodeMap.SetNamedItemNS(arg: TDOMNode): TDOMNode;
-var
-  res: Integer;
 begin
 begin
-  // TODO: implement TDOMNamedNodeMap.SetNamedItemNS
-  res := ValidateInsert(arg);
-  if res <> 0 then
-    raise EDOMError.Create(res, 'NamedNodeMap.SetNamedItemNS');
-
-    Result := nil;
+{ Since the map contains only namespaceless nodes (all having empty
+  localName and namespaceURI properties), a namespaced arg won't match
+  any of them. Therefore, add it using nodeName as key.
+  Note: a namespaceless arg is another story, as it will match *any* node
+  in the map. This can be considered as a flaw in specs. }
+  Result := SetNamedItem(arg);
 end;
 end;
 
 
 function TDOMNamedNodeMap.Delete(index: LongWord): TDOMNode;
 function TDOMNamedNodeMap.Delete(index: LongWord): TDOMNode;
@@ -1670,12 +1772,112 @@ end;
 
 
 function TDOMNamedNodeMap.RemoveNamedItemNS(const namespaceURI, localName: DOMString): TDOMNode;
 function TDOMNamedNodeMap.RemoveNamedItemNS(const namespaceURI, localName: DOMString): TDOMNode;
 begin
 begin
-  if nfReadOnly in FOwner.FFlags then
-    raise EDOMError.Create(NO_MODIFICATION_ALLOWED_ERR, 'NamedNodeMap.RemoveNamedItemNS');
-  // TODO: Implement TDOMNamedNodeMap.RemoveNamedItemNS
+// see comments to SetNamedItemNS. Related tests are written clever enough
+// in the sense they don't expect NO_MODIFICATION_ERR in first place.
+  raise EDOMNotFound.Create('NamedNodeMap.RemoveNamedItemNS');
+  Result := nil;
+end;
+
+{ TAttributeMap }
+
+// Since list is kept sorted by nodeName, we must use linear search here.
+// This routine is not called while parsing, so parsing speed is not lowered.
+function TAttributeMap.FindNS(nsIndex: Integer; const aLocalName: DOMString;
+  out Index: LongWord): Boolean;
+var
+  I: Integer;
+  P: DOMPChar;
+begin
+  for I := 0 to FList.Count-1 do
+  begin
+    with TDOMAttr(FList.List^[I]) do
+    begin
+      if nsIndex = FNSI.NSIndex then
+      begin
+        P := DOMPChar(FNSI.QName^.Key);
+        if FNSI.PrefixLen > 1 then
+          Inc(P, FNSI.PrefixLen);
+        if CompareDOMStrings(DOMPChar(aLocalName), P, System.Length(aLocalName), System.Length(FNSI.QName^.Key) - FNSI.PrefixLen) = 0 then
+        begin
+          Index := I;
+          Result := True;
+          Exit;
+        end;
+      end;
+    end;
+  end;
+  Result := False;
+end;
+
+function TAttributeMap.InternalRemoveNS(const nsURI, aLocalName: DOMString): TDOMNode;
+var
+  i: Cardinal;
+  nsIndex: Integer;
+begin
   Result := nil;
   Result := nil;
+  nsIndex := FOwner.FOwnerDocument.IndexOfNS(nsURI);
+  if (nsIndex >= 0) and FindNS(nsIndex, aLocalName, i) then
+  begin
+    Result := Delete(I);
+    RestoreDefault(TDOMAttr(Result).FNSI.QName^.Key);
+  end;
 end;
 end;
 
 
+function TAttributeMap.getNamedItemNS(const namespaceURI, localName: DOMString): TDOMNode;
+var
+  nsIndex: Integer;
+  i: LongWord;
+begin
+  nsIndex := FOwner.FOwnerDocument.IndexOfNS(namespaceURI);
+  if (nsIndex >= 0) and FindNS(nsIndex, localName, i) then
+    Result := TDOMNode(FList.List^[i])
+  else
+    Result := nil;
+end;
+
+function TAttributeMap.setNamedItemNS(arg: TDOMNode): TDOMNode;
+var
+  i: LongWord;
+  res: Integer;
+  Exists: Boolean;
+begin
+  res := ValidateInsert(arg);
+  if res <> 0 then
+    raise EDOMError.Create(res, 'NamedNodeMap.SetNamedItemNS');
+
+  Result := nil;
+  with TDOMAttr(arg) do
+  begin
+    // calling LocalName is no good... but it is done once
+    if FindNS(FNSI.NSIndex, localName, i) then
+    begin
+      Result := TDOMNode(FList.List^[i]);
+      FList.Delete(i);
+    end;
+    // Do a non-namespace search in order to keep the list sorted on nodeName
+    Exists := Find(FNSI.QName^.Key, i);
+    if Exists and (Result = nil) then  // case when arg has no namespace
+    begin
+      Result := TDOMNode(FList.List^[i]);
+      FList.List^[i] := arg;
+    end
+    else
+      FList.Insert(i, arg);
+  end;
+  if Assigned(Result) then
+    TDOMAttr(Result).FOwnerElement := nil;
+  TDOMAttr(arg).FOwnerElement := TDOMElement(FOwner);
+end;
+
+function TAttributeMap.removeNamedItemNS(const namespaceURI,
+  localName: DOMString): TDOMNode;
+begin
+  if nfReadOnly in FOwner.FFlags then
+    raise EDOMError.Create(NO_MODIFICATION_ALLOWED_ERR, 'NamedNodeMap.RemoveNamedItemNS');
+  Result := InternalRemoveNS(namespaceURI, localName);
+  if Result = nil then
+     raise EDOMNotFound.Create('NamedNodeMap.RemoveNamedItemNS');
+end;
 
 
 // -------------------------------------------------------
 // -------------------------------------------------------
 //   CharacterData
 //   CharacterData
@@ -1805,7 +2007,9 @@ var
   s: string;
   s: string;
 begin
 begin
   s := feature;   // force Ansi, features do not contain non-ASCII chars
   s := feature;   // force Ansi, features do not contain non-ASCII chars
-  Result := SameText(s, 'XML') and ((version = '') or (version = '1.0'));
+  Result := (SameText(s, 'XML') and ((version = '') or (version = '1.0') or (version = '2.0'))) or
+            (SameText(s, 'Core') and ((version = '') or (version = '2.0')));
+
 end;
 end;
 
 
 function TDOMImplementation.CreateDocumentType(const QualifiedName, PublicID,
 function TDOMImplementation.CreateDocumentType(const QualifiedName, PublicID,
@@ -2353,7 +2557,10 @@ end;
 function TDOMAttr.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
 function TDOMAttr.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
 begin
 begin
   // Cloned attribute is always specified and carries its children
   // Cloned attribute is always specified and carries its children
-  Result := ACloneOwner.CreateAttribute(NodeName);
+  if nfLevel2 in FFlags then
+    Result := ACloneOwner.CreateAttributeNS(namespaceURI, NodeName)
+  else
+    Result := ACloneOwner.CreateAttribute(NodeName);
   TDOMAttr(Result).FDataType := FDataType;
   TDOMAttr(Result).FDataType := FDataType;
   CloneChildren(Result, ACloneOwner);
   CloneChildren(Result, ACloneOwner);
 end;
 end;
@@ -2376,6 +2583,11 @@ begin
   Result := nfSpecified in FFlags;
   Result := nfSpecified in FFlags;
 end;
 end;
 
 
+function TDOMAttr.GetIsID: Boolean;
+begin
+  Result := FDataType = dtID;
+end;
+
 // -------------------------------------------------------
 // -------------------------------------------------------
 //   Element
 //   Element
 // -------------------------------------------------------
 // -------------------------------------------------------
@@ -2390,7 +2602,6 @@ begin
   Include(FFlags, nfDestroying);
   Include(FFlags, nfDestroying);
   if Assigned(FOwnerDocument.FIDList) then
   if Assigned(FOwnerDocument.FIDList) then
     FOwnerDocument.RemoveID(Self);
     FOwnerDocument.RemoveID(Self);
-  // FIX: Attribute nodes are now freed by TDOMNamedNodeMap.Destroy
   FreeAndNil(FAttributes);
   FreeAndNil(FAttributes);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
@@ -2398,12 +2609,45 @@ end;
 function TDOMElement.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
 function TDOMElement.CloneNode(deep: Boolean; ACloneOwner: TDOMDocument): TDOMNode;
 var
 var
   i: Integer;
   i: Integer;
+  Attr, AttrClone: TDOMAttr;
 begin
 begin
-  Result := ACloneOwner.CreateElement(NodeName);
-  if Assigned(FAttributes) then
+  if ACloneOwner <> FOwnerDocument then
   begin
   begin
-    for i := 0 to FAttributes.Length - 1 do
-      TDOMElement(Result).SetAttributeNode(TDOMAttr(FAttributes[i].CloneNode(True, ACloneOwner)));
+    // Importing has to go the hard way...
+    if nfLevel2 in FFlags then
+      Result := ACloneOwner.CreateElementNS(NamespaceURI, NodeName)
+    else
+      Result := ACloneOwner.CreateElement(NodeName);
+    if Assigned(FAttributes) then
+    begin
+      for i := 0 to FAttributes.Length - 1 do
+      begin
+        Attr := TDOMAttr(FAttributes[i]);
+        // destroy defaulted attributes (if any), it is safe because caller had not seen them yet
+        if Attr.Specified then
+          TDOMElement(Result).SetAttributeNode(TDOMAttr(Attr.CloneNode(True, ACloneOwner))).Free;
+      end;
+    end;
+  end
+  else   // Cloning may cheat a little bit.
+  begin
+    Result := FOwnerDocument.Alloc(TDOMElement);
+    TDOMElement(Result).Create(FOwnerDocument);
+    TDOMElement(Result).FNSI := FNSI;
+    if nfLevel2 in FFlags then
+      Include(Result.FFlags, nfLevel2);
+    if Assigned(FAttributes) then
+    begin
+      // clone all attributes, but preserve nfSpecified flag
+      for i := 0 to FAttributes.Length - 1 do
+      begin
+        Attr := TDOMAttr(FAttributes[i]);
+        AttrClone := TDOMAttr(Attr.CloneNode(True, ACloneOwner));
+        if not Attr.Specified then
+          Exclude(AttrClone.FFlags, nfSpecified);
+        TDOMElement(Result).SetAttributeNode(AttrClone);
+      end;
+    end;
   end;
   end;
   if deep then
   if deep then
     CloneChildren(Result, ACloneOwner);
     CloneChildren(Result, ACloneOwner);
@@ -2432,8 +2676,33 @@ end;
 procedure TDOMElement.RestoreDefaultAttr(AttrDef: TDOMAttr);
 procedure TDOMElement.RestoreDefaultAttr(AttrDef: TDOMAttr);
 var
 var
   Attr: TDOMAttr;
   Attr: TDOMAttr;
+  ColonPos: Integer;
+  AttrName, nsuri: DOMString;
 begin
 begin
   Attr := TDOMAttr(AttrDef.CloneNode(True));
   Attr := TDOMAttr(AttrDef.CloneNode(True));
+  AttrName := Attr.Name;
+  ColonPos := Pos(WideChar(':'), AttrName);
+  if Pos(DOMString('xmlns'), AttrName) = 1 then
+  begin
+    if (Length(AttrName) = 5) or (ColonPos = 6) then
+      Attr.SetNSI(stduri_xmlns, ColonPos);
+  end
+  else if ColonPos > 0 then
+  begin
+    if (ColonPos = 4) and (Pos(DOMString('xml'), AttrName) = 1) then
+      Attr.SetNSI(stduri_xml, 4)
+    else
+    begin
+      nsuri := LookupNamespaceURI(Copy(AttrName, 1, ColonPos-1));
+      // TODO: what if prefix isn't defined?
+      Attr.SetNSI(nsuri, ColonPos);
+    end
+  end;
+  // TODO: this is cheat, should look at config['namespaces'] instead.
+  // revisit when it is implemented.
+  if nfLevel2 in FFlags then
+    Include(Attr.FFlags, nfLevel2);
+  // There should be no matching attribute at this point, so non-namespace method is ok
   SetAttributeNode(Attr);
   SetAttributeNode(Attr);
 end;
 end;
 
 
@@ -2450,7 +2719,7 @@ end;
 function TDOMElement.GetAttributes: TDOMNamedNodeMap;
 function TDOMElement.GetAttributes: TDOMNamedNodeMap;
 begin
 begin
   if FAttributes=nil then
   if FAttributes=nil then
-    FAttributes := TDOMNamedNodeMap.Create(Self, ATTRIBUTE_NODE);
+    FAttributes := TAttributeMap.Create(Self, ATTRIBUTE_NODE);
   Result := FAttributes;
   Result := FAttributes;
 end;
 end;
 
 
@@ -2509,13 +2778,14 @@ procedure TDOMElement.RemoveAttributeNS(const nsURI,
   aLocalName: DOMString);
   aLocalName: DOMString);
 begin
 begin
   Changing;
   Changing;
-  // TODO: Implement TDOMElement.RemoveAttributeNS
-  raise EDOMNotSupported.Create('TDOMElement.RemoveAttributeNS');
+  if Assigned(FAttributes) then
+    TAttributeMap(FAttributes).InternalRemoveNS(nsURI, aLocalName).Free;
 end;
 end;
 
 
 procedure TDOMElement.SetAttributeNS(const nsURI, qualifiedName,
 procedure TDOMElement.SetAttributeNS(const nsURI, qualifiedName,
   value: DOMString);
   value: DOMString);
 var
 var
+  I: Cardinal;
   Attr: TDOMAttr;
   Attr: TDOMAttr;
   idx, prefIdx: Integer;
   idx, prefIdx: Integer;
 begin
 begin
@@ -2524,14 +2794,27 @@ begin
   prefIdx := CheckQName(qualifiedName, idx, FOwnerDocument.FXml11);
   prefIdx := CheckQName(qualifiedName, idx, FOwnerDocument.FXml11);
   if prefIdx < 0 then
   if prefIdx < 0 then
     raise EDOMError.Create(-prefIdx, 'Element.SetAttributeNS');
     raise EDOMError.Create(-prefIdx, 'Element.SetAttributeNS');
-    
-  Attr := Attributes.GetNamedItemNS(nsURI, qualifiedName) as TDOMAttr;
-  if attr = nil then
+
+  if TAttributeMap(Attributes).FindNS(idx, Copy(qualifiedName, prefIdx+1, MaxInt), I) then
   begin
   begin
-    attr := FOwnerDocument.CreateAttributeNS(nsURI, qualifiedName);
-    // TODO 5: keep sorted!
-    FAttributes.FList.Add(attr);
-  end;
+    Attr := TDOMAttr(FAttributes[I]);
+    // need to reinsert because the nodeName may change
+    FAttributes.FList.Delete(I);
+  end
+  else
+  begin
+    TDOMNode(Attr) := FOwnerDocument.Alloc(TDOMAttr);
+    Attr.Create(FOwnerDocument);
+    Attr.FOwnerElement := Self;
+    Attr.FNSI.NSIndex := Word(idx);
+    Include(Attr.FFlags, nfLevel2);
+  end;
+  // keep list sorted by DOM Level 1 name
+  FAttributes.Find(qualifiedName, I);
+  FAttributes.FList.Insert(I, Attr);
+  // TODO: rehash properly, same issue as with Node.SetPrefix()
+  Attr.FNSI.QName := FOwnerDocument.FNames.FindOrAdd(DOMPChar(qualifiedName), Length(qualifiedName));
+  Attr.FNSI.PrefixLen := Word(prefIdx);
   attr.NodeValue := value;
   attr.NodeValue := value;
 end;
 end;
 
 

+ 6 - 1
packages/fcl-xml/src/htmwrite.pp

@@ -180,8 +180,13 @@ begin
     wc := Cardinal(Src^);  Inc(Src);
     wc := Cardinal(Src^);  Inc(Src);
     case wc of
     case wc of
       $0A: pb := StrECopy(pb, PChar(FLineBreak));
       $0A: pb := StrECopy(pb, PChar(FLineBreak));
+      $0D: begin
+        pb := StrECopy(pb, PChar(FLineBreak));
+        if (Src < SrcEnd) and (Src^ = #$0A) then
+          Inc(Src);
+      end;
 
 
-      0..$09, $0B..$7F:  begin
+      0..$09, $0B, $0C, $0E..$7F:  begin
         pb^ := char(wc); Inc(pb);
         pb^ := char(wc); Inc(pb);
       end;
       end;
 
 

+ 15 - 5
packages/fcl-xml/src/sax_html.pp

@@ -505,14 +505,20 @@ var
   Element: TDOMElement;
   Element: TDOMElement;
   i: Integer;
   i: Integer;
 begin
 begin
-  // WriteLn('Start: ', LocalName, '. Node buffer before: ', FNodeBuffer.Count, ' elements');
+  {$ifdef SAX_HTML_DEBUG}
+  WriteLn('Start: ', LocalName, '. Node buffer before: ', FNodeBuffer.Count, ' elements');
+  {$endif}
   Element := FDocument.CreateElement(LocalName);
   Element := FDocument.CreateElement(LocalName);
   if Assigned(Attr) then
   if Assigned(Attr) then
   begin
   begin
-    // WriteLn('Attribute: ', Attr.GetLength);
+    {$ifdef SAX_HTML_DEBUG}
+     WriteLn('Attribute: ', Attr.GetLength);
+    {$endif}
     for i := 0 to Attr.GetLength - 1 do
     for i := 0 to Attr.GetLength - 1 do
     begin
     begin
-      // WriteLn('#', i, ': LocalName = ', Attr.GetLocalName(i), ', Value = ', Attr.GetValue(i));
+      {$ifdef SAX_HTML_DEBUG}
+       WriteLn('#', i, ': LocalName = ', Attr.GetLocalName(i), ', Value = ', Attr.GetValue(i));
+      {$endif}
       Element[Attr.GetLocalName(i)] := Attr.GetValue(i);
       Element[Attr.GetLocalName(i)] := Attr.GetValue(i);
     end;
     end;
   end;
   end;
@@ -531,7 +537,9 @@ begin
     if not Assigned(FDocument.DocumentElement) then
     if not Assigned(FDocument.DocumentElement) then
       FDocument.AppendChild(Element);
       FDocument.AppendChild(Element);
   FNodeBuffer.Add(NodeInfo);
   FNodeBuffer.Add(NodeInfo);
-  // WriteLn('Start: ', LocalName, '. Node buffer after: ', FNodeBuffer.Count, ' elements');
+  {$ifdef SAX_HTML_DEBUG}
+    WriteLn('Start: ', LocalName, '. Node buffer after: ', FNodeBuffer.Count, ' elements');
+  {$endif}
 end;
 end;
 
 
 procedure THTMLToDOMConverter.ReaderEndElement(Sender: TObject;
 procedure THTMLToDOMConverter.ReaderEndElement(Sender: TObject;
@@ -543,7 +551,9 @@ var
   TagInfo: PHTMLElementProps;
   TagInfo: PHTMLElementProps;
 
 
 begin
 begin
-  // WriteLn('End: ', LocalName, '. Node buffer: ', FNodeBuffer.Count, ' elements');
+  {$ifdef SAX_HTML_DEBUG}
+    WriteLn('End: ', LocalName, '. Node buffer: ', FNodeBuffer.Count, ' elements');
+  {$endif}
   // Find the matching start tag
   // Find the matching start tag
   i := FNodeBuffer.Count - 1;
   i := FNodeBuffer.Count - 1;
   while i >= 0 do
   while i >= 0 do

+ 180 - 115
packages/fcl-xml/src/xmlread.pp

@@ -66,6 +66,8 @@ type
     FCDSectionsAsText: Boolean;
     FCDSectionsAsText: Boolean;
     FResolveExternals: Boolean;
     FResolveExternals: Boolean;
     FNamespaces: Boolean;
     FNamespaces: Boolean;
+    FDisallowDoctype: Boolean;
+    FMaxChars: Cardinal;
   public
   public
     property Validate: Boolean read FValidate write FValidate;
     property Validate: Boolean read FValidate write FValidate;
     property PreserveWhitespace: Boolean read FPreserveWhitespace write FPreserveWhitespace;
     property PreserveWhitespace: Boolean read FPreserveWhitespace write FPreserveWhitespace;
@@ -74,6 +76,8 @@ type
     property CDSectionsAsText: Boolean read FCDSectionsAsText write FCDSectionsAsText;
     property CDSectionsAsText: Boolean read FCDSectionsAsText write FCDSectionsAsText;
     property ResolveExternals: Boolean read FResolveExternals write FResolveExternals;
     property ResolveExternals: Boolean read FResolveExternals write FResolveExternals;
     property Namespaces: Boolean read FNamespaces write FNamespaces;
     property Namespaces: Boolean read FNamespaces write FNamespaces;
+    property DisallowDoctype: Boolean read FDisallowDoctype write FDisallowDoctype;
+    property MaxChars: Cardinal read FMaxChars write FMaxChars;
   end;
   end;
 
 
   // NOTE: DOM 3 LS ACTION_TYPE enumeration starts at 1
   // NOTE: DOM 3 LS ACTION_TYPE enumeration starts at 1
@@ -162,7 +166,9 @@ type
     FOnStack: Boolean;
     FOnStack: Boolean;
     FBetweenDecls: Boolean;
     FBetweenDecls: Boolean;
     FReplacementText: DOMString;
     FReplacementText: DOMString;
+    FURI: DOMString;
     FStartLocation: TLocation;
     FStartLocation: TLocation;
+    FCharCount: Cardinal;
   end;
   end;
 
 
   PWideCharBuf = ^TWideCharBuf;
   PWideCharBuf = ^TWideCharBuf;
@@ -186,6 +192,7 @@ type
     FXML11Rules: Boolean;
     FXML11Rules: Boolean;
     FSystemID: WideString;
     FSystemID: WideString;
     FPublicID: WideString;
     FPublicID: WideString;
+    FCharCount: Cardinal;
     function GetSystemID: WideString;
     function GetSystemID: WideString;
     function GetPublicID: WideString;
     function GetPublicID: WideString;
   protected
   protected
@@ -233,6 +240,7 @@ type
     FStream: TStream;
     FStream: TStream;
     FCapacity: Integer;
     FCapacity: Integer;
     FOwnStream: Boolean;
     FOwnStream: Boolean;
+    FEof: Boolean;
   public
   public
     constructor Create(AStream: TStream; AOwnStream: Boolean);
     constructor Create(AStream: TStream; AOwnStream: Boolean);
     destructor Destroy; override;
     destructor Destroy; override;
@@ -279,6 +287,7 @@ type
   end;
   end;
 
 
   TElementValidator = object
   TElementValidator = object
+    FElement: TDOMElement;
     FElementDef: TDOMElementDef;
     FElementDef: TDOMElementDef;
     FCurCP: TContentParticle;
     FCurCP: TContentParticle;
     FFailed: Boolean;
     FFailed: Boolean;
@@ -289,6 +298,7 @@ type
   TXMLReadState = (rsProlog, rsDTD, rsRoot, rsEpilog);
   TXMLReadState = (rsProlog, rsDTD, rsRoot, rsEpilog);
 
 
   TElementContentType = (
   TElementContentType = (
+    ctUndeclared,
     ctAny,
     ctAny,
     ctEmpty,
     ctEmpty,
     ctMixed,
     ctMixed,
@@ -353,12 +363,12 @@ type
     FCDSectionsAsText: Boolean;
     FCDSectionsAsText: Boolean;
     FResolveExternals: Boolean;
     FResolveExternals: Boolean;
     FNamespaces: Boolean;
     FNamespaces: Boolean;
+    FDisallowDoctype: Boolean;
+    FMaxChars: Cardinal;
 
 
     procedure RaiseExpectedQmark;
     procedure RaiseExpectedQmark;
-    procedure GetChar;
     procedure Initialize(ASource: TXMLCharSource);
     procedure Initialize(ASource: TXMLCharSource);
     function DoParseAttValue(Delim: WideChar): Boolean;
     function DoParseAttValue(Delim: WideChar): Boolean;
-    procedure DoParseFragment;
     function ContextPush(AEntity: TDOMEntityEx): Boolean;
     function ContextPush(AEntity: TDOMEntityEx): Boolean;
     function ContextPop: Boolean;
     function ContextPop: Boolean;
     procedure XML11_BuildTables;
     procedure XML11_BuildTables;
@@ -373,6 +383,7 @@ type
     procedure CallErrorHandler(E: EXMLReadError);
     procedure CallErrorHandler(E: EXMLReadError);
     function  FindOrCreateElDef: TDOMElementDef;
     function  FindOrCreateElDef: TDOMElementDef;
     function  SkipUntilSeq(const Delim: TSetOfChar; const More: array of WideChar): Boolean;
     function  SkipUntilSeq(const Delim: TSetOfChar; const More: array of WideChar): Boolean;
+    procedure CheckMaxChars;
   protected
   protected
     FCursor: TDOMNode_WithChildren;
     FCursor: TDOMNode_WithChildren;
     FNesting: Integer;
     FNesting: Integer;
@@ -406,6 +417,8 @@ type
     procedure ParseDoctypeDecl;                                         // [28]
     procedure ParseDoctypeDecl;                                         // [28]
     procedure ParseMarkupDecl;                                          // [29]
     procedure ParseMarkupDecl;                                          // [29]
     procedure ParseElement;                                             // [39]
     procedure ParseElement;                                             // [39]
+    procedure ParseEndTag;                                              // [42]
+    procedure DoEndElement(ErrOffset: Integer);
     procedure ParseAttribute(Elem: TDOMElement; ElDef: TDOMElementDef);
     procedure ParseAttribute(Elem: TDOMElement; ElDef: TDOMElementDef);
     procedure ParseContent;                                             // [43]
     procedure ParseContent;                                             // [43]
     function  ResolvePredefined: Boolean;
     function  ResolvePredefined: Boolean;
@@ -422,13 +435,13 @@ type
     procedure ExpectChoiceOrSeq(CP: TContentParticle);
     procedure ExpectChoiceOrSeq(CP: TContentParticle);
     procedure ParseElementDecl;
     procedure ParseElementDecl;
     procedure ParseNotationDecl;
     procedure ParseNotationDecl;
-    function ResolveEntity(const SystemID, PublicID: WideString; out Source: TXMLCharSource): Boolean;
+    function ResolveEntity(const AbsSysID, PublicID: WideString; out Source: TXMLCharSource): Boolean;
     procedure ProcessDefaultAttributes(Element: TDOMElement; Map: TDOMNamedNodeMap);
     procedure ProcessDefaultAttributes(Element: TDOMElement; Map: TDOMNamedNodeMap);
     procedure ProcessNamespaceAtts(Element: TDOMElement);
     procedure ProcessNamespaceAtts(Element: TDOMElement);
     procedure AddBinding(Attr: TDOMAttr; Prefix: PHashItem; var Chain: TBinding);
     procedure AddBinding(Attr: TDOMAttr; Prefix: PHashItem; var Chain: TBinding);
     procedure EndNamespaceScope(var Chain: TBinding);
     procedure EndNamespaceScope(var Chain: TBinding);
 
 
-    procedure PushVC(aElDef: TDOMElementDef);
+    procedure PushVC(aElement: TDOMElement; aElDef: TDOMElementDef);
     procedure PopVC;
     procedure PopVC;
     procedure UpdateConstraints;
     procedure UpdateConstraints;
     procedure ValidateDTD;
     procedure ValidateDTD;
@@ -458,7 +471,6 @@ type
   public
   public
     FExternallyDeclared: Boolean;
     FExternallyDeclared: Boolean;
     ContentType: TElementContentType;
     ContentType: TElementContentType;
-    HasElementDecl: Boolean;
     IDAttr: TDOMAttrDef;
     IDAttr: TDOMAttrDef;
     NotationAttr: TDOMAttrDef;
     NotationAttr: TDOMAttrDef;
     RootCP: TContentParticle;
     RootCP: TContentParticle;
@@ -795,6 +807,7 @@ begin
   FBuf := PWideChar(AData);
   FBuf := PWideChar(AData);
   FBufEnd := FBuf + Length(AData);
   FBufEnd := FBuf + Length(AData);
   LFPos := FBuf-1;
   LFPos := FBuf-1;
+  FCharCount := Length(AData);
 end;
 end;
 
 
 procedure TXMLCharSource.Initialize;
 procedure TXMLCharSource.Initialize;
@@ -947,7 +960,12 @@ begin
     if rslt = 0 then
     if rslt = 0 then
       Break
       Break
     else if rslt < 0 then
     else if rslt < 0 then
-      DecodingError('Invalid character in input stream');
+      DecodingError('Invalid character in input stream')
+    else
+    begin
+      Inc(FCharCount, rslt);
+      FReader.CheckMaxChars;
+    end;
   until False;
   until False;
 
 
   FBufEnd^ := #0;
   FBufEnd^ := #0;
@@ -1082,7 +1100,8 @@ var
   OldBuf: PChar;
   OldBuf: PChar;
 begin
 begin
   Assert(FCharBufEnd - FCharBuf < Slack-4);
   Assert(FCharBufEnd - FCharBuf < Slack-4);
-
+  if FEof then
+    Exit;
   OldBuf := FCharBuf;
   OldBuf := FCharBuf;
   Remainder := FCharBufEnd - FCharBuf;
   Remainder := FCharBufEnd - FCharBuf;
   if Remainder < 0 then
   if Remainder < 0 then
@@ -1091,6 +1110,8 @@ begin
   if Remainder > 0 then
   if Remainder > 0 then
     Move(OldBuf^, FCharBuf^, Remainder);
     Move(OldBuf^, FCharBuf^, Remainder);
   BytesRead := FStream.Read(FAllocated[Slack-4], FCapacity);
   BytesRead := FStream.Read(FAllocated[Slack-4], FCapacity);
+  if BytesRead < FCapacity then
+    FEof := True;
   FCharBufEnd := FAllocated + (Slack-4) + BytesRead;
   FCharBufEnd := FAllocated + (Slack-4) + BytesRead;
   PWideChar(FCharBufEnd)^ := #0;
   PWideChar(FCharBufEnd)^ := #0;
 end;
 end;
@@ -1152,20 +1173,14 @@ begin
   Loc.LinePos := FSource.FBuf-FSource.LFPos;
   Loc.LinePos := FSource.FBuf-FSource.LFPos;
 end;
 end;
 
 
-function TXMLReader.ResolveEntity(const SystemID, PublicID: WideString; out Source: TXMLCharSource): Boolean;
+function TXMLReader.ResolveEntity(const AbsSysID, PublicID: WideString; out Source: TXMLCharSource): Boolean;
 var
 var
-  AbsSysID: WideString;
   Filename: string;
   Filename: string;
   Stream: TStream;
   Stream: TStream;
   fd: THandle;
   fd: THandle;
 begin
 begin
   Source := nil;
   Source := nil;
   Result := False;
   Result := False;
-  if not Assigned(FSource) then
-    AbsSysID := SystemID
-  else
-    if not ResolveRelativeURI(FSource.SystemID, SystemID, AbsSysID) then
-      Exit;
   { TODO: alternative resolvers
   { TODO: alternative resolvers
     These may be 'internal' resolvers or a handler set by application.
     These may be 'internal' resolvers or a handler set by application.
     Internal resolvers should probably produce a TStream
     Internal resolvers should probably produce a TStream
@@ -1195,11 +1210,6 @@ begin
   FSource.Initialize;
   FSource.Initialize;
 end;
 end;
 
 
-procedure TXMLReader.GetChar;
-begin
-  FSource.NextChar;
-end;
-
 procedure TXMLReader.RaiseExpectedQmark;
 procedure TXMLReader.RaiseExpectedQmark;
 begin
 begin
   FatalError('Expected single or double quote');
   FatalError('Expected single or double quote');
@@ -1260,6 +1270,23 @@ begin
   E.Free;
   E.Free;
 end;
 end;
 
 
+procedure TXMLReader.CheckMaxChars;
+var
+  src: TXMLCharSource;
+  total: Cardinal;
+begin
+  if FMaxChars = 0 then
+    Exit;
+  src := FSource;
+  total := 0;
+  repeat
+    Inc(total, src.FCharCount);
+    if total > FMaxChars then
+      FatalError('Exceeded character count limit');
+    src := src.FParent;
+  until src = nil;
+end;
+
 procedure TXMLReader.CallErrorHandler(E: EXMLReadError);
 procedure TXMLReader.CallErrorHandler(E: EXMLReadError);
 begin
 begin
   try
   try
@@ -1406,6 +1433,8 @@ begin
   FIgnoreComments := FCtrl.Options.IgnoreComments;
   FIgnoreComments := FCtrl.Options.IgnoreComments;
   FResolveExternals := FCtrl.Options.ResolveExternals;
   FResolveExternals := FCtrl.Options.ResolveExternals;
   FNamespaces := FCtrl.Options.Namespaces;
   FNamespaces := FCtrl.Options.Namespaces;
+  FDisallowDoctype := FCtrl.Options.DisallowDoctype;
+  FMaxChars := FCtrl.Options.MaxChars;
 end;
 end;
 
 
 destructor TXMLReader.Destroy;
 destructor TXMLReader.Destroy;
@@ -1442,11 +1471,12 @@ end;
 procedure TXMLReader.ProcessXML(ASource: TXMLCharSource);
 procedure TXMLReader.ProcessXML(ASource: TXMLCharSource);
 begin
 begin
   doc := TXMLDocument.Create;
   doc := TXMLDocument.Create;
+  doc.documentURI := ASource.SystemID;  // TODO: to be changed to URI or BaseURI  
   FCursor := doc;
   FCursor := doc;
   FState := rsProlog;
   FState := rsProlog;
   FNesting := 0;
   FNesting := 0;
   Initialize(ASource);
   Initialize(ASource);
-  DoParseFragment;
+  ParseContent;
 
 
   if FState < rsRoot then
   if FState < rsRoot then
     FatalError('Root element is missing');
     FatalError('Root element is missing');
@@ -1462,7 +1492,7 @@ begin
   FState := rsRoot;
   FState := rsRoot;
   Initialize(ASource);
   Initialize(ASource);
   FXML11 := doc.InheritsFrom(TXMLDocument) and (TXMLDocument(doc).XMLVersion = '1.1');
   FXML11 := doc.InheritsFrom(TXMLDocument) and (TXMLDocument(doc).XMLVersion = '1.1');
-  DoParseFragment;
+  ParseContent;
 end;
 end;
 
 
 function TXMLReader.CheckName(aFlags: TCheckNameFlags): Boolean;
 function TXMLReader.CheckName(aFlags: TCheckNameFlags): Boolean;
@@ -1526,6 +1556,7 @@ begin
     end;
     end;
 
 
     BufAppendChunk(FName, FSource.FBuf, p);
     BufAppendChunk(FName, FSource.FBuf, p);
+    Result := (FName.Length > 0);
 
 
     FSource.FBuf := p;
     FSource.FBuf := p;
     if (p^ <> #0) or not FSource.Reload then
     if (p^ <> #0) or not FSource.Reload then
@@ -1533,7 +1564,6 @@ begin
 
 
     p := FSource.FBuf;
     p := FSource.FBuf;
   until False;
   until False;
-  Result := (FName.Length > 0);
   if not (Result or (cnOptional in aFlags)) then
   if not (Result or (cnOptional in aFlags)) then
     RaiseNameNotFound;
     RaiseNameNotFound;
 end;
 end;
@@ -1615,7 +1645,7 @@ begin
       else
       else
         Break;
         Break;
       end;
       end;
-      GetChar;
+      FSource.NextChar;
     until Value > $10FFFF
     until Value > $10FFFF
     else
     else
     repeat
     repeat
@@ -1624,7 +1654,7 @@ begin
       else
       else
         Break;
         Break;
       end;
       end;
-      GetChar;
+      FSource.NextChar;
     until Value > $10FFFF;
     until Value > $10FFFF;
 
 
     case Value of
     case Value of
@@ -1693,22 +1723,13 @@ begin
   Result := wc <> #0;
   Result := wc <> #0;
 end;
 end;
 
 
-procedure TXMLReader.DoParseFragment;
-begin
-  // SAX: ContentHandler.StartDocument() - here?
-  ParseContent;
-  if FSource.FBuf^ <> #0 then
-    FatalError('End-tag is not allowed here');
-  // SAX: ContentHandler.EndDocument() - here? or somewhere in destructor?  
-end;
-
 function TXMLReader.ContextPush(AEntity: TDOMEntityEx): Boolean;
 function TXMLReader.ContextPush(AEntity: TDOMEntityEx): Boolean;
 var
 var
   Src: TXMLCharSource;
   Src: TXMLCharSource;
 begin
 begin
-  if AEntity.SystemID <> '' then
+  if (AEntity.SystemID <> '') and not AEntity.FResolved then
   begin
   begin
-    Result := ResolveEntity(AEntity.SystemID, AEntity.PublicID, Src);
+    Result := ResolveEntity(AEntity.FURI, AEntity.PublicID, Src);
     if not Result then
     if not Result then
     begin
     begin
       // TODO: a detailed message like SysErrorMessage(GetLastError) would be great here 
       // TODO: a detailed message like SysErrorMessage(GetLastError) would be great here 
@@ -1719,6 +1740,8 @@ begin
   else
   else
   begin
   begin
     Src := TXMLCharSource.Create(AEntity.FReplacementText);
     Src := TXMLCharSource.Create(AEntity.FReplacementText);
+    // needed in case of prefetched external PE
+    Src.SystemID := AEntity.FURI;
     Src.FLineNo := AEntity.FStartLocation.Line;
     Src.FLineNo := AEntity.FStartLocation.Line;
     Src.LFPos := Src.FBuf - AEntity.FStartLocation.LinePos;
     Src.LFPos := Src.FBuf - AEntity.FStartLocation.LinePos;
   end;
   end;
@@ -1743,6 +1766,7 @@ begin
     if Assigned(FSource.FEntity) then
     if Assigned(FSource.FEntity) then
     begin
     begin
       TDOMEntityEx(FSource.FEntity).FOnStack := False;
       TDOMEntityEx(FSource.FEntity).FOnStack := False;
+      TDOMEntityEx(FSource.FEntity).FCharCount := FSource.FCharCount;
 // [28a] PE that was started between MarkupDecls may not end inside MarkupDecl
 // [28a] PE that was started between MarkupDecls may not end inside MarkupDecl
       Error := TDOMEntityEx(FSource.FEntity).FBetweenDecls and FInsideDecl;
       Error := TDOMEntityEx(FSource.FEntity).FBetweenDecls and FInsideDecl;
     end;
     end;
@@ -1760,9 +1784,11 @@ var
   RefName: WideString;
   RefName: WideString;
   Child: TDOMNode;
   Child: TDOMNode;
   SaveCursor: TDOMNode_WithChildren;
   SaveCursor: TDOMNode_WithChildren;
+  cnt: Cardinal;
 begin
 begin
   AEntity := nil;
   AEntity := nil;
   SetString(RefName, FName.Buffer, FName.Length);
   SetString(RefName, FName.Buffer, FName.Length);
+  cnt := FName.Length+2;
 
 
   if Assigned(FDocType) then
   if Assigned(FDocType) then
     AEntity := FDocType.Entities.GetNamedItem(RefName) as TDOMEntityEx;
     AEntity := FDocType.Entities.GetNamedItem(RefName) as TDOMEntityEx;
@@ -1770,19 +1796,19 @@ begin
   if AEntity = nil then
   if AEntity = nil then
   begin
   begin
     if FStandalone or (FDocType = nil) or not (FHavePERefs or (FDocType.SystemID <> '')) then
     if FStandalone or (FDocType = nil) or not (FHavePERefs or (FDocType.SystemID <> '')) then
-      FatalError('Reference to undefined entity ''%s''', [RefName], FName.Length+2)
+      FatalError('Reference to undefined entity ''%s''', [RefName], cnt)
     else
     else
-      ValidationError('Undefined entity ''%s'' referenced', [RefName], FName.Length+2);
+      ValidationError('Undefined entity ''%s'' referenced', [RefName], cnt);
     FCursor.AppendChild(doc.CreateEntityReference(RefName));
     FCursor.AppendChild(doc.CreateEntityReference(RefName));
     Exit;
     Exit;
   end;
   end;
 
 
   if InAttr and (AEntity.SystemID <> '') then
   if InAttr and (AEntity.SystemID <> '') then
-    FatalError('External entity reference is not allowed in attribute value', FName.Length+2);
+    FatalError('External entity reference is not allowed in attribute value', cnt);
   if FStandalone and AEntity.FExternallyDeclared then
   if FStandalone and AEntity.FExternallyDeclared then
-    FatalError('Standalone constraint violation', FName.Length+2);
+    FatalError('Standalone constraint violation', cnt);
   if AEntity.NotationName <> '' then
   if AEntity.NotationName <> '' then
-    FatalError('Reference to unparsed entity ''%s''', [RefName], FName.Length+2);
+    FatalError('Reference to unparsed entity ''%s''', [RefName], cnt);
 
 
   if not AEntity.FResolved then
   if not AEntity.FResolved then
   begin
   begin
@@ -1798,7 +1824,7 @@ begin
         if InAttr then
         if InAttr then
           DoParseAttValue(#0)
           DoParseAttValue(#0)
         else
         else
-          DoParseFragment;
+          ParseContent;
         AEntity.FResolved := True;
         AEntity.FResolved := True;
       finally
       finally
         AEntity.SetReadOnly(True);
         AEntity.SetReadOnly(True);
@@ -1808,6 +1834,9 @@ begin
       end;
       end;
     end;
     end;
   end;
   end;
+  // charcount of the entity included is known at this point
+  Inc(FSource.FCharCount, AEntity.FCharCount - cnt);
+  CheckMaxChars;
   if (not FExpandEntities) or (not AEntity.FResolved) then
   if (not FExpandEntities) or (not AEntity.FResolved) then
   begin
   begin
     // This will clone Entity children
     // This will clone Entity children
@@ -1841,6 +1870,27 @@ begin
   if PEnt.FOnStack then
   if PEnt.FOnStack then
     FatalError('Entity ''%%%s'' recursively references itself', [PEnt.NodeName]);
     FatalError('Entity ''%%%s'' recursively references itself', [PEnt.NodeName]);
 
 
+  { cache an external PE so it's only fetched once }
+  if (PEnt.SystemID <> '') and not PEnt.FResolved then
+  begin
+    if ContextPush(PEnt) then
+    try
+      FValue.Length := 0;
+      FSource.SkipUntil(FValue, [#0]);
+      SetString(PEnt.FReplacementText, FValue.Buffer, FValue.Length);
+      PEnt.FCharCount := FValue.Length;
+      PEnt.FStartLocation.Line := 1;
+      PEnt.FStartLocation.LinePos := 1;
+    finally
+      ContextPop;
+      PEnt.FResolved := True;
+      FValue.Length := 0;
+    end;
+  end;
+
+  Inc(FSource.FCharCount, PEnt.FCharCount);
+  CheckMaxChars;
+
   PEnt.FBetweenDecls := not FInsideDecl;
   PEnt.FBetweenDecls := not FInsideDecl;
   ContextPush(PEnt);
   ContextPush(PEnt);
   FHavePERefs := True;
   FHavePERefs := True;
@@ -1853,7 +1903,7 @@ begin
   if (FSource.FBuf^ <> '''') and (FSource.FBuf^ <> '"') then
   if (FSource.FBuf^ <> '''') and (FSource.FBuf^ <> '"') then
     RaiseExpectedQmark;
     RaiseExpectedQmark;
   Delim := FSource.FBuf^;
   Delim := FSource.FBuf^;
-  GetChar;  // skip quote
+  FSource.NextChar;  // skip quote
   StoreLocation(FTokenStart);
   StoreLocation(FTokenStart);
   if not DoParseAttValue(Delim) then
   if not DoParseAttValue(Delim) then
     FatalError('Literal has no closing quote',-1);
     FatalError('Literal has no closing quote',-1);
@@ -1866,7 +1916,7 @@ begin
   if (FSource.FBuf^ = '''') or (FSource.FBuf^ = '"') then
   if (FSource.FBuf^ = '''') or (FSource.FBuf^ = '"') then
   begin
   begin
     Delim := FSource.FBuf^;
     Delim := FSource.FBuf^;
-    GetChar;  // skip quote
+    FSource.NextChar;  // skip quote
     StoreLocation(FTokenStart);
     StoreLocation(FTokenStart);
     FValue.Length := 0;
     FValue.Length := 0;
     if Delim = '''' then
     if Delim = '''' then
@@ -1955,7 +2005,7 @@ var
   Name, Value: WideString;
   Name, Value: WideString;
   PINode: TDOMProcessingInstruction;
   PINode: TDOMProcessingInstruction;
 begin
 begin
-  GetChar;      // skip '?'
+  FSource.NextChar;      // skip '?'
   Name := ExpectName;
   Name := ExpectName;
   CheckNCName;
   CheckNCName;
   with FName do
   with FName do
@@ -2083,9 +2133,12 @@ end;
 procedure TXMLReader.ParseDoctypeDecl;    // [28]
 procedure TXMLReader.ParseDoctypeDecl;    // [28]
 var
 var
   Src: TXMLCharSource;
   Src: TXMLCharSource;
+  DoctypeURI: WideString;
 begin
 begin
   if FState >= rsDTD then
   if FState >= rsDTD then
     FatalError('Markup declaration is not allowed here');
     FatalError('Markup declaration is not allowed here');
+  if FDisallowDoctype then
+    FatalError('Document type is prohibited by parser settings');
 
 
   ExpectString('DOCTYPE');
   ExpectString('DOCTYPE');
   SkipS(True);
   SkipS(True);
@@ -2123,7 +2176,8 @@ begin
 
 
   if (FDocType.SystemID <> '') then
   if (FDocType.SystemID <> '') then
   begin
   begin
-    if ResolveEntity(FDocType.SystemID, FDocType.PublicID, Src) then
+    ResolveRelativeURI(FSource.SystemID, FDocType.SystemID, DoctypeURI);
+    if ResolveEntity(DocTypeURI, FDocType.PublicID, Src) then
     begin
     begin
       Initialize(Src);
       Initialize(Src);
       try
       try
@@ -2148,7 +2202,7 @@ begin
     SkipS;
     SkipS;
   if FSource.FBuf^ <> '=' then
   if FSource.FBuf^ <> '=' then
     FatalError('Expected "="');
     FatalError('Expected "="');
-  GetChar;
+  FSource.NextChar;
   SkipS;
   SkipS;
 end;
 end;
 
 
@@ -2209,7 +2263,7 @@ begin
       ExpectChoiceOrSeq(CurrentCP);
       ExpectChoiceOrSeq(CurrentCP);
       if CurrentEntity <> FSource.FEntity then
       if CurrentEntity <> FSource.FEntity then
         BadPENesting;
         BadPENesting;
-      GetChar;
+      FSource.NextChar;
     end
     end
     else
     else
       CurrentCP.Def := FindOrCreateElDef;
       CurrentCP.Def := FindOrCreateElDef;
@@ -2228,7 +2282,7 @@ begin
     else
     else
       if FSource.FBuf^ <> Delim then
       if FSource.FBuf^ <> Delim then
         FatalError(Delim);
         FatalError(Delim);
-    GetChar; // skip delimiter
+    FSource.NextChar; // skip delimiter
   until False;
   until False;
   if Delim = '|' then
   if Delim = '|' then
     CP.CPType := ctChoice
     CP.CPType := ctChoice
@@ -2246,10 +2300,10 @@ var
   ExtDecl: Boolean;
   ExtDecl: Boolean;
 begin
 begin
   CP := nil;
   CP := nil;
-  Typ := ctAny;         // satisfy compiler
+  Typ := ctUndeclared;         // satisfy compiler
   ExpectWhitespace;
   ExpectWhitespace;
   ElDef := FindOrCreateElDef;
   ElDef := FindOrCreateElDef;
-  if ElDef.HasElementDecl then
+  if ElDef.ContentType <> ctUndeclared then
     ValidationError('Duplicate declaration of element ''%s''', [ElDef.TagName], FName.Length);
     ValidationError('Duplicate declaration of element ''%s''', [ElDef.TagName], FName.Length);
 
 
   ExtDecl := FSource.DTDSubsetType <> dsInternal;
   ExtDecl := FSource.DTDSubsetType <> dsInternal;
@@ -2285,7 +2339,7 @@ begin
         end;
         end;
         if CurrentEntity <> FSource.FEntity then
         if CurrentEntity <> FSource.FEntity then
           BadPENesting;
           BadPENesting;
-        GetChar;
+        FSource.NextChar;
         if (not CheckForChar('*')) and (CP.ChildCount > 0) then
         if (not CheckForChar('*')) and (CP.ChildCount > 0) then
           FatalError(WideChar('*'));
           FatalError(WideChar('*'));
       end
       end
@@ -2295,7 +2349,7 @@ begin
         ExpectChoiceOrSeq(CP);
         ExpectChoiceOrSeq(CP);
         if CurrentEntity <> FSource.FEntity then
         if CurrentEntity <> FSource.FEntity then
           BadPENesting;
           BadPENesting;
-        GetChar;
+        FSource.NextChar;
         ParseQuantity(CP);
         ParseQuantity(CP);
       end;
       end;
     except
     except
@@ -2306,9 +2360,8 @@ begin
   else
   else
     FatalError('Invalid content specification');
     FatalError('Invalid content specification');
   // SAX: DeclHandler.ElementDecl(name, model);
   // SAX: DeclHandler.ElementDecl(name, model);
-  if not ElDef.HasElementDecl then
+  if ElDef.ContentType = ctUndeclared then
   begin
   begin
-    ElDef.HasElementDecl := True;
     ElDef.FExternallyDeclared := ExtDecl;
     ElDef.FExternallyDeclared := ExtDecl;
     ElDef.ContentType := Typ;
     ElDef.ContentType := Typ;
     ElDef.RootCP := CP;
     ElDef.RootCP := CP;
@@ -2414,6 +2467,7 @@ begin
             ExpectChar('(');
             ExpectChar('(');
             repeat
             repeat
               SkipWhitespace;
               SkipWhitespace;
+              StoreLocation(FTokenStart);
               CheckName;
               CheckName;
               CheckNCName;
               CheckNCName;
               if not AttDef.AddEnumToken(FName.Buffer, FName.Length) then
               if not AttDef.AddEnumToken(FName.Buffer, FName.Length) then
@@ -2463,8 +2517,7 @@ begin
       if DiscardIt then
       if DiscardIt then
         AttDef.Free;
         AttDef.Free;
     except
     except
-      if AttDef.OwnerElement = nil then
-        AttDef.Free;
+      AttDef.Free;
       raise;
       raise;
     end;
     end;
     SkipWhitespace;
     SkipWhitespace;
@@ -2547,15 +2600,21 @@ begin
     begin
     begin
       NDataAllowed := False;
       NDataAllowed := False;
       Delim := FSource.FBuf^;
       Delim := FSource.FBuf^;
-      GetChar;
+      FSource.NextChar;
       StoreLocation(Entity.FStartLocation);
       StoreLocation(Entity.FStartLocation);
       if not ParseEntityDeclValue(Delim) then
       if not ParseEntityDeclValue(Delim) then
         DoErrorPos(esFatal, 'Literal has no closing quote', Entity.FStartLocation);
         DoErrorPos(esFatal, 'Literal has no closing quote', Entity.FStartLocation);
       SetString(Entity.FReplacementText, FEntityValue.Buffer, FEntityValue.Length);
       SetString(Entity.FReplacementText, FEntityValue.Buffer, FEntityValue.Length);
+      Entity.FCharCount := FEntityValue.Length;
     end
     end
     else
     else
+    begin
       if not ParseExternalID(Entity.FSystemID, Entity.FPublicID, False) then
       if not ParseExternalID(Entity.FSystemID, Entity.FPublicID, False) then
         FatalError('Expected entity value or external ID');
         FatalError('Expected entity value or external ID');
+      { need to resolve entity's SystemID relative to the current source,
+        which may differ from the source at the point of inclusion }
+      ResolveRelativeURI(FSource.SystemID, Entity.SystemID, Entity.FURI);
+    end;
 
 
     if NDataAllowed then                // [76]
     if NDataAllowed then                // [76]
     begin
     begin
@@ -2564,6 +2623,7 @@ begin
       if FSource.Matches('NDATA') then
       if FSource.Matches('NDATA') then
       begin
       begin
         ExpectWhitespace;
         ExpectWhitespace;
+        StoreLocation(FTokenStart);
         Entity.FNotationName := ExpectName;
         Entity.FNotationName := ExpectName;
         AddForwardRef(FNotationRefs, FName.Buffer, FName.Length);
         AddForwardRef(FNotationRefs, FName.Buffer, FName.Length);
         // SAX: DTDHandler.UnparsedEntityDecl(...);
         // SAX: DTDHandler.UnparsedEntityDecl(...);
@@ -2771,16 +2831,24 @@ procedure TXMLReader.ParseContent;
 var
 var
   nonWs: Boolean;
   nonWs: Boolean;
   wc: WideChar;
   wc: WideChar;
+  StartNesting: Integer;
 begin
 begin
+  StartNesting := FNesting;
   with FSource do
   with FSource do
   repeat
   repeat
     if FBuf^ = '<' then
     if FBuf^ = '<' then
     begin
     begin
-      if FBufEnd < FBuf + 3 then
-        Reload;
       Inc(FBuf);
       Inc(FBuf);
-      if FBuf^ = '/' then Break;     // end tag case is as frequent as start tag
-      if CheckName([cnOptional]) then
+      if FBufEnd < FBuf + 2 then
+        Reload;
+      if FBuf^ = '/' then
+      begin
+        if FNesting <= StartNesting then
+          FatalError('End-tag is not allowed here');
+        Inc(FBuf);
+        ParseEndTag;
+      end
+      else if CheckName([cnOptional]) then
         ParseElement
         ParseElement
       else if FBuf^ = '!' then
       else if FBuf^ = '!' then
       begin
       begin
@@ -2849,6 +2917,8 @@ begin
         FatalError('Illegal at document level', -1);
         FatalError('Illegal at document level', -1);
     end;
     end;
   until FBuf^ = #0;
   until FBuf^ = #0;
+  if FNesting > StartNesting then
+    FatalError('End-tag is missing for ''%s''', [FValidator[FNesting].FElement.NSI.QName^.Key]);
 end;
 end;
 
 
 procedure TXMLCharSource.NextChar;
 procedure TXMLCharSource.NextChar;
@@ -2872,7 +2942,6 @@ var
   NewElem: TDOMElement;
   NewElem: TDOMElement;
   ElDef: TDOMElementDef;
   ElDef: TDOMElementDef;
   IsEmpty: Boolean;
   IsEmpty: Boolean;
-  ErrOffset: Integer;
   ElName: PHashItem;
   ElName: PHashItem;
 begin
 begin
   if FState > rsRoot then
   if FState > rsRoot then
@@ -2894,7 +2963,7 @@ begin
 
 
   // Find declaration for this element
   // Find declaration for this element
   ElDef := TDOMElementDef(ElName^.Data);
   ElDef := TDOMElementDef(ElName^.Data);
-  if (ElDef = nil) or (not ElDef.HasElementDecl) then
+  if (ElDef = nil) or (ElDef.ContentType = ctUndeclared) then
     ValidationError('Using undeclared element ''%s''',[ElName^.Key], FName.Length);
     ValidationError('Using undeclared element ''%s''',[ElName^.Key], FName.Length);
 
 
   // Check if new element is allowed in current context
   // Check if new element is allowed in current context
@@ -2913,65 +2982,69 @@ begin
   if FSource.FBuf^ = '/' then
   if FSource.FBuf^ = '/' then
   begin
   begin
     IsEmpty := True;
     IsEmpty := True;
-    GetChar;
+    FSource.NextChar;
   end;
   end;
   ExpectChar('>');
   ExpectChar('>');
 
 
   if Assigned(ElDef) and Assigned(ElDef.FAttributes) then
   if Assigned(ElDef) and Assigned(ElDef.FAttributes) then
     ProcessDefaultAttributes(NewElem, ElDef.FAttributes);
     ProcessDefaultAttributes(NewElem, ElDef.FAttributes);
-  PushVC(ElDef);  // this increases FNesting
+  PushVC(NewElem, ElDef);  // this increases FNesting
   if FNamespaces then
   if FNamespaces then
     ProcessNamespaceAtts(NewElem);
     ProcessNamespaceAtts(NewElem);
 
 
-  // SAX: ContentHandler.StartElement(...)
-  // SAX: ContentHandler.StartPrefixMapping(...)
-
-  ErrOffset := 0;
   if not IsEmpty then
   if not IsEmpty then
   begin
   begin
     FCursor := NewElem;
     FCursor := NewElem;
     if not FPreserveWhitespace then   // critical for testsuite compliance
     if not FPreserveWhitespace then   // critical for testsuite compliance
       SkipS;
       SkipS;
-    ParseContent;
-    if FSource.FBuf^ = '/' then         // Get ETag [42]
-    begin
-      FSource.NextChar;
-      CheckName;
-      if not BufEquals(FName, ElName^.Key) then
-        FatalError('Unmatching element end tag (expected "</%s>")', [ElName^.Key], FName.Length);
-      if FSource.FBuf^ = '>' then    // this handles majority of cases
-      begin
-        ErrOffset := FName.Length+1;
-        FSource.NextChar;
-      end
-      else    // but if closing '>' is preceded by whitespace,
-      begin   // skipping it is likely to lose position info.
-        StoreLocation(FTokenStart);
-        Dec(FTokenStart.LinePos, FName.Length);
-        ErrOffset := -1;
-        SkipS;
-        ExpectChar('>');
-      end;
-    end
-    else if FSource.FBuf^ <> #0 then
-      RaiseNameNotFound
-    else // End of stream in content
-      FatalError('End-tag is missing for ''%s''', [ElName^.Key]);
-  end;
-  // SAX: ContentHandler.EndElement(...)
-  // SAX: ContentHandler.EndPrefixMapping(...)
+  end
+  else
+    DoEndElement(0);
+end;
+
+procedure TXMLReader.DoEndElement(ErrOffset: Integer);
+var
+  NewElem: TDOMElement;
+begin
+  NewElem := FValidator[FNesting].FElement;
   TDOMNode(FCursor) := NewElem.ParentNode;
   TDOMNode(FCursor) := NewElem.ParentNode;
   if FCursor = doc then
   if FCursor = doc then
     FState := rsEpilog;
     FState := rsEpilog;
 
 
   if FValidate and FValidator[FNesting].Incomplete then
   if FValidate and FValidator[FNesting].Incomplete then
-    ValidationError('Element ''%s'' is missing required sub-elements', [ElName^.Key], ErrOffset);
+    ValidationError('Element ''%s'' is missing required sub-elements', [NewElem.NSI.QName^.Key], ErrOffset);
 
 
   if FNamespaces then
   if FNamespaces then
     EndNamespaceScope(FBindingStack[FNesting]);
     EndNamespaceScope(FBindingStack[FNesting]);
   PopVC;
   PopVC;
 end;
 end;
 
 
+procedure TXMLReader.ParseEndTag;     // [42]
+var
+  ErrOffset: Integer;
+  ElName: PHashItem;
+begin
+  ElName := FValidator[FNesting].FElement.NSI.QName;
+
+  CheckName;
+  if not BufEquals(FName, ElName^.Key) then
+    FatalError('Unmatching element end tag (expected "</%s>")', [ElName^.Key], FName.Length);
+  if FSource.FBuf^ = '>' then    // this handles majority of cases
+  begin
+    ErrOffset := FName.Length+1;
+    FSource.NextChar;
+  end
+  else    // but if closing '>' is preceded by whitespace,
+  begin   // skipping it is likely to lose position info.
+    StoreLocation(FTokenStart);
+    Dec(FTokenStart.LinePos, FName.Length);
+    ErrOffset := -1;
+    SkipS;
+    ExpectChar('>');
+  end;
+  DoEndElement(ErrOffset);
+end;
+
 procedure TXMLReader.ParseAttribute(Elem: TDOMElement; ElDef: TDOMElementDef);
 procedure TXMLReader.ParseAttribute(Elem: TDOMElement; ElDef: TDOMElementDef);
 var
 var
   attr: TDOMAttr;
   attr: TDOMAttr;
@@ -3038,14 +3111,8 @@ var
   w: PForwardRef;
   w: PForwardRef;
 begin
 begin
   New(w);
   New(w);
-  SetString(w^.Value, Buf, Abs(Length));
-  if Length > 0 then
-  begin
-    StoreLocation(w^.Loc);
-    Dec(w^.Loc.LinePos, Length);
-  end
-  else
-    w^.Loc := FTokenStart;
+  SetString(w^.Value, Buf, Length);
+  w^.Loc := FTokenStart;
   aList.Add(w);
   aList.Add(w);
 end;
 end;
 
 
@@ -3299,8 +3366,7 @@ begin
         EndPos := StartPos;
         EndPos := StartPos;
         while (EndPos <= L) and (aValue[EndPos] <> #32) do
         while (EndPos <= L) and (aValue[EndPos] <> #32) do
           Inc(EndPos);
           Inc(EndPos);
-        // pass negative length, so uses FTokenStart as location
-        AddForwardRef(FIDRefs, @aValue[StartPos], StartPos-EndPos);
+        AddForwardRef(FIDRefs, @aValue[StartPos], EndPos-StartPos);
         StartPos := EndPos + 1;
         StartPos := EndPos + 1;
       end;
       end;
     end;
     end;
@@ -3421,11 +3487,12 @@ begin
     ValidationError('Duplicate notation declaration: ''%s''', [aName]);
     ValidationError('Duplicate notation declaration: ''%s''', [aName]);
 end;
 end;
 
 
-procedure TXMLReader.PushVC(aElDef: TDOMElementDef);
+procedure TXMLReader.PushVC(aElement: TDOMElement; aElDef: TDOMElementDef);
 begin
 begin
   Inc(FNesting);
   Inc(FNesting);
   if FNesting >= Length(FValidator) then
   if FNesting >= Length(FValidator) then
     SetLength(FValidator, FNesting * 2);
     SetLength(FValidator, FNesting * 2);
+  FValidator[FNesting].FElement := aElement;
   FValidator[FNesting].FElementDef := aElDef;
   FValidator[FNesting].FElementDef := aElDef;
   FValidator[FNesting].FCurCP := nil;
   FValidator[FNesting].FCurCP := nil;
   FValidator[FNesting].FFailed := False;
   FValidator[FNesting].FFailed := False;
@@ -3486,7 +3553,7 @@ begin
         else
         else
           FFailed := True;  // used to prevent extra error at the end of element
           FFailed := True;  // used to prevent extra error at the end of element
       end;
       end;
-      // ctAny: returns True by default
+      // ctAny, ctUndeclared: returns True by default
     end;
     end;
   end;
   end;
 end;
 end;
@@ -3639,8 +3706,8 @@ begin
   Reader := TXMLReader.Create;
   Reader := TXMLReader.Create;
   try
   try
     Reader.ProcessXML(Src);
     Reader.ProcessXML(Src);
-    ADoc := TXMLDocument(Reader.Doc);
   finally
   finally
+    ADoc := TXMLDocument(Reader.Doc);
     Reader.Free;
     Reader.Free;
   end;
   end;
 end;
 end;
@@ -3688,7 +3755,6 @@ begin
   Reader := TXMLReader.Create;
   Reader := TXMLReader.Create;
   try
   try
     Src := TXMLFileInputSource.Create(f);
     Src := TXMLFileInputSource.Create(f);
-    Src.SystemID := FilenameToURI(TTextRec(f).Name);
     Reader.ProcessFragment(Src, AParentNode);
     Reader.ProcessFragment(Src, AParentNode);
   finally
   finally
     Reader.Free;
     Reader.Free;
@@ -3737,10 +3803,9 @@ begin
   Reader := TXMLReader.Create;
   Reader := TXMLReader.Create;
   try
   try
     Src := TXMLFileInputSource.Create(f);
     Src := TXMLFileInputSource.Create(f);
-    Src.SystemID := FilenameToURI(TTextRec(f).Name);
     Reader.ProcessDTD(Src);
     Reader.ProcessDTD(Src);
-    ADoc := TXMLDocument(Reader.doc);
   finally
   finally
+    ADoc := TXMLDocument(Reader.doc);
     Reader.Free;
     Reader.Free;
   end;
   end;
 end;
 end;
@@ -3756,8 +3821,8 @@ begin
     Src := TXMLStreamInputSource.Create(f, False);
     Src := TXMLStreamInputSource.Create(f, False);
     Src.SystemID := ABaseURI;
     Src.SystemID := ABaseURI;
     Reader.ProcessDTD(Src);
     Reader.ProcessDTD(Src);
-    ADoc := TXMLDocument(Reader.doc);
   finally
   finally
+    ADoc := TXMLDocument(Reader.doc);
     Reader.Free;
     Reader.Free;
   end;
   end;
 end;
 end;

+ 6 - 1
packages/fcl-xml/src/xmlwrite.pp

@@ -191,8 +191,13 @@ begin
     wc := Cardinal(Src^);  Inc(Src);
     wc := Cardinal(Src^);  Inc(Src);
     case wc of
     case wc of
       $0A: pb := StrECopy(pb, PChar(FLineBreak));
       $0A: pb := StrECopy(pb, PChar(FLineBreak));
+      $0D: begin
+        pb := StrECopy(pb, PChar(FLineBreak));
+        if (Src < SrcEnd) and (Src^ = #$0A) then
+          Inc(Src);
+      end;
 
 
-      0..$09, $0B..$7F:  begin
+      0..$09, $0B, $0C, $0E..$7F:  begin
         pb^ := char(wc); Inc(pb);
         pb^ := char(wc); Inc(pb);
       end;
       end;
 
 

文件差异内容过多而无法显示
+ 365 - 321
packages/fcl-xml/src/xpath.pp


+ 7 - 3
packages/fcl-xml/tests/api.xml

@@ -195,7 +195,7 @@
   <arg>namespaceURI</arg>
   <arg>namespaceURI</arg>
   <arg>qualifiedName</arg>
   <arg>qualifiedName</arg>
 </item>
 </item>
-<item id="createDocument">
+<item id="createDocument" gc="yes">
   <arg>namespaceURI</arg>
   <arg>namespaceURI</arg>
   <arg>qualifiedName</arg>
   <arg>qualifiedName</arg>
   <arg>doctype</arg>
   <arg>doctype</arg>
@@ -258,8 +258,10 @@
 <item id="canSetParameter"/>
 <item id="canSetParameter"/>
 <item id="setParameter"/>
 <item id="setParameter"/>
 <item id="normalizeDocument"/>
 <item id="normalizeDocument"/>
+-->
 <item id="isId"/>
 <item id="isId"/>
-
+<item id="documentURI" type="prop"/>
+<!--
 // assertNotEquals
 // assertNotEquals
 // assertLowerSeverity
 // assertLowerSeverity
 
 
@@ -267,9 +269,11 @@
 <item id="setUserData"/>
 <item id="setUserData"/>
 <item id="isEqualNode"/>
 <item id="isEqualNode"/>
 <item id="isSameNode"/>
 <item id="isSameNode"/>
+-->
 <item id="lookupNamespaceURI">
 <item id="lookupNamespaceURI">
   <arg>prefix</arg>
   <arg>prefix</arg>
 </item>
 </item>
+<!--
 <item id="lookupPrefix"/>
 <item id="lookupPrefix"/>
 <item id="isDefaultNamespace"/>
 <item id="isDefaultNamespace"/>
 <item id="adoptNode"/>
 <item id="adoptNode"/>
@@ -703,4 +707,4 @@
 
 
 
 
 </api>
 </api>
-</test-data>
+</test-data>

+ 147 - 30
packages/fcl-xml/tests/xpathts.pp

@@ -22,13 +22,13 @@ uses
   dom, xmlread, xmlwrite, xpath;
   dom, xmlread, xmlwrite, xpath;
 
 
 type
 type
-  TResultType = (rtString, rtNumber, rtBool, rtNodeset);
+  TResultType = (rtString, rtNumber, rtBool, rtNodeStr, rtOther);
 
 
   TTestRec = record
   TTestRec = record
     data: string;              // UTF-8 encoded
     data: string;              // UTF-8 encoded
     expr: DOMString;
     expr: DOMString;
   case rt: TResultType of
   case rt: TResultType of
-    rtString: (s: DOMPChar);   // cannot use DOMString here
+    rtString, rtNodeStr: (s: DOMPChar);   // cannot use DOMString here
     rtNumber: (n: Extended);
     rtNumber: (n: Extended);
     rtBool:   (b: Boolean);
     rtBool:   (b: Boolean);
   end;
   end;
@@ -414,12 +414,20 @@ const
   '<a id="c"/>'+
   '<a id="c"/>'+
   '<a id="d"/>'+
   '<a id="d"/>'+
   '</t04>';
   '</t04>';
+  
+  pos04='<doc>'+
+  '<a test="true"><num>1</num></a>'+
+  '<a><num>1191</num></a>'+
+  '<a><num>263</num></a>'+
+  '<a test="true"><num>2</num></a>'+
+  '<a><num>827</num></a>'+
+  '<a><num>256</num></a>'+
+  '<a test="true"><num>3</num></a>'+
+  '<a test="true"><num>4</num></a>'+
+  '</doc>';
 
 
-  FunctionTests: array[0..50] of TTestRec = (
+  FunctionTests: array[0..51] of TTestRec = (
   // last()
   // last()
-  // position()
-  // count()
-  // id()
   // local-name()
   // local-name()
   // namespace-uri()
   // namespace-uri()
   // name()
   // name()
@@ -442,13 +450,15 @@ const
     (expr: 'not("")';      rt: rtBool; b: True),
     (expr: 'not("")';      rt: rtBool; b: True),
 
 
     // lang() tests. These ones, however, test much more than lang().
     // lang() tests. These ones, however, test much more than lang().
-    // Moreover, I've added string(), otherwise result would be a nodeset
-    (data: expr01; expr: 'string(para[@id="1" and lang("en")])'; rt: rtString; s: 'en'),     // expression01
-    (data: expr01; expr: 'string(para[@id="4" and lang("en")])'; rt: rtString; s: 'en-us'),  // expression03
-    (data: expr01; expr: 'string(div/para[lang("en")])'; rt: rtString; s: 'en'),             // expression04
-    (data: expr01; expr: 'string(para[@id="3" and lang("en")])'; rt: rtString; s: 'EN'),     // expression05
+    (data: expr01; expr: 'para[@id="1" and lang("en")]'; rt: rtNodeStr; s: 'en'),     // expression01
+    (data: expr01; expr: 'para[@id="4" and lang("en")]'; rt: rtNodeStr; s: 'en-us'),  // expression03
+    (data: expr01; expr: 'div/para[lang("en")]'; rt: rtNodeStr; s: 'en'),             // expression04
+    (data: expr01; expr: 'para[@id="3" and lang("en")]'; rt: rtNodeStr; s: 'EN'),     // expression05
+    
+    (data: id04; expr: 'id("c")/@id'; rt: rtNodeStr; s: 'c'),  // idkey04
     
     
-    (data: id04; expr: 'id("c")/@id'; rt: rtString; s: 'c'),  // idkey04
+    // position() tests
+    (data: pos04; expr: '*[@test][position()=4]/num'; rt: rtNodeStr; s: '4'),
 
 
     (expr: 'number("1.5")';   rt: rtNumber; n: 1.5),
     (expr: 'number("1.5")';   rt: rtNumber; n: 1.5),
     (expr: 'number("abc")';   rt: rtNumber; n: NaN),
     (expr: 'number("abc")';   rt: rtNumber; n: NaN),
@@ -512,10 +522,32 @@ const
 '      e'#10+
 '      e'#10+
 '    ';
 '    ';
 
 
-  StringTests: array[0..59] of TTestRec = (
-    (expr: 'string(5)';       rt: rtString; s: '5'),
+  node08='<docs xmlns:ped="http://www.ped.com"><?MyPI DoesNothing ?><!-- This is a big tree containing all letters of the alphabet -->'#10+
+  '<a attr1="This should not be seen">A</a>'#10+
+  '<b><c attr1="tsnbs" attr2="tsnbs">B-C</c>'#10+
+  '<d><e><f>TextNode_between_F_and_G'#10+
+  '<g><h><i><j><k><l><m><n><o><p><q><r><s><t><u><v><w><x><y><z><Yahoo>Yahoo</Yahoo>'#10+
+  '</z></y></x></w></v></u></t></s></r></q></p></o></n></m></l></k></j></i></h>SecondNode_after_H</g></f></e></d></b>'#10+
+  '</docs>';
+  
+  out08=#10+
+  'A'#10+
+  'B-C'#10+
+  'TextNode_between_F_and_G'#10+
+  'Yahoo'#10+
+  'SecondNode_after_H'#10;
+
+  str30='<doc xmlns="http://xsl.lotus.com/ns2" xmlns:ns1="http://xsl.lotus.com/ns1">'#10+
+  '<ns1:a attrib1="test" xmlns="http://xsl.lotus.com/ns2" xmlns:ns1="http://xsl.lotus.com/ns1"/>'#10+
+  '<b ns1:attrib2="test"/>'#10+
+  '</doc>';
+
+  StringTests: array[0..75] of TTestRec = (             // numbers refer to xalan/string/stringXX
+    (expr: 'string(5)';       rt: rtString; s: '5'),    // #38/39
     (expr: 'string(0.5)';     rt: rtString; s: '0.5'),
     (expr: 'string(0.5)';     rt: rtString; s: '0.5'),
     (expr: 'string(-0.5)';    rt: rtString; s: '-0.5'),
     (expr: 'string(-0.5)';    rt: rtString; s: '-0.5'),
+    (expr: 'string("test")';  rt: rtString; s: 'test'), // #40
+    (expr: 'string("")';      rt: rtString; s: ''),     // #41
     (expr: 'string(true())';  rt: rtString; s: 'true'),
     (expr: 'string(true())';  rt: rtString; s: 'true'),
     (expr: 'string(false())'; rt: rtString; s: 'false'),
     (expr: 'string(false())'; rt: rtString; s: 'false'),
     (expr: 'string(0 div 0)'; rt: rtString; s: 'NaN'),
     (expr: 'string(0 div 0)'; rt: rtString; s: 'NaN'),
@@ -523,6 +555,7 @@ const
     (expr: 'string(-1 div 0)'; rt: rtString; s: '-Infinity'),
     (expr: 'string(-1 div 0)'; rt: rtString; s: '-Infinity'),
     // maybe other checks for correct numeric formats
     // maybe other checks for correct numeric formats
     (data: str14; expr: 'string(av//*)'; rt: rtString; s: out14),
     (data: str14; expr: 'string(av//*)'; rt: rtString; s: out14),
+    (data: node08; expr: '/'; rt: rtNodeStr; s: out08),
 
 
     (expr: 'concat("titi","toto")'; rt: rtString; s: 'tititoto'),
     (expr: 'concat("titi","toto")'; rt: rtString; s: 'tititoto'),
     (expr: 'concat("titi","toto","tata")'; rt: rtString; s: 'tititototata'),
     (expr: 'concat("titi","toto","tata")'; rt: rtString; s: 'tititototata'),
@@ -533,9 +566,11 @@ const
 
 
     (expr: 'starts-with("tititoto","titi")'; rt: rtBool; b: True),
     (expr: 'starts-with("tititoto","titi")'; rt: rtBool; b: True),
     (expr: 'starts-with("tititoto","to")';   rt: rtBool; b: False),
     (expr: 'starts-with("tititoto","to")';   rt: rtBool; b: False),
-    (expr: 'starts-with("ab", "abc")';       rt: rtBool; b: False),
-    (expr: 'starts-with("abc", "")';         rt: rtBool; b: True),     // xalan/string/string48
+    (expr: 'starts-with("ab", "abc")';       rt: rtBool; b: False),    // #46
+    (expr: 'starts-with("abc", "bc")';       rt: rtBool; b: False),    // #47
+    (expr: 'starts-with("abc", "")';         rt: rtBool; b: True),     // #48
     (expr: 'starts-with("", "")';            rt: rtBool; b: True),     // #49
     (expr: 'starts-with("", "")';            rt: rtBool; b: True),     // #49
+    (expr: 'starts-with(true(), "tr")';      rt: rtBool; b: True),     // #50
 
 
 
 
 
 
@@ -543,11 +578,12 @@ const
     (expr: 'contains("tititototata","toto")'; rt: rtBool; b: True),
     (expr: 'contains("tititototata","toto")'; rt: rtBool; b: True),
     (expr: 'contains("tititototata","tata")'; rt: rtBool; b: True),
     (expr: 'contains("tititototata","tata")'; rt: rtBool; b: True),
     (expr: 'contains("tititototata","tita")'; rt: rtBool; b: False),
     (expr: 'contains("tititototata","tita")'; rt: rtBool; b: False),
-    (expr: 'contains("ab", "abc")';           rt: rtBool; b: False),   // #59
+    // 'contains(concat(.,'BC'),concat('A','B','C'))' == true          // #57    
+    (expr: 'contains("ab", "abc")';           rt: rtBool; b: False),   // #58
     (expr: 'contains("abc", "bcd")';          rt: rtBool; b: False),   // #60
     (expr: 'contains("abc", "bcd")';          rt: rtBool; b: False),   // #60
     (expr: 'contains("abc", "")';             rt: rtBool; b: True),    // #61
     (expr: 'contains("abc", "")';             rt: rtBool; b: True),    // #61
     (expr: 'contains("", "")';                rt: rtBool; b: True),    // #62
     (expr: 'contains("", "")';                rt: rtBool; b: True),    // #62
-    // 'contains(concat(.,'BC'),concat('A','B','C'))' == true
+    (expr: 'contains(true(), "e")';           rt: rtBool; b: True),    // #63    
 
 
     (expr: 'substring("12345",2,3)'; rt: rtString; s: '234'),
     (expr: 'substring("12345",2,3)'; rt: rtString; s: '234'),
     (expr: 'substring("12345",2)';   rt: rtString; s: '2345'),
     (expr: 'substring("12345",2)';   rt: rtString; s: '2345'),
@@ -555,24 +591,24 @@ const
     (expr: 'substring("12345",3.4)'; rt: rtString; s: '345'),
     (expr: 'substring("12345",3.4)'; rt: rtString; s: '345'),
     (expr: 'substring("12345",3.6)'; rt: rtString; s: '45'),
     (expr: 'substring("12345",3.6)'; rt: rtString; s: '45'),
 
 
-    (expr: 'substring("12345",1.5,2.6)'; rt: rtString; s: '234'),
+    (expr: 'substring("12345",1.5,2.6)'; rt: rtString; s: '234'), // #16
     (expr: 'substring("12345",2.2,2.2)'; rt: rtString; s: '23'),
     (expr: 'substring("12345",2.2,2.2)'; rt: rtString; s: '23'),
-    (expr: 'substring("12345",0,3)';     rt: rtString; s: '12'),
+    (expr: 'substring("12345",0,3)';     rt: rtString; s: '12'),  // #17
     (expr: 'substring("12345",-8,10)';   rt: rtString; s: '1'),
     (expr: 'substring("12345",-8,10)';   rt: rtString; s: '1'),
     (expr: 'substring("12345",4,-10)';   rt: rtString; s: ''),
     (expr: 'substring("12345",4,-10)';   rt: rtString; s: ''),
 
 
-    (expr: 'substring("12345",0 div 0, 3)'; rt: rtString; s: ''),
-    (expr: 'substring("12345",1, 0 div 0)'; rt: rtString; s: ''),
+    (expr: 'substring("12345",0 div 0, 3)'; rt: rtString; s: ''), // #18
+    (expr: 'substring("12345",1, 0 div 0)'; rt: rtString; s: ''), // #19
     (expr: 'substring("12345",1 div 0, 3)'; rt: rtString; s: ''),
     (expr: 'substring("12345",1 div 0, 3)'; rt: rtString; s: ''),
     (expr: 'substring("12345",3,-1 div 0)'; rt: rtString; s: ''),
     (expr: 'substring("12345",3,-1 div 0)'; rt: rtString; s: ''),
-    (expr: 'substring("12345",-42, 1 div 0)'; rt: rtString; s: '12345'),
+    (expr: 'substring("12345",-42, 1 div 0)'; rt: rtString; s: '12345'), // #20
 
 
-    (expr: 'substring("12345",-1 div 0, 1 div 0)'; rt: rtString; s: ''),
+    (expr: 'substring("12345",-1 div 0, 1 div 0)'; rt: rtString; s: ''), // #21
     (expr: 'substring("12345",-1 div 0,5)';        rt: rtString; s: ''),
     (expr: 'substring("12345",-1 div 0,5)';        rt: rtString; s: ''),
 
 
-    (expr: 'substring-before("1999/04/01","/")'; rt: rtString; s: '1999'),
-    (expr: 'substring-before("1999/04/01","a")'; rt: rtString; s: ''),
-    (expr: 'substring-after("1999/04/01","/")'; rt: rtString; s: '04/01'),
+    (expr: 'substring-before("1999/04/01","/")'; rt: rtString; s: '1999'),  // #08
+    (expr: 'substring-before("1999/04/01","a")'; rt: rtString; s: ''),      // #68 modified
+    (expr: 'substring-after("1999/04/01","/")'; rt: rtString; s: '04/01'),  // #09
     (expr: 'substring-after("1999/04/01","19")'; rt: rtString; s: '99/04/01'),
     (expr: 'substring-after("1999/04/01","19")'; rt: rtString; s: '99/04/01'),
     (expr: 'substring-after("1999/04/01","a")'; rt: rtString; s: ''),
     (expr: 'substring-after("1999/04/01","a")'; rt: rtString; s: ''),
 
 
@@ -582,11 +618,80 @@ const
     (data: str04;  expr: 'string-length(/)'; rt: rtNumber; n:27),    // #04.1 modified
     (data: str04;  expr: 'string-length(/)'; rt: rtNumber; n:27),    // #04.1 modified
     (data: str04;  expr: 'string-length(/doc/a)'; rt: rtNumber; n: 12), // #04.2
     (data: str04;  expr: 'string-length(/doc/a)'; rt: rtNumber; n: 12), // #04.2
     (data: str04;  expr: 'string-length()';  rt: rtNumber; n: 27),
     (data: str04;  expr: 'string-length()';  rt: rtNumber; n: 27),
-    (expr: 'normalize-space("'#9#10#13' ab   cd'#10#13#9'ef'#9#10#13'  ")'; rt: rtString; s: 'ab cd ef'),
+    (expr: 'normalize-space("'#9#10#13' ab   cd'#10#13#9'ef'#9#10#13'  ")'; rt: rtString; s: 'ab cd ef'), // #10
 
 
-    (expr: 'translate("bar", "abc", "ABC")'; rt: rtString; s: 'BAr'),
+    (expr: 'translate("bar", "abc", "ABC")'; rt: rtString; s: 'BAr'),  // #11
     (expr: 'translate("--aaa--","abc-","ABC")'; rt: rtString; s: 'AAA'),
     (expr: 'translate("--aaa--","abc-","ABC")'; rt: rtString; s: 'AAA'),
-    (expr: 'translate("ddaaadddd","abcd","ABCxy")'; rt: rtString; s: 'xxAAAxxxx')   // #96
+    (expr: 'translate("ddaaadddd","abcd","ABCxy")'; rt: rtString; s: 'xxAAAxxxx'),   // #96
+
+    (data: str30; expr: 'namespace-uri(baz1:a/@baz2:attrib1)'; rt: rtString; s: ''), // #30
+    (data: str30; expr: 'namespace-uri(baz2:b/@baz1:attrib2)'; rt: rtString; s: 'http://xsl.lotus.com/ns1'), // #31
+    (data: str30; expr: 'name(*)'; rt: rtString; s: 'ns1:a'),       // #32
+    (data: str30; expr: 'name(baz1:a)'; rt: rtString; s: 'ns1:a'),  // #33
+    (data: str30; expr: 'name(baz2:b)'; rt: rtString; s: 'b'),      // #34
+    (data: str30; expr: 'name(baz1:a/@baz2:attrib1)'; rt: rtString; s: ''),            // #35
+    (data: str30; expr: 'name(baz2:b/@baz1:attrib2)'; rt: rtString; s: 'ns1:attrib2'), // #36
+
+    (data: str30; expr: 'local-name(baz2:b)'; rt: rtString; s: 'b'), // namespace07
+    (data: str30; expr: 'local-name(baz2:b/@baz1:attrib2)'; rt: rtString; s: 'attrib2'), // namespace09
+    (data: str30; expr: 'local-name()'; rt: rtString; s: 'doc')      // namespace26
+  );
+  
+  ax114='<doc>'+
+  '<foo att1="c">'+
+  '  <foo att1="b">'+
+  '     <foo att1="a"/>'+
+  '  </foo>'+
+  '</foo>'+
+  '<baz/>'+
+  '</doc>';
+
+  ax115='<doc>'+
+  '<foo att1="c"/>'+
+  '<foo att1="b"/>'+
+  '<foo att1="a"/>'+
+  '<baz/>'+
+  '</doc>';
+
+
+  ax117='<chapter title="A" x="0">'+
+  '<section title="A1" x="1">'+
+  '  <subsection title="A1a" x="2">hello</subsection>'+
+  '  <subsection title="A1b">ahoy</subsection>'+
+  '</section>'+
+  '<section title="A2">'+
+  '  <subsection title="A2a">goodbye</subsection>'+
+  '  <subsection title="A2b">sayonara</subsection>'+
+  '  <subsection title="A2c">adios</subsection>'+
+  '</section>'+
+  '<section title="A3">'+
+  '  <subsection title="A3a">aloha</subsection>'+
+  '  <subsection title="A3b">'+
+  '    <footnote x="3">A3b-1</footnote>'+
+  '    <footnote>A3b-2</footnote>'+
+  '  </subsection>'+
+  '  <subsection title="A3c">shalom</subsection>'+
+  '</section>'+
+  '</chapter>';
+
+  AxesTests: array[0..13] of TTestRec = (
+    (data: ax117; expr: 'count(//@*)';                        rt: rtNumber; n: 16),
+    (data: ax117; expr: 'count(//@title)';                    rt: rtNumber; n: 12),
+    (data: ax117; expr: 'count(//section//@*)';               rt: rtNumber; n: 14),
+    (data: ax117; expr: 'count(//section//@title)';           rt: rtNumber; n: 11),
+    (data: ax117; expr: 'count(/chapter/.//@*)';              rt: rtNumber; n: 16),
+    (data: ax117; expr: 'count(/chapter/.//@title)';          rt: rtNumber; n: 12),
+    (data: ax117; expr: 'count(/chapter/section[1]//@*)';     rt: rtNumber; n: 5),
+    (data: ax117; expr: 'count(/chapter/section[1]//@title)'; rt: rtNumber; n: 3),
+    (data: ax117; expr: 'count(/chapter/section[2]//@*)';     rt: rtNumber; n: 4),
+    (data: ax117; expr: 'count(/chapter/section[2]//@title)'; rt: rtNumber; n: 4),
+    (data: ax117; expr: 'count(/chapter/section[3]//@*)';     rt: rtNumber; n: 5),
+    (data: ax117; expr: 'count(/chapter/section[3]//@title)'; rt: rtNumber; n: 4),
+
+    (data: ax114; expr: '//baz/preceding::foo[1]/@att1';    rt: rtNodeStr; s: 'a'),
+//  (data: ax114; expr: '//baz/(preceding::foo)[1]/@att1';  rt: rtNodeStr; s: 'c'),         // won't parse
+    (data: ax115; expr: '//baz/preceding-sibling::foo[1]/@att1';    rt: rtNodeStr; s: 'a')
+//  (data: ax115; expr: '//baz/(preceding-sibling::foo)[1]/@att1';  rt: rtNodeStr; s: 'c')  // won't parse
   );
   );
 {$warnings on}
 {$warnings on}
 
 
@@ -629,6 +734,16 @@ begin
       writeln('Failed: ', t.expr);
       writeln('Failed: ', t.expr);
       writeln('Expected: ', DOMString(t.s), ' got: ', r.AsText);
       writeln('Expected: ', DOMString(t.s), ' got: ', r.AsText);
     end;
     end;
+    rtNodeStr:
+    begin
+      if (r is TXPathNodeSetVariable) and (r.AsNodeSet.Count = 1) and (r.AsText = DOMString(t.s)) then
+        Exit;
+      writeln;  
+      writeln('Failed: ', t.expr);
+      if r.AsNodeSet.Count > 1 then
+        writeln('Result is not a single node');
+      writeln('Expected: ', DOMString(t.s), ' got: ', r.AsText);
+    end;
   end;
   end;
   Inc(FailCount);
   Inc(FailCount);
 end;
 end;
@@ -641,6 +756,7 @@ begin
   parser := TDOMParser.Create;
   parser := TDOMParser.Create;
   try
   try
     parser.Options.PreserveWhitespace := True;
     parser.Options.PreserveWhitespace := True;
+    parser.Options.Namespaces := True;
     src := TXMLInputSource.Create(data);
     src := TXMLInputSource.Create(data);
     try
     try
       parser.Parse(src, Result);
       parser.Parse(src, Result);
@@ -693,6 +809,7 @@ begin
   DoSuite(FloatTests);
   DoSuite(FloatTests);
   DoSuite(FunctionTests);
   DoSuite(FunctionTests);
   DoSuite(StringTests);
   DoSuite(StringTests);
+  DoSuite(AxesTests);
 
 
   writeln;
   writeln;
   writeln('Total failed tests: ', FailCount);
   writeln('Total failed tests: ', FailCount);

+ 5 - 5
packages/fpgtk/src/fpgtk.pp

@@ -606,9 +606,9 @@ TYPE
   Protected
   Protected
     procedure CreateGtkObject; override;
     procedure CreateGtkObject; override;
   Public
   Public
-    function TheGtkObject : PGtkImage;
     FMask:PGdkBitMap;
     FMask:PGdkBitMap;
     FImage:PGdkImage;
     FImage:PGdkImage;
+    function TheGtkObject : PGtkImage;
     property Image : PGdkImage read GetImageProp write SetImageProp;
     property Image : PGdkImage read GetImageProp write SetImageProp;
     property Mask : PGdkBitMap read GetMask write SetMask;
     property Mask : PGdkBitMap read GetMask write SetMask;
     procedure SetImage (anImage:PGdkImage; aMask:PGdkBitmap);
     procedure SetImage (anImage:PGdkImage; aMask:PGdkBitmap);
@@ -629,9 +629,9 @@ TYPE
   Protected
   Protected
     procedure CreateGtkObject; override;
     procedure CreateGtkObject; override;
   Public
   Public
-    function TheGtkObject : PGtkPixmap;
     FMask:PGdkBitMap;
     FMask:PGdkBitMap;
     FPixMap:PGdkPixmap;
     FPixMap:PGdkPixmap;
+    function TheGtkObject : PGtkPixmap;
     property BuildInsensitive : longbool read GetBuildInsensitive write SetBuildInsensitive;
     property BuildInsensitive : longbool read GetBuildInsensitive write SetBuildInsensitive;
     constructor Create;
     constructor Create;
     constructor CreateFromFile (Filename:string; Window:TFPgtkWidget);
     constructor CreateFromFile (Filename:string; Window:TFPgtkWidget);
@@ -655,8 +655,8 @@ TYPE
     procedure SetBorder (TheValue : integer);
     procedure SetBorder (TheValue : integer);
     function GetChildren : TFPgtkWidgetGroup;
     function GetChildren : TFPgtkWidgetGroup;
   Public
   Public
-    function TheGtkObject : PGtkContainer;
     FChildren:TFPgtkWidgetGroup;
     FChildren:TFPgtkWidgetGroup;
+    function TheGtkObject : PGtkContainer;
     property Border : integer read GetBorder write SetBorder;
     property Border : integer read GetBorder write SetBorder;
     procedure Add (AWidget:TFPgtkWidget; IsVisible:boolean); Overload;
     procedure Add (AWidget:TFPgtkWidget; IsVisible:boolean); Overload;
     procedure Add (AWidget:TFPgtkWidget); Overload;
     procedure Add (AWidget:TFPgtkWidget); Overload;
@@ -802,8 +802,8 @@ TYPE
   Protected
   Protected
     procedure CreateGtkObject; Override;
     procedure CreateGtkObject; Override;
   Public
   Public
-    function TheGtkObject : PGtkRadioButton;
     FGroup:TFPgtkRadioButtonGroup;
     FGroup:TFPgtkRadioButtonGroup;
+    function TheGtkObject : PGtkRadioButton;
     constructor Create (AGroup:TFPgtkRadioButtonGroup);
     constructor Create (AGroup:TFPgtkRadioButtonGroup);
     constructor CreateWithLabel (AGroup:TFPgtkRadioButtonGroup; aText:string);
     constructor CreateWithLabel (AGroup:TFPgtkRadioButtonGroup; aText:string);
   end;
   end;
@@ -1957,8 +1957,8 @@ TYPE
     procedure GtkInsert (MenuItem:TFPgtkWidget; position:integer); Override;
     procedure GtkInsert (MenuItem:TFPgtkWidget; position:integer); Override;
     procedure GtkAppend (MenuItem:TFPgtkWidget); Override;
     procedure GtkAppend (MenuItem:TFPgtkWidget); Override;
   Public
   Public
-    function TheGtkObject : PGtkMenu;
     FDetacher:TFPgtkMenuDetachFunction;
     FDetacher:TFPgtkMenuDetachFunction;
+    function TheGtkObject : PGtkMenu;
     procedure ReorderChild (MenuItem:TFPgtkWidget; position:integer);
     procedure ReorderChild (MenuItem:TFPgtkWidget; position:integer);
     procedure Popup (button:guint); Overload;
     procedure Popup (button:guint); Overload;
     procedure Popup (ParentShell:TFPgtkWidget; ParentItem:TFPgtkWidget; func:TFPgtkMenuPosFunction; data:pointer; button:guint; ActivateTime:guint32); Overload;
     procedure Popup (ParentShell:TFPgtkWidget; ParentItem:TFPgtkWidget; func:TFPgtkMenuPosFunction; data:pointer; button:guint; ActivateTime:guint32); Overload;

+ 186 - 22
packages/fpmkunit/src/fpmkunit.pp

@@ -210,13 +210,19 @@ Type
     FCommandAt: TCommandAt;
     FCommandAt: TCommandAt;
     FDestFile: String;
     FDestFile: String;
     FIgnoreResult: Boolean;
     FIgnoreResult: Boolean;
-    FOptions: String;
+    FOptions: TStrings;
     FSourceFile: String;
     FSourceFile: String;
+    Function GetOptions : TStrings;
+    Procedure SetOptions(Const Value : TStrings);
   Public
   Public
+    Destructor Destroy; override;
+    Function HaveOptions : Boolean;
+    Function CmdLineOptions : String;
+    Procedure ParseOptions(S : String);
     Property SourceFile : String Read FSourceFile Write FSourceFile;
     Property SourceFile : String Read FSourceFile Write FSourceFile;
     Property DestFile : String Read FDestFile Write FDestFile;
     Property DestFile : String Read FDestFile Write FDestFile;
     Property Command : String Read FCommand Write FCommand;
     Property Command : String Read FCommand Write FCommand;
-    Property Options : String Read FOptions Write FOptions;
+    Property Options : TStrings Read GetOptions Write SetOptions;
     Property At : TCommandAt Read FCommandAt Write FCommandAt;
     Property At : TCommandAt Read FCommandAt Write FCommandAt;
     Property IgnoreResult : Boolean Read FIgnoreResult Write FIgnoreResult;
     Property IgnoreResult : Boolean Read FIgnoreResult Write FIgnoreResult;
     Property BeforeCommand : TNotifyEvent Read FBeforeCommand Write FBeforeCommand;
     Property BeforeCommand : TNotifyEvent Read FBeforeCommand Write FBeforeCommand;
@@ -370,10 +376,12 @@ Type
     FExtension: String;
     FExtension: String;
     FTargetSourceFileName : String;
     FTargetSourceFileName : String;
     FFileType: TFileType;
     FFileType: TFileType;
-    FOptions: String;
+    FOptions: TStrings;
     FFPCTarget: String;
     FFPCTarget: String;
     FTargetState: TTargetState;
     FTargetState: TTargetState;
     FTargetType: TTargetType;
     FTargetType: TTargetType;
+    function GetOptions: TStrings;
+    procedure SetOptions(const AValue: TStrings);
   Protected
   Protected
     Function GetSourceFileName : String; virtual;
     Function GetSourceFileName : String; virtual;
     Function GetUnitFileName : String; virtual;
     Function GetUnitFileName : String; virtual;
@@ -384,6 +392,7 @@ Type
     Constructor Create(ACollection : TCollection); override;
     Constructor Create(ACollection : TCollection); override;
     Destructor Destroy; override;
     Destructor Destroy; override;
     Function  GetOutputFileName (AOs : TOS) : String; Virtual;
     Function  GetOutputFileName (AOs : TOS) : String; Virtual;
+    Function HaveOptions : Boolean;
     procedure SetName(const AValue: String);override;
     procedure SetName(const AValue: String);override;
     Procedure GetCleanFiles(List : TStrings; const APrefixU, APrefixB : String; ACPU:TCPU; AOS : TOS); virtual;
     Procedure GetCleanFiles(List : TStrings; const APrefixU, APrefixB : String; ACPU:TCPU; AOS : TOS); virtual;
     Procedure GetInstallFiles(List : TStrings; const APrefixU, APrefixB: String; ACPU:TCPU; AOS : TOS); virtual;
     Procedure GetInstallFiles(List : TStrings; const APrefixU, APrefixB: String; ACPU:TCPU; AOS : TOS); virtual;
@@ -395,7 +404,7 @@ Type
     Property OSes : TOSes Read FOSes Write FOSes;
     Property OSes : TOSes Read FOSes Write FOSes;
     Property CPUs : TCPUs Read FCPUs Write FCPUs;
     Property CPUs : TCPUs Read FCPUs Write FCPUs;
     Property Mode : TCompilerMode Read FMode Write FMode;
     Property Mode : TCompilerMode Read FMode Write FMode;
-    Property Options : String Read FOptions Write Foptions;
+    Property Options : TStrings Read GetOptions Write SetOptions;
     Property SourceFileName: String Read GetSourceFileName ;
     Property SourceFileName: String Read GetSourceFileName ;
     Property UnitFileName : String Read GetUnitFileName;
     Property UnitFileName : String Read GetUnitFileName;
     Property ObjectFileName : String Read GetObjectFileName;
     Property ObjectFileName : String Read GetObjectFileName;
@@ -515,7 +524,7 @@ Type
     FTargets: TTargets;
     FTargets: TTargets;
     FSources: TSources;
     FSources: TSources;
     FDirectory: String;
     FDirectory: String;
-    FOptions: String;
+    FOptions: TStrings;
     FFileName: String;
     FFileName: String;
     FAuthor: String;
     FAuthor: String;
     FLicense: String;
     FLicense: String;
@@ -532,7 +541,9 @@ Type
     FUnitDir : String;
     FUnitDir : String;
     Function GetDescription : string;
     Function GetDescription : string;
     Function GetFileName : string;
     Function GetFileName : string;
+    function GetOptions: TStrings;
     Function GetVersion : string;
     Function GetVersion : string;
+    procedure SetOptions(const AValue: TStrings);
     Procedure SetVersion(const V : string);
     Procedure SetVersion(const V : string);
   Protected
   Protected
     procedure SetName(const AValue: String);override;
     procedure SetName(const AValue: String);override;
@@ -541,6 +552,7 @@ Type
   Public
   Public
     constructor Create(ACollection: TCollection); override;
     constructor Create(ACollection: TCollection); override;
     destructor destroy; override;
     destructor destroy; override;
+    Function HaveOptions : Boolean;
     Function  GetUnitsOutputDir(ACPU:TCPU; AOS : TOS):String;
     Function  GetUnitsOutputDir(ACPU:TCPU; AOS : TOS):String;
     Function  GetBinOutputDir(ACPU:TCPU; AOS : TOS) : String;
     Function  GetBinOutputDir(ACPU:TCPU; AOS : TOS) : String;
     Procedure GetCleanFiles(List : TStrings; ACPU:TCPU; AOS : TOS); virtual;
     Procedure GetCleanFiles(List : TStrings; ACPU:TCPU; AOS : TOS); virtual;
@@ -562,7 +574,7 @@ Type
     Property OSes : TOSes Read FOSes Write FOSes;
     Property OSes : TOSes Read FOSes Write FOSes;
     Property CPUs : TCPUs Read FCPUs Write FCPUs;
     Property CPUs : TCPUs Read FCPUs Write FCPUs;
     Property NeedLibC : Boolean Read FNeedLibC Write FNeedLibC;
     Property NeedLibC : Boolean Read FNeedLibC Write FNeedLibC;
-    Property Options: String Read FOptions Write FOptions;
+    Property Options: TStrings Read GetOptions Write SetOptions;
     Property UnitPath : TConditionalStrings Read FUnitPath;
     Property UnitPath : TConditionalStrings Read FUnitPath;
     Property ObjectPath : TConditionalStrings Read FObjectPath;
     Property ObjectPath : TConditionalStrings Read FObjectPath;
     Property IncludePath : TConditionalStrings Read FIncludePath;
     Property IncludePath : TConditionalStrings Read FIncludePath;
@@ -613,7 +625,7 @@ Type
     FCopy: String;
     FCopy: String;
     FMkDir: String;
     FMkDir: String;
     FMove: String;
     FMove: String;
-    FOptions: String;
+    FOptions: TStrings;
     FCPU: TCPU;
     FCPU: TCPU;
     FOS: TOS;
     FOS: TOS;
     FMode : TCompilerMode;
     FMode : TCompilerMode;
@@ -637,19 +649,23 @@ Type
     function GetCompiler: String;
     function GetCompiler: String;
     function GetDocInstallDir: String;
     function GetDocInstallDir: String;
     function GetExamplesInstallDir: String;
     function GetExamplesInstallDir: String;
+    function GetOptions: TStrings;
     function GetUnitInstallDir: String;
     function GetUnitInstallDir: String;
     procedure SetLocalUnitDir(const AValue: String);
     procedure SetLocalUnitDir(const AValue: String);
     procedure SetGlobalUnitDir(const AValue: String);
     procedure SetGlobalUnitDir(const AValue: String);
     procedure SetBaseInstallDir(const AValue: String);
     procedure SetBaseInstallDir(const AValue: String);
     procedure SetCPU(const AValue: TCPU);
     procedure SetCPU(const AValue: TCPU);
+    procedure SetOptions(const AValue: TStrings);
     procedure SetOS(const AValue: TOS);
     procedure SetOS(const AValue: TOS);
     procedure SetPrefix(const AValue: String);
     procedure SetPrefix(const AValue: String);
     procedure SetTarget(const AValue: String);
     procedure SetTarget(const AValue: String);
   Protected
   Protected
     procedure RecalcTarget;
     procedure RecalcTarget;
+    Function CmdLineOptions : String;
   Public
   Public
     Constructor Create;
     Constructor Create;
     Procedure InitDefaults;
     Procedure InitDefaults;
+    Function HaveOptions: Boolean;
     procedure CompilerDefaults; virtual;
     procedure CompilerDefaults; virtual;
     Procedure LocalInit(Const AFileName : String);
     Procedure LocalInit(Const AFileName : String);
     Procedure LoadFromFile(Const AFileName : String);
     Procedure LoadFromFile(Const AFileName : String);
@@ -662,7 +678,7 @@ Type
     Property CPU : TCPU Read FCPU Write SetCPU;
     Property CPU : TCPU Read FCPU Write SetCPU;
     Property Mode : TCompilerMode Read FMode Write FMode;
     Property Mode : TCompilerMode Read FMode Write FMode;
     Property UnixPaths : Boolean Read FUnixPaths Write FUnixPaths;
     Property UnixPaths : Boolean Read FUnixPaths Write FUnixPaths;
-    Property Options : String Read FOptions Write FOptions;    // Default compiler options.
+    Property Options : TStrings Read GetOptions Write SetOptions;    // Default compiler options.
     Property NoFPCCfg : Boolean Read FNoFPCCfg Write FNoFPCCfg;
     Property NoFPCCfg : Boolean Read FNoFPCCfg Write FNoFPCCfg;
     // paths etc.
     // paths etc.
     Property LocalUnitDir : String Read GetLocalUnitDir Write SetLocalUnitDir;
     Property LocalUnitDir : String Read GetLocalUnitDir Write SetLocalUnitDir;
@@ -1435,13 +1451,12 @@ begin
     List[i] := ExtractRelativepath(IncludeTrailingPathDelimiter(CurrDir), List[i]);
     List[i] := ExtractRelativepath(IncludeTrailingPathDelimiter(CurrDir), List[i]);
 end;
 end;
 
 
-
-procedure SplitCommand(const Cmd : String; var Exe, Options : String);
-
 Const
 Const
   WhiteSpace = [#9,#10,#13,' '];
   WhiteSpace = [#9,#10,#13,' '];
   QuoteChars = ['''','"'];
   QuoteChars = ['''','"'];
 
 
+procedure SplitCommand(const Cmd : String; var Exe, Options : String);
+
 Var
 Var
   I : Integer;
   I : Integer;
   InQuote : Boolean;
   InQuote : Boolean;
@@ -1470,6 +1485,46 @@ begin
   Options:=Trim(S);
   Options:=Trim(S);
 end;
 end;
 
 
+Function OptionListToString(L : TStrings) : String;
+
+var
+  I : Integer;
+  S : String;
+
+begin
+  Result:='';
+  For I:=0 to L.Count-1 do
+    begin
+    If (Result<>'') then
+      Result:=Result+' ';
+    S:=L[I];
+    If (Pos(' ',S)<>0) or (S='') then
+     Result:='"'+S+'"';
+    end;
+end;
+
+Function OptionsToStringList(S : String) : TStrings;
+
+Var
+  P : Integer;
+
+begin
+  Result:=Nil;
+  If (S='') then
+    Exit;
+  Result:=TStringList.Create;
+  Repeat
+    P:=Pos(' ',S);
+    If P=0 then
+      P:=Length(S)+1;
+    Result.Add(Copy(S,1,P-1));
+    Delete(S,1,P);
+    S:=Trim(S);
+  Until Length(S)=0;
+  If Result.Count=0 then
+    FreeAndNil(Result);
+end;
+
 
 
 {$ifdef HAS_UNIT_PROCESS}
 {$ifdef HAS_UNIT_PROCESS}
 function GetCompilerInfo(const ACompiler,AOptions:string):string;
 function GetCompilerInfo(const ACompiler,AOptions:string):string;
@@ -1883,9 +1938,15 @@ begin
   FreeAndNil(FSources);
   FreeAndNil(FSources);
   FreeAndNil(FTargets);
   FreeAndNil(FTargets);
   FreeAndNil(FVersion);
   FreeAndNil(FVersion);
+  FreeAndNil(FOptions);
   inherited destroy;
   inherited destroy;
 end;
 end;
 
 
+function TPackage.HaveOptions: Boolean;
+begin
+  Result:=(FOptions<>Nil);
+end;
+
 
 
 procedure TPackage.SetName(const AValue: String);
 procedure TPackage.SetName(const AValue: String);
 begin
 begin
@@ -1981,6 +2042,14 @@ begin
   result:=FVersion.AsString;
   result:=FVersion.AsString;
 end;
 end;
 
 
+procedure TPackage.SetOptions(const AValue: TStrings);
+begin
+  If (AValue=Nil) or (AValue.Count=0) then
+    FreeAndNil(Foptions)
+  else
+    Options.Assign(AValue);
+end;
+
 
 
 Procedure TPackage.SetVersion(const V : string);
 Procedure TPackage.SetVersion(const V : string);
 begin
 begin
@@ -1999,6 +2068,13 @@ begin
       Result := Name;
       Result := Name;
 end;
 end;
 
 
+function TPackage.GetOptions: TStrings;
+begin
+  If (FOptions=Nil) then
+    FOptions:=TStringList.Create;
+  Result:=FOptions;
+end;
+
 
 
 Procedure TPackage.GetManifest(Manifest : TStrings);
 Procedure TPackage.GetManifest(Manifest : TStrings);
 
 
@@ -2204,6 +2280,14 @@ begin
   RecalcTarget;
   RecalcTarget;
 end;
 end;
 
 
+procedure TCustomDefaults.SetOptions(const AValue: TStrings);
+begin
+  If (AValue=Nil) or (AValue.Count=0) then
+    FreeAndNil(Foptions)
+  else
+    Options.Assign(AValue)
+end;
+
 
 
 function TCustomDefaults.GetBaseInstallDir: String;
 function TCustomDefaults.GetBaseInstallDir: String;
 begin
 begin
@@ -2261,6 +2345,13 @@ begin
       Result:=BaseInstallDir+'examples';
       Result:=BaseInstallDir+'examples';
 end;
 end;
 
 
+function TCustomDefaults.GetOptions: TStrings;
+begin
+  If (FOptions=Nil) then
+    FOptions:=TStringList.Create;
+  Result:=FOptions;
+end;
+
 
 
 function TCustomDefaults.GetUnitInstallDir: String;
 function TCustomDefaults.GetUnitInstallDir: String;
 begin
 begin
@@ -2361,6 +2452,12 @@ begin
   Ftarget:=CPUToString(FCPU)+'-'+OStoString(FOS);
   Ftarget:=CPUToString(FCPU)+'-'+OStoString(FOS);
 end;
 end;
 
 
+function TCustomDefaults.CmdLineOptions: String;
+begin
+  If Haveoptions then
+    Result:=OptionListToString(FOptions);
+end;
+
 
 
 constructor TCustomDefaults.Create;
 constructor TCustomDefaults.Create;
 begin
 begin
@@ -2380,6 +2477,11 @@ begin
   FOS:=osNone;
   FOS:=osNone;
 end;
 end;
 
 
+function TCustomDefaults.HaveOptions: Boolean;
+begin
+  Result:=Assigned(FOptions);
+end;
+
 
 
 procedure TCustomDefaults.LocalInit(Const AFileName : String);
 procedure TCustomDefaults.LocalInit(Const AFileName : String);
 Var
 Var
@@ -2486,7 +2588,7 @@ begin
       Values[KeyCopy]:=FCopy;
       Values[KeyCopy]:=FCopy;
       Values[KeyMkDir]:=FMkDir;
       Values[KeyMkDir]:=FMkDir;
       Values[KeyMove]:=FMove;
       Values[KeyMove]:=FMove;
-      Values[KeyOptions]:=FOptions;
+      Values[KeyOptions]:=CmdLineOptions;
       Values[KeyCPU]:=CPUToString(FCPU);
       Values[KeyCPU]:=CPUToString(FCPU);
       Values[KeyOS]:=OSToString(FOS);
       Values[KeyOS]:=OSToString(FOS);
       Values[KeyMode]:=ModeToString(FMode);
       Values[KeyMode]:=ModeToString(FMode);
@@ -2538,7 +2640,7 @@ begin
       FMkDir:=Values[KeyMkDir];
       FMkDir:=Values[KeyMkDir];
       FMove:=Values[KeyMove];
       FMove:=Values[KeyMove];
       FRemove:=Values[KeyRemove];
       FRemove:=Values[KeyRemove];
-      FOptions:=Values[KeyOptions];
+      Options:=OptionsToStringList(Values[KeyOptions]);
       Line:=Values[KeyCPU];
       Line:=Values[KeyCPU];
       If (Line<>'') then
       If (Line<>'') then
         FCPU:=StringToCPU(Line);
         FCPU:=StringToCPU(Line);
@@ -3228,7 +3330,7 @@ begin
             begin
             begin
             If Assigned(C.BeforeCommand) then
             If Assigned(C.BeforeCommand) then
               C.BeforeCommand(C);
               C.BeforeCommand(C);
-            O:=Substitute(C.Options,['SOURCE',C.SourceFile,'DEST',C.DestFile]);
+            O:=Substitute(C.CmdLineOptions,['SOURCE',C.SourceFile,'DEST',C.DestFile]);
             Cmd:=C.Command;
             Cmd:=C.Command;
             If (ExtractFilePath(Cmd)='') then
             If (ExtractFilePath(Cmd)='') then
               Cmd:=ExeSearch(Cmd,GetEnvironmentvariable('PATH'));
               Cmd:=ExeSearch(Cmd,GetEnvironmentvariable('PATH'));
@@ -3556,12 +3658,12 @@ begin
     Args.Add('-Fi'+L[i]);
     Args.Add('-Fi'+L[i]);
   FreeAndNil(L);
   FreeAndNil(L);
   // Custom Options
   // Custom Options
-  If (Defaults.Options<>'') then
-    Args.Add(Defaults.Options);
-  If (APackage.Options<>'') then
-    Args.Add(APackage.Options);
-  If (ATarget.Options<>'') then
-    Args.Add(ATarget.Options);
+  If (Defaults.HaveOptions) then
+    Args.AddStrings(Defaults.Options);
+  If (APackage.HaveOptions) then
+    Args.AddStrings(APackage.Options);
+  If (ATarget.HaveOptions) then
+    Args.AddStrings(ATarget.Options);
   // Add Filename to compile
   // Add Filename to compile
   Args.Add(ATarget.TargetSourceFileName);
   Args.Add(ATarget.TargetSourceFileName);
   // Convert to string
   // Convert to string
@@ -4432,9 +4534,24 @@ begin
   FreeAndNil(FIncludePath);
   FreeAndNil(FIncludePath);
   FreeAndNil(FDependencies);
   FreeAndNil(FDependencies);
   FreeAndNil(FCommands);
   FreeAndNil(FCommands);
+  FreeAndNil(Foptions);
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
+function TTarget.GetOptions: TStrings;
+begin
+  If Foptions=Nil then
+    FOptions:=TStringList.Create;
+  Result:=FOptions;
+end;
+
+procedure TTarget.SetOptions(const AValue: TStrings);
+begin
+  If (AValue=Nil) or (AValue.Count=0) then
+    FreeAndNil(FOptions)
+  else
+    Options.Assign(AValue);
+end;
 
 
 function TTarget.GetSourceFileName: String;
 function TTarget.GetSourceFileName: String;
 begin
 begin
@@ -4477,6 +4594,11 @@ begin
     Result:=GetProgramFileName(AOs);
     Result:=GetProgramFileName(AOs);
 end;
 end;
 
 
+function TTarget.HaveOptions: Boolean;
+begin
+  Result:=(FOptions<>Nil);
+end;
+
 
 
 procedure TTarget.SetName(const AValue: String);
 procedure TTarget.SetName(const AValue: String);
 Var
 Var
@@ -4615,7 +4737,8 @@ function TCommands.AddCommand(At: TCommandAt; const Cmd, Options, Dest, Source:
 begin
 begin
   Result:=Add as TCommand;
   Result:=Add as TCommand;
   Result.Command:=Cmd;
   Result.Command:=Cmd;
-  Result.Options:=Options;
+  If (Options<>'') then
+    Result.ParseOptions(Options);
   Result.At:=At;
   Result.At:=At;
   Result.SourceFile:=Source;
   Result.SourceFile:=Source;
   Result.DestFile:=Dest;
   Result.DestFile:=Dest;
@@ -4972,7 +5095,6 @@ begin
     end;
     end;
 end;
 end;
 
 
-
 {****************************************************************************
 {****************************************************************************
                                  Default Instances
                                  Default Instances
 ****************************************************************************}
 ****************************************************************************}
@@ -4994,6 +5116,48 @@ begin
 end;
 end;
 
 
 
 
+
+{ TCommand }
+
+function TCommand.GetOptions: TStrings;
+begin
+  If (FOptions=Nil) then
+    FOptions:=TStringList.Create;
+  Result:=FOptions;
+end;
+
+procedure TCommand.SetOptions(const Value: TStrings);
+begin
+  If (Value=Nil) or (Value.Count=0) then
+    FreeAndNil(FOptions)
+  else
+    Options.Assign(Value);
+end;
+
+destructor TCommand.Destroy;
+begin
+  FreeAndNil(FOptions);
+  inherited Destroy;
+end;
+
+function TCommand.HaveOptions: Boolean;
+begin
+  Result:=(FOptions<>Nil);
+end;
+
+
+function TCommand.CmdLineOptions: String;
+begin
+  If HaveOptions then
+    Result:=OptionListToString(Options);
+end;
+
+procedure TCommand.ParseOptions(S: String);
+
+begin
+  Options:=OptionsToStringList(S);
+end;
+
 Initialization
 Initialization
   OnGetApplicationName:=@GetFPMakeName;
   OnGetApplicationName:=@GetFPMakeName;
 
 

+ 3 - 2
packages/gdbint/src/gdbint.pp

@@ -459,6 +459,9 @@ type
     last_breakpoint_line : longint;
     last_breakpoint_line : longint;
     last_breakpoint_file : pchar;
     last_breakpoint_file : pchar;
     invalid_breakpoint_line : boolean;
     invalid_breakpoint_line : boolean;
+    user_screen_shown,
+    switch_to_user     : boolean;
+
     { init }
     { init }
     constructor init;
     constructor init;
     destructor  done;
     destructor  done;
@@ -475,8 +478,6 @@ type
     function  set_current_frame(level : longint) : boolean;
     function  set_current_frame(level : longint) : boolean;
     procedure clear_frames;
     procedure clear_frames;
     { Highlevel }
     { Highlevel }
-    user_screen_shown,
-    switch_to_user     : boolean;
     procedure GetAddrSyminfo(addr:ptrint;var si:tsyminfo);
     procedure GetAddrSyminfo(addr:ptrint;var si:tsyminfo);
     procedure SelectSourceline(fn:pchar;line:longint);
     procedure SelectSourceline(fn:pchar;line:longint);
     procedure StartSession;
     procedure StartSession;

+ 4 - 2
packages/graph/src/inc/fills.inc

@@ -78,9 +78,11 @@ begin
     p0 := ptable[i];
     p0 := ptable[i];
     if (i+1) >= numpoints then p1 := ptable[0]
     if (i+1) >= numpoints then p1 := ptable[0]
     else p1 := ptable[i+1];
     else p1 := ptable[i+1];
+   { draw the edges }
+    Line(p0.x,p0.y,p1.x,p1.y);
    { ignore if this is a horizontal edge}
    { ignore if this is a horizontal edge}
     if (p0.y = p1.y) then continue;
     if (p0.y = p1.y) then continue;
-    {swap ptable if necessary to ensure p0 contains yMin}
+   { swap ptable if necessary to ensure p0 contains yMin}
     if (p0.y > p1.y) then begin
     if (p0.y > p1.y) then begin
       p0 := p1;
       p0 := p1;
       p1 := ptable[i];
       p1 := ptable[i];
@@ -169,7 +171,7 @@ begin
       x0 := AET^[i]^.x;
       x0 := AET^[i]^.x;
       x1 := AET^[i+1]^.x;
       x1 := AET^[i+1]^.x;
       {Left edge adjustment for positive fraction.  0 is interior. }
       {Left edge adjustment for positive fraction.  0 is interior. }
-      if (AET^[i]^.frac > 0) then inc(x0);
+      if (AET^[i]^.frac >= 0) then inc(x0);
       {Right edge adjustment for negative fraction.  0 is exterior. }
       {Right edge adjustment for negative fraction.  0 is exterior. }
       if (AET^[i+1]^.frac <= 0) then dec(x1);
       if (AET^[i+1]^.frac <= 0) then dec(x1);
 
 

+ 18 - 15
packages/graph/src/inc/graph.inc

@@ -466,7 +466,7 @@ var
                     { with predefined line patterns...                 }
                     { with predefined line patterns...                 }
                     if LinePatterns[PixelCount and 15] = TRUE then
                     if LinePatterns[PixelCount and 15] = TRUE then
                       begin
                       begin
-                    DirectPutPixel(x1,PixelCount);
+                        DirectPutPixel(x1,PixelCount);
                       end;
                       end;
               end
               end
             else
             else
@@ -590,7 +590,7 @@ var
              begin
              begin
                   if LinePatterns[i and 15] = TRUE then
                   if LinePatterns[i and 15] = TRUE then
                     begin
                     begin
-                          DirectPutPixel(x,y);
+                      DirectPutPixel(x,y);
                     end;
                     end;
              if d < 0 then
              if d < 0 then
                  begin
                  begin
@@ -843,24 +843,29 @@ var
              Begin
              Begin
                for j:=0 to 7 do
                for j:=0 to 7 do
                     Begin
                     Begin
-                            { x1 mod 8 }
+                    { x1 mod 8 }
                     if RevBitArray[x1 and 7] and TmpFillPattern <> 0 then
                     if RevBitArray[x1 and 7] and TmpFillPattern <> 0 then
-                       DirectPutpixel(x1,y)
+                      begin
+                        OldCurrentColor := CurrentColor;
+                        CurrentColor := FillSettings.Color;
+                        DirectPutpixel(x1,y);
+                        CurrentColor := OldCurrentColor;
+                      end
                     else
                     else
                       begin
                       begin
-                            { According to the TP graph manual, we overwrite everything }
-                            { which is filled up - checked against VGA and CGA drivers  }
-                            { of TP.                                                    }
-                            OldCurrentColor := CurrentColor;
-                            CurrentColor := CurrentBkColor;
-                            DirectPutPixel(x1,y);
-                            CurrentColor := OldCurrentColor;
+                        { According to the TP graph manual, we overwrite everything }
+                        { which is filled up - checked against VGA and CGA drivers  }
+                        { of TP.                                                    }
+                        OldCurrentColor := CurrentColor;
+                        CurrentColor := CurrentBkColor;
+                        DirectPutPixel(x1,y);
+                        CurrentColor := OldCurrentColor;
                       end;
                       end;
                     Inc(x1);
                     Inc(x1);
                     if x1 > x2 then
                     if x1 > x2 then
                      begin
                      begin
-                           CurrentWriteMode := OldWriteMode;
-                           exit;
+                       CurrentWriteMode := OldWriteMode;
+                       exit;
                      end;
                      end;
                    end;
                    end;
              end;
              end;
@@ -870,8 +875,6 @@ var
    end;
    end;
 
 
 
 
-
-
   procedure LineRel(Dx, Dy: smallint);
   procedure LineRel(Dx, Dy: smallint);
 
 
    Begin
    Begin

+ 7 - 5
packages/gtk2/src/gtk+/gdk/gdkevents.inc

@@ -455,11 +455,13 @@ const
    GDK_SCROLL_MASK              = 1 shl 21;
    GDK_SCROLL_MASK              = 1 shl 21;
    GDK_ALL_EVENTS_MASK          = $3FFFFE;
    GDK_ALL_EVENTS_MASK          = $3FFFFE;
 
 
-   GDK_WINDOW_STATE_WITHDRAWN = 1 shl 0;
-   GDK_WINDOW_STATE_ICONIFIED = 1 shl 1;
-   GDK_WINDOW_STATE_MAXIMIZED = 1 shl 2;
-   GDK_WINDOW_STATE_STICKY    = 1 shl 3;
-
+   GDK_WINDOW_STATE_WITHDRAWN  = 1 shl 0;
+   GDK_WINDOW_STATE_ICONIFIED  = 1 shl 1;
+   GDK_WINDOW_STATE_MAXIMIZED  = 1 shl 2;
+   GDK_WINDOW_STATE_STICKY     = 1 shl 3;
+   GDK_WINDOW_STATE_FULLSCREEN = 1 shl 4;
+   GDK_WINDOW_STATE_ABOVE      = 1 shl 5;
+   GDK_WINDOW_STATE_BELOW      = 1 shl 6;
 
 
 function gdk_event_get_type:GType; cdecl; external gdklib;
 function gdk_event_get_type:GType; cdecl; external gdklib;
 function gdk_events_pending:gboolean; cdecl; external gdklib;
 function gdk_events_pending:gboolean; cdecl; external gdklib;

+ 9 - 1
packages/iconvenc/src/iconvert.inc

@@ -49,7 +49,15 @@ begin
 
 
     // iconv has a buffer that needs flushing, specially if the last char is not #0
     // iconv has a buffer that needs flushing, specially if the last char is not #0
     iconv(H, nil, nil, @Dst, @Outlen);
     iconv(H, nil, nil, @Dst, @Outlen);
-
+    lerr:=cerrno;
+    if (iconvres=Cint(-1)) and (lerr=ESysE2BIG) then
+      begin
+        Offset:=Dst-PChar(Res);
+        SetLength(Res, Length(Res)+InLen*2+5); // 5 is minimally one utf-8 char
+        Dst:=PChar(Res)+Offset;
+        OutLen:=Length(Res)-Offset;
+        iconv(H, nil, nil, @Dst, @Outlen);
+      end;
     // trim output buffer
     // trim output buffer
     SetLength(Res, Length(Res) - Outlen);
     SetLength(Res, Length(Res) - Outlen);
   finally
   finally

+ 3 - 2
packages/libxml/src/xml2.pas

@@ -22,6 +22,7 @@ const
 {$IF Defined(WINDOWS)}
 {$IF Defined(WINDOWS)}
   xml2lib = 'libxml2.'+sharedsuffix;
   xml2lib = 'libxml2.'+sharedsuffix;
   {$DEFINE EXTDECL := cdecl}
   {$DEFINE EXTDECL := cdecl}
+  {$DEFINE NO_EXTERNAL_VARS}
 {$ELSEIF Defined(UNIX)}
 {$ELSEIF Defined(UNIX)}
   xml2lib = 'libxml2.'+sharedsuffix;
   xml2lib = 'libxml2.'+sharedsuffix;
   {$DEFINE EXTDECL := cdecl}
   {$DEFINE EXTDECL := cdecl}
@@ -264,7 +265,7 @@ begin
   Result := not assigned(ns) or (ns^.nodeNr = 0) or (ns^.nodeTab = nil);
   Result := not assigned(ns) or (ns^.nodeNr = 0) or (ns^.nodeTab = nil);
 end;
 end;
 
 
-{$IFDEF WINDOWS}
+{$IFDEF NO_EXTERNAL_VARS}
 procedure LoadExternalVariables;
 procedure LoadExternalVariables;
 var
 var
   libHandle: THandle;
   libHandle: THandle;
@@ -311,7 +312,7 @@ end;
 {$ENDIF}
 {$ENDIF}
 
 
 initialization
 initialization
-{$IFDEF WINDOWS}
+{$IFDEF NO_EXTERNAL_VARS}
   LoadExternalVariables;
   LoadExternalVariables;
 {$ENDIF}
 {$ENDIF}
 
 

+ 25 - 0
packages/mysql/src/mysql.inc

@@ -540,6 +540,31 @@ uses
 {  ------------ Stop of declaration in "mysql_com.h"   -----------------------  }
 {  ------------ Stop of declaration in "mysql_com.h"   -----------------------  }
 
 
 { $include "mysql_time.h"}
 { $include "mysql_time.h"}
+    type
+        mysql_timestamp_type = (
+          MYSQL_TIMESTAMP_NONE = -2,
+          MYSQL_TIMESTAMP_ERROR = -1,
+          MYSQL_TIMESTAMP_DATE = 0,
+          MYSQL_TIMESTAMP_DATETIME = 1,
+          MYSQL_TIMESTAMP_TIME = 2
+        );
+
+        Pst_mysql_time = ^st_mysql_time;
+        st_mysql_time = record
+          year:        cuint;
+          month:       cuint;
+          day:         cuint;
+          hour:        cuint;
+          minute:      cuint;
+          second:      cuint;
+          second_part: culong;
+          neg:         my_bool;
+          time_type:   mysql_timestamp_type;
+        end;
+
+        PMYSQL_TIME = ^MYSQL_TIME;
+        MYSQL_TIME = st_mysql_time;
+
 { $include "mysql_version.h"}
 { $include "mysql_version.h"}
 { $include "typelib.h"}
 { $include "typelib.h"}
 { $include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */}
 { $include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */}

+ 11 - 3
packages/objcrtl/src/objcrtlutils.pas

@@ -28,6 +28,11 @@ function super(obj: id): objc_super;
 
 
 implementation
 implementation
 
 
+var
+  SEL_alloc   : SEL = nil;
+  SEL_init    : SEL = nil;
+  SEL_release : SEL = nil;
+
 function super(obj: id): objc_super;
 function super(obj: id): objc_super;
 begin
 begin
   Result.reciever := obj;
   Result.reciever := obj;
@@ -57,17 +62,20 @@ end;
 
 
 procedure release(objc: id); inline;
 procedure release(objc: id); inline;
 begin
 begin
-  objc_msgSend(objc, selector('release'), []);
+  if SEL_release=nil then SEL_release := selector('release');
+  objc_msgSend(objc, SEL_release, []);
 end;
 end;
 
 
 function AllocAndInit(classname: PChar): id; inline;
 function AllocAndInit(classname: PChar): id; inline;
 begin
 begin
-  Result:= objc_msgSend( alloc( classname ), selector('init'), []);
+  if SEL_init=nil then SEL_init := selector('init');
+  Result:= objc_msgSend( alloc( classname ), SEL_init, []);
 end;
 end;
 
 
 function AllocAndInitEx(classname: PChar; extraBytes: Integer): id; inline;
 function AllocAndInitEx(classname: PChar; extraBytes: Integer): id; inline;
 begin
 begin
-  Result := objc_msgSend( allocEx( classname, extraBytes ), selector('init'), []);
+  if SEL_init=nil then SEL_init := selector('init');
+  Result := objc_msgSend( allocEx( classname, extraBytes ), SEL_init, []);
 end;
 end;
 
 
 
 

+ 59 - 59
packages/winunits-base/Makefile

@@ -1,5 +1,5 @@
 #
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2009/05/10]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2009/06/04]
 #
 #
 default: all
 default: all
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian 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 sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded
 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 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 sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded
@@ -439,178 +439,178 @@ ifeq ($(FULL_TARGET),armeb-embedded)
 override TARGET_UNITS+=buildwinutilsbase
 override TARGET_UNITS+=buildwinutilsbase
 endif
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme
+override TARGET_IMPLICITUNITS+=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 endif
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
 override TARGET_RSTS+=jwawintype comconst
 override TARGET_RSTS+=jwawintype comconst

+ 1 - 1
packages/winunits-base/Makefile.fpc

@@ -9,7 +9,7 @@ version=2.2.2
 [target]
 [target]
 units=buildwinutilsbase
 units=buildwinutilsbase
 implicitunits=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver \
 implicitunits=flatsb winver mmsystem comobj comconst commdlg commctrl ole2 activex shellapi shlobj oleserver \
-               shfolder richedit imagehlp wininet uxtheme
+               shfolder richedit imagehlp wininet uxtheme dwmapi multimon htmlhelp
 
 
 examples=examples
 examples=examples
 
 

+ 6 - 0
packages/winunits-base/fpmake.pp

@@ -49,6 +49,9 @@ begin
 	  AddUnit('wininet');
 	  AddUnit('wininet');
           AddUnit('uxtheme');  
           AddUnit('uxtheme');  
           AddInclude('tmschema.inc');
           AddInclude('tmschema.inc');
+          AddUnit('dwmapi');
+          AddUnit('multimon');
+          AddUnit('htmlhelp');
         end;
         end;
     T:=P.Targets.AddImplicitUnit('activex.pp');
     T:=P.Targets.AddImplicitUnit('activex.pp');
     T:=P.Targets.AddImplicitUnit('comconst.pp');
     T:=P.Targets.AddImplicitUnit('comconst.pp');
@@ -69,6 +72,9 @@ begin
     T:=P.Targets.AddImplicitUnit('commdlg.pp');
     T:=P.Targets.AddImplicitUnit('commdlg.pp');
     T:=P.Targets.AddImplicitUnit('wininet.pp');
     T:=P.Targets.AddImplicitUnit('wininet.pp');
     T:=P.Targets.AddImplicitUnit('uxtheme.pp');
     T:=P.Targets.AddImplicitUnit('uxtheme.pp');
+    T:=P.Targets.AddImplicitUnit('multimon.pp');
+    T:=P.Targets.AddImplicitUnit('dwmapi.pp');
+    T:=P.Targets.AddImplicitUnit('htmlhelp.pp');
     T.Dependencies.AddInclude('tmschema.inc');
     T.Dependencies.AddInclude('tmschema.inc');
     P.ExamplePath.Add('tests/');
     P.ExamplePath.Add('tests/');
     P.Targets.AddExampleProgram('testcom1.pp');
     P.Targets.AddExampleProgram('testcom1.pp');

+ 2 - 2
packages/winunits-base/src/activex.pp

@@ -2036,7 +2036,7 @@ TYPE
      IEnumUnknown = Interface(IUnknown)
      IEnumUnknown = Interface(IUnknown)
         ['{00000100-0000-0000-C000-000000000046}']
         ['{00000100-0000-0000-C000-000000000046}']
         //    pointer_default(unique)
         //    pointer_default(unique)
-     Function Next(Celt:Ulong;out rgelt:IUnknown;out pCeltFetched:pulong):HRESULT;StdCall;
+     Function Next(Celt:Ulong;out rgelt;out pCeltFetched:pulong):HRESULT;StdCall;
 //    HRESULT RemoteNext(        [in] ULONG celt,        [out, size_is(celt), length_is( *pceltFetched)]        IUnknown **rgelt,        [out] ULONG *pceltFetched);
 //    HRESULT RemoteNext(        [in] ULONG celt,        [out, size_is(celt), length_is( *pceltFetched)]        IUnknown **rgelt,        [out] ULONG *pceltFetched);
      Function Skip(Celt:Ulong):HResult;StdCall;
      Function Skip(Celt:Ulong):HResult;StdCall;
      Function Reset():HResult;
      Function Reset():HResult;
@@ -2940,7 +2940,7 @@ TYPE
      Function  FindName(szNameBuf: pOleStr; lHashVal: ULONG; OUT ppTInfo: ITypeInfo; OUT rgMemId: MEMBERID; VAR pcFound: USHORT; OUT pBstrLibName: WideString):HResult;StdCall;
      Function  FindName(szNameBuf: pOleStr; lHashVal: ULONG; OUT ppTInfo: ITypeInfo; OUT rgMemId: MEMBERID; VAR pcFound: USHORT; OUT pBstrLibName: WideString):HResult;StdCall;
      {$endif}
      {$endif}
      {$ifndef Call_as}
      {$ifndef Call_as}
-      Procedure ReleaseTLibAttr(Const pTLibAttr : TLIBATTR); StdCall;
+      Procedure ReleaseTLibAttr( pTLibAttr : LPTLIBATTR); StdCall;
       {$else}
       {$else}
      Function  LocalReleaseTLibAttr:HResult;StdCall;
      Function  LocalReleaseTLibAttr:HResult;StdCall;
      {$endif}
      {$endif}

+ 2 - 1
packages/winunits-base/src/buildwinutilsbase.pp

@@ -22,7 +22,8 @@ interface
 
 
 uses
 uses
     flatsb, winver, mmsystem, comconst, commctrl, comobj, commdlg,
     flatsb, winver, mmsystem, comconst, commctrl, comobj, commdlg,
-    ole2, activex, shellapi, shlobj, oleserver,  shfolder, richedit,imagehlp,wininet,uxtheme;
+    ole2, activex, shellapi, shlobj, oleserver,  shfolder, richedit,
+    imagehlp, wininet, uxtheme, dwmapi, multimon, htmlhelp;
 
 
 implementation
 implementation
 
 

+ 525 - 0
packages/winunits-base/src/dwmapi.pp

@@ -0,0 +1,525 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2009 by the Free Pascal development team
+    member of the Free Pascal development team.
+
+    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.
+
+ **********************************************************************}
+{*=========================================================================*
+
+    Copyright (c) Microsoft Corporation.  All rights reserved.
+
+    File: dwmapi.h
+
+    Module Name: dwmapi
+
+    Description: DWM API declarations
+
+ *=========================================================================*}
+unit DwmApi;
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Windows, UxTheme;
+
+procedure FreeDwmLibrary;
+function InitDwmLibrary: Boolean;
+function DwmCompositionEnabled: Boolean;
+
+// Blur behind data structures
+const
+  DWM_BB_ENABLE                = $00000001; // fEnable has been specified
+  DWM_BB_BLURREGION            = $00000002; // hRgnBlur has been specified
+  DWM_BB_TRANSITIONONMAXIMIZED = $00000004; // fTransitionOnMaximized has been specified
+
+type
+  _DWM_BLURBEHIND = record
+    dwFlags: DWORD;
+    fEnable: BOOL;
+    hRgnBlur: HRGN;
+    fTransitionOnMaximized: BOOL;
+  end;
+  DWM_BLURBEHIND = _DWM_BLURBEHIND;
+  PDWM_BLURBEHIND = ^_DWM_BLURBEHIND;
+  TDWMBlurBehind = DWM_BLURBEHIND;
+  PDWMBlurBehind = PDWM_BLURBEHIND;
+
+// Window attributes
+const
+  DWMWA_NCRENDERING_ENABLED         = 01; // [get] Is non-client rendering enabled/disabled
+  DWMWA_NCRENDERING_POLICY          = 02; // [set] Non-client rendering policy
+  DWMWA_TRANSITIONS_FORCEDISABLED   = 03; // [set] Potentially enable/forcibly disable transitions
+  DWMWA_ALLOW_NCPAINT               = 04; // [set] Allow contents rendered in the non-client area to be visible on the DWM-drawn frame.
+  DWMWA_CAPTION_BUTTON_BOUNDS       = 05; // [get] Bounds of the caption button area in window-relative space.
+  DWMWA_NONCLIENT_RTL_LAYOUT        = 06; // [set] Is non-client content RTL mirrored
+  DWMWA_FORCE_ICONIC_REPRESENTATION = 07; // [set] Force this window to display iconic thumbnails.
+  DWMWA_FLIP3D_POLICY               = 08; // [set] Designates how Flip3D will treat the window.
+  DWMWA_EXTENDED_FRAME_BOUNDS       = 09; // [get] Gets the extended frame bounds rectangle in screen space
+  DWMWA_HAS_ICONIC_BITMAP           = 10; // [set] Indicates an available bitmap when there is no better thumbnail representation.
+  DWMWA_DISALLOW_PEEK               = 11; // [set] Don't invoke Peek on the window.
+  DWMWA_EXCLUDED_FROM_PEEK          = 12; // [set] LivePreview exclusion information
+  DWMWA_LAST                        = 13;
+
+// Non-client rendering policy attribute values
+const
+  DWMNCRP_USEWINDOWSTYLE = 0; // Enable/disable non-client rendering based on window style
+  DWMNCRP_DISABLED       = 1; // Disabled non-client rendering; window style is ignored
+  DWMNCRP_ENABLED        = 2; // Enabled non-client rendering; window style is ignored
+  DWMNCRP_LAST           = 3;
+
+// Values designating how Flip3D treats a given window.
+const
+  DWMFLIP3D_DEFAULT      = 0; // Hide or include the window in Flip3D based on window style and visibility.
+  DWMFLIP3D_EXCLUDEBELOW = 1; // Display the window under Flip3D and disabled.
+  DWMFLIP3D_EXCLUDEABOVE = 2; // Display the window above Flip3D and enabled.
+  DWMFLIP3D_LAST         = 3;
+
+// Thumbnails
+type
+  HTHUMBNAIL = HANDLE;
+  PHTHUMBNAIL = ^HTHUMBNAIL;
+
+const
+  DWM_TNP_RECTDESTINATION      = $00000001;
+  DWM_TNP_RECTSOURCE           = $00000002;
+  DWM_TNP_OPACITY              = $00000004;
+  DWM_TNP_VISIBLE              = $00000008;
+  DWM_TNP_SOURCECLIENTAREAONLY = $00000010;
+
+type
+  _DWM_THUMBNAIL_PROPERTIES = record
+    dwFlags: DWORD;
+    rcDestination: TRect;
+    rcSource: TRect;
+    opacity: Byte;
+    fVisible: BOOL;
+    fSourceClientAreaOnly: BOOL;
+  end;
+  DWM_THUMBNAIL_PROPERTIES = _DWM_THUMBNAIL_PROPERTIES;
+  PDWM_THUMBNAIL_PROPERTIES = ^_DWM_THUMBNAIL_PROPERTIES;
+  TDWMThumbnailProperties = DWM_THUMBNAIL_PROPERTIES;
+  PDWMThumbnailProperties = PDWM_THUMBNAIL_PROPERTIES;
+
+// Video enabling apis
+
+type
+  DWM_FRAME_COUNT = ULONGLONG;
+  QPC_TIME = ULONGLONG;
+
+type
+  _UNSIGNED_RATIO = record
+    uiNumerator: LongWord;
+    uiDenominator: LongWord;
+  end;
+  UNSIGNED_RATIO = _UNSIGNED_RATIO;
+  TUnsignedRatio = UNSIGNED_RATIO;
+
+type
+  _DWM_TIMING_INFO = record
+    cbSize: LongWord;
+
+    // Data on DWM composition overall
+
+    // Monitor refresh rate
+    rateRefresh: UNSIGNED_RATIO;
+
+    // Actual period
+    qpcRefreshPeriod: QPC_TIME;
+
+    // composition rate
+    rateCompose: UNSIGNED_RATIO;
+
+    // QPC time at a VSync interupt
+    qpcVBlank: QPC_TIME;
+
+    // DWM refresh count of the last vsync
+    // DWM refresh count is a 64bit number where zero is
+    // the first refresh the DWM woke up to process
+    cRefresh: DWM_FRAME_COUNT;
+
+    // DX refresh count at the last Vsync Interupt
+    // DX refresh count is a 32bit number with zero
+    // being the first refresh after the card was initialized
+    // DX increments a counter when ever a VSync ISR is processed
+    // It is possible for DX to miss VSyncs
+    //
+    // There is not a fixed mapping between DX and DWM refresh counts
+    // because the DX will rollover and may miss VSync interupts
+    cDXRefresh: UINT;
+
+    // QPC time at a compose time.
+    qpcCompose: QPC_TIME;
+
+    // Frame number that was composed at qpcCompose
+    cFrame: DWM_FRAME_COUNT;
+
+    // The present number DX uses to identify renderer frames
+    cDXPresent: UINT;
+
+    // Refresh count of the frame that was composed at qpcCompose
+    cRefreshFrame: DWM_FRAME_COUNT;
+
+
+    // DWM frame number that was last submitted
+    cFrameSubmitted: DWM_FRAME_COUNT;
+
+    // DX Present number that was last submitted
+    cDXPresentSubmitted: UINT;
+
+    // DWM frame number that was last confirmed presented
+    cFrameConfirmed: DWM_FRAME_COUNT;
+
+    // DX Present number that was last confirmed presented
+    cDXPresentConfirmed: UINT;
+
+    // The target refresh count of the last
+    // frame confirmed completed by the GPU
+    cRefreshConfirmed: DWM_FRAME_COUNT;
+
+    // DX refresh count when the frame was confirmed presented
+    cDXRefreshConfirmed: UINT;
+
+    // Number of frames the DWM presented late
+    // AKA Glitches
+    cFramesLate: DWM_FRAME_COUNT;
+
+    // the number of composition frames that
+    // have been issued but not confirmed completed
+    cFramesOutstanding: UINT;
+
+
+    // Following fields are only relavent when an HWND is specified
+    // Display frame
+
+
+    // Last frame displayed
+    cFrameDisplayed: DWM_FRAME_COUNT;
+
+    // QPC time of the composition pass when the frame was displayed
+    qpcFrameDisplayed: QPC_TIME;
+
+    // Count of the VSync when the frame should have become visible
+    cRefreshFrameDisplayed: DWM_FRAME_COUNT;
+
+    // Complete frames: DX has notified the DWM that the frame is done rendering
+
+    // ID of the the last frame marked complete (starts at 0)
+    cFrameComplete: DWM_FRAME_COUNT;
+
+    // QPC time when the last frame was marked complete
+    qpcFrameComplete: QPC_TIME;
+
+    // Pending frames:
+    // The application has been submitted to DX but not completed by the GPU
+
+    // ID of the the last frame marked pending (starts at 0)
+    cFramePending: DWM_FRAME_COUNT;
+
+    // QPC time when the last frame was marked pending
+    qpcFramePending: QPC_TIME;
+
+    // number of unique frames displayed
+    cFramesDisplayed: DWM_FRAME_COUNT;
+
+    // number of new completed frames that have been received
+    cFramesComplete: DWM_FRAME_COUNT;
+
+     // number of new frames submitted to DX but not yet complete
+    cFramesPending: DWM_FRAME_COUNT;
+
+    // number of frames available but not displayed, used or dropped
+    cFramesAvailable: DWM_FRAME_COUNT;
+
+    // number of rendered frames that were never
+    // displayed because composition occured too late
+    cFramesDropped: DWM_FRAME_COUNT;
+
+    // number of times an old frame was composed
+    // when a new frame should have been used
+    // but was not available
+    cFramesMissed: DWM_FRAME_COUNT;
+
+    // the refresh at which the next frame is
+    // scheduled to be displayed
+    cRefreshNextDisplayed: DWM_FRAME_COUNT;
+
+    // the refresh at which the next DX present is
+    // scheduled to be displayed
+    cRefreshNextPresented: DWM_FRAME_COUNT;
+
+    // The total number of refreshes worth of content
+    // for this HWND that have been displayed by the DWM
+    // since DwmSetPresentParameters was called
+    cRefreshesDisplayed: DWM_FRAME_COUNT;
+
+    // The total number of refreshes worth of content
+    // that have been presented by the application
+    // since DwmSetPresentParameters was called
+    cRefreshesPresented: DWM_FRAME_COUNT;
+
+
+    // The actual refresh # when content for this
+    // window started to be displayed
+    // it may be different than that requested
+    // DwmSetPresentParameters
+    cRefreshStarted: DWM_FRAME_COUNT;
+
+    // Total number of pixels DX redirected
+    // to the DWM.
+    // If Queueing is used the full buffer
+    // is transfered on each present.
+    // If not queuing it is possible only
+    // a dirty region is updated
+    cPixelsReceived: ULONGLONG;
+
+    // Total number of pixels drawn.
+    // Does not take into account if
+    // if the window is only partial drawn
+    // do to clipping or dirty rect management
+    cPixelsDrawn: ULONGLONG;
+
+    // The number of buffers in the flipchain
+    // that are empty.   An application can
+    // present that number of times and guarantee
+    // it won't be blocked waiting for a buffer to
+    // become empty to present to
+    cBuffersEmpty: DWM_FRAME_COUNT;
+
+  end;
+  DWM_TIMING_INFO = _DWM_TIMING_INFO;
+  TDWMTimingInfo = DWM_TIMING_INFO;
+
+const
+  // Use the first source frame that
+  // includes the first refresh of the output frame
+  DWM_SOURCE_FRAME_SAMPLING_POINT = 0;
+
+  // use the source frame that includes the most
+  // refreshes of out the output frame
+  // in case of multiple source frames with the
+  // same coverage the last will be used
+  DWM_SOURCE_FRAME_SAMPLING_COVERAGE = 1;
+
+     // Sentinel value
+  DWM_SOURCE_FRAME_SAMPLING_LAST = 2;
+
+const
+  c_DwmMaxQueuedBuffers = 8;
+  c_DwmMaxMonitors = 16;
+  c_DwmMaxAdapters = 16;
+
+type
+  _DWM_PRESENT_PARAMETERS = record
+    cbSize: LongWord;
+    fQueue: BOOL;
+    cRefreshStart: DWM_FRAME_COUNT;
+    cBuffer: UINT;
+    fUseSourceRate: BOOL;
+    rateSource: UNSIGNED_RATIO;
+    cRefreshesPerFrame: UINT;
+    eSampling: LongWord;
+  end;
+  DWM_PRESENT_PARAMETERS = _DWM_PRESENT_PARAMETERS;
+  TDWMPresentParameters = DWM_PRESENT_PARAMETERS;
+
+const
+  DWM_FRAME_DURATION_DEFAULT = -1;
+
+var
+  DwmDefWindowProc: function(hWnd: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM; out plResult: LRESULT): BOOL; stdcall;
+
+  DwmEnableBlurBehindWindow: function(hWnd: HWND; pBlurBehind: PDWM_BLURBEHIND): HRESULT; stdcall;
+
+const
+  DWM_EC_DISABLECOMPOSITION = 0;
+  DWM_EC_ENABLECOMPOSITION  = 1;
+
+var
+  DwmEnableComposition: function(uCompositionAction: UINT): HRESULT; stdcall;
+
+  DwmEnableMMCSS: function(fEnableMMCSS: BOOL): HRESULT; stdcall;
+
+  DwmExtendFrameIntoClientArea: function(hWnd: HWND; pMarInset: PMARGINS): HRESULT; stdcall;
+
+  DwmGetColorizationColor: function(out pcrColorization: DWORD; out pfOpaqueBlend: BOOL): HRESULT; stdcall;
+
+  DwmGetCompositionTimingInfo: function(hwnd: HWND; out pTimingInfo: DWM_TIMING_INFO): HRESULT; stdcall;
+
+  DwmGetWindowAttribute: function(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; stdcall;
+
+  DwmIsCompositionEnabled: function(out pfEnabled: BOOL): HRESULT; stdcall;
+
+  DwmModifyPreviousDxFrameDuration: function(hwnd: HWND; cRefreshes: Integer; fRelative: BOOL): HRESULT; stdcall;
+
+  DwmQueryThumbnailSourceSize: function(hThumbnail: HTHUMBNAIL; out pSize: TSIZE): HRESULT; stdcall;
+
+  DwmRegisterThumbnail: function(hwndDestination: HWND; hwndSource: HWND; out phThumbnailId: HTHUMBNAIL): HRESULT; stdcall;
+
+  DwmSetDxFrameDuration: function(hwnd: HWND; cRefreshes: Integer): HRESULT; stdcall;
+
+  DwmSetPresentParameters: function(hwnd: HWND; var pPresentParams: DWM_PRESENT_PARAMETERS): HRESULT; stdcall;
+
+  DwmSetWindowAttribute: function(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; stdcall;
+
+  DwmUnregisterThumbnail: function(hThumbnailId: HTHUMBNAIL): HRESULT; stdcall;
+
+  DwmUpdateThumbnailProperties: function(hThumbnailId: HTHUMBNAIL; ptnProperties: PDWM_THUMBNAIL_PROPERTIES): HRESULT; stdcall;
+
+// if(_WIN32_WINNT >= 0x0601)
+const
+  DWM_SIT_DISPLAYFRAME = $00000001; // Display a window frame around the provided bitmap
+
+var
+  DwmSetIconicThumbnail: function(hwnd: HWND; hbmp: HBITMAP; dwSITFlags: DWORD): HRESULT; stdcall;
+
+  DwmSetIconicLivePreviewBitmap: function(hwnd: HWND; hbmp: HBITMAP; var ptClient: PPOINT; dwSITFlags: DWORD): HRESULT; stdcall;
+
+  DwmInvalidateIconicBitmaps: function(hwnd: HWND): HRESULT; stdcall;
+
+// endif /* _WIN32_WINNT >= 0x0601 */
+
+var
+  DwmAttachMilContent: function(hwnd: HWND): HRESULT; stdcall;
+
+  DwmDetachMilContent: function(hwnd: HWND): HRESULT; stdcall;
+
+  DwmFlush: function(): HRESULT; stdcall;
+
+type
+  _MilMatrix3x2D = record
+    S_11: DOUBLE;
+    S_12: DOUBLE;
+    S_21: DOUBLE;
+    S_22: DOUBLE;
+    DX: DOUBLE;
+    DY: DOUBLE;
+  end;
+  MilMatrix3x2D = _MilMatrix3x2D;
+  TMilMatrix3x2D = MilMatrix3x2D;
+
+var
+  DwmGetGraphicsStreamTransformHint: function(uIndex: UINT; out pTransform: MilMatrix3x2D): HRESULT; stdcall;
+
+  DwmGetGraphicsStreamClient: function(uIndex: UINT; out pClientUuid: TGUID): HRESULT; stdcall;
+
+  DwmGetTransportAttributes: function(out pfIsRemoting: BOOL; out pfIsConnected: BOOL; out pDwGeneration: DWORD): HRESULT; stdcall;
+
+implementation
+
+const
+  dwmlib = 'dwmapi.dll';
+
+var
+  DwmLibrary: THandle;
+  ReferenceCount: Integer;  // We have to keep track of several load/unload calls.
+
+procedure FreeDwmLibrary;
+begin
+  if ReferenceCount > 0 then
+    Dec(ReferenceCount);
+
+  if (DwmLibrary <> 0) and (ReferenceCount = 0) then
+  begin
+    FreeLibrary(DwmLibrary);
+    DwmLibrary := 0;
+
+    DwmDefWindowProc := nil;
+    DwmEnableBlurBehindWindow := nil;
+    DwmEnableComposition := nil;
+    DwmEnableMMCSS := nil;
+    DwmExtendFrameIntoClientArea := nil;
+    DwmGetColorizationColor := nil;
+    DwmGetCompositionTimingInfo := nil;
+    DwmGetWindowAttribute := nil;
+    DwmIsCompositionEnabled := nil;
+    DwmModifyPreviousDxFrameDuration := nil;
+    DwmQueryThumbnailSourceSize := nil;
+    DwmRegisterThumbnail := nil;
+    DwmSetDxFrameDuration := nil;
+    DwmSetPresentParameters := nil;
+    DwmSetWindowAttribute := nil;
+    DwmUnregisterThumbnail := nil;
+    DwmUpdateThumbnailProperties := nil;
+    DwmAttachMilContent := nil;
+    DwmDetachMilContent := nil;
+    DwmFlush := nil;
+    DwmGetGraphicsStreamTransformHint := nil;
+    DwmGetGraphicsStreamClient := nil;
+    DwmGetTransportAttributes := nil;
+
+    DwmSetIconicThumbnail := nil;
+    DwmSetIconicLivePreviewBitmap := nil;
+    DwmInvalidateIconicBitmaps := nil;
+  end;
+end;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+function InitDwmLibrary: Boolean;
+begin
+  Inc(ReferenceCount);
+
+  if DwmLibrary = 0 then
+  begin
+    DwmLibrary := LoadLibrary(dwmlib);
+    if DwmLibrary > 0 then
+    begin
+      // windows vista
+      Pointer(DwmDefWindowProc) := GetProcAddress(DwmLibrary, 'DwmDefWindowProc');
+      Pointer(DwmEnableBlurBehindWindow) := GetProcAddress(DwmLibrary, 'DwmEnableBlurBehindWindow');
+      Pointer(DwmEnableComposition) := GetProcAddress(DwmLibrary, 'DwmEnableComposition');
+      Pointer(DwmEnableMMCSS) := GetProcAddress(DwmLibrary, 'DwmEnableMMCSS');
+      Pointer(DwmExtendFrameIntoClientArea) := GetProcAddress(DwmLibrary, 'DwmExtendFrameIntoClientArea');
+      Pointer(DwmGetColorizationColor) := GetProcAddress(DwmLibrary, 'DwmGetColorizationColor');
+      Pointer(DwmGetCompositionTimingInfo) := GetProcAddress(DwmLibrary, 'DwmGetCompositionTimingInfo');
+      Pointer(DwmGetWindowAttribute) := GetProcAddress(DwmLibrary, 'DwmGetWindowAttribute');
+      Pointer(DwmIsCompositionEnabled) := GetProcAddress(DwmLibrary, 'DwmIsCompositionEnabled');
+      Pointer(DwmModifyPreviousDxFrameDuration) := GetProcAddress(DwmLibrary, 'DwmModifyPreviousDxFrameDuration');
+      Pointer(DwmQueryThumbnailSourceSize) := GetProcAddress(DwmLibrary, 'DwmQueryThumbnailSourceSize');
+      Pointer(DwmRegisterThumbnail) := GetProcAddress(DwmLibrary, 'DwmRegisterThumbnail');
+      Pointer(DwmSetDxFrameDuration) := GetProcAddress(DwmLibrary, 'DwmSetDxFrameDuration');
+      Pointer(DwmSetPresentParameters) := GetProcAddress(DwmLibrary, 'DwmSetPresentParameters');
+      Pointer(DwmSetWindowAttribute) := GetProcAddress(DwmLibrary, 'DwmSetWindowAttribute');
+      Pointer(DwmUnregisterThumbnail) := GetProcAddress(DwmLibrary, 'DwmUnregisterThumbnail');
+      Pointer(DwmUpdateThumbnailProperties) := GetProcAddress(DwmLibrary, 'DwmUpdateThumbnailProperties');
+      Pointer(DwmAttachMilContent) := GetProcAddress(DwmLibrary, 'DwmAttachMilContent');
+      Pointer(DwmDetachMilContent) := GetProcAddress(DwmLibrary, 'DwmDetachMilContent');
+      Pointer(DwmFlush) := GetProcAddress(DwmLibrary, 'DwmFlush');
+      Pointer(DwmGetGraphicsStreamTransformHint) := GetProcAddress(DwmLibrary, 'DwmGetGraphicsStreamTransformHint');
+      Pointer(DwmGetGraphicsStreamClient) := GetProcAddress(DwmLibrary, 'DwmGetGraphicsStreamClient');
+      Pointer(DwmGetTransportAttributes) := GetProcAddress(DwmLibrary, 'DwmGetTransportAttributes');
+
+      // windows 7
+      Pointer(DwmSetIconicThumbnail) := GetProcAddress(DwmLibrary, 'DwmSetIconicThumbnail');
+      Pointer(DwmSetIconicLivePreviewBitmap) := GetProcAddress(DwmLibrary, 'DwmSetIconicLivePreviewBitmap');
+      Pointer(DwmInvalidateIconicBitmaps) := GetProcAddress(DwmLibrary, 'DwmInvalidateIconicBitmaps');
+    end;
+  end;
+  Result := DwmLibrary > 0;
+end;
+
+function DwmCompositionEnabled: Boolean;
+var
+  B: BOOL;
+begin
+  Result := DwmLibrary > 0;
+  if Result then
+    Result := (DwmIsCompositionEnabled(B) = S_OK) and B;
+end;
+
+initialization
+  ReferenceCount := 0;
+
+finalization
+  while ReferenceCount > 0 do
+    FreeDwmLibrary;
+
+end.

部分文件因为文件数量过多而无法显示