diff options
-rwxr-xr-x | build.bat | 1 | ||||
-rw-r--r-- | build64.bat | 172 | ||||
-rwxr-xr-x | compiler/extccomp.nim | 2 | ||||
-rwxr-xr-x | compiler/nimrod.ini | 5 | ||||
-rwxr-xr-x | compiler/nimrod.nim | 9 | ||||
-rw-r--r-- | icons/koch_icon.o | bin | 0 -> 5768 bytes | |||
-rw-r--r-- | icons/nimrod_icon.o | bin | 0 -> 30830 bytes | |||
-rwxr-xr-x | install.sh | 4 | ||||
-rwxr-xr-x | install.txt | 8 | ||||
-rwxr-xr-x | koch.nim | 10 | ||||
-rw-r--r-- | lib/pure/memfiles.nim | 30 | ||||
-rwxr-xr-x | lib/pure/os.nim | 280 | ||||
-rwxr-xr-x | lib/pure/osproc.nim | 25 | ||||
-rwxr-xr-x | lib/system/sysio.nim | 31 | ||||
-rw-r--r-- | lib/system/widestrs.nim | 260 | ||||
-rwxr-xr-x | lib/windows/winlean.nim | 228 | ||||
-rwxr-xr-x | todo.txt | 2 | ||||
-rwxr-xr-x | tools/nimgrep.nimrod.cfg | 6 | ||||
-rwxr-xr-x | tools/niminst/buildbat.tmpl | 29 | ||||
-rwxr-xr-x | tools/niminst/niminst.nim | 10 | ||||
-rwxr-xr-x | web/download.txt | 4 | ||||
-rwxr-xr-x | web/news.txt | 14 |
22 files changed, 931 insertions, 199 deletions
diff --git a/build.bat b/build.bat index 42fd98bea..2cd3d31fc 100755 --- a/build.bat +++ b/build.bat @@ -167,5 +167,6 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\parseopt.c -o build\1_1\parseopt.o ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_1\nim__dat.o build\1_1\system.o build\1_1\nimrod.o build\1_1\times.o build\1_1\strutils.o build\1_1\parseutils.o build\1_1\winlean.o build\1_1\commands.o build\1_1\os.o build\1_1\msgs.o build\1_1\options.o build\1_1\lists.o build\1_1\strtabs.o build\1_1\hashes.o build\1_1\tables.o build\1_1\math.o build\1_1\nversion.o build\1_1\condsyms.o build\1_1\ast.o build\1_1\crc.o build\1_1\ropes.o build\1_1\platform.o build\1_1\idents.o build\1_1\intsets.o build\1_1\idgen.o build\1_1\astalgo.o build\1_1\rodutils.o build\1_1\extccomp.o build\1_1\osproc.o build\1_1\streams.o build\1_1\wordrecg.o build\1_1\lexer.o build\1_1\lexbase.o build\1_1\llstream.o build\1_1\nimconf.o build\1_1\main.o build\1_1\syntaxes.o build\1_1\parser.o build\1_1\pbraces.o build\1_1\filters.o build\1_1\renderer.o build\1_1\filter_tmpl.o build\1_1\rodread.o build\1_1\memfiles.o build\1_1\rodwrite.o build\1_1\passes.o build\1_1\types.o build\1_1\trees.o build\1_1\magicsys.o build\1_1\nimsets.o build\1_1\bitsets.o build\1_1\semthreads.o build\1_1\importer.o build\1_1\lookups.o build\1_1\semdata.o build\1_1\treetab.o build\1_1\evals.o build\1_1\semfold.o build\1_1\transf.o build\1_1\cgmeth.o build\1_1\sem.o build\1_1\procfind.o build\1_1\pragmas.o build\1_1\semtypinst.o build\1_1\sigmatch.o build\1_1\suggest.o build\1_1\aliases.o build\1_1\docgen.o build\1_1\rst.o build\1_1\highlite.o build\1_1\cgen.o build\1_1\ccgutils.o build\1_1\cgendata.o build\1_1\ccgmerge.o build\1_1\ecmasgen.o build\1_1\passaux.o build\1_1\depends.o build\1_1\parseopt.o %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_1\nim__dat.o build\1_1\system.o build\1_1\nimrod.o build\1_1\times.o build\1_1\strutils.o build\1_1\parseutils.o build\1_1\winlean.o build\1_1\commands.o build\1_1\os.o build\1_1\msgs.o build\1_1\options.o build\1_1\lists.o build\1_1\strtabs.o build\1_1\hashes.o build\1_1\tables.o build\1_1\math.o build\1_1\nversion.o build\1_1\condsyms.o build\1_1\ast.o build\1_1\crc.o build\1_1\ropes.o build\1_1\platform.o build\1_1\idents.o build\1_1\intsets.o build\1_1\idgen.o build\1_1\astalgo.o build\1_1\rodutils.o build\1_1\extccomp.o build\1_1\osproc.o build\1_1\streams.o build\1_1\wordrecg.o build\1_1\lexer.o build\1_1\lexbase.o build\1_1\llstream.o build\1_1\nimconf.o build\1_1\main.o build\1_1\syntaxes.o build\1_1\parser.o build\1_1\pbraces.o build\1_1\filters.o build\1_1\renderer.o build\1_1\filter_tmpl.o build\1_1\rodread.o build\1_1\memfiles.o build\1_1\rodwrite.o build\1_1\passes.o build\1_1\types.o build\1_1\trees.o build\1_1\magicsys.o build\1_1\nimsets.o build\1_1\bitsets.o build\1_1\semthreads.o build\1_1\importer.o build\1_1\lookups.o build\1_1\semdata.o build\1_1\treetab.o build\1_1\evals.o build\1_1\semfold.o build\1_1\transf.o build\1_1\cgmeth.o build\1_1\sem.o build\1_1\procfind.o build\1_1\pragmas.o build\1_1\semtypinst.o build\1_1\sigmatch.o build\1_1\suggest.o build\1_1\aliases.o build\1_1\docgen.o build\1_1\rst.o build\1_1\highlite.o build\1_1\cgen.o build\1_1\ccgutils.o build\1_1\cgendata.o build\1_1\ccgmerge.o build\1_1\ecmasgen.o build\1_1\passaux.o build\1_1\depends.o build\1_1\parseopt.o + ECHO SUCCESS diff --git a/build64.bat b/build64.bat new file mode 100644 index 000000000..8e9a56258 --- /dev/null +++ b/build64.bat @@ -0,0 +1,172 @@ +@echo off +REM Generated by niminst +SET CC=gcc +SET LINKER=gcc +SET COMP_FLAGS= -w -O3 -fno-strict-aliasing +SET LINK_FLAGS= + +REM call the compiler: + +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\nim__dat.c -o build\1_2\nim__dat.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\nim__dat.c -o build\1_2\nim__dat.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\system.c -o build\1_2\system.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\system.c -o build\1_2\system.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\nimrod.c -o build\1_2\nimrod.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\nimrod.c -o build\1_2\nimrod.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\times.c -o build\1_2\times.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\times.c -o build\1_2\times.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\strutils.c -o build\1_2\strutils.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\strutils.c -o build\1_2\strutils.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\parseutils.c -o build\1_2\parseutils.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\parseutils.c -o build\1_2\parseutils.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\winlean.c -o build\1_2\winlean.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\winlean.c -o build\1_2\winlean.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\commands.c -o build\1_2\commands.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\commands.c -o build\1_2\commands.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\os.c -o build\1_2\os.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\os.c -o build\1_2\os.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\msgs.c -o build\1_2\msgs.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\msgs.c -o build\1_2\msgs.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\options.c -o build\1_2\options.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\options.c -o build\1_2\options.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\lists.c -o build\1_2\lists.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\lists.c -o build\1_2\lists.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\strtabs.c -o build\1_2\strtabs.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\strtabs.c -o build\1_2\strtabs.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\hashes.c -o build\1_2\hashes.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\hashes.c -o build\1_2\hashes.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\tables.c -o build\1_2\tables.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\tables.c -o build\1_2\tables.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\math.c -o build\1_2\math.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\math.c -o build\1_2\math.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\nversion.c -o build\1_2\nversion.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\nversion.c -o build\1_2\nversion.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\condsyms.c -o build\1_2\condsyms.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\condsyms.c -o build\1_2\condsyms.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\ast.c -o build\1_2\ast.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\ast.c -o build\1_2\ast.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\crc.c -o build\1_2\crc.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\crc.c -o build\1_2\crc.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\ropes.c -o build\1_2\ropes.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\ropes.c -o build\1_2\ropes.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\platform.c -o build\1_2\platform.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\platform.c -o build\1_2\platform.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\idents.c -o build\1_2\idents.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\idents.c -o build\1_2\idents.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\intsets.c -o build\1_2\intsets.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\intsets.c -o build\1_2\intsets.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\idgen.c -o build\1_2\idgen.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\idgen.c -o build\1_2\idgen.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\astalgo.c -o build\1_2\astalgo.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\astalgo.c -o build\1_2\astalgo.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\rodutils.c -o build\1_2\rodutils.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\rodutils.c -o build\1_2\rodutils.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\extccomp.c -o build\1_2\extccomp.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\extccomp.c -o build\1_2\extccomp.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\osproc.c -o build\1_2\osproc.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\osproc.c -o build\1_2\osproc.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\streams.c -o build\1_2\streams.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\streams.c -o build\1_2\streams.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\wordrecg.c -o build\1_2\wordrecg.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\wordrecg.c -o build\1_2\wordrecg.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\lexer.c -o build\1_2\lexer.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\lexer.c -o build\1_2\lexer.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\lexbase.c -o build\1_2\lexbase.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\lexbase.c -o build\1_2\lexbase.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\llstream.c -o build\1_2\llstream.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\llstream.c -o build\1_2\llstream.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\nimconf.c -o build\1_2\nimconf.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\nimconf.c -o build\1_2\nimconf.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\main.c -o build\1_2\main.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\main.c -o build\1_2\main.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\syntaxes.c -o build\1_2\syntaxes.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\syntaxes.c -o build\1_2\syntaxes.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\parser.c -o build\1_2\parser.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\parser.c -o build\1_2\parser.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\pbraces.c -o build\1_2\pbraces.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\pbraces.c -o build\1_2\pbraces.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\filters.c -o build\1_2\filters.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\filters.c -o build\1_2\filters.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\renderer.c -o build\1_2\renderer.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\renderer.c -o build\1_2\renderer.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\filter_tmpl.c -o build\1_2\filter_tmpl.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\filter_tmpl.c -o build\1_2\filter_tmpl.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\rodread.c -o build\1_2\rodread.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\rodread.c -o build\1_2\rodread.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\memfiles.c -o build\1_2\memfiles.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\memfiles.c -o build\1_2\memfiles.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\rodwrite.c -o build\1_2\rodwrite.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\rodwrite.c -o build\1_2\rodwrite.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\passes.c -o build\1_2\passes.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\passes.c -o build\1_2\passes.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\types.c -o build\1_2\types.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\types.c -o build\1_2\types.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\trees.c -o build\1_2\trees.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\trees.c -o build\1_2\trees.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\magicsys.c -o build\1_2\magicsys.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\magicsys.c -o build\1_2\magicsys.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\nimsets.c -o build\1_2\nimsets.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\nimsets.c -o build\1_2\nimsets.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\bitsets.c -o build\1_2\bitsets.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\bitsets.c -o build\1_2\bitsets.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\semthreads.c -o build\1_2\semthreads.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\semthreads.c -o build\1_2\semthreads.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\importer.c -o build\1_2\importer.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\importer.c -o build\1_2\importer.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\lookups.c -o build\1_2\lookups.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\lookups.c -o build\1_2\lookups.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\semdata.c -o build\1_2\semdata.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\semdata.c -o build\1_2\semdata.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\treetab.c -o build\1_2\treetab.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\treetab.c -o build\1_2\treetab.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\evals.c -o build\1_2\evals.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\evals.c -o build\1_2\evals.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\semfold.c -o build\1_2\semfold.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\semfold.c -o build\1_2\semfold.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\transf.c -o build\1_2\transf.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\transf.c -o build\1_2\transf.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\cgmeth.c -o build\1_2\cgmeth.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\cgmeth.c -o build\1_2\cgmeth.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\sem.c -o build\1_2\sem.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\sem.c -o build\1_2\sem.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\procfind.c -o build\1_2\procfind.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\procfind.c -o build\1_2\procfind.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\pragmas.c -o build\1_2\pragmas.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\pragmas.c -o build\1_2\pragmas.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\semtypinst.c -o build\1_2\semtypinst.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\semtypinst.c -o build\1_2\semtypinst.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\sigmatch.c -o build\1_2\sigmatch.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\sigmatch.c -o build\1_2\sigmatch.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\suggest.c -o build\1_2\suggest.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\suggest.c -o build\1_2\suggest.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\aliases.c -o build\1_2\aliases.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\aliases.c -o build\1_2\aliases.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\docgen.c -o build\1_2\docgen.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\docgen.c -o build\1_2\docgen.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\rst.c -o build\1_2\rst.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\rst.c -o build\1_2\rst.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\highlite.c -o build\1_2\highlite.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\highlite.c -o build\1_2\highlite.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\cgen.c -o build\1_2\cgen.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\cgen.c -o build\1_2\cgen.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\ccgutils.c -o build\1_2\ccgutils.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\ccgutils.c -o build\1_2\ccgutils.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\cgendata.c -o build\1_2\cgendata.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\cgendata.c -o build\1_2\cgendata.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\ccgmerge.c -o build\1_2\ccgmerge.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\ccgmerge.c -o build\1_2\ccgmerge.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\ecmasgen.c -o build\1_2\ecmasgen.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\ecmasgen.c -o build\1_2\ecmasgen.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\passaux.c -o build\1_2\passaux.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\passaux.c -o build\1_2\passaux.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\depends.c -o build\1_2\depends.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\depends.c -o build\1_2\depends.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\parseopt.c -o build\1_2\parseopt.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\parseopt.c -o build\1_2\parseopt.o + +ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_2\nim__dat.o build\1_2\system.o build\1_2\nimrod.o build\1_2\times.o build\1_2\strutils.o build\1_2\parseutils.o build\1_2\winlean.o build\1_2\commands.o build\1_2\os.o build\1_2\msgs.o build\1_2\options.o build\1_2\lists.o build\1_2\strtabs.o build\1_2\hashes.o build\1_2\tables.o build\1_2\math.o build\1_2\nversion.o build\1_2\condsyms.o build\1_2\ast.o build\1_2\crc.o build\1_2\ropes.o build\1_2\platform.o build\1_2\idents.o build\1_2\intsets.o build\1_2\idgen.o build\1_2\astalgo.o build\1_2\rodutils.o build\1_2\extccomp.o build\1_2\osproc.o build\1_2\streams.o build\1_2\wordrecg.o build\1_2\lexer.o build\1_2\lexbase.o build\1_2\llstream.o build\1_2\nimconf.o build\1_2\main.o build\1_2\syntaxes.o build\1_2\parser.o build\1_2\pbraces.o build\1_2\filters.o build\1_2\renderer.o build\1_2\filter_tmpl.o build\1_2\rodread.o build\1_2\memfiles.o build\1_2\rodwrite.o build\1_2\passes.o build\1_2\types.o build\1_2\trees.o build\1_2\magicsys.o build\1_2\nimsets.o build\1_2\bitsets.o build\1_2\semthreads.o build\1_2\importer.o build\1_2\lookups.o build\1_2\semdata.o build\1_2\treetab.o build\1_2\evals.o build\1_2\semfold.o build\1_2\transf.o build\1_2\cgmeth.o build\1_2\sem.o build\1_2\procfind.o build\1_2\pragmas.o build\1_2\semtypinst.o build\1_2\sigmatch.o build\1_2\suggest.o build\1_2\aliases.o build\1_2\docgen.o build\1_2\rst.o build\1_2\highlite.o build\1_2\cgen.o build\1_2\ccgutils.o build\1_2\cgendata.o build\1_2\ccgmerge.o build\1_2\ecmasgen.o build\1_2\passaux.o build\1_2\depends.o build\1_2\parseopt.o +%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_2\nim__dat.o build\1_2\system.o build\1_2\nimrod.o build\1_2\times.o build\1_2\strutils.o build\1_2\parseutils.o build\1_2\winlean.o build\1_2\commands.o build\1_2\os.o build\1_2\msgs.o build\1_2\options.o build\1_2\lists.o build\1_2\strtabs.o build\1_2\hashes.o build\1_2\tables.o build\1_2\math.o build\1_2\nversion.o build\1_2\condsyms.o build\1_2\ast.o build\1_2\crc.o build\1_2\ropes.o build\1_2\platform.o build\1_2\idents.o build\1_2\intsets.o build\1_2\idgen.o build\1_2\astalgo.o build\1_2\rodutils.o build\1_2\extccomp.o build\1_2\osproc.o build\1_2\streams.o build\1_2\wordrecg.o build\1_2\lexer.o build\1_2\lexbase.o build\1_2\llstream.o build\1_2\nimconf.o build\1_2\main.o build\1_2\syntaxes.o build\1_2\parser.o build\1_2\pbraces.o build\1_2\filters.o build\1_2\renderer.o build\1_2\filter_tmpl.o build\1_2\rodread.o build\1_2\memfiles.o build\1_2\rodwrite.o build\1_2\passes.o build\1_2\types.o build\1_2\trees.o build\1_2\magicsys.o build\1_2\nimsets.o build\1_2\bitsets.o build\1_2\semthreads.o build\1_2\importer.o build\1_2\lookups.o build\1_2\semdata.o build\1_2\treetab.o build\1_2\evals.o build\1_2\semfold.o build\1_2\transf.o build\1_2\cgmeth.o build\1_2\sem.o build\1_2\procfind.o build\1_2\pragmas.o build\1_2\semtypinst.o build\1_2\sigmatch.o build\1_2\suggest.o build\1_2\aliases.o build\1_2\docgen.o build\1_2\rst.o build\1_2\highlite.o build\1_2\cgen.o build\1_2\ccgutils.o build\1_2\cgendata.o build\1_2\ccgmerge.o build\1_2\ecmasgen.o build\1_2\passaux.o build\1_2\depends.o build\1_2\parseopt.o + + +ECHO SUCCESS + diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index eaaf4a578..fb2e5f3f5 100755 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -403,7 +403,7 @@ proc execExternalProgram*(cmd: string) = if execCmd(cmd) != 0: rawMessage(errExecutionOfProgramFailed, "") proc generateScript(projectFile: string, script: PRope) = - var (dir, name, ext) = splitFile(projectFile) + let (dir, name, ext) = splitFile(projectFile) WriteRope(script, dir / addFileExt("compile_" & name, platform.os[targetOS].scriptExt)) diff --git a/compiler/nimrod.ini b/compiler/nimrod.ini index b689ec1c4..9fd6f0ce6 100755 --- a/compiler/nimrod.ini +++ b/compiler/nimrod.ini @@ -43,9 +43,11 @@ Files: "koch.nim" Files: "icons/nimrod.ico" Files: "icons/nimrod.rc" Files: "icons/nimrod.res" +Files: "icons/nimrod_icon.o" Files: "icons/koch.ico" Files: "icons/koch.rc" Files: "icons/koch.res" +Files: "icons/koch_icon.o" Files: "compiler/readme.txt" Files: "compiler/nimrod.ini" @@ -101,6 +103,8 @@ Files: "examples/*.tmpl" Files: "bin/nimrod.exe" Files: "bin/c2nim.exe" Files: "bin/niminst.exe" +Files: "bin/nimgrep.exe" + Files: "dist/*.dll" Files: "koch.exe" Files: "dist/mingw" @@ -128,3 +132,4 @@ buildDepends: "gcc (>= 4:4.3.2)" pkgDepends: "gcc (>= 4:4.3.2)" shortDesc: "The Nimrod Compiler" licenses: "bin/nimrod,gpl2;lib/*,lgpl;" + diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim index 10e10e1ec..e9c674a07 100755 --- a/compiler/nimrod.nim +++ b/compiler/nimrod.nim @@ -7,8 +7,11 @@ # distribution, for details about the copyright. # -when defined(gcc) and defined(windows): - {.link: "icons/nimrod.res".} +when defined(gcc) and defined(windows): + when defined(x86): + {.link: "icons/nimrod.res".} + else: + {.link: "icons/nimrod_icon.o".} import times, commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes, @@ -96,7 +99,7 @@ proc HandleCmdLine() = formatSize(getTotalMem())]) if optRun in gGlobalOptions: var ex = quoteIfContainsWhite( - changeFileExt(gProjectFull, "").prependCurDir) + changeFileExt(gProjectFull, exeExt).prependCurDir) execExternalProgram(ex & ' ' & arguments) #GC_disableMarkAndSweep() diff --git a/icons/koch_icon.o b/icons/koch_icon.o new file mode 100644 index 000000000..b780f4d88 --- /dev/null +++ b/icons/koch_icon.o Binary files differdiff --git a/icons/nimrod_icon.o b/icons/nimrod_icon.o new file mode 100644 index 000000000..c8c364412 --- /dev/null +++ b/icons/nimrod_icon.o Binary files differdiff --git a/install.sh b/install.sh index 6bfdfcb49..1f4e9be68 100755 --- a/install.sh +++ b/install.sh @@ -132,6 +132,8 @@ if [ $# -eq 1 ] ; then chmod 644 $docdir/tut1.txt cp doc/tut2.txt $docdir/tut2.txt || exit 1 chmod 644 $docdir/tut2.txt + cp doc/actors.html $docdir/actors.html || exit 1 + chmod 644 $docdir/actors.html cp doc/algorithm.html $docdir/algorithm.html || exit 1 chmod 644 $docdir/algorithm.html cp doc/apis.html $docdir/apis.html || exit 1 @@ -386,6 +388,8 @@ if [ $# -eq 1 ] ; then chmod 644 $libdir/system/sysstr.nim cp lib/system/threads.nim $libdir/system/threads.nim || exit 1 chmod 644 $libdir/system/threads.nim + cp lib/system/widestrs.nim $libdir/system/widestrs.nim || exit 1 + chmod 644 $libdir/system/widestrs.nim cp lib/core/locks.nim $libdir/core/locks.nim || exit 1 chmod 644 $libdir/core/locks.nim cp lib/core/macros.nim $libdir/core/macros.nim || exit 1 diff --git a/install.txt b/install.txt index 3c916132f..8021abfbb 100755 --- a/install.txt +++ b/install.txt @@ -56,8 +56,8 @@ Currently, the following C compilers are supported under Windows: the win32api header files and import libraries are essential.) - | Gnu C Compiler (the mingw version; the cygwin version has not been tested!) | http://www.mingw.org/download.shtml -- | LLVM with GNU C/C++ frontend - | http://llvm.org/releases/download.html#2.2 +- | LLVM with Clang or GNU C/C++ frontend + | http://llvm.org/releases/download.html - | Digital Mars C++ | http://www.digitalmars.com/download/freecompiler.html @@ -92,6 +92,10 @@ On Windows * ``bin\nimrod c koch`` * ``koch boot -d:release`` +If you want a 64 bit build, make sure that you have a GCC built for Win64 and +execute ``build64.bat`` instead of ``build.bat``. + + On UNIX ~~~~~~~ diff --git a/koch.nim b/koch.nim index d0b9de7a2..add08625a 100755 --- a/koch.nim +++ b/koch.nim @@ -7,8 +7,11 @@ # distribution, for details about the copyright. # -when defined(gcc) and defined(windows): - {.link: "icons/koch.res".} +when defined(gcc) and defined(windows): + when defined(x86): + {.link: "icons/koch.res".} + else: + {.link: "icons/koch_icon.o".} import os, strutils, parseopt, osproc, streams @@ -74,7 +77,8 @@ proc buildTool(toolname, args: string) = proc inno(args: string) = # make sure we have generated the c2nim and niminst executables: buildTool("tools/niminst/niminst", args) - buildTool("compiler/c2nim/c2nim", args) + buildTool("tools/nimgrep", args) + buildTool("compiler/c2nim/c2nim", args) exec("tools" / "niminst" / "niminst --var:version=$# inno compiler/nimrod" % NimrodVersion) diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index e6389e426..3f56d2465 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -57,15 +57,23 @@ proc open*(filename: string, mode: TFileMode = fmRead, OSError() # return false #raise newException(EIO, msg) - - result.fHandle = CreateFileA( - filename, - if readonly: GENERIC_READ else: GENERIC_ALL, - FILE_SHARE_READ, - nil, - if newFileSize != -1: CREATE_ALWAYS else: OPEN_EXISTING, - if readonly: FILE_ATTRIBUTE_READONLY else: FILE_ATTRIBUTE_TEMPORARY, - 0) + + template callCreateFile(winApiProc, filename: expr): expr = + winApiProc( + filename, + if readonly: GENERIC_READ else: GENERIC_ALL, + FILE_SHARE_READ, + nil, + if newFileSize != -1: CREATE_ALWAYS else: OPEN_EXISTING, + if readonly: FILE_ATTRIBUTE_READONLY else: FILE_ATTRIBUTE_TEMPORARY, + 0) + + when useWinUnicode: + var f = allocWideCString(filename) + result.fHandle = callCreateFile(CreateFileW, f) + dealloc f + else: + result.fHandle = callCreateFile(CreateFileA, filename) if result.fHandle == INVALID_HANDLE_VALUE: fail "error opening file" @@ -81,7 +89,9 @@ proc open*(filename: string, mode: TFileMode = fmRead, (SetEndOfFile(result.fHandle) == 0): fail "error setting file size" - result.mapHandle = CreateFileMapping( + # since the strings are always 'nil', we simply always call + # CreateFileMappingW which should be slightly faster anyway: + result.mapHandle = CreateFileMappingW( result.fHandle, nil, if readonly: PAGE_READONLY else: PAGE_READWRITE, 0, 0, nil) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 5b3859bd2..76f934c04 100755 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -168,13 +168,18 @@ proc OSErrorMsg*(): string {.rtl, extern: "nos$1".} = when defined(Windows): var err = GetLastError() if err != 0'i32: - var msgbuf: cstring - if FormatMessageA(0x00000100 or 0x00001000 or 0x00000200, - nil, err, 0, addr(msgbuf), 0, nil) != 0'i32: - var m = $msgbuf - if msgbuf != nil: - LocalFree(msgbuf) - result = m + when useWinUnicode: + var msgbuf: widecstring + if FormatMessageW(0x00000100 or 0x00001000 or 0x00000200, + nil, err, 0, addr(msgbuf), 0, nil) != 0'i32: + result = $msgbuf + if msgbuf != nil: LocalFree(msgbuf) + else: + var msgbuf: cstring + if FormatMessageA(0x00000100 or 0x00001000 or 0x00000200, + nil, err, 0, addr(msgbuf), 0, nil) != 0'i32: + result = $msgbuf + if msgbuf != nil: LocalFree(msgbuf) if errno != 0'i32: result = $os.strerror(errno) @@ -236,10 +241,47 @@ proc UnixToNativePath*(path: string): string {. add result, path[i] inc(i) +when defined(windows): + template wrapUnary(varname, winApiProc, arg: expr) = + var tmp = allocWideCString(arg) + var varname = winApiProc(tmp) + dealloc tmp + + template wrapBinary(varname, winApiProc, arg, arg2: expr) = + var tmp2 = allocWideCString(arg) + var varname = winApiProc(tmp2, arg2) + dealloc tmp2 + + when useWinUnicode: + proc FindFirstFile(a: string, b: var TWIN32_FIND_DATA): THandle = + var aa = allocWideCString(a) + result = FindFirstFileW(aa, b) + dealloc aa + template FindNextFile(a, b: expr): expr = FindNextFileW(a, b) + template getCommandLine(): expr = getCommandLineW() + + proc skipFindData(f: TWIN32_FIND_DATA): bool {.inline.} = + result = f.cFilename[0].int == ord('.') + + template getFilename(f: expr): expr = + $cast[WideCString](addr(f.cFilename[0])) + else: + template FindFirstFile(a, b: expr): expr = FindFirstFileA(a, b) + template FindNextFile(a, b: expr): expr = FindNextFileA(a, b) + template getCommandLine(): expr = getCommandLineA() + + proc skipFindData(f: TWIN32_FIND_DATA): bool {.inline.} = + result = f.cFilename[0] == '.' + + template getFilename(f: expr): expr = $f.cFilename + proc existsFile*(filename: string): bool {.rtl, extern: "nos$1".} = ## Returns true if the file exists, false otherwise. when defined(windows): - var a = GetFileAttributesA(filename) + when useWinUnicode: + wrapUnary(a, GetFileAttributesW, filename) + else: + var a = GetFileAttributesA(filename) if a != -1'i32: result = (a and FILE_ATTRIBUTE_DIRECTORY) == 0'i32 else: @@ -250,7 +292,10 @@ proc existsDir*(dir: string): bool {.rtl, extern: "nos$1".} = ## Returns true iff the directory `dir` exists. If `dir` is a file, false ## is returned. when defined(windows): - var a = GetFileAttributesA(dir) + when useWinUnicode: + wrapUnary(a, GetFileAttributesW, dir) + else: + var a = GetFileAttributesA(dir) if a != -1'i32: result = (a and FILE_ATTRIBUTE_DIRECTORY) != 0'i32 else: @@ -265,7 +310,7 @@ proc getLastModificationTime*(file: string): TTime {.rtl, extern: "nos$1".} = return res.st_mtime else: var f: TWIN32_Find_Data - var h = findfirstFileA(file, f) + var h = findfirstFile(file, f) if h == -1'i32: OSError() result = winTimeToUnixTime(rdFileTime(f.ftLastWriteTime)) findclose(h) @@ -278,7 +323,7 @@ proc getLastAccessTime*(file: string): TTime {.rtl, extern: "nos$1".} = return res.st_atime else: var f: TWIN32_Find_Data - var h = findfirstFileA(file, f) + var h = findfirstFile(file, f) if h == -1'i32: OSError() result = winTimeToUnixTime(rdFileTime(f.ftLastAccessTime)) findclose(h) @@ -291,7 +336,7 @@ proc getCreationTime*(file: string): TTime {.rtl, extern: "nos$1".} = return res.st_ctime else: var f: TWIN32_Find_Data - var h = findfirstFileA(file, f) + var h = findfirstFile(file, f) if h == -1'i32: OSError() result = winTimeToUnixTime(rdFileTime(f.ftCreationTime)) findclose(h) @@ -304,12 +349,20 @@ proc fileNewer*(a, b: string): bool {.rtl, extern: "nos$1".} = proc getCurrentDir*(): string {.rtl, extern: "nos$1".} = ## Returns the `current working directory`:idx:. const bufsize = 512 # should be enough - result = newString(bufsize) when defined(windows): - var L = GetCurrentDirectoryA(bufsize, result) - if L == 0'i32: OSError() - setLen(result, L) + when useWinUnicode: + var res = cast[wideCString](alloc0(bufsize+1)) + var L = GetCurrentDirectoryW(bufsize, res) + result = res$L + dealloc res + if L == 0'i32: OSError() + else: + result = newString(bufsize) + var L = GetCurrentDirectoryA(bufsize, result) + if L == 0'i32: OSError() + setLen(result, L) else: + result = newString(bufsize) if getcwd(result, bufsize) != nil: setlen(result, c_strlen(result)) else: @@ -319,7 +372,13 @@ proc setCurrentDir*(newDir: string) {.inline.} = ## Sets the `current working directory`:idx:; `EOS` is raised if ## `newDir` cannot been set. when defined(Windows): - if SetCurrentDirectoryA(newDir) == 0'i32: OSError() + when useWinUnicode: + var x = allocWideCString(newDir) + let res = SetCurrentDirectoryW(x) + dealloc x + if res == 0'i32: OSError() + else: + if SetCurrentDirectoryA(newDir) == 0'i32: OSError() else: if chdir(newDir) != 0'i32: OSError() @@ -377,8 +436,7 @@ proc SplitPath*(path: string): tuple[head, tail: string] {. ## SplitPath("bin") -> ("", "bin") ## SplitPath("/bin") -> ("", "bin") ## SplitPath("") -> ("", "") - var - sepPos = -1 + var sepPos = -1 for i in countdown(len(path)-1, 0): if path[i] in {dirsep, altsep}: sepPos = i @@ -504,11 +562,24 @@ proc extractFilename*(path: string): string {. proc expandFilename*(filename: string): string {.rtl, extern: "nos$1".} = ## Returns the full path of `filename`, raises EOS in case of an error. when defined(windows): - var unused: cstring - result = newString(3072) - var L = GetFullPathNameA(filename, 3072'i32, result, unused) - if L <= 0'i32 or L >= 3072'i32: OSError() - setLen(result, L) + const bufsize = 3072'i32 + when useWinUnicode: + var unused: widecstring + var res = cast[widecstring](alloc(bufsize*2+2)) + var f = allocWideCString(filename) + var L = GetFullPathNameW(f, bufsize, res, unused) + dealloc f + if L <= 0'i32 or L >= bufsize: + dealloc res + OSError() + result = res$L + dealloc res + else: + var unused: cstring + result = newString(bufsize) + var L = GetFullPathNameA(filename, bufsize, result, unused) + if L <= 0'i32 or L >= bufsize: OSError() + setLen(result, L) elif defined(macosx): # On Mac OS X 10.5, realpath does not allocate the buffer on its own var pathBuffer: cstring = newString(pathMax) @@ -585,14 +656,26 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1".} = ## sym-linked paths to the same file or directory. when defined(Windows): var success = true - - template OpenHandle(path: expr): expr = - CreateFileA(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or - FILE_SHARE_WRITE, nil, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL, 0) - var f1 = OpenHandle(path1) - var f2 = OpenHandle(path2) + when useWinUnicode: + var p1 = allocWideCString(path1) + var p2 = allocWideCString(path2) + template OpenHandle(path: expr): expr = + CreateFileW(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL, 0) + + var f1 = OpenHandle(p1) + var f2 = OpenHandle(p2) + + else: + template OpenHandle(path: expr): expr = + CreateFileA(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL, 0) + + var f1 = OpenHandle(path1) + var f2 = OpenHandle(path2) if f1 != INVALID_HANDLE_VALUE and f2 != INVALID_HANDLE_VALUE: var fi1, fi2: TBY_HANDLE_FILE_INFORMATION @@ -607,13 +690,13 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1".} = discard CloseHandle(f1) discard CloseHandle(f2) + when useWinUnicode: + dealloc p1 + dealloc p2 - if not success: - OSError() - + if not success: OSError() else: - var - a, b: TStat + var a, b: TStat if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32: OSError() else: @@ -653,7 +736,15 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1".} = ## Copies a file from `source` to `dest`. If this fails, ## `EOS` is raised. when defined(Windows): - if CopyFileA(source, dest, 0'i32) == 0'i32: OSError() + when useWinUnicode: + var s = allocWideCString(source) + var d = allocWideCString(dest) + let res = CopyFileW(s, d, 0'i32) + dealloc s + dealloc d + if res == 0'i32: OSError() + else: + if CopyFileA(source, dest, 0'i32) == 0'i32: OSError() else: # generic version of copyFile which works for any platform: const bufSize = 8000 # better for memory manager @@ -710,23 +801,39 @@ var when defined(windows): # because we support Windows GUI applications, things get really # messy here... - proc strEnd(cstr: CString, c = 0'i32): CString {. - importc: "strchr", header: "<string.h>".} + when useWinUnicode: + proc strEnd(cstr: wideCString, c = 0'i32): wideCString {. + importc: "wcschr", header: "<string.h>".} + else: + proc strEnd(cstr: CString, c = 0'i32): CString {. + importc: "strchr", header: "<string.h>".} proc getEnvVarsC() = if not envComputed: environment = @[] - var - env = getEnvironmentStringsA() - e = env - if e == nil: return # an error occured - while True: - var eend = strEnd(e) - add(environment, $e) - e = cast[CString](cast[TAddress](eend)+1) - if eend[1] == '\0': break + when useWinUnicode: + var + env = getEnvironmentStringsW() + e = env + if e == nil: return # an error occured + while True: + var eend = strEnd(e) + add(environment, $e) + e = cast[wideCString](cast[TAddress](eend)+2) + if eend[1].int == 0: break + discard FreeEnvironmentStringsW(env) + else: + var + env = getEnvironmentStringsA() + e = env + if e == nil: return # an error occured + while True: + var eend = strEnd(e) + add(environment, $e) + e = cast[CString](cast[TAddress](eend)+1) + if eend[1] == '\0': break + discard FreeEnvironmentStringsA(env) envComputed = true - discard FreeEnvironmentStringsA(env) else: const @@ -804,8 +911,15 @@ proc putEnv*(key, val: string) = if cputenv(environment[indx]) != 0'i32: OSError() else: - if SetEnvironmentVariableA(key, val) == 0'i32: - OSError() + when useWinUnicode: + var k = allocWideCString(key) + var v = allocWideCString(val) + let res = SetEnvironmentVariableW(k, v) + dealloc k + dealloc v + if res == 0'i32: OSError() + else: + if SetEnvironmentVariableA(key, val) == 0'i32: OSError() iterator envPairs*(): tuple[key, value: TaintedString] = ## Iterate over all `environments variables`:idx:. In the first component @@ -821,18 +935,18 @@ iterator walkFiles*(pattern: string): string = ## Iterate over all the files that match the `pattern`. On POSIX this uses ## the `glob`:idx: call. ## - ## `pattern` is OS dependant, but at least the "\*.ext" + ## `pattern` is OS dependent, but at least the "\*.ext" ## notation is supported. when defined(windows): var f: TWin32FindData res: int - res = findfirstFileA(pattern, f) + res = findfirstFile(pattern, f) if res != -1: while true: - if f.cFileName[0] != '.': - yield splitFile(pattern).dir / extractFilename($f.cFileName) - if findnextFileA(res, f) == 0'i32: break + if not skipFindData(f): + yield splitFile(pattern).dir / extractFilename(getFilename(f)) + if findnextFile(res, f) == 0'i32: break findclose(res) else: # here we use glob var @@ -878,15 +992,15 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] = ## dirA/fileA2.txt when defined(windows): var f: TWIN32_Find_Data - var h = findfirstFileA(dir / "*", f) + var h = findfirstFile(dir / "*", f) if h != -1: while true: var k = pcFile - if f.cFilename[0] != '.': + if not skipFindData(f): if (f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) != 0'i32: k = pcDir - yield (k, dir / extractFilename($f.cFilename)) - if findnextFileA(h, f) == 0'i32: break + yield (k, dir / extractFilename(getFilename(f))) + if findnextFile(h, f) == 0'i32: break findclose(h) else: var d = openDir(dir) @@ -929,7 +1043,11 @@ iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string = proc rawRemoveDir(dir: string) = when defined(windows): - if RemoveDirectoryA(dir) == 0'i32 and GetLastError() != 3'i32 and + when useWinUnicode: + wrapUnary(res, RemoveDirectoryW, dir) + else: + var res = RemoveDirectoryA(dir) + if res == 0'i32 and GetLastError() != 3'i32 and GetLastError() != 18'i32: OSError() else: if rmdir(dir) != 0'i32 and errno != ENOENT: OSError() @@ -949,7 +1067,11 @@ proc rawCreateDir(dir: string) = if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST: OSError() else: - if CreateDirectoryA(dir, nil) == 0'i32 and GetLastError() != 183'i32: + when useWinUnicode: + wrapUnary(res, CreateDirectoryW, dir) + else: + var res = CreateDirectoryA(dir) + if res == 0'i32 and GetLastError() != 183'i32: OSError() proc createDir*(dir: string) {.rtl, extern: "nos$1".} = @@ -1097,7 +1219,10 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {. if (a.st_mode and S_IWOTH) != 0'i32: result.incl(fpOthersWrite) if (a.st_mode and S_IXOTH) != 0'i32: result.incl(fpOthersExec) else: - var res = GetFileAttributesA(filename) + when useWinUnicode: + wrapUnary(res, GetFileAttributesW, filename) + else: + var res = GetFileAttributesA(filename) if res == -1'i32: OSError() if (res and FILE_ATTRIBUTE_READONLY) != 0'i32: result = {fpUserExec, fpUserRead, fpGroupExec, fpGroupRead, @@ -1126,14 +1251,20 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. if chmod(filename, p) != 0: OSError() else: - var res = GetFileAttributesA(filename) + when useWinUnicode: + wrapUnary(res, GetFileAttributesW, filename) + else: + var res = GetFileAttributesA(filename) if res == -1'i32: OSError() if fpUserWrite in permissions: res = res and not FILE_ATTRIBUTE_READONLY else: res = res or FILE_ATTRIBUTE_READONLY - if SetFileAttributesA(filename, res) == - 1'i32: - OSError() + when useWinUnicode: + wrapBinary(res2, SetFileAttributesW, filename, res) + else: + var res2 = SetFileAttributesA(filename, res) + if res2 == - 1'i32: OSError() proc inclFilePermissions*(filename: string, permissions: set[TFilePermission]) {. @@ -1181,7 +1312,7 @@ when defined(windows): proc paramCount*(): int {.rtl, extern: "nos$1".} = ## Returns the number of `command line arguments`:idx: given to the ## application. - if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLineA()) + if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine()) result = ownArgv.len-1 proc paramStr*(i: int): TaintedString {.rtl, extern: "nos$1".} = @@ -1190,7 +1321,7 @@ when defined(windows): ## ## `i` should be in the range `1..paramCount()`, else ## the `EOutOfIndex` exception is raised. - if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLineA()) + if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine()) return TaintedString(ownArgv[i]) elif not defined(createNimRtl): @@ -1232,9 +1363,14 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1".} = # *BSD (and maybe Darwin too): # /proc/<pid>/file when defined(windows): - result = newString(256) - var len = getModuleFileNameA(0, result, 256) - setlen(result, int(len)) + when useWinUnicode: + var buf = cast[wideCString](alloc(256*2)) + var len = getModuleFileNameW(0, buf, 256) + result = buf$len + else: + result = newString(256) + var len = getModuleFileNameA(0, result, 256) + setlen(result, int(len)) elif defined(linux) or defined(aix): result = getApplAux("/proc/self/exe") elif defined(solaris): @@ -1290,7 +1426,7 @@ proc getFileSize*(file: string): biggestInt {.rtl, extern: "nos$1".} = ## returns the file size of `file`. Can raise ``EOS``. when defined(windows): var a: TWin32FindData - var resA = findfirstFileA(file, a) + var resA = findfirstFile(file, a) if resA == -1: OSError() result = rdFileSize(a) findclose(resA) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 2ed435b07..2807743fe 100755 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -343,8 +343,18 @@ when defined(Windows) and not defined(useNimRtl): if len(workingDir) > 0: wd = workingDir if env != nil: e = buildEnv(env) if poEchoCmd in options: echo($cmdl) - success = winlean.CreateProcess(nil, - cmdl, nil, nil, 1, NORMAL_PRIORITY_CLASS, e, wd, SI, ProcInfo) + when useWinUnicode: + var tmp = allocWideCString(cmdl) + var ee = allocWideCString(e) + var wwd = allocWideCString(wd) + success = winlean.CreateProcessW(nil, + tmp, nil, nil, 1, NORMAL_PRIORITY_CLASS, ee, wwd, SI, ProcInfo) + if tmp != nil: dealloc tmp + if ee != nil: dealloc ee + if wwd != nil: dealloc wwd + else: + success = winlean.CreateProcessA(nil, + cmdl, nil, nil, 1, NORMAL_PRIORITY_CLASS, e, wd, SI, ProcInfo) if poParentStreams notin options: FileClose(si.hStdInput) @@ -417,8 +427,15 @@ when defined(Windows) and not defined(useNimRtl): SI.hStdError = GetStdHandle(STD_ERROR_HANDLE) SI.hStdInput = GetStdHandle(STD_INPUT_HANDLE) SI.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE) - if winlean.CreateProcess(nil, command, nil, nil, 0, - NORMAL_PRIORITY_CLASS, nil, nil, SI, ProcInfo) == 0: + when useWinUnicode: + var c = allocWideCString(command) + var res = winlean.CreateProcessW(nil, c, nil, nil, 0, + NORMAL_PRIORITY_CLASS, nil, nil, SI, ProcInfo) + dealloc c + else: + var res = winlean.CreateProcessA(nil, command, nil, nil, 0, + NORMAL_PRIORITY_CLASS, nil, nil, SI, ProcInfo) + if res == 0: OSError() else: Process = ProcInfo.hProcess diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index 33d7dc5f2..0180bcdae 100755 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -34,9 +34,6 @@ proc ftell(f: TFile): int {.importc: "ftell", noDecl.} proc setvbuf(stream: TFile, buf: pointer, typ, size: cint): cint {. importc, nodecl.} -proc freopen(path, mode: cstring, stream: TFile): TFile {.importc: "freopen", - nodecl.} - proc write(f: TFile, c: cstring) = fputs(c, f) var @@ -161,7 +158,33 @@ proc rawEcho(x: string) {.inline, compilerproc.} = write(stdout, x) proc rawEchoNL() {.inline, compilerproc.} = write(stdout, "\n") # interface to the C procs: -proc fopen(filename, mode: CString): pointer {.importc: "fopen", noDecl.} + +when defined(windows) and not defined(useWinAnsi): + include "system/widestrs" + + proc wfopen(filename, mode: widecstring): pointer {. + importc: "_wfopen", nodecl.} + proc wfreopen(filename, mode: widecstring, stream: TFile): TFile {. + importc: "_wfreopen", nodecl.} + + proc fopen(filename, mode: CString): pointer = + var f = allocWideCString(filename) + var m = allocWideCString(mode) + result = wfopen(f, m) + dealloc m + dealloc f + + proc freopen(filename, mode: cstring, stream: TFile): TFile = + var f = allocWideCString(filename) + var m = allocWideCString(mode) + result = wfreopen(f, m, stream) + dealloc m + dealloc f + +else: + proc fopen(filename, mode: CString): pointer {.importc: "fopen", noDecl.} + proc freopen(filename, mode: cstring, stream: TFile): TFile {. + importc: "freopen", nodecl.} const FormatOpen: array [TFileMode, string] = ["rb", "wb", "w+b", "r+b", "ab"] diff --git a/lib/system/widestrs.nim b/lib/system/widestrs.nim new file mode 100644 index 000000000..588093d10 --- /dev/null +++ b/lib/system/widestrs.nim @@ -0,0 +1,260 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2012 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Nimrod support for C/C++'s `wide strings`:idx:. This is part of the system +## module! Do not import it directly! + +type + TUtf16Char* = distinct int16 + WideCString* = ptr array[0.. 1_000_000, TUtf16Char] + +proc len*(w: WideCString): int = + ## returns the length of a widestring. This traverses the whole string to + ## find the binary zero end marker! + while int16(w[result]) != 0'i16: inc result + +when true: + const + UNI_REPLACEMENT_CHAR = TUtf16Char(0xFFFD'i16) + UNI_MAX_BMP = 0x0000FFFF + UNI_MAX_UTF16 = 0x0010FFFF + UNI_MAX_UTF32 = 0x7FFFFFFF + UNI_MAX_LEGAL_UTF32 = 0x0010FFFF + + halfShift = 10 + halfBase = 0x0010000 + halfMask = 0x3FF + + UNI_SUR_HIGH_START = 0xD800 + UNI_SUR_HIGH_END = 0xDBFF + UNI_SUR_LOW_START = 0xDC00 + UNI_SUR_LOW_END = 0xDFFF + + template ones(n: expr): expr = ((1 shl n)-1) + + template fastRuneAt(s: cstring, i: int, result: expr, doInc = true) = + ## Returns the unicode character ``s[i]`` in `result`. If ``doInc == true`` + ## `i` is incremented by the number of bytes that have been processed. + bind ones + + if ord(s[i]) <=% 127: + result = ord(s[i]) + when doInc: inc(i) + elif ord(s[i]) shr 5 == 0b110: + #assert(ord(s[i+1]) shr 6 == 0b10) + result = (ord(s[i]) and (ones(5))) shl 6 or (ord(s[i+1]) and ones(6)) + when doInc: inc(i, 2) + elif ord(s[i]) shr 4 == 0b1110: + #assert(ord(s[i+1]) shr 6 == 0b10) + #assert(ord(s[i+2]) shr 6 == 0b10) + result = (ord(s[i]) and ones(4)) shl 12 or + (ord(s[i+1]) and ones(6)) shl 6 or + (ord(s[i+2]) and ones(6)) + when doInc: inc(i, 3) + elif ord(s[i]) shr 3 == 0b11110: + #assert(ord(s[i+1]) shr 6 == 0b10) + #assert(ord(s[i+2]) shr 6 == 0b10) + #assert(ord(s[i+3]) shr 6 == 0b10) + result = (ord(s[i]) and ones(3)) shl 18 or + (ord(s[i+1]) and ones(6)) shl 12 or + (ord(s[i+2]) and ones(6)) shl 6 or + (ord(s[i+3]) and ones(6)) + when doInc: inc(i, 4) + else: + result = 0xFFFD + when doInc: inc(i) + + iterator runes(s: cstring): int = + var + i = 0 + result: int + while s[i] != '\0': + fastRuneAt(s, i, result, true) + yield result + + proc allocWideCString*(source: cstring, L: int): WideCString = + ## free after usage with `dealloc`. + result = cast[wideCString](alloc(L * 4 + 2)) + var d = 0 + for ch in runes(source): + if ch <=% UNI_MAX_BMP: + if ch >=% UNI_SUR_HIGH_START and ch <=% UNI_SUR_LOW_END: + result[d] = UNI_REPLACEMENT_CHAR + else: + result[d] = TUtf16Char(toU16(ch)) + elif ch >% UNI_MAX_UTF16: + result[d] = UNI_REPLACEMENT_CHAR + else: + let ch = ch -% halfBase + result[d] = TUtf16Char(toU16((ch shr halfShift) +% UNI_SUR_HIGH_START)) + inc d + result[d] = TUtf16Char(toU16((ch and halfMask) +% UNI_SUR_LOW_START)) + inc d + result[d] = TUtf16Char(0'i16) + + proc allocWideCString*(s: cstring): WideCString = + ## free after usage with `dealloc`. + if s.isNil: return nil + + when not defined(c_strlen): + proc c_strlen(a: CString): int {.nodecl, noSideEffect, importc: "strlen".} + + let L = cstrlen(s) + result = allocWideCString(s, L) + + proc allocWideCString*(s: string): WideCString = + ## free after usage with `dealloc`. + result = allocWideCString(s, s.len) + + proc `$`*(w: wideCString, estimate: int): string = + result = newStringOfCap(estimate + estimate shr 2) + + var i = 0 + while w[i].int16 != 0'i16: + var ch = w[i].int + inc i + if ch >=% UNI_SUR_HIGH_START and ch <=% UNI_SUR_HIGH_END: + # If the 16 bits following the high surrogate are in the source buffer... + let ch2 = w[i].int + # If it's a low surrogate, convert to UTF32: + if ch2 >=% UNI_SUR_LOW_START and ch2 <=% UNI_SUR_LOW_END: + ch = ((ch -% UNI_SUR_HIGH_START) shr halfShift) +% + (ch2 -% UNI_SUR_LOW_START) +% halfBase + inc i + + if ch <=% 127: + result.add chr(ch) + elif ch <=% 0x07FF: + result.add chr((ch shr 6) or 0b110_00000) + result.add chr((ch and ones(6)) or 0b10_000000) + elif ch <=% 0xFFFF: + result.add chr(ch shr 12 or 0b1110_0000) + result.add chr(ch shr 6 and ones(6) or 0b10_0000_00) + result.add chr(ch and ones(6) or 0b10_0000_00) + elif ch <=% 0x0010FFFF: + result.add chr(ch shr 18 or 0b1111_0000) + result.add chr(ch shr 12 and ones(6) or 0b10_0000_00) + result.add chr(ch shr 6 and ones(6) or 0b10_0000_00) + result.add chr(ch and ones(6) or 0b10_0000_00) + else: + # replacement char: + result.add chr(0xFFFD shr 12 or 0b1110_0000) + result.add chr(0xFFFD shr 6 and ones(6) or 0b10_0000_00) + result.add chr(0xFFFD and ones(6) or 0b10_0000_00) + + proc `$`*(s: WideCString): string = + result = s $ 80 + +else: + const + utf8Encoding = 65001 + + proc MultiByteToWideChar*( + CodePage: int32, + dwFlags: int32, + lpMultiByteStr: cstring, + cbMultiByte: cint, + lpWideCharStr: WideCString, + cchWideChar: cint): cint {. + stdcall, importc: "MultiByteToWideChar", dynlib: "kernel32".} + + proc WideCharToMultiByte*( + CodePage: int32, + dwFlags: int32, + lpWideCharStr: WideCString, + cchWideChar: cint, + lpMultiByteStr: cstring, + cbMultiByte: cint, + lpDefaultChar: cstring=nil, + lpUsedDefaultChar: pointer=nil): cint {. + stdcall, importc: "WideCharToMultiByte", dynlib: "kernel32".} + + proc raiseEncodingError() {.noinline, noreturn.} = + raise newException(EOS, "error in unicode conversion") + + proc `$`*(s: WideCString, len: int): string = + # special case: empty string: needed because MultiByteToWideChar + # returns 0 in case of error: + if len == 0: return "" + + # educated guess of capacity: + var cap = len + len shr 2 + result = newStringOfCap(cap) + + let m = WideCharToMultiByte( + CodePage = utf8Encoding, + dwFlags = 0'i32, + lpWideCharStr = s, + cchWideChar = cint(len), + lpMultiByteStr = cstring(result), + cbMultiByte = cap) + if m == 0: + # try again; ask for capacity: + cap = WideCharToMultiByte( + CodePage = utf8Encoding, + dwFlags = 0'i32, + lpWideCharStr = s, + cchWideChar = cint(len), + lpMultiByteStr = nil, + cbMultiByte = cint(0)) + # and do the conversion properly: + result = newStringOfCap(cap) + let m = WideCharToMultiByte( + CodePage = utf8Encoding, + dwFlags = 0'i32, + lpWideCharStr = s, + cchWideChar = cint(len), + lpMultiByteStr = cstring(result), + cbMultiByte = cap) + if m == 0: raiseEncodingError() + setLen(result, m) + elif m <= cap: + setLen(result, m) + else: + sysAssert(false, "") # cannot happen + + proc `$`*(s: WideCString): string = + result = s $ s.len + + proc allocWideCString*(s: string): WideCString = + ## free after usage with `dealloc`. + let cap = s.len+1 + result = cast[wideCString](alloc0(cap * 2)) + # special case: empty string: needed because MultiByteToWideChar + # return 0 in case of error: + if s.len == 0: return + # convert to utf-16 LE + let m = MultiByteToWideChar(CodePage = utf8Encoding, dwFlags = 0'i32, + lpMultiByteStr = cstring(s), + cbMultiByte = cint(s.len), + lpWideCharStr = result, + cchWideChar = cint(cap)) + if m == 0: raiseEncodingError() + + proc allocWideCString*(s: cstring): WideCString = + ## free after usage with `dealloc`. + if s.isNil: return nil + + when not defined(c_strlen): + proc c_strlen(a: CString): int {.nodecl, noSideEffect, importc: "strlen".} + + let len = cstrlen(s) + let cap = len+1 + result = cast[wideCString](alloc0(cap * 2)) + # special case: empty string: needed because MultiByteToWideChar + # return 0 in case of error: + if s.len == 0: return + # convert to utf-16 LE + let m = MultiByteToWideChar(CodePage = utf8Encoding, dwFlags = 0'i32, + lpMultiByteStr = s, + cbMultiByte = cint(len), + lpWideCharStr = result, + cchWideChar = cint(cap)) + if m == 0: raiseEncodingError() + diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 59c758241..adbabfa0f 100755 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -10,6 +10,9 @@ ## This module implements a small wrapper for some needed Win API procedures, ## so that the Nimrod compiler does not depend on the huge Windows module. +const + useWinUnicode* = not defined(useWinAnsi) + type THandle* = int LONG* = int @@ -63,6 +66,11 @@ type nFileIndexHigh*: DWORD nFileIndexLow*: DWORD +when useWinUnicode: + type TWinChar* = TUtf16Char +else: + type TWinChar* = char + const STARTF_USESHOWWINDOW* = 1'i32 STARTF_USESTDHANDLES* = 256'i32 @@ -100,15 +108,27 @@ proc CreatePipe*(hReadPipe, hWritePipe: var THandle, lpPipeAttributes: var TSECURITY_ATTRIBUTES, nSize: int32): WINBOOL{. stdcall, dynlib: "kernel32", importc: "CreatePipe".} - -proc CreateProcess*(lpApplicationName, lpCommandLine: cstring, - lpProcessAttributes: ptr TSECURITY_ATTRIBUTES, - lpThreadAttributes: ptr TSECURITY_ATTRIBUTES, - bInheritHandles: WINBOOL, dwCreationFlags: int32, - lpEnvironment: pointer, lpCurrentDirectory: cstring, - lpStartupInfo: var TSTARTUPINFO, - lpProcessInformation: var TPROCESS_INFORMATION): WINBOOL{. - stdcall, dynlib: "kernel32", importc: "CreateProcessA".} + +when useWinUnicode: + proc CreateProcessW*(lpApplicationName, lpCommandLine: widecstring, + lpProcessAttributes: ptr TSECURITY_ATTRIBUTES, + lpThreadAttributes: ptr TSECURITY_ATTRIBUTES, + bInheritHandles: WINBOOL, dwCreationFlags: int32, + lpEnvironment: pointer, lpCurrentDirectory: widecstring, + lpStartupInfo: var TSTARTUPINFO, + lpProcessInformation: var TPROCESS_INFORMATION): WINBOOL{. + stdcall, dynlib: "kernel32", importc: "CreateProcessW".} + +else: + proc CreateProcessA*(lpApplicationName, lpCommandLine: cstring, + lpProcessAttributes: ptr TSECURITY_ATTRIBUTES, + lpThreadAttributes: ptr TSECURITY_ATTRIBUTES, + bInheritHandles: WINBOOL, dwCreationFlags: int32, + lpEnvironment: pointer, lpCurrentDirectory: cstring, + lpStartupInfo: var TSTARTUPINFO, + lpProcessInformation: var TPROCESS_INFORMATION): WINBOOL{. + stdcall, dynlib: "kernel32", importc: "CreateProcessA".} + proc SuspendThread*(hThread: THANDLE): int32 {.stdcall, dynlib: "kernel32", importc: "SuspendThread".} @@ -132,27 +152,53 @@ proc FlushFileBuffers*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32", importc: "FlushFileBuffers".} proc GetLastError*(): int32 {.importc, stdcall, dynlib: "kernel32".} -proc FormatMessageA*(dwFlags: int32, lpSource: pointer, + +when useWinUnicode: + proc FormatMessageW*(dwFlags: int32, lpSource: pointer, + dwMessageId, dwLanguageId: int32, + lpBuffer: pointer, nSize: int32, + Arguments: pointer): int32 {. + importc, stdcall, dynlib: "kernel32".} +else: + proc FormatMessageA*(dwFlags: int32, lpSource: pointer, dwMessageId, dwLanguageId: int32, lpBuffer: pointer, nSize: int32, Arguments: pointer): int32 {. importc, stdcall, dynlib: "kernel32".} -proc LocalFree*(p: pointer) {.importc, stdcall, dynlib: "kernel32".} - -proc GetCurrentDirectoryA*(nBufferLength: int32, lpBuffer: cstring): int32 {. - importc, dynlib: "kernel32", stdcall.} -proc SetCurrentDirectoryA*(lpPathName: cstring): int32 {. - importc, dynlib: "kernel32", stdcall.} -proc CreateDirectoryA*(pathName: cstring, security: Pointer): int32 {. - importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.} -proc RemoveDirectoryA*(lpPathName: cstring): int32 {. - importc, dynlib: "kernel32", stdcall.} -proc SetEnvironmentVariableA*(lpName, lpValue: cstring): int32 {. - stdcall, dynlib: "kernel32", importc.} -proc GetModuleFileNameA*(handle: THandle, buf: CString, size: int32): int32 {. - importc, dynlib: "kernel32", stdcall.} +proc LocalFree*(p: pointer) {.importc, stdcall, dynlib: "kernel32".} +when useWinUnicode: + proc GetCurrentDirectoryW*(nBufferLength: int32, + lpBuffer: widecstring): int32 {. + importc, dynlib: "kernel32", stdcall.} + proc SetCurrentDirectoryW*(lpPathName: widecstring): int32 {. + importc, dynlib: "kernel32", stdcall.} + proc CreateDirectoryW*(pathName: widecstring, security: Pointer=nil): int32 {. + importc: "CreateDirectoryW", dynlib: "kernel32", stdcall.} + proc RemoveDirectoryW*(lpPathName: widecstring): int32 {. + importc, dynlib: "kernel32", stdcall.} + proc SetEnvironmentVariableW*(lpName, lpValue: widecstring): int32 {. + stdcall, dynlib: "kernel32", importc.} + + proc GetModuleFileNameW*(handle: THandle, buf: wideCString, + size: int32): int32 {.importc, + dynlib: "kernel32", stdcall.} +else: + proc GetCurrentDirectoryA*(nBufferLength: int32, lpBuffer: cstring): int32 {. + importc, dynlib: "kernel32", stdcall.} + proc SetCurrentDirectoryA*(lpPathName: cstring): int32 {. + importc, dynlib: "kernel32", stdcall.} + proc CreateDirectoryA*(pathName: cstring, security: Pointer=nil): int32 {. + importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.} + proc RemoveDirectoryA*(lpPathName: cstring): int32 {. + importc, dynlib: "kernel32", stdcall.} + proc SetEnvironmentVariableA*(lpName, lpValue: cstring): int32 {. + stdcall, dynlib: "kernel32", importc.} + + proc GetModuleFileNameA*(handle: THandle, buf: CString, size: int32): int32 {. + importc, dynlib: "kernel32", stdcall.} + const FILE_ATTRIBUTE_ARCHIVE* = 32'i32 FILE_ATTRIBUTE_COMPRESSED* = 2048'i32 @@ -174,36 +220,69 @@ type nFileSizeLow*: int32 dwReserved0: int32 dwReserved1: int32 - cFileName*: array[0..(MAX_PATH) - 1, char] - cAlternateFileName*: array[0..13, char] - -proc FindFirstFileA*(lpFileName: cstring, - lpFindFileData: var TWIN32_FIND_DATA): THANDLE {. - stdcall, dynlib: "kernel32", importc: "FindFirstFileA".} -proc FindNextFileA*(hFindFile: THANDLE, - lpFindFileData: var TWIN32_FIND_DATA): int32 {. - stdcall, dynlib: "kernel32", importc: "FindNextFileA".} + cFileName*: array[0..(MAX_PATH) - 1, TWinChar] + cAlternateFileName*: array[0..13, TWinChar] + +when useWinUnicode: + proc FindFirstFileW*(lpFileName: widecstring, + lpFindFileData: var TWIN32_FIND_DATA): THANDLE {. + stdcall, dynlib: "kernel32", importc: "FindFirstFileW".} + proc FindNextFileW*(hFindFile: THANDLE, + lpFindFileData: var TWIN32_FIND_DATA): int32 {. + stdcall, dynlib: "kernel32", importc: "FindNextFileW".} +else: + proc FindFirstFileA*(lpFileName: cstring, + lpFindFileData: var TWIN32_FIND_DATA): THANDLE {. + stdcall, dynlib: "kernel32", importc: "FindFirstFileA".} + proc FindNextFileA*(hFindFile: THANDLE, + lpFindFileData: var TWIN32_FIND_DATA): int32 {. + stdcall, dynlib: "kernel32", importc: "FindNextFileA".} + proc FindClose*(hFindFile: THANDLE) {.stdcall, dynlib: "kernel32", importc: "FindClose".} -proc GetFullPathNameA*(lpFileName: cstring, nBufferLength: int32, - lpBuffer: cstring, lpFilePart: var cstring): int32 {. - stdcall, dynlib: "kernel32", importc.} -proc GetFileAttributesA*(lpFileName: cstring): int32 {. +when useWinUnicode: + proc GetFullPathNameW*(lpFileName: widecstring, nBufferLength: int32, + lpBuffer: widecstring, + lpFilePart: var widecstring): int32 {. + stdcall, dynlib: "kernel32", importc.} + proc GetFileAttributesW*(lpFileName: widecstring): int32 {. + stdcall, dynlib: "kernel32", importc.} + proc SetFileAttributesW*(lpFileName: widecstring, + dwFileAttributes: int32): WINBOOL {. + stdcall, dynlib: "kernel32", importc: "SetFileAttributesW".} + + proc CopyFileW*(lpExistingFileName, lpNewFileName: wideCString, + bFailIfExists: cint): cint {. + importc, stdcall, dynlib: "kernel32".} + + proc GetEnvironmentStringsW*(): widecstring {. + stdcall, dynlib: "kernel32", importc.} + proc FreeEnvironmentStringsW*(para1: widecstring): int32 {. + stdcall, dynlib: "kernel32", importc.} + + proc GetCommandLineW*(): wideCString {.importc, stdcall, dynlib: "kernel32".} + +else: + proc GetFullPathNameA*(lpFileName: cstring, nBufferLength: int32, + lpBuffer: cstring, lpFilePart: var cstring): int32 {. stdcall, dynlib: "kernel32", importc.} -proc SetFileAttributesA*(lpFileName: cstring, dwFileAttributes: int32): WINBOOL {. - stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".} + proc GetFileAttributesA*(lpFileName: cstring): int32 {. + stdcall, dynlib: "kernel32", importc.} + proc SetFileAttributesA*(lpFileName: cstring, + dwFileAttributes: int32): WINBOOL {. + stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".} -proc CopyFileA*(lpExistingFileName, lpNewFileName: CString, - bFailIfExists: cint): cint {. - importc, stdcall, dynlib: "kernel32".} + proc CopyFileA*(lpExistingFileName, lpNewFileName: CString, + bFailIfExists: cint): cint {. + importc, stdcall, dynlib: "kernel32".} -proc GetEnvironmentStringsA*(): cstring {. - stdcall, dynlib: "kernel32", importc.} -proc FreeEnvironmentStringsA*(para1: cstring): int32 {. - stdcall, dynlib: "kernel32", importc.} + proc GetEnvironmentStringsA*(): cstring {. + stdcall, dynlib: "kernel32", importc.} + proc FreeEnvironmentStringsA*(para1: cstring): int32 {. + stdcall, dynlib: "kernel32", importc.} -proc GetCommandLineA*(): CString {.importc, stdcall, dynlib: "kernel32".} + proc GetCommandLineA*(): CString {.importc, stdcall, dynlib: "kernel32".} proc rdFileTime*(f: TFILETIME): int64 = result = ze64(f.dwLowDateTime) or (ze64(f.dwHighDateTime) shl 32) @@ -217,11 +296,18 @@ proc GetSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var TFILETIME) {. proc Sleep*(dwMilliseconds: int32){.stdcall, dynlib: "kernel32", importc: "Sleep".} -proc ShellExecute*(HWND: THandle, lpOperation, lpFile, - lpParameters, lpDirectory: cstring, - nShowCmd: int32): THandle{. - stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".} - +when useWinUnicode: + proc ShellExecuteW*(HWND: THandle, lpOperation, lpFile, + lpParameters, lpDirectory: widecstring, + nShowCmd: int32): THandle{. + stdcall, dynlib: "shell32.dll", importc: "ShellExecuteW".} + +else: + proc ShellExecuteA*(HWND: THandle, lpOperation, lpFile, + lpParameters, lpDirectory: cstring, + nShowCmd: int32): THandle{. + stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".} + proc GetFileInformationByHandle*(hFile: THandle, lpFileInformation: ptr TBY_HANDLE_FILE_INFORMATION): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetFileInformationByHandle".} @@ -446,11 +532,18 @@ const FILE_FLAG_BACKUP_SEMANTICS* = 33554432'i32 -proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD, - lpSecurityAttributes: pointer, - dwCreationDisposition, dwFlagsAndAttributes: DWORD, - hTemplateFile: THANDLE): THANDLE {. - stdcall, dynlib: "kernel32", importc: "CreateFileA".} +when useWinUnicode: + proc CreateFileW*(lpFileName: widecstring, dwDesiredAccess, dwShareMode: DWORD, + lpSecurityAttributes: pointer, + dwCreationDisposition, dwFlagsAndAttributes: DWORD, + hTemplateFile: THANDLE): THANDLE {. + stdcall, dynlib: "kernel32", importc: "CreateFileW".} +else: + proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD, + lpSecurityAttributes: pointer, + dwCreationDisposition, dwFlagsAndAttributes: DWORD, + hTemplateFile: THANDLE): THANDLE {. + stdcall, dynlib: "kernel32", importc: "CreateFileA".} proc SetEndOfFile*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32", importc: "SetEndOfFile".} @@ -469,11 +562,20 @@ proc MapViewOfFileEx*(hFileMappingObject: THANDLE, dwDesiredAccess: DWORD, lpBaseAddress: pointer): pointer{. stdcall, dynlib: "kernel32", importc: "MapViewOfFileEx".} -proc CreateFileMapping*(hFile: THANDLE, - lpFileMappingAttributes: pointer, - flProtect, dwMaximumSizeHigh: DWORD, - dwMaximumSizeLow: DWORD, lpName: cstring): THANDLE {. - stdcall, dynlib: "kernel32", importc: "CreateFileMappingA".} +proc CreateFileMappingW*(hFile: THANDLE, + lpFileMappingAttributes: pointer, + flProtect, dwMaximumSizeHigh: DWORD, + dwMaximumSizeLow: DWORD, + lpName: pointer): THANDLE {. + stdcall, dynlib: "kernel32", importc: "CreateFileMappingW".} + +when not useWinUnicode: + proc CreateFileMappingA*(hFile: THANDLE, + lpFileMappingAttributes: pointer, + flProtect, dwMaximumSizeHigh: DWORD, + dwMaximumSizeLow: DWORD, lpName: cstring): THANDLE {. + stdcall, dynlib: "kernel32", importc: "CreateFileMappingA".} proc UnmapViewOfFile*(lpBaseAddress: pointer): WINBOOL {.stdcall, dynlib: "kernel32", importc: "UnmapViewOfFile".} + diff --git a/todo.txt b/todo.txt index 3269b7fb5..2b4fdecaf 100755 --- a/todo.txt +++ b/todo.txt @@ -23,8 +23,6 @@ version 0.9.0 - we need to support iteration of 2 different data structures in parallel - make exceptions compatible with C++ exceptions - 'const' objects including case objects -- os module should use Windows Unicode versions -- 64bit build for Windows - change how comments are part of the AST - optional indentation for 'case' statement; hm, keep in mind other syntax changes that people want; may turn out to be a bad idea diff --git a/tools/nimgrep.nimrod.cfg b/tools/nimgrep.nimrod.cfg index b931ff567..6d0ea5aad 100755 --- a/tools/nimgrep.nimrod.cfg +++ b/tools/nimgrep.nimrod.cfg @@ -1,5 +1,5 @@ -# The GC is still too fragile; I don't want that ``--replace`` does bad things -# to important files. Nimgrep does not really need a GC anyway. +# The GC is stable enough now: + +#--gc:none ---gc:none diff --git a/tools/niminst/buildbat.tmpl b/tools/niminst/buildbat.tmpl index fdb55c8de..11fa97a5a 100755 --- a/tools/niminst/buildbat.tmpl +++ b/tools/niminst/buildbat.tmpl @@ -1,5 +1,5 @@ #! stdtmpl(subsChar='?') | standard -#proc GenerateBuildBatchScript(c: TConfigData): string = +#proc GenerateBuildBatchScript(c: TConfigData, target: TTarget): string = # result = "@echo off\nREM Generated by niminst\n" SET CC=gcc SET LINKER=gcc @@ -8,13 +8,9 @@ SET LINK_FLAGS=?{c.linker.flags} REM call the compiler: -IF EXIST %SystemRoot%\SysWOW64 GOTO :Win64 - -ECHO Building for Win32 - # block win32: # var linkCmd = "" -# for ff in items(c.cfiles[1][1]): +# for ff in items(c.cfiles[1][ord(target)]): # let f = ff.replace('/', '\\') ECHO %CC% %COMP_FLAGS% -Ibuild -c ?{f} -o ?{changeFileExt(f, "o")} %CC% %COMP_FLAGS% -Ibuild -c ?{f} -o ?{changeFileExt(f, "o")} @@ -26,25 +22,4 @@ ECHO %LINKER% %LINK_FLAGS% -o ?{firstBinPath(c)\toLower(c.name)}.exe ?linkCmd # end block -GOTO :end - -:Win64 -ECHO Building for Win64 - -# block win64: -# var linkCmd = "" -# for ff in items(c.cfiles[1][2]): -# let f = ff.replace('/', '\\') -ECHO %CC% %COMP_FLAGS% -Ibuild -c ?{f} -o ?{changeFileExt(f, "o")} -%CC% %COMP_FLAGS% -Ibuild -c ?{f} -o ?{changeFileExt(f, "o")} -# linkCmd.add(" " & changeFileExt(f, "o")) -# end for - -ECHO %LINKER% %LINK_FLAGS% -o ?{firstBinPath(c)\toLower(c.name)}.exe ?linkCmd -%LINKER% %LINK_FLAGS% -o ?{firstBinPath(c)\toLower(c.name)}.exe ?linkCmd - -# end block - -:end - ECHO SUCCESS diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index 207df0d32..5059d3bba 100755 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -20,12 +20,14 @@ const maxOS = 20 # max number of OSes maxCPU = 10 # max number of CPUs buildShFile = "build.sh" - buildBatFile = "build.bat" + buildBatFile32 = "build.bat" + buildBatFile64 = "build64.bat" installShFile = "install.sh" deinstallShFile = "deinstall.sh" type TAppType = enum appConsole, appGUI + TTarget = enum tWin32 = 1, tWin64 = 2 TAction = enum actionNone, # action not yet known actionCSource # action: create C sources @@ -404,7 +406,8 @@ proc srcdist(c: var TConfigData) = # second pass: remove duplicate files removeDuplicateFiles(c) writeFile(buildShFile, GenerateBuildShellScript(c), "\10") - writeFile(buildBatFile, GenerateBuildBatchScript(c), "\13\10") + writeFile(buildBatFile32, GenerateBuildBatchScript(c, tWin32), "\13\10") + writeFile(buildBatFile64, GenerateBuildBatchScript(c, tWin64), "\13\10") if c.installScript: writeFile(installShFile, GenerateInstallScript(c), "\10") if c.uninstallScript: @@ -436,7 +439,8 @@ when haveZipLib: else: n = c.outdir / n var z: TZipArchive if open(z, n, fmWrite): - addFile(z, proj / buildBatFile, buildBatFile) + addFile(z, proj / buildBatFile32, buildBatFile32) + addFile(z, proj / buildBatFile64, buildBatFile64) addFile(z, proj / buildShFile, buildShFile) addFile(z, proj / installShFile, installShFile) addFile(z, proj / deinstallShFile, deinstallShFile) diff --git a/web/download.txt b/web/download.txt index 47c2501e9..48c5459d6 100755 --- a/web/download.txt +++ b/web/download.txt @@ -4,12 +4,12 @@ Here you can download the latest version of the Nimrod Compiler. Please choose your platform: * source-based installation: `<download/nimrod_0.8.14.zip>`_ -* installer for Windows XP/Vista (i386): `<download/nimrod_0.8.14.exe>`_ +* installer for Windows XP/Vista/7 (i386, 32bit): `<download/nimrod_0.8.14.exe>`_ (includes GCC and everything else you need) The source-based installation has been tested on these systems: * Linux: i386, AMD64, PowerPC -* Mac OS X: i386 +* Mac OS X: i386, AMD64 Other UNIX-based operating systems may work. An older version was tested on FreeBSD (i386). diff --git a/web/news.txt b/web/news.txt index 6c0e85f6b..540ba144a 100755 --- a/web/news.txt +++ b/web/news.txt @@ -27,6 +27,20 @@ Library Additions code during compilation. +Changes affecting backwards compatibility +----------------------------------------- + +- On Windows filenames and paths are supposed to be in UTF-8. + The ``system``, ``os``, ``osproc`` and ``memfiles`` modules use the wide + string versions of the WinAPI. Use the ``-d:useWinAnsi`` switch to revert + back to the old behaviour which uses the Ansi string versions. + +Compiler Additions +------------------ + +- Win64 is now an officially supported target. + + 2012-02-09 Version 0.8.14 released ================================== |