Browse Source

o merged cpstrrtl branch (includes unicode branch). In general, this adds
support for arbitrarily encoded ansistrings to many routines related to
file system access (and some others).

WARNING: while the parameters of many routines have been changed from
"ansistring" to "rawbytestring" to avoid data loss due to conversions,
this is not a panacea. If you pass a string concatenation to such a
parameter and not all strings in this concatenation have the same
code page, all strings and the result will be converted to
DefaultSystemCodePage (= ansi code page by default). In particular,
concatenating e.g. an Utf8String with a constant string and passing
the result to a RawByteString parameter will convert the result into
the DefaultSystemCodePage (unless the source code is compiler with
{$modeswitch systemcodepage} or {$mode delphiunicode} *and* the ansi
code page on the system you are compiling *on* happens to be UTF-8)

You can define and use alternative routines that explicitly accept
Utf8String parameters to avoid this pitfall. Internally, all of these
routines ensure that they never trigger this condition and ensure that
not unnecessary/unwanted code page conversions occur.

+ DefaultFileSystemCodePage variable that holds the code page used for
communicating with the OS single byte file system APIs, and for the
strings returned by those same APIs. Initialized with
o the result of GetACP in the system unit of Windows platforms, except for
WinCE which uses UTF-8 since its file system OS API calls already use
the UTF-16 versions
o CP_UTF8 on Unix platforms with FPCRTL_FILESYSTEM_UTF8 defined, and with
DefaultSystemCodePage on other Unix platforms
o DefaultSystemCodePage on Java/Android JVM targets
+ DefaultRTLFileSystemCodePage variable that holds the code page used to
encode strings returned by RTL routines that return filenames obtained
from OS API calls. By default the same as DefaultFileSystemCodePage on
all platforms. Separate from DefaultFileSystemCodePage for clarity on
platforms that may use either utf-16 or single byte OS API calls to
send/receive file names (such as most Windows platforms)
+ new scpFileSystemSingleByte enum that can be passed to
GetStandardCodePage() to get the default code page for OS single byte file
system APIs, with implementations for Unix and Windows
+ SetMultiByteFileSystemCodePage() procedure to override the value of
DefaultFileSystemCodePage
+ ToSingleByteFileSystemEncodedFileName() function to convert a string to to
DefaultFileSystemCodePage (does *not* take care of OS-specific quirks like
Darwin always returning file names in decomposed UTF-8)
+ support for CP_OEMCP
* textrec/filerec now store the filename by default using widechar. It is
possible to switch back to ansichars using the FPC_ANSI_TEXTFILEREC define.
In that case, from now on the filename will always be stored in
DefaultFileSystemEncoding
* fixed potential buffer overflows and non-null-terminated file names in
textrec/filerec

* when concatenating ansistrings, do not map CP_NONE (rawbytestring) to
CP_ACP (defaultsystemcodepage), because if all input strings have the
same code page then the result should also have that code page if it's
assigned to a rawbytestring rather than getting defaultsystemcodepage
* do not consider empty strings to determine the code page of the result
in fpc_AnsiStr_Concat_multi(), because that will cause a different
result than when using a sequence of fpc_AnsiStr_Concat() calls (it
ignores empty strings to determine the result code page) and it's also
slower

* do not consider the run time code page of the destination string in
fpc_AnsiStr_Concat(_multi)() because Delphi does not do so either. This
was introduced in r19118, probably to hide another bug + test
* never change the code page of a non-empty string when calling setlength on
it

* handle the fact that GetEnvironmentStringsA returns the environment in the
OEM instead of in the Ansi code page (mantis #22524, #15233)
* don't truncate environment variable strings in GetEnvironmentString(),
its result is now ansistring/unicodestring depending on whether the
RTL was compiled with FPC_RTL_UNICODE

* unix:
o made the ansistring parameters of the fp*() file system routine overloads
constant, changed them to rawbytestring and added
DefaultFileSystemCodePage conversions
o unicodestring support for POpen(), and DefaultFileSystemCodePage support
for POpen(RawByteString)

+ DefaultFileSystemCodePage support for dynlibs unit

+ rawbytestring/unicodestring overloads for:
o system: fexpand, lowercase, uppercase, getdir, mkdir, chdir, rmdir,
assign, erase, rename
o objpas: AssignFile,
o sysutils: FileCreate, FileOpen, FileExists, DirectoryExists, FileSetDate,
FileGetAttr, FileSetAttr, DeleteFile, RenameFile, FileSearch, ExeSearch,
FindFirst, FindNext, FindClose, FileIsReadOnly, GetCurrentDir,
SetCurrentDir, ChangeFileExt, ExtractFilePath, ExtractFileDrive,
ExtractFileName, ExtractFileExt, ExtractFileDir, ExtractShortPathName,
ExpandFileName, ExpandFileNameCase, ExpandUNCFileName,
ExtractRelativepath, IncludeTrailingPathDelimiter,
IncludeTrailingBackslash, ExcludeTrailingBackslash,
ExcludeTrailingPathDelimiter, IncludeLeadingPathDelimiter,
ExcludeLeadingPathDelimiter, IsPathDelimiter, DoDirSeparators,
SetDirSeparators, GetDirs, ConcatPaths, GetEnvironmentVariable

-- the default string type used by FindFirst/Next depends on whether the
RTL was compiled with FPC_RTL_UNICODE. To force the RawByteString
version pass a TRawByteSearchRec, for the UnicodeString version pass
a TUnicodeSearchRec.

+ paramstr(longint):unicodestring available for {$modeswitch unicodestrings}

+ pwidechar versions in sysutils of strecopy, strend, strcat, strcomp,
strlcomp, stricomp, strlcat, strrscan,strlower, strupper, strlicomp,
strpos, WideStrAlloc, StrBufSize, StrDispose + tests


git-svn-id: trunk@25432 -

Jonas Maebe 12 years ago
parent
commit
cde2d1b8ee
100 changed files with 3366 additions and 1724 deletions
  1. 52 0
      .gitattributes
  2. 1 1
      compiler/assemble.pas
  3. 1 1
      compiler/cfileutl.pas
  4. 8 2
      compiler/defcmp.pas
  5. 1 1
      compiler/globals.pas
  6. 6 2
      compiler/nadd.pas
  7. 32 52
      compiler/ncnv.pas
  8. 6 2
      compiler/nopt.pas
  9. 1 1
      compiler/options.pas
  10. 21 55
      compiler/symdef.pas
  11. 24 0
      rtl/aix/rtldefs.inc
  12. 28 6
      rtl/amiga/dos.pp
  13. 24 0
      rtl/amiga/rtldefs.inc
  14. 23 26
      rtl/amiga/sysdir.inc
  15. 3 3
      rtl/amiga/sysfile.inc
  16. 35 0
      rtl/amiga/sysos.inc
  17. 51 68
      rtl/amiga/sysutils.pp
  18. 24 0
      rtl/atari/rtldefs.inc
  19. 24 0
      rtl/beos/rtldefs.inc
  20. 24 0
      rtl/darwin/rtldefs.inc
  21. 29 0
      rtl/embedded/rtldefs.inc
  22. 27 3
      rtl/embedded/sysdir.inc
  23. 3 3
      rtl/embedded/sysfile.inc
  24. 20 39
      rtl/embedded/sysutils.pp
  25. 10 4
      rtl/emx/dos.pas
  26. 24 0
      rtl/emx/rtldefs.inc
  27. 35 40
      rtl/emx/sysdir.inc
  28. 26 11
      rtl/emx/sysfile.inc
  29. 99 107
      rtl/emx/sysutils.pp
  30. 24 0
      rtl/freebsd/rtldefs.inc
  31. 24 0
      rtl/gba/rtldefs.inc
  32. 4 4
      rtl/gba/sysdir.inc
  33. 3 3
      rtl/gba/sysfile.inc
  34. 20 39
      rtl/gba/sysutils.pp
  35. 18 0
      rtl/go32v2/dos.pp
  36. 24 0
      rtl/go32v2/rtldefs.inc
  37. 28 24
      rtl/go32v2/sysdir.inc
  38. 24 7
      rtl/go32v2/sysfile.inc
  39. 59 65
      rtl/go32v2/sysutils.pp
  40. 24 0
      rtl/haiku/rtldefs.inc
  41. 117 84
      rtl/inc/astrings.inc
  42. 5 1
      rtl/inc/compproc.inc
  43. 75 20
      rtl/inc/dynlibs.pas
  44. 6 6
      rtl/inc/exeinfo.pp
  45. 126 23
      rtl/inc/fexpand.inc
  46. 175 35
      rtl/inc/file.inc
  47. 1 1
      rtl/inc/filerec.inc
  48. 1 1
      rtl/inc/objects.pp
  49. 312 43
      rtl/inc/system.inc
  50. 99 37
      rtl/inc/systemh.inc
  51. 173 33
      rtl/inc/text.inc
  52. 4 2
      rtl/inc/textrec.inc
  53. 24 16
      rtl/inc/typefile.inc
  54. 8 3
      rtl/inc/ustringh.inc
  55. 50 15
      rtl/inc/ustrings.inc
  56. 24 0
      rtl/inc/uuchar.pp
  57. 2 5
      rtl/inc/wstrings.inc
  58. 73 55
      rtl/java/jastrings.inc
  59. 2 2
      rtl/java/jcompproc.inc
  60. 3 3
      rtl/java/jsstrings.inc
  61. 8 0
      rtl/java/jsystemh_types.inc
  62. 20 10
      rtl/java/justrings.inc
  63. 24 0
      rtl/java/rtldefs.inc
  64. 24 0
      rtl/linux/rtldefs.inc
  65. 10 2
      rtl/macos/dos.pp
  66. 24 0
      rtl/macos/rtldefs.inc
  67. 7 21
      rtl/macos/sysdir.inc
  68. 3 3
      rtl/macos/sysfile.inc
  69. 33 58
      rtl/macos/sysutils.pp
  70. 28 6
      rtl/morphos/dos.pp
  71. 24 0
      rtl/morphos/rtldefs.inc
  72. 22 19
      rtl/morphos/sysdir.inc
  73. 3 3
      rtl/morphos/sysfile.inc
  74. 35 0
      rtl/morphos/sysos.inc
  75. 56 76
      rtl/morphos/sysutils.pp
  76. 26 4
      rtl/msdos/dos.pp
  77. 24 0
      rtl/msdos/rtldefs.inc
  78. 28 24
      rtl/msdos/sysdir.inc
  79. 24 7
      rtl/msdos/sysfile.inc
  80. 27 54
      rtl/msdos/sysutils.pp
  81. 148 146
      rtl/nativent/Makefile
  82. 5 2
      rtl/nativent/Makefile.fpc
  83. 2 2
      rtl/nativent/ndkutils.pas
  84. 24 0
      rtl/nativent/rtldefs.inc
  85. 16 15
      rtl/nativent/sysdir.inc
  86. 26 11
      rtl/nativent/sysfile.inc
  87. 25 1
      rtl/nativent/sysos.inc
  88. 239 157
      rtl/nativent/sysutils.pp
  89. 24 0
      rtl/nds/rtldefs.inc
  90. 4 7
      rtl/nds/sysdir.inc
  91. 3 3
      rtl/nds/sysfile.inc
  92. 52 48
      rtl/nds/sysutils.pp
  93. 24 0
      rtl/netbsd/rtldefs.inc
  94. 3 3
      rtl/netware/dynlibs.inc
  95. 24 0
      rtl/netware/rtldefs.inc
  96. 13 13
      rtl/netware/sysdir.inc
  97. 3 3
      rtl/netware/sysfile.inc
  98. 61 67
      rtl/netware/sysutils.pp
  99. 24 3
      rtl/netwlibc/dos.pp
  100. 2 2
      rtl/netwlibc/dynlibs.inc

+ 52 - 0
.gitattributes

@@ -7432,6 +7432,7 @@ rtl/aix/osmacro.inc svneol=native#text/plain
 rtl/aix/ostypes.inc svneol=native#text/plain
 rtl/aix/ostypes.inc svneol=native#text/plain
 rtl/aix/pthread.inc svneol=native#text/plain
 rtl/aix/pthread.inc svneol=native#text/plain
 rtl/aix/ptypes.inc svneol=native#text/plain
 rtl/aix/ptypes.inc svneol=native#text/plain
+rtl/aix/rtldefs.inc svneol=native#text/plain
 rtl/aix/sighnd.inc svneol=native#text/plain
 rtl/aix/sighnd.inc svneol=native#text/plain
 rtl/aix/sighndh.inc svneol=native#text/plain
 rtl/aix/sighndh.inc svneol=native#text/plain
 rtl/aix/signal.inc svneol=native#text/plain
 rtl/aix/signal.inc svneol=native#text/plain
@@ -7466,6 +7467,7 @@ rtl/amiga/powerpc/utild1.inc svneol=native#text/plain
 rtl/amiga/powerpc/utild2.inc svneol=native#text/plain
 rtl/amiga/powerpc/utild2.inc svneol=native#text/plain
 rtl/amiga/powerpc/utilf.inc svneol=native#text/plain
 rtl/amiga/powerpc/utilf.inc svneol=native#text/plain
 rtl/amiga/printer.pp svneol=native#text/plain
 rtl/amiga/printer.pp svneol=native#text/plain
+rtl/amiga/rtldefs.inc svneol=native#text/plain
 rtl/amiga/sysdir.inc svneol=native#text/plain
 rtl/amiga/sysdir.inc svneol=native#text/plain
 rtl/amiga/sysfile.inc svneol=native#text/plain
 rtl/amiga/sysfile.inc svneol=native#text/plain
 rtl/amiga/sysheap.inc svneol=native#text/plain
 rtl/amiga/sysheap.inc svneol=native#text/plain
@@ -7508,6 +7510,7 @@ rtl/arm/thumb2.inc svneol=native#text/plain
 rtl/atari/os.inc svneol=native#text/plain
 rtl/atari/os.inc svneol=native#text/plain
 rtl/atari/prt0.as svneol=native#text/plain
 rtl/atari/prt0.as svneol=native#text/plain
 rtl/atari/readme -text
 rtl/atari/readme -text
+rtl/atari/rtldefs.inc svneol=native#text/plain
 rtl/atari/sysatari.pas svneol=native#text/plain
 rtl/atari/sysatari.pas svneol=native#text/plain
 rtl/atari/system.pas svneol=native#text/plain
 rtl/atari/system.pas svneol=native#text/plain
 rtl/avr/avr.inc svneol=native#text/plain
 rtl/avr/avr.inc svneol=native#text/plain
@@ -7535,6 +7538,7 @@ rtl/beos/osmacro.inc svneol=native#text/plain
 rtl/beos/ossysc.inc svneol=native#text/plain
 rtl/beos/ossysc.inc svneol=native#text/plain
 rtl/beos/ostypes.inc svneol=native#text/plain
 rtl/beos/ostypes.inc svneol=native#text/plain
 rtl/beos/ptypes.inc svneol=native#text/plain
 rtl/beos/ptypes.inc svneol=native#text/plain
+rtl/beos/rtldefs.inc svneol=native#text/plain
 rtl/beos/settimeo.inc svneol=native#text/plain
 rtl/beos/settimeo.inc svneol=native#text/plain
 rtl/beos/signal.inc svneol=native#text/plain
 rtl/beos/signal.inc svneol=native#text/plain
 rtl/beos/suuid.inc svneol=native#text/plain
 rtl/beos/suuid.inc svneol=native#text/plain
@@ -7616,6 +7620,7 @@ rtl/darwin/ppcgen/ppchnd.inc svneol=native#text/plain
 rtl/darwin/ppcgen/sig_ppc.inc svneol=native#text/plain
 rtl/darwin/ppcgen/sig_ppc.inc svneol=native#text/plain
 rtl/darwin/pthread.inc svneol=native#text/plain
 rtl/darwin/pthread.inc svneol=native#text/plain
 rtl/darwin/ptypes.inc svneol=native#text/plain
 rtl/darwin/ptypes.inc svneol=native#text/plain
+rtl/darwin/rtldefs.inc svneol=native#text/plain
 rtl/darwin/signal.inc svneol=native#text/plain
 rtl/darwin/signal.inc svneol=native#text/plain
 rtl/darwin/sysctlh.inc svneol=native#text/plain
 rtl/darwin/sysctlh.inc svneol=native#text/plain
 rtl/darwin/termio.pp svneol=native#text/plain
 rtl/darwin/termio.pp svneol=native#text/plain
@@ -7662,6 +7667,7 @@ rtl/embedded/consoleio.pp svneol=native#text/pascal
 rtl/embedded/empty.cfg svneol=native#text/plain
 rtl/embedded/empty.cfg svneol=native#text/plain
 rtl/embedded/heapmgr.pp svneol=native#text/pascal
 rtl/embedded/heapmgr.pp svneol=native#text/pascal
 rtl/embedded/rtl.cfg svneol=native#text/plain
 rtl/embedded/rtl.cfg svneol=native#text/plain
+rtl/embedded/rtldefs.inc svneol=native#text/plain
 rtl/embedded/sysdir.inc svneol=native#text/plain
 rtl/embedded/sysdir.inc svneol=native#text/plain
 rtl/embedded/sysfile.inc svneol=native#text/plain
 rtl/embedded/sysfile.inc svneol=native#text/plain
 rtl/embedded/sysheap.inc svneol=native#text/plain
 rtl/embedded/sysheap.inc svneol=native#text/plain
@@ -7679,6 +7685,7 @@ rtl/emx/emxwrap.imp -text
 rtl/emx/ports.pas svneol=native#text/plain
 rtl/emx/ports.pas svneol=native#text/plain
 rtl/emx/prt0.as svneol=native#text/plain
 rtl/emx/prt0.as svneol=native#text/plain
 rtl/emx/prt1.as svneol=native#text/plain
 rtl/emx/prt1.as svneol=native#text/plain
+rtl/emx/rtldefs.inc svneol=native#text/plain
 rtl/emx/sysdir.inc svneol=native#text/plain
 rtl/emx/sysdir.inc svneol=native#text/plain
 rtl/emx/sysemx.pas svneol=native#text/plain
 rtl/emx/sysemx.pas svneol=native#text/plain
 rtl/emx/sysfile.inc svneol=native#text/plain
 rtl/emx/sysfile.inc svneol=native#text/plain
@@ -7713,6 +7720,7 @@ rtl/freebsd/i386/x86h.inc svneol=native#text/plain
 rtl/freebsd/pmutext.inc svneol=native#text/plain
 rtl/freebsd/pmutext.inc svneol=native#text/plain
 rtl/freebsd/pthread.inc svneol=native#text/plain
 rtl/freebsd/pthread.inc svneol=native#text/plain
 rtl/freebsd/ptypes.inc svneol=native#text/plain
 rtl/freebsd/ptypes.inc svneol=native#text/plain
+rtl/freebsd/rtldefs.inc svneol=native#text/plain
 rtl/freebsd/si_crt.pp svneol=native#text/plain
 rtl/freebsd/si_crt.pp svneol=native#text/plain
 rtl/freebsd/si_intf.inc svneol=native#text/plain
 rtl/freebsd/si_intf.inc svneol=native#text/plain
 rtl/freebsd/signal.inc svneol=native#text/plain
 rtl/freebsd/signal.inc svneol=native#text/plain
@@ -7744,6 +7752,7 @@ rtl/gba/gbabiosh.inc svneol=native#text/plain
 rtl/gba/libc.inc svneol=native#text/plain
 rtl/gba/libc.inc svneol=native#text/plain
 rtl/gba/libch.inc svneol=native#text/plain
 rtl/gba/libch.inc svneol=native#text/plain
 rtl/gba/prt0.as svneol=native#text/plain
 rtl/gba/prt0.as svneol=native#text/plain
+rtl/gba/rtldefs.inc svneol=native#text/plain
 rtl/gba/sysdir.inc svneol=native#text/plain
 rtl/gba/sysdir.inc svneol=native#text/plain
 rtl/gba/sysfile.inc svneol=native#text/plain
 rtl/gba/sysfile.inc svneol=native#text/plain
 rtl/gba/sysheap.inc svneol=native#text/plain
 rtl/gba/sysheap.inc svneol=native#text/plain
@@ -7776,6 +7785,7 @@ rtl/go32v2/msmouse.pp svneol=native#text/plain
 rtl/go32v2/ports.pp svneol=native#text/plain
 rtl/go32v2/ports.pp svneol=native#text/plain
 rtl/go32v2/printer.pp svneol=native#text/plain
 rtl/go32v2/printer.pp svneol=native#text/plain
 rtl/go32v2/profile.pp svneol=native#text/plain
 rtl/go32v2/profile.pp svneol=native#text/plain
+rtl/go32v2/rtldefs.inc svneol=native#text/plain
 rtl/go32v2/sbrk16.ah -text
 rtl/go32v2/sbrk16.ah -text
 rtl/go32v2/sbrk16.asm -text
 rtl/go32v2/sbrk16.asm -text
 rtl/go32v2/sysdir.inc svneol=native#text/plain
 rtl/go32v2/sysdir.inc svneol=native#text/plain
@@ -7809,6 +7819,7 @@ rtl/haiku/ossysc.inc svneol=native#text/plain
 rtl/haiku/ostypes.inc svneol=native#text/plain
 rtl/haiku/ostypes.inc svneol=native#text/plain
 rtl/haiku/pthread.inc svneol=native#text/plain
 rtl/haiku/pthread.inc svneol=native#text/plain
 rtl/haiku/ptypes.inc svneol=native#text/plain
 rtl/haiku/ptypes.inc svneol=native#text/plain
+rtl/haiku/rtldefs.inc svneol=native#text/plain
 rtl/haiku/settimeo.inc svneol=native#text/plain
 rtl/haiku/settimeo.inc svneol=native#text/plain
 rtl/haiku/signal.inc svneol=native#text/plain
 rtl/haiku/signal.inc svneol=native#text/plain
 rtl/haiku/suuid.inc svneol=native#text/plain
 rtl/haiku/suuid.inc svneol=native#text/plain
@@ -7989,6 +8000,7 @@ rtl/java/objpas.inc svneol=native#text/plain
 rtl/java/objpas.pp svneol=native#text/plain
 rtl/java/objpas.pp svneol=native#text/plain
 rtl/java/objpash.inc svneol=native#text/plain
 rtl/java/objpash.inc svneol=native#text/plain
 rtl/java/rtl.cfg svneol=native#text/plain
 rtl/java/rtl.cfg svneol=native#text/plain
+rtl/java/rtldefs.inc svneol=native#text/plain
 rtl/java/rtti.inc svneol=native#text/plain
 rtl/java/rtti.inc svneol=native#text/plain
 rtl/java/sysos.inc svneol=native#text/plain
 rtl/java/sysos.inc svneol=native#text/plain
 rtl/java/sysosh.inc svneol=native#text/plain
 rtl/java/sysosh.inc svneol=native#text/plain
@@ -8113,6 +8125,7 @@ rtl/linux/powerpc64/syscallh.inc svneol=native#text/plain
 rtl/linux/powerpc64/sysnr.inc svneol=native#text/plain
 rtl/linux/powerpc64/sysnr.inc svneol=native#text/plain
 rtl/linux/pthread.inc svneol=native#text/plain
 rtl/linux/pthread.inc svneol=native#text/plain
 rtl/linux/ptypes.inc svneol=native#text/plain
 rtl/linux/ptypes.inc svneol=native#text/plain
+rtl/linux/rtldefs.inc svneol=native#text/plain
 rtl/linux/si_c.pp svneol=native#text/plain
 rtl/linux/si_c.pp svneol=native#text/plain
 rtl/linux/si_c21.pp svneol=native#text/plain
 rtl/linux/si_c21.pp svneol=native#text/plain
 rtl/linux/si_c21g.pp svneol=native#text/plain
 rtl/linux/si_c21g.pp svneol=native#text/plain
@@ -8184,6 +8197,7 @@ rtl/macos/macostp.inc svneol=native#text/plain
 rtl/macos/macostp.pp svneol=native#text/plain
 rtl/macos/macostp.pp svneol=native#text/plain
 rtl/macos/macutils.inc svneol=native#text/plain
 rtl/macos/macutils.inc svneol=native#text/plain
 rtl/macos/macutils.pp svneol=native#text/plain
 rtl/macos/macutils.pp svneol=native#text/plain
+rtl/macos/rtldefs.inc svneol=native#text/plain
 rtl/macos/sysdir.inc svneol=native#text/plain
 rtl/macos/sysdir.inc svneol=native#text/plain
 rtl/macos/sysfile.inc svneol=native#text/plain
 rtl/macos/sysfile.inc svneol=native#text/plain
 rtl/macos/sysheap.inc svneol=native#text/plain
 rtl/macos/sysheap.inc svneol=native#text/plain
@@ -8242,6 +8256,7 @@ rtl/morphos/mouse.pp svneol=native#text/plain
 rtl/morphos/mui.pas -text svneol=unset#text/plain
 rtl/morphos/mui.pas -text svneol=unset#text/plain
 rtl/morphos/muihelper.pas -text svneol=unset#text/plain
 rtl/morphos/muihelper.pas -text svneol=unset#text/plain
 rtl/morphos/prt0.as svneol=native#text/plain
 rtl/morphos/prt0.as svneol=native#text/plain
+rtl/morphos/rtldefs.inc svneol=native#text/plain
 rtl/morphos/sockets.pp svneol=native#text/plain
 rtl/morphos/sockets.pp svneol=native#text/plain
 rtl/morphos/sysdir.inc svneol=native#text/plain
 rtl/morphos/sysdir.inc svneol=native#text/plain
 rtl/morphos/sysfile.inc svneol=native#text/plain
 rtl/morphos/sysfile.inc svneol=native#text/plain
@@ -8274,6 +8289,7 @@ rtl/msdos/prt0s.asm svneol=native#text/plain
 rtl/msdos/prt0stm.asm svneol=native#text/plain
 rtl/msdos/prt0stm.asm svneol=native#text/plain
 rtl/msdos/prt0t.asm svneol=native#text/plain
 rtl/msdos/prt0t.asm svneol=native#text/plain
 rtl/msdos/registers.inc svneol=native#text/plain
 rtl/msdos/registers.inc svneol=native#text/plain
+rtl/msdos/rtldefs.inc svneol=native#text/plain
 rtl/msdos/sysdir.inc svneol=native#text/plain
 rtl/msdos/sysdir.inc svneol=native#text/plain
 rtl/msdos/sysfile.inc svneol=native#text/plain
 rtl/msdos/sysfile.inc svneol=native#text/plain
 rtl/msdos/sysheap.inc svneol=native#text/plain
 rtl/msdos/sysheap.inc svneol=native#text/plain
@@ -8306,6 +8322,7 @@ rtl/nativent/ndk/rtltypes.inc svneol=native#text/plain
 rtl/nativent/ndk/umtypes.inc svneol=native#text/plain
 rtl/nativent/ndk/umtypes.inc svneol=native#text/plain
 rtl/nativent/ndk/winnt.inc svneol=native#text/plain
 rtl/nativent/ndk/winnt.inc svneol=native#text/plain
 rtl/nativent/ndkutils.pas svneol=native#text/pascal
 rtl/nativent/ndkutils.pas svneol=native#text/pascal
+rtl/nativent/rtldefs.inc svneol=native#text/plain
 rtl/nativent/sysdir.inc svneol=native#text/plain
 rtl/nativent/sysdir.inc svneol=native#text/plain
 rtl/nativent/sysfile.inc svneol=native#text/plain
 rtl/nativent/sysfile.inc svneol=native#text/plain
 rtl/nativent/sysheap.inc svneol=native#text/plain
 rtl/nativent/sysheap.inc svneol=native#text/plain
@@ -8330,6 +8347,7 @@ 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/rtldefs.inc svneol=native#text/plain
 rtl/nds/sysdir.inc svneol=native#text/plain
 rtl/nds/sysdir.inc svneol=native#text/plain
 rtl/nds/sysfile.inc svneol=native#text/plain
 rtl/nds/sysfile.inc svneol=native#text/plain
 rtl/nds/sysheap.inc svneol=native#text/plain
 rtl/nds/sysheap.inc svneol=native#text/plain
@@ -8357,6 +8375,7 @@ rtl/netbsd/powerpc/prt0.as svneol=native#text/plain
 rtl/netbsd/powerpc/sighnd.inc svneol=native#text/plain
 rtl/netbsd/powerpc/sighnd.inc svneol=native#text/plain
 rtl/netbsd/pthread.inc svneol=native#text/plain
 rtl/netbsd/pthread.inc svneol=native#text/plain
 rtl/netbsd/ptypes.inc svneol=native#text/plain
 rtl/netbsd/ptypes.inc svneol=native#text/plain
+rtl/netbsd/rtldefs.inc svneol=native#text/plain
 rtl/netbsd/signal.inc svneol=native#text/plain
 rtl/netbsd/signal.inc svneol=native#text/plain
 rtl/netbsd/syscalls.inc svneol=native#text/plain
 rtl/netbsd/syscalls.inc svneol=native#text/plain
 rtl/netbsd/sysconst.inc svneol=native#text/plain
 rtl/netbsd/sysconst.inc svneol=native#text/plain
@@ -8431,6 +8450,7 @@ rtl/netware/nwsys.inc svneol=native#text/plain
 rtl/netware/prelude.as svneol=native#text/plain
 rtl/netware/prelude.as svneol=native#text/plain
 rtl/netware/qos.inc svneol=native#text/plain
 rtl/netware/qos.inc svneol=native#text/plain
 rtl/netware/requestr.imp -text
 rtl/netware/requestr.imp -text
+rtl/netware/rtldefs.inc svneol=native#text/plain
 rtl/netware/sockets.pp svneol=native#text/plain
 rtl/netware/sockets.pp svneol=native#text/plain
 rtl/netware/socklib.imp -text
 rtl/netware/socklib.imp -text
 rtl/netware/streams.imp -text
 rtl/netware/streams.imp -text
@@ -8475,6 +8495,7 @@ rtl/netwlibc/nwsnut.imp -text
 rtl/netwlibc/nwsnut.pp svneol=native#text/plain
 rtl/netwlibc/nwsnut.pp svneol=native#text/plain
 rtl/netwlibc/pre/libcpre.gcc.o -text
 rtl/netwlibc/pre/libcpre.gcc.o -text
 rtl/netwlibc/qos.inc svneol=native#text/plain
 rtl/netwlibc/qos.inc svneol=native#text/plain
+rtl/netwlibc/rtldefs.inc svneol=native#text/plain
 rtl/netwlibc/sockets.pp svneol=native#text/plain
 rtl/netwlibc/sockets.pp svneol=native#text/plain
 rtl/netwlibc/sysdir.inc svneol=native#text/plain
 rtl/netwlibc/sysdir.inc svneol=native#text/plain
 rtl/netwlibc/sysfile.inc svneol=native#text/plain
 rtl/netwlibc/sysfile.inc svneol=native#text/plain
@@ -8557,7 +8578,9 @@ rtl/objpas/strutils.pp svneol=native#text/plain
 rtl/objpas/sysconst.pp svneol=native#text/plain
 rtl/objpas/sysconst.pp svneol=native#text/plain
 rtl/objpas/sysutils/dati.inc svneol=native#text/plain
 rtl/objpas/sysutils/dati.inc svneol=native#text/plain
 rtl/objpas/sysutils/datih.inc svneol=native#text/plain
 rtl/objpas/sysutils/datih.inc svneol=native#text/plain
+rtl/objpas/sysutils/disk.inc svneol=native#text/plain
 rtl/objpas/sysutils/diskh.inc svneol=native#text/plain
 rtl/objpas/sysutils/diskh.inc svneol=native#text/plain
+rtl/objpas/sysutils/filutil.inc svneol=native#text/plain
 rtl/objpas/sysutils/filutilh.inc svneol=native#text/plain
 rtl/objpas/sysutils/filutilh.inc svneol=native#text/plain
 rtl/objpas/sysutils/fina.inc svneol=native#text/plain
 rtl/objpas/sysutils/fina.inc svneol=native#text/plain
 rtl/objpas/sysutils/finah.inc svneol=native#text/plain
 rtl/objpas/sysutils/finah.inc svneol=native#text/plain
@@ -8617,6 +8640,7 @@ rtl/openbsd/osdefs.inc svneol=native#text/plain
 rtl/openbsd/pmutext.inc svneol=native#text/plain
 rtl/openbsd/pmutext.inc svneol=native#text/plain
 rtl/openbsd/pthread.inc svneol=native#text/plain
 rtl/openbsd/pthread.inc svneol=native#text/plain
 rtl/openbsd/ptypes.inc svneol=native#text/plain
 rtl/openbsd/ptypes.inc svneol=native#text/plain
+rtl/openbsd/rtldefs.inc svneol=native#text/plain
 rtl/openbsd/signal.inc svneol=native#text/plain
 rtl/openbsd/signal.inc svneol=native#text/plain
 rtl/openbsd/syscalls.inc svneol=native#text/plain
 rtl/openbsd/syscalls.inc svneol=native#text/plain
 rtl/openbsd/sysconst.inc svneol=native#text/plain
 rtl/openbsd/sysconst.inc svneol=native#text/plain
@@ -8669,6 +8693,7 @@ rtl/os2/pmwsock.pas svneol=native#text/plain
 rtl/os2/ports.pas svneol=native#text/plain
 rtl/os2/ports.pas svneol=native#text/plain
 rtl/os2/printer.pas svneol=native#text/plain
 rtl/os2/printer.pas svneol=native#text/plain
 rtl/os2/prt0.as svneol=native#text/plain
 rtl/os2/prt0.as svneol=native#text/plain
+rtl/os2/rtldefs.inc svneol=native#text/plain
 rtl/os2/so32dll.pas svneol=native#text/plain
 rtl/os2/so32dll.pas svneol=native#text/plain
 rtl/os2/sockets.pas svneol=native#text/plain
 rtl/os2/sockets.pas svneol=native#text/plain
 rtl/os2/sysdir.inc svneol=native#text/plain
 rtl/os2/sysdir.inc svneol=native#text/plain
@@ -8724,6 +8749,7 @@ rtl/palmos/m68k/prt0.as svneol=native#text/plain
 rtl/palmos/os.inc svneol=native#text/plain
 rtl/palmos/os.inc svneol=native#text/plain
 rtl/palmos/pilot.pp svneol=native#text/plain
 rtl/palmos/pilot.pp svneol=native#text/plain
 rtl/palmos/readme -text
 rtl/palmos/readme -text
+rtl/palmos/rtldefs.inc svneol=native#text/plain
 rtl/palmos/syspalm.pp svneol=native#text/plain
 rtl/palmos/syspalm.pp svneol=native#text/plain
 rtl/palmos/system.pp svneol=native#text/plain
 rtl/palmos/system.pp svneol=native#text/plain
 rtl/palmos/systraps.pp svneol=native#text/plain
 rtl/palmos/systraps.pp svneol=native#text/plain
@@ -8764,6 +8790,7 @@ rtl/qnx/osposix.inc svneol=native#text/plain
 rtl/qnx/osposixh.inc svneol=native#text/plain
 rtl/qnx/osposixh.inc svneol=native#text/plain
 rtl/qnx/posix.pp svneol=native#text/plain
 rtl/qnx/posix.pp svneol=native#text/plain
 rtl/qnx/qnx.inc svneol=native#text/plain
 rtl/qnx/qnx.inc svneol=native#text/plain
+rtl/qnx/rtldefs.inc svneol=native#text/plain
 rtl/qnx/signal.inc svneol=native#text/plain
 rtl/qnx/signal.inc svneol=native#text/plain
 rtl/qnx/system.pp svneol=native#text/plain
 rtl/qnx/system.pp svneol=native#text/plain
 rtl/solaris/Makefile svneol=native#text/plain
 rtl/solaris/Makefile svneol=native#text/plain
@@ -8779,6 +8806,7 @@ rtl/solaris/osmacro.inc svneol=native#text/plain
 rtl/solaris/ostypes.inc svneol=native#text/plain
 rtl/solaris/ostypes.inc svneol=native#text/plain
 rtl/solaris/pthread.inc svneol=native#text/plain
 rtl/solaris/pthread.inc svneol=native#text/plain
 rtl/solaris/ptypes.inc svneol=native#text/plain
 rtl/solaris/ptypes.inc svneol=native#text/plain
+rtl/solaris/rtldefs.inc svneol=native#text/plain
 rtl/solaris/signal.inc svneol=native#text/plain
 rtl/solaris/signal.inc svneol=native#text/plain
 rtl/solaris/sparc/sighnd.inc svneol=native#text/plain
 rtl/solaris/sparc/sighnd.inc svneol=native#text/plain
 rtl/solaris/sparc/sighndh.inc svneol=native#text/plain
 rtl/solaris/sparc/sighndh.inc svneol=native#text/plain
@@ -8811,6 +8839,7 @@ rtl/symbian/Makefile svneol=native#text/plain
 rtl/symbian/Makefile.fpc svneol=native#text/plain
 rtl/symbian/Makefile.fpc svneol=native#text/plain
 rtl/symbian/bindings/pbeexe.cpp -text
 rtl/symbian/bindings/pbeexe.cpp -text
 rtl/symbian/buildrtl.pp svneol=native#text/plain
 rtl/symbian/buildrtl.pp svneol=native#text/plain
+rtl/symbian/rtldefs.inc svneol=native#text/plain
 rtl/symbian/symbian.pas svneol=native#text/plain
 rtl/symbian/symbian.pas svneol=native#text/plain
 rtl/symbian/symbianinc/e32def.inc svneol=native#text/plain
 rtl/symbian/symbianinc/e32def.inc svneol=native#text/plain
 rtl/symbian/symbianinc/e32err.inc svneol=native#text/plain
 rtl/symbian/symbianinc/e32err.inc svneol=native#text/plain
@@ -8909,6 +8938,7 @@ rtl/watcom/classes.pp svneol=native#text/plain
 rtl/watcom/crt.pp svneol=native#text/plain
 rtl/watcom/crt.pp svneol=native#text/plain
 rtl/watcom/dos.pp svneol=native#text/plain
 rtl/watcom/dos.pp svneol=native#text/plain
 rtl/watcom/prt0.as -text
 rtl/watcom/prt0.as -text
+rtl/watcom/rtldefs.inc svneol=native#text/plain
 rtl/watcom/sysdir.inc svneol=native#text/plain
 rtl/watcom/sysdir.inc svneol=native#text/plain
 rtl/watcom/sysfile.inc svneol=native#text/plain
 rtl/watcom/sysfile.inc svneol=native#text/plain
 rtl/watcom/sysheap.inc svneol=native#text/plain
 rtl/watcom/sysheap.inc svneol=native#text/plain
@@ -8924,6 +8954,7 @@ rtl/wii/classes.pp svneol=native#text/plain
 rtl/wii/dos.pp svneol=native#text/plain
 rtl/wii/dos.pp svneol=native#text/plain
 rtl/wii/libc.inc svneol=native#text/plain
 rtl/wii/libc.inc svneol=native#text/plain
 rtl/wii/libch.inc svneol=native#text/plain
 rtl/wii/libch.inc svneol=native#text/plain
+rtl/wii/rtldefs.inc svneol=native#text/plain
 rtl/wii/sysdir.inc svneol=native#text/plain
 rtl/wii/sysdir.inc svneol=native#text/plain
 rtl/wii/sysfile.inc svneol=native#text/plain
 rtl/wii/sysfile.inc svneol=native#text/plain
 rtl/wii/sysheap.inc svneol=native#text/plain
 rtl/wii/sysheap.inc svneol=native#text/plain
@@ -8987,6 +9018,7 @@ rtl/win32/classes.pp svneol=native#text/plain
 rtl/win32/gprt0.as svneol=native#text/plain
 rtl/win32/gprt0.as svneol=native#text/plain
 rtl/win32/initc.pp svneol=native#text/plain
 rtl/win32/initc.pp svneol=native#text/plain
 rtl/win32/objinc.inc svneol=native#text/plain
 rtl/win32/objinc.inc svneol=native#text/plain
+rtl/win32/rtldefs.inc svneol=native#text/plain
 rtl/win32/signals.pp svneol=native#text/plain
 rtl/win32/signals.pp svneol=native#text/plain
 rtl/win32/sysinit.inc svneol=native#text/plain
 rtl/win32/sysinit.inc svneol=native#text/plain
 rtl/win32/sysinitcyg.pp svneol=native#text/plain
 rtl/win32/sysinitcyg.pp svneol=native#text/plain
@@ -9002,6 +9034,7 @@ rtl/win64/Makefile svneol=native#text/plain
 rtl/win64/Makefile.fpc svneol=native#text/plain
 rtl/win64/Makefile.fpc svneol=native#text/plain
 rtl/win64/buildrtl.pp svneol=native#text/plain
 rtl/win64/buildrtl.pp svneol=native#text/plain
 rtl/win64/classes.pp svneol=native#text/plain
 rtl/win64/classes.pp svneol=native#text/plain
+rtl/win64/rtldefs.inc svneol=native#text/plain
 rtl/win64/seh64.inc svneol=native#text/plain
 rtl/win64/seh64.inc svneol=native#text/plain
 rtl/win64/signals.pp svneol=native#text/plain
 rtl/win64/signals.pp svneol=native#text/plain
 rtl/win64/system.pp svneol=native#text/plain
 rtl/win64/system.pp svneol=native#text/plain
@@ -9013,6 +9046,7 @@ rtl/wince/dos.pp svneol=native#text/plain
 rtl/wince/dynlibs.inc svneol=native#text/plain
 rtl/wince/dynlibs.inc svneol=native#text/plain
 rtl/wince/messages.pp svneol=native#text/plain
 rtl/wince/messages.pp svneol=native#text/plain
 rtl/wince/readme.txt svneol=native#text/plain
 rtl/wince/readme.txt svneol=native#text/plain
+rtl/wince/rtldefs.inc svneol=native#text/plain
 rtl/wince/system.pp svneol=native#text/plain
 rtl/wince/system.pp svneol=native#text/plain
 rtl/wince/sysutils.pp svneol=native#text/plain
 rtl/wince/sysutils.pp svneol=native#text/plain
 rtl/wince/varutils.pp svneol=native#text/plain
 rtl/wince/varutils.pp svneol=native#text/plain
@@ -9979,6 +10013,7 @@ tests/tbs/tb0596.pp svneol=native#text/pascal
 tests/tbs/tb0597.pp svneol=native#text/plain
 tests/tbs/tb0597.pp svneol=native#text/plain
 tests/tbs/tb0598.pp svneol=native#text/plain
 tests/tbs/tb0598.pp svneol=native#text/plain
 tests/tbs/tb0599.pp svneol=native#text/plain
 tests/tbs/tb0599.pp svneol=native#text/plain
+tests/tbs/tb0600.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tbs0594.pp svneol=native#text/pascal
 tests/tbs/tbs0594.pp svneol=native#text/pascal
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0060.pp svneol=native#text/plain
@@ -10979,6 +11014,12 @@ tests/test/tcpstr21a.pp svneol=native#text/pascal
 tests/test/tcpstr22.pp svneol=native#text/pascal
 tests/test/tcpstr22.pp svneol=native#text/pascal
 tests/test/tcpstr23.pp svneol=native#text/pascal
 tests/test/tcpstr23.pp svneol=native#text/pascal
 tests/test/tcpstr24.pp svneol=native#text/plain
 tests/test/tcpstr24.pp svneol=native#text/plain
+tests/test/tcpstr25.pp svneol=native#text/plain
+tests/test/tcpstr26.pp svneol=native#text/plain
+tests/test/tcpstr26a.pp svneol=native#text/plain
+tests/test/tcpstr26b.pp svneol=native#text/plain
+tests/test/tcpstr26c.pp svneol=native#text/plain
+tests/test/tcpstr26d.pp svneol=native#text/plain
 tests/test/tcpstr2a.pp svneol=native#text/plain
 tests/test/tcpstr2a.pp svneol=native#text/plain
 tests/test/tcpstr3.pp svneol=native#text/plain
 tests/test/tcpstr3.pp svneol=native#text/plain
 tests/test/tcpstr4.pp svneol=native#text/plain
 tests/test/tcpstr4.pp svneol=native#text/plain
@@ -10997,6 +11038,7 @@ tests/test/tcpstrchar2ansistr.pp svneol=native#text/plain
 tests/test/tcpstrconcat.pp svneol=native#text/plain
 tests/test/tcpstrconcat.pp svneol=native#text/plain
 tests/test/tcpstrconcat2.pp svneol=native#text/plain
 tests/test/tcpstrconcat2.pp svneol=native#text/plain
 tests/test/tcpstrconcat3.pp svneol=native#text/plain
 tests/test/tcpstrconcat3.pp svneol=native#text/plain
+tests/test/tcpstrconcat4.pp svneol=native#text/plain
 tests/test/tcpstrconcatmulti.pp svneol=native#text/plain
 tests/test/tcpstrconcatmulti.pp svneol=native#text/plain
 tests/test/tcpstrconcatmulti2.pp svneol=native#text/plain
 tests/test/tcpstrconcatmulti2.pp svneol=native#text/plain
 tests/test/tcpstrpchar2ansistr.pp svneol=native#text/plain
 tests/test/tcpstrpchar2ansistr.pp svneol=native#text/plain
@@ -12044,10 +12086,12 @@ tests/test/units/system/tassert6.pp svneol=native#text/plain
 tests/test/units/system/tassert7.pp svneol=native#text/plain
 tests/test/units/system/tassert7.pp svneol=native#text/plain
 tests/test/units/system/tassignd.pp svneol=native#text/plain
 tests/test/units/system/tassignd.pp svneol=native#text/plain
 tests/test/units/system/tdir.pp svneol=native#text/plain
 tests/test/units/system/tdir.pp svneol=native#text/plain
+tests/test/units/system/tdir2.pp svneol=native#text/plain
 tests/test/units/system/testmac.txt svneol=native#text/plain
 tests/test/units/system/testmac.txt svneol=native#text/plain
 tests/test/units/system/testpc.txt svneol=native#text/plain
 tests/test/units/system/testpc.txt svneol=native#text/plain
 tests/test/units/system/teststk.pp svneol=native#text/plain
 tests/test/units/system/teststk.pp svneol=native#text/plain
 tests/test/units/system/testux.txt svneol=native#text/plain
 tests/test/units/system/testux.txt svneol=native#text/plain
+tests/test/units/system/tfiledir.pp svneol=native#text/plain
 tests/test/units/system/tgenstr.pp svneol=native#text/pascal
 tests/test/units/system/tgenstr.pp svneol=native#text/pascal
 tests/test/units/system/tincdec.pp svneol=native#text/plain
 tests/test/units/system/tincdec.pp svneol=native#text/plain
 tests/test/units/system/tint.pp svneol=native#text/plain
 tests/test/units/system/tint.pp svneol=native#text/plain
@@ -12108,6 +12152,8 @@ tests/test/units/sysutils/texec1.pp svneol=native#text/plain
 tests/test/units/sysutils/texec2.pp svneol=native#text/plain
 tests/test/units/sysutils/texec2.pp svneol=native#text/plain
 tests/test/units/sysutils/texpfncase.pp svneol=native#text/plain
 tests/test/units/sysutils/texpfncase.pp svneol=native#text/plain
 tests/test/units/sysutils/textractquote.pp svneol=native#text/plain
 tests/test/units/sysutils/textractquote.pp svneol=native#text/plain
+tests/test/units/sysutils/tfexpand2.pp svneol=native#text/plain
+tests/test/units/sysutils/tffirst.pp svneol=native#text/plain
 tests/test/units/sysutils/tfile1.pp svneol=native#text/plain
 tests/test/units/sysutils/tfile1.pp svneol=native#text/plain
 tests/test/units/sysutils/tfile2.pp svneol=native#text/plain
 tests/test/units/sysutils/tfile2.pp svneol=native#text/plain
 tests/test/units/sysutils/tfilename.pp svneol=native#text/plain
 tests/test/units/sysutils/tfilename.pp svneol=native#text/plain
@@ -12116,7 +12162,11 @@ tests/test/units/sysutils/tformat.pp svneol=native#text/plain
 tests/test/units/sysutils/tlocale.pp svneol=native#text/plain
 tests/test/units/sysutils/tlocale.pp svneol=native#text/plain
 tests/test/units/sysutils/trwsync.pp svneol=native#text/plain
 tests/test/units/sysutils/trwsync.pp svneol=native#text/plain
 tests/test/units/sysutils/tsscanf.pp svneol=native#text/plain
 tests/test/units/sysutils/tsscanf.pp svneol=native#text/plain
+tests/test/units/sysutils/tstrcmp.pp svneol=native#text/plain
 tests/test/units/sysutils/tstrtobool.pp svneol=native#text/plain
 tests/test/units/sysutils/tstrtobool.pp svneol=native#text/plain
+tests/test/units/sysutils/tunifile.pp svneol=native#text/plain
+tests/test/units/sysutils/tuplow.pp svneol=native#text/plain
+tests/test/units/sysutils/twstrcmp.pp svneol=native#text/plain
 tests/test/units/ucomplex/tcsqr1.pp svneol=native#text/pascal
 tests/test/units/ucomplex/tcsqr1.pp svneol=native#text/pascal
 tests/test/units/variants/tcustomvariant.pp svneol=native#text/plain
 tests/test/units/variants/tcustomvariant.pp svneol=native#text/plain
 tests/test/units/variants/tvararrayofintf.pp svneol=native#text/plain
 tests/test/units/variants/tvararrayofintf.pp svneol=native#text/plain
@@ -13356,6 +13406,7 @@ tests/webtbs/tw21329.pp svneol=native#text/pascal
 tests/webtbs/tw21350a.pp svneol=native#text/pascal
 tests/webtbs/tw21350a.pp svneol=native#text/pascal
 tests/webtbs/tw21350b.pp svneol=native#text/pascal
 tests/webtbs/tw21350b.pp svneol=native#text/pascal
 tests/webtbs/tw21443.pp svneol=native#text/plain
 tests/webtbs/tw21443.pp svneol=native#text/plain
+tests/webtbs/tw21443a.pp svneol=native#text/plain
 tests/webtbs/tw2145.pp svneol=native#text/plain
 tests/webtbs/tw2145.pp svneol=native#text/plain
 tests/webtbs/tw21457.pp svneol=native#text/pascal
 tests/webtbs/tw21457.pp svneol=native#text/pascal
 tests/webtbs/tw21472.pp svneol=native#text/pascal
 tests/webtbs/tw21472.pp svneol=native#text/pascal
@@ -13695,6 +13746,7 @@ tests/webtbs/tw3226.pp svneol=native#text/plain
 tests/webtbs/tw3227.pp svneol=native#text/plain
 tests/webtbs/tw3227.pp svneol=native#text/plain
 tests/webtbs/tw3227a.pp svneol=native#text/plain
 tests/webtbs/tw3227a.pp svneol=native#text/plain
 tests/webtbs/tw3235.pp svneol=native#text/plain
 tests/webtbs/tw3235.pp svneol=native#text/plain
+tests/webtbs/tw3235a.pp svneol=native#text/plain
 tests/webtbs/tw3241a.pp svneol=native#text/plain
 tests/webtbs/tw3241a.pp svneol=native#text/plain
 tests/webtbs/tw3252.pp svneol=native#text/plain
 tests/webtbs/tw3252.pp svneol=native#text/plain
 tests/webtbs/tw3255.pp svneol=native#text/plain
 tests/webtbs/tw3255.pp svneol=native#text/plain

+ 1 - 1
compiler/assemble.pas

@@ -295,7 +295,7 @@ Implementation
 
 
         procedure DeleteFilesWithExt(const AExt:string);
         procedure DeleteFilesWithExt(const AExt:string);
         var
         var
-          dir : TSearchRec;
+          dir : TRawByteSearchRec;
         begin
         begin
           if findfirst(s+source_info.dirsep+'*'+AExt,faAnyFile,dir) = 0 then
           if findfirst(s+source_info.dirsep+'*'+AExt,faAnyFile,dir) = 0 then
             begin
             begin

+ 1 - 1
compiler/cfileutl.pas

@@ -269,7 +269,7 @@ end;
 
 
     procedure TCachedDirectory.Reload;
     procedure TCachedDirectory.Reload;
       var
       var
-        dir   : TSearchRec;
+        dir   : TRawByteSearchRec;
         entry : PCachedDirectoryEntry;
         entry : PCachedDirectoryEntry;
       begin
       begin
         FreeDirectoryEntries;
         FreeDirectoryEntries;

+ 8 - 2
compiler/defcmp.pas

@@ -1144,7 +1144,10 @@ implementation
                         (is_pchar(def_to) or is_pwidechar(def_to)) then
                         (is_pchar(def_to) or is_pwidechar(def_to)) then
                       begin
                       begin
                         doconv:=tc_cstring_2_pchar;
                         doconv:=tc_cstring_2_pchar;
-                        eq:=te_convert_l2;
+                        if is_pwidechar(def_to)=(m_default_unicodestring in current_settings.modeswitches) then
+                          eq:=te_convert_l2
+                        else
+                          eq:=te_convert_l3
                       end
                       end
                      else
                      else
                       if (cdo_explicit in cdoptions) or (fromtreetype = arrayconstructorn) then
                       if (cdo_explicit in cdoptions) or (fromtreetype = arrayconstructorn) then
@@ -1175,7 +1178,10 @@ implementation
                            (is_pchar(def_to) or is_pwidechar(def_to)) then
                            (is_pchar(def_to) or is_pwidechar(def_to)) then
                          begin
                          begin
                            doconv:=tc_cchar_2_pchar;
                            doconv:=tc_cchar_2_pchar;
-                           eq:=te_convert_l1;
+                           if is_pwidechar(def_to)=(m_default_unicodestring in current_settings.modeswitches) then
+                             eq:=te_convert_l1
+                           else
+                             eq:=te_convert_l2
                          end
                          end
                         else
                         else
                          if (m_delphi in current_settings.modeswitches) and is_integer(def_from) then
                          if (m_delphi in current_settings.modeswitches) and is_integer(def_from) then

+ 1 - 1
compiler/globals.pas

@@ -889,7 +889,7 @@ implementation
       {$endif}
       {$endif}
       {$ifdef mswindows}
       {$ifdef mswindows}
         GetEnvPchar:=nil;
         GetEnvPchar:=nil;
-        p:=GetEnvironmentStrings;
+        p:=GetEnvironmentStringsA;
         hp:=p;
         hp:=p;
         while hp^<>#0 do
         while hp^<>#0 do
          begin
          begin

+ 6 - 2
compiler/nadd.pas

@@ -2179,7 +2179,9 @@ implementation
                   if is_ansistring(resultdef) then
                   if is_ansistring(resultdef) then
                     para:=ccallparanode.create(
                     para:=ccallparanode.create(
                             cordconstnode.create(
                             cordconstnode.create(
-                              getparaencoding(resultdef),
+                              { don't use getparaencoding(), we have to know
+                                when the result is rawbytestring }
+                              tstringdef(resultdef).encoding,
                               u16inttype,
                               u16inttype,
                               true
                               true
                             ),
                             ),
@@ -2217,7 +2219,9 @@ implementation
                   if is_ansistring(resultdef) then
                   if is_ansistring(resultdef) then
                     para:=ccallparanode.create(
                     para:=ccallparanode.create(
                             cordconstnode.create(
                             cordconstnode.create(
-                              getparaencoding(resultdef),
+                              { don't use getparaencoding(), we have to know
+                                when the result is rawbytestring }
+                              tstringdef(resultdef).encoding,
                               u16inttype,
                               u16inttype,
                               true
                               true
                             ),
                             ),

+ 32 - 52
compiler/ncnv.pas

@@ -1125,9 +1125,11 @@ implementation
                               // Delphi converts UniocodeChar to ansistring at the compile time
                               // Delphi converts UniocodeChar to ansistring at the compile time
                               // old behavior:
                               // old behavior:
                               // hp:=cstringconstnode.createstr(unicode2asciichar(tcompilerwidechar(tordconstnode(left).value.uvalue)));
                               // hp:=cstringconstnode.createstr(unicode2asciichar(tcompilerwidechar(tordconstnode(left).value.uvalue)));
+                              para:=ccallparanode.create(left,nil);
+                              if tstringdef(resultdef).stringtype=st_ansistring then
+                                para:=ccallparanode.create(cordconstnode.create(getparaencoding(resultdef),u16inttype,true),para);
                               result:=ccallnode.createinternres('fpc_uchar_to_'+tstringdef(resultdef).stringtypname,
                               result:=ccallnode.createinternres('fpc_uchar_to_'+tstringdef(resultdef).stringtypname,
-                                   ccallparanode.create(cordconstnode.create(getparaencoding(resultdef),u16inttype,true),
-                                   ccallparanode.create(left,nil)),resultdef);
+                                para,resultdef);
                               left:=nil;
                               left:=nil;
                               exit;
                               exit;
                             end
                             end
@@ -1159,57 +1161,35 @@ implementation
               (torddef(left.resultdef).ordtype=uwidechar) or
               (torddef(left.resultdef).ordtype=uwidechar) or
               (target_info.system in systems_managed_vm) then
               (target_info.system in systems_managed_vm) then
              begin
              begin
-               if (tstringdef(resultdef).stringtype<>st_shortstring) then
+               { parameter }
+               para:=ccallparanode.create(left,nil);
+               { encoding required? }
+               if tstringdef(resultdef).stringtype=st_ansistring then
+                 para:=ccallparanode.create(cordconstnode.create(getparaencoding(resultdef),u16inttype,true),para);
+
+               { create the procname }
+               if torddef(left.resultdef).ordtype<>uwidechar then
                  begin
                  begin
-                   { parameter }
-                   para:=ccallparanode.create(left,nil);
-                   { encoding required? }
-                   if tstringdef(resultdef).stringtype=st_ansistring then
-                     para:=ccallparanode.create(cordconstnode.create(getparaencoding(resultdef),u16inttype,true),para);
-
-                   { create the procname }
-                   if torddef(left.resultdef).ordtype<>uwidechar then
-                     begin
-                       procname:='fpc_char_to_';
-                       if tstringdef(resultdef).stringtype in [st_widestring,st_unicodestring] then
-                         if nf_explicit in flags then
-                           Message2(type_w_explicit_string_cast,left.resultdef.typename,resultdef.typename)
-                         else
-                           Message2(type_w_implicit_string_cast,left.resultdef.typename,resultdef.typename);
-                     end
-                   else
-                     begin
-                       procname:='fpc_uchar_to_';
-                       if not (tstringdef(resultdef).stringtype in [st_widestring,st_unicodestring]) then
-                         if nf_explicit in flags then
-                           Message2(type_w_explicit_string_cast_loss,left.resultdef.typename,resultdef.typename)
-                         else
-                           Message2(type_w_implicit_string_cast_loss,left.resultdef.typename,resultdef.typename);
-                     end;
-                   procname:=procname+tstringdef(resultdef).stringtypname;
-
-                   { and finally the call }
-                   result:=ccallnode.createinternres(procname,para,resultdef);
+                   procname:='fpc_char_to_';
+                   if tstringdef(resultdef).stringtype in [st_widestring,st_unicodestring] then
+                     if nf_explicit in flags then
+                       Message2(type_w_explicit_string_cast,left.resultdef.typename,resultdef.typename)
+                     else
+                       Message2(type_w_implicit_string_cast,left.resultdef.typename,resultdef.typename);
                  end
                  end
                else
                else
                  begin
                  begin
-                   if nf_explicit in flags then
-                     Message2(type_w_explicit_string_cast_loss,left.resultdef.typename,resultdef.typename)
-                   else
-                     Message2(type_w_implicit_string_cast_loss,left.resultdef.typename,resultdef.typename);
-                   newblock:=internalstatements(newstat);
-                   restemp:=ctempcreatenode.create(resultdef,resultdef.size,tt_persistent,false);
-                   addstatement(newstat,restemp);
-                   if torddef(left.resultdef).ordtype<>uwidechar then
-                     procname := 'fpc_char_to_shortstr'
-                   else
-                     procname := 'fpc_uchar_to_shortstr';
-                   addstatement(newstat,ccallnode.createintern(procname,ccallparanode.create(left,ccallparanode.create(
-                     ctemprefnode.create(restemp),nil))));
-                   addstatement(newstat,ctempdeletenode.create_normal_temp(restemp));
-                   addstatement(newstat,ctemprefnode.create(restemp));
-                   result:=newblock;
+                   procname:='fpc_uchar_to_';
+                   if not (tstringdef(resultdef).stringtype in [st_widestring,st_unicodestring]) then
+                     if nf_explicit in flags then
+                       Message2(type_w_explicit_string_cast_loss,left.resultdef.typename,resultdef.typename)
+                     else
+                       Message2(type_w_implicit_string_cast_loss,left.resultdef.typename,resultdef.typename);
                  end;
                  end;
+               procname:=procname+tstringdef(resultdef).stringtypname;
+
+               { and finally the call }
+               result:=ccallnode.createinternres(procname,para,resultdef);
                left := nil;
                left := nil;
              end
              end
            else
            else
@@ -1478,10 +1458,10 @@ implementation
 
 
       begin
       begin
          result:=nil;
          result:=nil;
-         if is_pwidechar(resultdef) then
-           inserttypeconv(left,cunicodestringtype)
-         else
-           inserttypeconv(left,cshortstringtype);
+         { handle any constants via cunicodestringtype because the compiler
+           cannot convert arbitrary unicodechar constants at compile time to
+           a shortstring (since it doesn't know the code page to use) }
+         inserttypeconv(left,cunicodestringtype);
          { evaluate again, reset resultdef so the convert_typ
          { evaluate again, reset resultdef so the convert_typ
            will be calculated again and cstring_to_pchar will
            will be calculated again and cstring_to_pchar will
            be used for futher conversion }
            be used for futher conversion }

+ 6 - 2
compiler/nopt.pas

@@ -349,7 +349,9 @@ begin
       if is_ansistring(p.resultdef) then
       if is_ansistring(p.resultdef) then
         para:=ccallparanode.create(
         para:=ccallparanode.create(
                 cordconstnode.create(
                 cordconstnode.create(
-                  getparaencoding(p.resultdef),
+                  { don't use getparaencoding(), we have to know
+                    when the result is rawbytestring }
+                  tstringdef(p.resultdef).encoding,
                   u16inttype,
                   u16inttype,
                   true
                   true
                 ),
                 ),
@@ -383,7 +385,9 @@ begin
       if is_ansistring(p.resultdef) then
       if is_ansistring(p.resultdef) then
         para:=ccallparanode.create(
         para:=ccallparanode.create(
                 cordconstnode.create(
                 cordconstnode.create(
-                  getparaencoding(p.resultdef),
+                  { don't use getparaencoding(), we have to know
+                    when the result is rawbytestring }
+                  tstringdef(p.resultdef).encoding,
                   u16inttype,
                   u16inttype,
                   true
                   true
                 ),
                 ),

+ 1 - 1
compiler/options.pas

@@ -3197,7 +3197,7 @@ begin
   { Add exepath if the exe is not in the current dir, because that is always searched already.
   { Add exepath if the exe is not in the current dir, because that is always searched already.
     Do not add it when linking on the target because then we can maybe already find
     Do not add it when linking on the target because then we can maybe already find
     .o files that are not for the target }
     .o files that are not for the target }
-  if (ExePath<>GetCurrentDir) and
+  if (ExePath<>cfileutl.GetCurrentDir) and
      not(cs_link_on_target in init_settings.globalswitches) then
      not(cs_link_on_target in init_settings.globalswitches) then
    UnitSearchPath.AddPath(ExePath,false);
    UnitSearchPath.AddPath(ExePath,false);
   { Add unit dir to the object and library path }
   { Add unit dir to the object and library path }

+ 21 - 55
compiler/symdef.pas

@@ -138,6 +138,7 @@ interface
           procedure deref;override;
           procedure deref;override;
           function  GetTypeName:string;override;
           function  GetTypeName:string;override;
           function  getmangledparaname:TSymStr;override;
           function  getmangledparaname:TSymStr;override;
+          function  size:asizeint;override;
           procedure setsize;
           procedure setsize;
        end;
        end;
 
 
@@ -1129,7 +1130,11 @@ implementation
     function getparaencoding(def:tdef):tstringencoding; inline;
     function getparaencoding(def:tdef):tstringencoding; inline;
       begin
       begin
         { don't pass CP_NONE encoding to internal functions
         { don't pass CP_NONE encoding to internal functions
-          they expect 0 encoding instead }
+          they expect 0 encoding instead
+          exception: result of string concatenation, because if you pass the
+          result of a string concatenation to a rawbytestring, the result of
+          that concatenation shouldn't be converted to defaultsystemcodepage
+          if all strings have the same type }
         result:=tstringdef(def).encoding;
         result:=tstringdef(def).encoding;
         if result=CP_NONE then
         if result=CP_NONE then
           result:=0
           result:=0
@@ -2614,7 +2619,6 @@ implementation
          inherited create(filedef);
          inherited create(filedef);
          filetyp:=ft_text;
          filetyp:=ft_text;
          typedfiledef:=nil;
          typedfiledef:=nil;
-         setsize;
       end;
       end;
 
 
 
 
@@ -2623,7 +2627,6 @@ implementation
          inherited create(filedef);
          inherited create(filedef);
          filetyp:=ft_untyped;
          filetyp:=ft_untyped;
          typedfiledef:=nil;
          typedfiledef:=nil;
-         setsize;
       end;
       end;
 
 
 
 
@@ -2632,7 +2635,6 @@ implementation
          inherited create(filedef);
          inherited create(filedef);
          filetyp:=ft_typed;
          filetyp:=ft_typed;
          typedfiledef:=def;
          typedfiledef:=def;
-         setsize;
       end;
       end;
 
 
 
 
@@ -2644,7 +2646,6 @@ implementation
            ppufile.getderef(typedfiledefderef)
            ppufile.getderef(typedfiledefderef)
          else
          else
            typedfiledef:=nil;
            typedfiledef:=nil;
-         setsize;
       end;
       end;
 
 
 
 
@@ -2679,58 +2680,23 @@ implementation
       end;
       end;
 
 
 
 
+    function  tfiledef.size:asizeint;
+      begin
+        if savesize=0 then
+          setsize;
+        size:=savesize;
+      end;
+
+
     procedure tfiledef.setsize;
     procedure tfiledef.setsize;
       begin
       begin
-{$ifdef cpu64bitaddr}
-        case filetyp of
-          ft_text :
-            if target_info.system in [system_x86_64_win64,system_ia64_win64] then
-              savesize:=640
-            else
-              savesize:=632;
-          ft_typed,
-          ft_untyped :
-            if target_info.system in [system_x86_64_win64,system_ia64_win64] then
-              savesize:=376
-            else
-              savesize:=368;
-        end;
-{$endif cpu64bitaddr}
-{$ifdef cpu32bitaddr}
-        case filetyp of
-          ft_text :
-            savesize:=596; { keep this dividable by 4 for proper alignment of arrays of text, see tw0754 e.g. on arm }
-          ft_typed,
-          ft_untyped :
-            savesize:=332;
-        end;
-{$endif cpu32bitaddr}
-{$ifdef cpu16bitaddr}
-        case filetyp of
-          ft_text :
-            {$if defined(avr)}
-              savesize:=96;
-            {$elseif defined(i8086)}
-              case current_settings.x86memorymodel of
-                mm_tiny,mm_small: savesize:=576;
-                mm_medium:        savesize:=584;
-                else
-                  internalerror(2013060901);
-              end;
-            {$else}
-              {$fatal TODO: define the textrec size for your cpu}
-            {$endif}
-          ft_typed,
-          ft_untyped :
-            {$if defined(avr)}
-              savesize:=76;
-            {$elseif defined(i8086)}
-              savesize:=316;
-            {$else}
-              {$fatal TODO: define the textrec size for your cpu}
-            {$endif}
-        end;
-{$endif cpu16bitaddr}
+       case filetyp of
+         ft_text    :
+           savesize:=search_system_type('TEXTREC').typedef.size;
+         ft_typed,
+         ft_untyped :
+           savesize:=search_system_type('FILEREC').typedef.size;
+         end;
       end;
       end;
 
 
 
 

+ 24 - 0
rtl/aix/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 28 - 6
rtl/amiga/dos.pp

@@ -725,7 +725,11 @@ var
 begin
 begin
     DosError:=0;
     DosError:=0;
     FTime := 0;
     FTime := 0;
-    Str := StrPas(filerec(f).name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+    Str := strpas(filerec(f).Name);
+{$else}
+    Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+{$endif}
     DoDirSeparators(Str);
     DoDirSeparators(Str);
     FLock := dosLock(Str, SHARED_LOCK);
     FLock := dosLock(Str, SHARED_LOCK);
     IF FLock <> 0 then begin
     IF FLock <> 0 then begin
@@ -756,7 +760,11 @@ end;
     FLock: longint;
     FLock: longint;
   Begin
   Begin
     new(DateStamp);
     new(DateStamp);
-    Str := StrPas(filerec(f).name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+    Str := strpas(filerec(f).Name);
+{$else}
+    Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+{$endif}
     DoDirSeparators(str);
     DoDirSeparators(str);
     { Check first of all, if file exists }
     { Check first of all, if file exists }
     FLock := dosLock(Str, SHARED_LOCK);
     FLock := dosLock(Str, SHARED_LOCK);
@@ -788,7 +796,11 @@ begin
     DosError:=0;
     DosError:=0;
     flags:=0;
     flags:=0;
     New(info);
     New(info);
-    Str := StrPas(filerec(f).name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+    Str := strpas(filerec(f).Name);
+{$else}
+    Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+{$endif}
     DoDirSeparators(str);
     DoDirSeparators(str);
     { open with shared lock to check if file exists }
     { open with shared lock to check if file exists }
     MyLock:=dosLock(Str,SHARED_LOCK);
     MyLock:=dosLock(Str,SHARED_LOCK);
@@ -825,7 +837,17 @@ procedure setfattr(var f; attr : word);
 var
 var
   flags: longint;
   flags: longint;
   tmpLock : longint;
   tmpLock : longint;
-begin
+{$ifndef FPC_ANSI_TEXTFILEREC}
+  r : rawbytestring;
+{$endif not FPC_ANSI_TEXTFILEREC}
+  p : pchar;
+begin
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  p := @filerec(f).Name;
+{$else}
+  r := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+  p := pchar(r);
+{$endif}
   DosError:=0;
   DosError:=0;
   flags:=FIBF_WRITE;
   flags:=FIBF_WRITE;
 
 
@@ -836,10 +858,10 @@ begin
   { converts the path (KB) }
   { converts the path (KB) }
 
 
   { create a shared lock on the file }
   { create a shared lock on the file }
-  tmpLock:=Lock(filerec(f).name,SHARED_LOCK);
+  tmpLock:=Lock(p,SHARED_LOCK);
   if tmpLock <> 0 then begin
   if tmpLock <> 0 then begin
     Unlock(tmpLock);
     Unlock(tmpLock);
-    if not SetProtection(filerec(f).name,flags) then DosError:=5;
+    if not SetProtection(p,flags) then DosError:=5;
   end else
   end else
     DosError:=3;
     DosError:=3;
 end;
 end;

+ 24 - 0
rtl/amiga/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 23 - 26
rtl/amiga/sysdir.inc

@@ -3,7 +3,7 @@
     Copyright (c) 1999-2000 by Florian Klaempfl and Pavel Ozerski
     Copyright (c) 1999-2000 by Florian Klaempfl and Pavel Ozerski
     member of the Free Pascal development team.
     member of the Free Pascal development team.
 
 
-    FPC Pascal system unit for the Win32 API.
+    FPC Pascal system unit for Amiga.
 
 
     See the file COPYING.FPC, included in this distribution,
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -18,15 +18,14 @@
 {*****************************************************************************
 {*****************************************************************************
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
-procedure mkdir(s : pchar; len : sizeuint); [IOCheck, public, alias : 'FPC_SYS_MKDIR'];
+procedure do_mkdir(const s : rawbytestring);
 var
 var
-  tmpStr : array[0..255] of char;
+  tmpStr : rawbytestring;
   tmpLock: LongInt;
   tmpLock: LongInt;
 begin
 begin
   checkCTRLC;
   checkCTRLC;
-  if (s='') or (InOutRes<>0) then exit;
-  tmpStr:=PathConv(s)+#0;
-  tmpLock:=dosCreateDir(@tmpStr);
+  tmpStr:=PathConv(s);
+  tmpLock:=dosCreateDir(pchar(tmpStr));
   if tmpLock=0 then begin
   if tmpLock=0 then begin
     dosError2InOut(IoErr);
     dosError2InOut(IoErr);
     exit;
     exit;
@@ -34,33 +33,35 @@ begin
   UnLock(tmpLock);
   UnLock(tmpLock);
 end;
 end;
 
 
-procedure rmdir(s : pchar; len : sizeuint); [IOCheck, public, alias : 'FPC_SYS_RMDIR'];
+procedure do_rmdir(const s : rawbytestring);
 var
 var
-  tmpStr : array[0..255] of Char;
+  tmpStr : rawbytestring;
 begin
 begin
   checkCTRLC;
   checkCTRLC;
-  if (s='.') then InOutRes:=16;
-  If (s='') or (InOutRes<>0) then exit;
-  tmpStr:=PathConv(s)+#0;
-  if not dosDeleteFile(@tmpStr) then
+  if (s='.') then
+    begin
+      InOutRes:=16;
+      exit;
+    end;
+  tmpStr:=PathConv(s);
+  if not dosDeleteFile(pchar(tmpStr)) then
     dosError2InOut(IoErr);
     dosError2InOut(IoErr);
 end;
 end;
 
 
-procedure sys_chdir(s : pchar);
+procedure do_ChDir(const s: rawbytestring);
 var
 var
-  tmpStr : array[0..255] of Char;
+  tmpStr : rawbytestring;
   tmpLock: LongInt;
   tmpLock: LongInt;
   FIB    : PFileInfoBlock;
   FIB    : PFileInfoBlock;
 begin
 begin
   checkCTRLC;
   checkCTRLC;
-  If (s='') or (InOutRes<>0) then exit;
-  tmpStr:=PathConv(s)+#0;
+  tmpStr:=PathConv(s);
   tmpLock:=0;
   tmpLock:=0;
 
 
   { Changing the directory is a pretty complicated affair }
   { Changing the directory is a pretty complicated affair }
   {   1) Obtain a lock on the directory                   }
   {   1) Obtain a lock on the directory                   }
   {   2) CurrentDir the lock                              }
   {   2) CurrentDir the lock                              }
-  tmpLock:=Lock(@tmpStr,SHARED_LOCK);
+  tmpLock:=Lock(pchar(tmpStr),SHARED_LOCK);
   if tmpLock=0 then begin
   if tmpLock=0 then begin
     dosError2InOut(IoErr);
     dosError2InOut(IoErr);
     exit;
     exit;
@@ -81,14 +82,7 @@ begin
   if assigned(FIB) then dispose(FIB);
   if assigned(FIB) then dispose(FIB);
 end;
 end;
 
 
-Procedure ChDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
-begin
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
-    exit;
-  sys_chdir(s);
-end;
-
-procedure GetDir (DriveNr: byte; var Dir: ShortString);
+procedure do_GetDir (DriveNr: byte; var Dir: RawByteString);
 var tmpbuf: array[0..255] of char;
 var tmpbuf: array[0..255] of char;
 begin
 begin
   checkCTRLC;
   checkCTRLC;
@@ -97,5 +91,8 @@ begin
   if not GetCurrentDirName(tmpbuf,256) then
   if not GetCurrentDirName(tmpbuf,256) then
     dosError2InOut(IoErr)
     dosError2InOut(IoErr)
   else
   else
-    Dir:=strpas(tmpbuf);
+    begin
+      Dir:=tmpbuf;
+      SetCodePage(Dir,DefaultFileSystemCodePage,false);
+    end;
 end;
 end;

+ 3 - 3
rtl/amiga/sysfile.inc

@@ -170,7 +170,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure do_erase(p : pchar);
+procedure do_erase(p : pchar; pchangeable: boolean);
 var
 var
   tmpStr: array[0..255] of Char;
   tmpStr: array[0..255] of Char;
 begin
 begin
@@ -180,7 +180,7 @@ begin
     dosError2InOut(IoErr);
     dosError2InOut(IoErr);
 end;
 end;
 
 
-procedure do_rename(p1,p2 : pchar);
+procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
 { quite stack-effective code, huh? :) damn path conversions... (KB) }
 { quite stack-effective code, huh? :) damn path conversions... (KB) }
 var
 var
   tmpStr1: array[0..255] of Char;
   tmpStr1: array[0..255] of Char;
@@ -306,7 +306,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
 {
 {
   filerec and textrec have both handle and mode as the first items so
   filerec and textrec have both handle and mode as the first items so
   they could use the same routine for opening/creating.
   they could use the same routine for opening/creating.

+ 35 - 0
rtl/amiga/sysos.inc

@@ -146,3 +146,38 @@ begin
   PathConv:=path;
   PathConv:=path;
 end;
 end;
 
 
+{ Converts an Unix-like path to Amiga-like path }
+function PathConv(const path: rawbytestring): rawbytestring; alias: 'PATHCONVRBS'; [public];
+var tmppos: longint;
+begin
+  { check for short paths }
+  if length(path)<=2 then begin
+    if (path='.') or (path='./') then PathConv:='' else
+    if path='..' then PathConv:='/' else
+    if path='*' then PathConv:='#?'
+    else PathConv:=path;
+  end else begin
+    { convert parent directories }
+    PathConv:=path;
+    tmppos:=pos('../',PathConv);
+    while tmppos<>0 do begin
+      { delete .. to have / as parent dir sign }
+      delete(PathConv,tmppos,2);
+      tmppos:=pos('../',PathConv);
+    end;
+    { convert current directories }
+    tmppos:=pos('./',PathConv);
+    while tmppos<>0 do begin
+      { delete ./ since we doesn't need to sign current directory }
+      delete(PathConv,tmppos,2);
+      tmppos:=pos('./',PathConv);
+    end;
+    { convert wildstart to #? }
+    tmppos:=pos('*',PathConv);
+    while tmppos<>0 do begin
+      delete(PathConv,tmppos,1);
+      insert('#?',PathConv,tmppos);
+      tmppos:=pos('*',PathConv);
+    end;
+  end;
+end;

+ 51 - 68
rtl/amiga/sysutils.pp

@@ -27,6 +27,12 @@ interface
 
 
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_OSERROR}
 {$DEFINE HAS_OSERROR}
+
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
 { Include platform independent interface part }
 { Include platform independent interface part }
 {$i sysutilh.inc}
 {$i sysutilh.inc}
 
 
@@ -57,6 +63,7 @@ uses dos,sysconst;
 
 
 { * Followings are implemented in the system unit! * }
 { * Followings are implemented in the system unit! * }
 function PathConv(path: shortstring): shortstring; external name 'PATHCONV';
 function PathConv(path: shortstring): shortstring; external name 'PATHCONV';
+function PathConv(path: RawByteString): shortstring; external name 'PATHCONVRBS';
 procedure AddToList(var l: Pointer; h: LongInt); external name 'ADDTOLIST';
 procedure AddToList(var l: Pointer; h: LongInt); external name 'ADDTOLIST';
 function RemoveFromList(var l: Pointer; h: LongInt): boolean; external name 'REMOVEFROMLIST';
 function RemoveFromList(var l: Pointer; h: LongInt): boolean; external name 'REMOVEFROMLIST';
 function CheckInList(var l: Pointer; h: LongInt): pointer; external name 'CHECKINLIST';
 function CheckInList(var l: Pointer; h: LongInt): pointer; external name 'CHECKINLIST';
@@ -106,14 +113,14 @@ end;
 
 
 (****** non portable routines ******)
 (****** non portable routines ******)
 
 
-function FileOpen(const FileName: string; Mode: Integer): LongInt;
+function FileOpen(const FileName: rawbytestring; Mode: Integer): LongInt;
 var
 var
+  SystemFileName: RawByteString;
   dosResult: LongInt;
   dosResult: LongInt;
-  tmpStr   : array[0..255] of char;
 begin
 begin
+  SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
   {$WARNING FIX ME! To do: FileOpen Access Modes}
   {$WARNING FIX ME! To do: FileOpen Access Modes}
-  tmpStr:=PathConv(FileName)+#0;
-  dosResult:=Open(@tmpStr,MODE_OLDFILE);
+  dosResult:=Open(PChar(SystemFileName),MODE_OLDFILE);
   if dosResult=0 then
   if dosResult=0 then
     dosResult:=-1
     dosResult:=-1
   else
   else
@@ -136,13 +143,13 @@ begin
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string) : LongInt;
+function FileCreate(const FileName: RawByteString) : LongInt;
 var
 var
+  SystemFileName: RawByteString;
   dosResult: LongInt;
   dosResult: LongInt;
-  tmpStr   : array[0..255] of char;
 begin
 begin
- tmpStr:=PathConv(FileName)+#0;
- dosResult:=Open(@tmpStr,MODE_NEWFILE);
+ SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
+ dosResult:=Open(PChar(FileName),MODE_NEWFILE);
  if dosResult=0 then
  if dosResult=0 then
    dosResult:=-1
    dosResult:=-1
  else
  else
@@ -152,13 +159,13 @@ begin
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string; Rights: integer): LongInt;
+function FileCreate(const FileName: RawByteString; Rights: integer): LongInt;
 begin
 begin
   {$WARNING FIX ME! To do: FileCreate Access Modes}
   {$WARNING FIX ME! To do: FileCreate Access Modes}
   FileCreate:=FileCreate(FileName);
   FileCreate:=FileCreate(FileName);
 end;
 end;
 
 
-function FileCreate(const FileName: string; ShareMode: integer; Rights : Integer): LongInt;
+function FileCreate(const FileName: RawByteString; ShareMode: integer; Rights : Integer): LongInt;
 begin
 begin
   {$WARNING FIX ME! To do: FileCreate Access Modes}
   {$WARNING FIX ME! To do: FileCreate Access Modes}
   FileCreate:=FileCreate(FileName);
   FileCreate:=FileCreate(FileName);
@@ -231,33 +238,33 @@ begin
 end;
 end;
 
 
 
 
-function DeleteFile(const FileName: string) : Boolean;
+function DeleteFile(const FileName: RawByteString) : Boolean;
 var
 var
-  tmpStr: array[0..255] of char;
+  SystemFileName: RawByteString;
 begin
 begin
-  tmpStr:=PathConv(FileName)+#0;
+  SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
 
 
-  DeleteFile:=dosDeleteFile(@tmpStr);
+  DeleteFile:=dosDeleteFile(PChar(SystemFileName));
 end;
 end;
 
 
 
 
 function RenameFile(const OldName, NewName: string): Boolean;
 function RenameFile(const OldName, NewName: string): Boolean;
 var
 var
-  tmpOldName, tmpNewName: array[0..255] of char;
+  OldSystemFileName, NewSystemFileName: RawByteString;
 begin
 begin
-  tmpOldName:=PathConv(OldName)+#0;
-  tmpNewName:=PathConv(NewName)+#0;
+  OldSystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(OldName));
+  NewSystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(NewName));
 
 
-  RenameFile:=dosRename(tmpOldName, tmpNewName);
+  RenameFile:=dosRename(PChar(OldSystemFileName), PChar(NewSystemFileName));
 end;
 end;
 
 
 
 
 (****** end of non portable routines ******)
 (****** end of non portable routines ******)
 
 
 
 
-function FileAge (const FileName : String): Longint;
+function FileAge (const FileName : RawByteString): Longint;
 var
 var
-  tmpName: String;
+  tmpName: RawByteString;
   tmpLock: Longint;
   tmpLock: Longint;
   tmpFIB : PFileInfoBlock;
   tmpFIB : PFileInfoBlock;
   tmpDateTime: TDateTime;
   tmpDateTime: TDateTime;
@@ -265,7 +272,7 @@ var
 
 
 begin
 begin
   validFile:=false;
   validFile:=false;
-  tmpName := PathConv(FileName);
+  tmpName := PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
   tmpLock := dosLock(tmpName, SHARED_LOCK);
   tmpLock := dosLock(tmpName, SHARED_LOCK);
 
 
   if (tmpLock <> 0) then begin
   if (tmpLock <> 0) then begin
@@ -284,16 +291,15 @@ begin
 end;
 end;
 
 
 
 
-function FileExists (const FileName : String) : Boolean;
+function FileExists (const FileName : RawByteString) : Boolean;
 var
 var
-  tmpName: String;
   tmpLock: LongInt;
   tmpLock: LongInt;
   tmpFIB : PFileInfoBlock;
   tmpFIB : PFileInfoBlock;
-
+  SystemFileName: RawByteString;
 begin
 begin
   result:=false;
   result:=false;
-  tmpName := PathConv(FileName);
-  tmpLock := dosLock(tmpName, SHARED_LOCK);
+  SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
+  tmpLock := dosLock(PChar(SystemFileName), SHARED_LOCK);
 
 
   if (tmpLock <> 0) then begin
   if (tmpLock <> 0) then begin
     new(tmpFIB);
     new(tmpFIB);
@@ -305,15 +311,15 @@ begin
 end;
 end;
 
 
 
 
-function FindFirst(const Path: String; Attr : Longint; out Rslt: TSearchRec): Longint;
+Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
 var
 var
-  tmpStr: array[0..255] of Char;
+  tmpStr: RawByteString;
   Anchor: PAnchorPath;
   Anchor: PAnchorPath;
   tmpDateTime: TDateTime;
   tmpDateTime: TDateTime;
   validDate: boolean;
   validDate: boolean;
 begin
 begin
   result:=-1; { We emulate Linux/Unix behaviour, and return -1 on errors. }
   result:=-1; { We emulate Linux/Unix behaviour, and return -1 on errors. }
-  tmpStr:=PathConv(path)+#0;
+  tmpStr:=PathConv(ToSingleByteEncodedFileName(path));
 
 
   { $1e = faHidden or faSysFile or faVolumeID or faDirectory }
   { $1e = faHidden or faSysFile or faVolumeID or faDirectory }
   Rslt.ExcludeAttr := (not Attr) and ($1e);
   Rslt.ExcludeAttr := (not Attr) and ($1e);
@@ -322,11 +328,12 @@ begin
   new(Anchor);
   new(Anchor);
   FillChar(Anchor^,sizeof(TAnchorPath),#0);
   FillChar(Anchor^,sizeof(TAnchorPath),#0);
 
 
-  if MatchFirst(@tmpStr,Anchor)<>0 then exit;
+  if MatchFirst(pchar(tmpStr),Anchor)<>0 then exit;
   Rslt.FindHandle := longint(Anchor);
   Rslt.FindHandle := longint(Anchor);
 
 
   with Anchor^.ap_Info do begin
   with Anchor^.ap_Info do begin
-    Rslt.Name := StrPas(fib_FileName);
+    Name := fib_FileName;
+    SetCodePage(Name,DefaultFileSystemCodePage,false);
 
 
     Rslt.Size := fib_Size;
     Rslt.Size := fib_Size;
     Rslt.Time := DateTimeToFileDate(AmigaFileDateToDateTime(fib_Date,validDate));
     Rslt.Time := DateTimeToFileDate(AmigaFileDateToDateTime(fib_Date,validDate));
@@ -344,7 +351,7 @@ begin
 end;
 end;
 
 
 
 
-function FindNext (var Rslt : TSearchRec): Longint;
+Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
 var
 var
   Anchor: PAnchorPath;
   Anchor: PAnchorPath;
   validDate: boolean;
   validDate: boolean;
@@ -356,7 +363,8 @@ begin
   if MatchNext(Anchor) <> 0 then exit;
   if MatchNext(Anchor) <> 0 then exit;
 
 
   with Anchor^.ap_Info do begin
   with Anchor^.ap_Info do begin
-    Rslt.Name := StrPas(fib_FileName);
+    Name := fib_FileName;
+    SetCodePage(Name,DefaultFileSystemCodePage,false);
     Rslt.Size := fib_Size;
     Rslt.Size := fib_Size;
     Rslt.Time := DateTimeToFileDate(AmigaFileDateToDateTime(fib_Date,validDate));
     Rslt.Time := DateTimeToFileDate(AmigaFileDateToDateTime(fib_Date,validDate));
     if not validDate then exit;
     if not validDate then exit;
@@ -372,20 +380,21 @@ begin
 end;
 end;
 
 
 
 
-procedure FindClose(var f: TSearchRec);
+Procedure InternalFindClose(var Handle: THandle);
 var
 var
   Anchor: PAnchorPath;
   Anchor: PAnchorPath;
 begin
 begin
-  Anchor:=PAnchorPath(f.FindHandle);
+  Anchor:=PAnchorPath(Handle);
   if not assigned(Anchor) then exit;
   if not assigned(Anchor) then exit;
   MatchEnd(Anchor);
   MatchEnd(Anchor);
   Dispose(Anchor);
   Dispose(Anchor);
+  Handle:=THandle(nil);
 end;
 end;
 
 
 
 
 (****** end of non portable routines ******)
 (****** end of non portable routines ******)
 
 
-Function FileGetAttr (Const FileName : String) : Longint;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
 var
 var
  F: file;
  F: file;
  attr: word;
  attr: word;
@@ -399,7 +408,7 @@ begin
 end;
 end;
 
 
 
 
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
 var
 var
  F: file;
  F: file;
 begin
 begin
@@ -461,44 +470,18 @@ Begin
   DiskSize := dos.DiskSize(Drive);
   DiskSize := dos.DiskSize(Drive);
 End;
 End;
 
 
-function GetCurrentDir : String;
-begin
-  GetDir (0,Result);
-end;
-
-
-Function SetCurrentDir (Const NewDir : String) : Boolean;
-begin
-  ChDir(NewDir);
-  result := (IOResult = 0);
-end;
-
-
-Function CreateDir (Const NewDir : String) : Boolean;
-begin
-  MkDir(NewDir);
-  result := (IOResult = 0);
-end;
-
-
-Function RemoveDir (Const Dir : String) : Boolean;
-begin
-  RmDir(Dir);
-  result := (IOResult = 0);
-end;
-
-
-function DirectoryExists(const Directory: string): Boolean;
+function DirectoryExists(const Directory: RawBytetring): Boolean;
 var
 var
   tmpStr : String;
   tmpStr : String;
   tmpLock: LongInt;
   tmpLock: LongInt;
   FIB    : PFileInfoBlock;
   FIB    : PFileInfoBlock;
+  SystemFileName: RawByteString;
 begin
 begin
   result:=false;
   result:=false;
   if (Directory='') or (InOutRes<>0) then exit;
   if (Directory='') or (InOutRes<>0) then exit;
-  tmpStr:=PathConv(Directory);
+  SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
 
 
-  tmpLock:=dosLock(tmpStr,SHARED_LOCK);
+  tmpLock:=dosLock(PChar(SystemFileName),SHARED_LOCK);
   if tmpLock=0 then exit;
   if tmpLock=0 then exit;
 
 
   FIB:=nil; new(FIB);
   FIB:=nil; new(FIB);
@@ -591,7 +574,7 @@ begin
   Result:=Dos.envCount;
   Result:=Dos.envCount;
 end;
 end;
 
 
-Function GetEnvironmentString(Index : Integer) : String;
+Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 
 
 begin
 begin
   // Result:=FPCGetEnvStrFromP(Envp,Index);
   // Result:=FPCGetEnvStrFromP(Envp,Index);

+ 24 - 0
rtl/atari/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 24 - 0
rtl/beos/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 24 - 0
rtl/darwin/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{$define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 29 - 0
rtl/embedded/rtldefs.inc

@@ -0,0 +1,29 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}
+
+{ Use the shortstring version of do_getdir (should be converted to rawbytestring or
+  unicodestring for all but the OSes that don't support code pages and/or are
+  resource limited) }
+{$define FPCRTL_DO_GETDIR_SHORTSTRING}

+ 27 - 3
rtl/embedded/sysdir.inc

@@ -19,17 +19,40 @@
 {*****************************************************************************
 {*****************************************************************************
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
-procedure mkdir(s: pchar;len:sizeuint);[IOCheck];
+{$if defined(FPC_HAS_FEATURE_ANSISTRINGS)}
+procedure do_mkdir(const s: rawbytestring);
 begin
 begin
   InOutRes:=3;
   InOutRes:=3;
 end;
 end;
 
 
-procedure rmdir(s: pchar;len:sizeuint);[IOCheck];
+procedure do_rmdir(const s: rawbytestring);
 begin
 begin
   InOutRes:=3;
   InOutRes:=3;
 end;
 end;
 
 
-procedure chdir(s: pchar;len:sizeuint);[IOCheck];
+procedure do_chdir(const s: rawbytestring);
+begin
+  InOutRes:=3;
+end;
+
+procedure do_GetDir (DriveNr: byte; var Dir: RawByteString);
+begin
+  InOutRes:=3;
+end;
+
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
+
+procedure mkdir(const s: shortstring);
+begin
+  InOutRes:=3;
+end;
+
+procedure rmdir(const s: shortstring);
+begin
+  InOutRes:=3;
+end;
+
+procedure chdir(const s: shortstring);
 begin
 begin
   InOutRes:=3;
   InOutRes:=3;
 end;
 end;
@@ -38,6 +61,7 @@ procedure GetDir (DriveNr: byte; var Dir: ShortString);
 begin
 begin
   InOutRes:=3;
   InOutRes:=3;
 end;
 end;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 
 
 
 
 

+ 3 - 3
rtl/embedded/sysfile.inc

@@ -27,11 +27,11 @@ begin
 
 
 end;
 end;
 
 
-procedure do_erase(p : pchar);
+procedure do_erase(p : pchar; pchangeable: boolean);
 begin
 begin
 end;
 end;
 
 
-procedure do_rename(p1,p2 : pchar);
+procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
 begin
 begin
 end;
 end;
 
 
@@ -69,7 +69,7 @@ procedure do_truncate(handle, pos: longint);
 begin
 begin
 end;
 end;
 
 
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
 begin
 begin
 end;
 end;
 
 

+ 20 - 39
rtl/embedded/sysutils.pp

@@ -20,6 +20,11 @@ unit sysutils;
 
 
 interface
 interface
 
 
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
   { Include platform independent interface part }
   { Include platform independent interface part }
   {$i sysutilh.inc}
   {$i sysutilh.inc}
 
 
@@ -34,7 +39,7 @@ uses
 {****************************************************************************
 {****************************************************************************
                               File Functions
                               File Functions
 ****************************************************************************}
 ****************************************************************************}
-function FileOpen(const FileName: string; Mode: Integer): LongInt;
+function FileOpen(const FileName: RawByteString; Mode: Integer): LongInt;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
@@ -52,19 +57,19 @@ begin
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string) : LongInt;
+function FileCreate(const FileName: RawByteString) : LongInt;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string; Rights: integer): LongInt;
+function FileCreate(const FileName: RawByteString; Rights: integer): LongInt;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string; ShareMode: integer; rights : integer): LongInt;
+function FileCreate(const FileName: RawByteString; ShareMode: integer; rights : integer): LongInt;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
@@ -104,54 +109,54 @@ begin
 end;
 end;
 
 
 
 
-function DeleteFile(const FileName: string) : Boolean;
+function DeleteFile(const FileName: RawByteString) : Boolean;
 begin
 begin
   result := false;
   result := false;
 end;
 end;
 
 
 
 
-function RenameFile(const OldName, NewName: string): Boolean;
+function RenameFile(const OldName, NewName: RawByteString): Boolean;
 begin
 begin
   result := false;
   result := false;
 end;
 end;
 
 
 
 
-Function FileAge (Const FileName : String): Longint;
+Function FileAge (Const FileName : RawByteString): Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-Function FileExists (Const FileName : String) : Boolean;
+Function FileExists (Const FileName : RawByteString) : Boolean;
 Begin
 Begin
   result := false;
   result := false;
 end;
 end;
 
 
 
 
-Function FindFirst (Const Path : String; Attr : Longint; Out Rslt : TSearchRec) : Longint;
+Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-Function FindNext (Var Rslt : TSearchRec) : Longint;
+Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-Procedure FindClose (Var F : TSearchrec);
+Procedure InternalFindClose(var Handle: THandle);
 begin
 begin
 end;
 end;
 
 
 
 
-Function FileGetAttr (Const FileName : String) : Longint;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
@@ -178,31 +183,7 @@ Begin
 End;
 End;
 
 
 
 
-Function GetCurrentDir : String;
-begin
-  result := '';
-end;
-
-
-Function SetCurrentDir (Const NewDir : String) : Boolean;
-begin
-  result := false;
-end;
-
-
-Function CreateDir (Const NewDir : String) : Boolean;
-begin
-  result := false;
-end;
-
-
-Function RemoveDir (Const Dir : String) : Boolean;
-begin
-  result := false;
-end;
-
-
-function DirectoryExists(const Directory: string): Boolean;
+function DirectoryExists(const Directory: RawByteString): Boolean;
 begin
 begin
   result := false;
   result := false;
 end;
 end;
@@ -249,7 +230,7 @@ begin
 end;
 end;
 
 
 
 
-Function GetEnvironmentString(Index : Integer) : String;
+Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 begin
 begin
   result := '';
   result := '';
 end;
 end;

+ 10 - 4
rtl/emx/dos.pas

@@ -944,8 +944,11 @@ var
  buffer:array[0..255] of char;
  buffer:array[0..255] of char;
 begin
 begin
   DosError := 0;
   DosError := 0;
-  path:='';
-  path := StrPas(filerec(f).Name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  path:=filerec(f).Name;
+{$else}
+  path:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+{$endif}
   { Takes care of slash and backslash support }
   { Takes care of slash and backslash support }
   path:=FExpand(path);
   path:=FExpand(path);
   move(path[1],buffer,length(path));
   move(path[1],buffer,length(path));
@@ -974,9 +977,12 @@ var
  path:  pathstr;
  path:  pathstr;
  buffer:array[0..255] of char;
  buffer:array[0..255] of char;
 begin
 begin
-  path:='';
   DosError := 0;
   DosError := 0;
-  path := StrPas(filerec(f).Name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  path:=filerec(f).Name;
+{$else}
+  path:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+{$endif}
   { Takes care of slash and backslash support }
   { Takes care of slash and backslash support }
   path:=FExpand(path);
   path:=FExpand(path);
   move(path[1],buffer,length(path));
   move(path[1],buffer,length(path));

+ 24 - 0
rtl/emx/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 35 - 40
rtl/emx/sysdir.inc

@@ -3,7 +3,7 @@
     Copyright (c) 1999-2000 by Florian Klaempfl and Pavel Ozerski
     Copyright (c) 1999-2000 by Florian Klaempfl and Pavel Ozerski
     member of the Free Pascal development team.
     member of the Free Pascal development team.
 
 
-    FPC Pascal system unit for the Win32 API.
+    FPC Pascal system unit for EMX.
 
 
     See the file COPYING.FPC, included in this distribution,
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -19,7 +19,7 @@
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
 
 
-procedure DosDir (Func: byte; S: PChar);
+procedure DosDir (Func: byte; S: rawbytestring);
 
 
 begin
 begin
   DoDirSeparators (S);
   DoDirSeparators (S);
@@ -33,17 +33,14 @@ begin
   end ['eax', 'edx'];
   end ['eax', 'edx'];
 end;
 end;
 
 
-procedure MkDir (S: pchar; Len: SizeUInt); [IOCheck, public, alias: 'FPC_SYS_MKDIR'];
+procedure do_MkDir (S: rawbytestring);
 var 
 var 
   RC: cardinal;
   RC: cardinal;
 begin
 begin
-  if not Assigned (S) or (Len = 0) or (InOutRes <> 0) then
-   Exit;
-
   if os_mode = osOs2 then
   if os_mode = osOs2 then
    begin
    begin
     DoDirSeparators (S);
     DoDirSeparators (S);
-    RC := DosCreateDir (S, nil);
+    RC := DosCreateDir (pchar(S), nil);
     if RC <> 0 then
     if RC <> 0 then
      begin
      begin
       InOutRes := RC;
       InOutRes := RC;
@@ -60,49 +57,46 @@ begin
 end;
 end;
 
 
 
 
-procedure RmDir (S: PChar; Len: SizeUInt); [IOCheck, public, alias: 'FPC_SYS_RMDIR'];
+procedure do_RmDir (S: rawbytestring);
 var
 var
   RC: cardinal;
   RC: cardinal;
 begin
 begin
-  if Assigned (S) and (Len <> 0) and (InOutRes = 0) then
-   begin
-    if (Len = 1) and (S^ = '.') then
-     InOutRes := 16
-    else
-     if os_mode = osOs2 then
+  if S = '.' then
+   InOutRes := 16
+  else
+   if os_mode = osOs2 then
+    begin
+     DoDirSeparators (S);
+     RC := DosDeleteDir (pchar(S));
+     if RC <> 0 then
       begin
       begin
-       DoDirSeparators (S);
-       RC := DosDeleteDir (S);
-       if RC <> 0 then
-        begin
-         InOutRes := RC;
-         Errno2InOutRes;
-        end;
-      end
-     else
-     { Under EMX 0.9d DOS this routine call may sometimes fail   }
-     { The syscall documentation indicates clearly that this     }
-     { routine was NOT tested.                                   }
-      DosDir ($3A, S);
-   end
+       InOutRes := RC;
+       Errno2InOutRes;
+      end;
+    end
+   else
+   { Under EMX 0.9d DOS this routine call may sometimes fail   }
+   { The syscall documentation indicates clearly that this     }
+   { routine was NOT tested.                                   }
+    DosDir ($3A, S);
 end;
 end;
 
 
 
 
 {$ASMMODE INTEL}
 {$ASMMODE INTEL}
 
 
-procedure ChDir (S: PChar; Len: SizeUInt); [IOCheck, public, alias: 'FPC_SYS_CHDIR'];
+procedure do_ChDir (S: rawbytestring);
 var
 var
   RC: cardinal;
   RC: cardinal;
+  Len: longint;
 begin
 begin
-  if not Assigned (S) or (Len = 0) or (InOutRes <> 0) then
-    exit;
 (* According to EMX documentation, EMX has only one current directory
 (* According to EMX documentation, EMX has only one current directory
    for all processes, so we'll use native calls under OS/2. *)
    for all processes, so we'll use native calls under OS/2. *)
+  Len := Length (S);
   if os_Mode = osOS2 then
   if os_Mode = osOS2 then
    begin
    begin
-    if (Len >= 2) and (S [1] = ':') then
+    if (Len >= 2) and (S [2] = ':') then
      begin
      begin
-      RC := DosSetDefaultDisk ((Ord (S^) and not ($20)) - $40);
+      RC := DosSetDefaultDisk ((Ord (S[1]) and not ($20)) - $40);
       if RC <> 0 then
       if RC <> 0 then
        begin
        begin
         InOutRes := RC;
         InOutRes := RC;
@@ -112,7 +106,7 @@ begin
        if Len > 2 then
        if Len > 2 then
         begin
         begin
          DoDirSeparators (S);
          DoDirSeparators (S);
-         RC := DosSetCurrentDir (S);
+         RC := DosSetCurrentDir (pchar(S));
          if RC <> 0 then
          if RC <> 0 then
           begin
           begin
            InOutRes := RC;
            InOutRes := RC;
@@ -123,7 +117,7 @@ begin
     else
     else
      begin
      begin
       DoDirSeparators (S);
       DoDirSeparators (S);
-      RC := DosSetCurrentDir (S);
+      RC := DosSetCurrentDir (pchar(S));
       if RC <> 0 then
       if RC <> 0 then
        begin
        begin
         InOutRes:= RC;
         InOutRes:= RC;
@@ -132,7 +126,7 @@ begin
      end;
      end;
    end
    end
   else
   else
-   if (Len >= 2) and (S [1] = ':') then
+   if (Len >= 2) and (S [2] = ':') then
     begin
     begin
      asm
      asm
       mov esi, S
       mov esi, S
@@ -163,7 +157,7 @@ end;
 
 
 {$ASMMODE ATT}
 {$ASMMODE ATT}
 
 
-procedure GetDir (DriveNr: byte; var Dir: ShortString);
+procedure do_GetDir (DriveNr: byte; var Dir: RawByteString);
 
 
 {Written by Michael Van Canneyt.}
 {Written by Michael Van Canneyt.}
 
 
@@ -171,6 +165,7 @@ var sof:Pchar;
     i:byte;
     i:byte;
 
 
 begin
 begin
+    SetLength(Dir,260);
     Dir [4] := #0;
     Dir [4] := #0;
     { Used in case the specified drive isn't available }
     { Used in case the specified drive isn't available }
     sof:=pchar(@dir[4]);
     sof:=pchar(@dir[4]);
@@ -189,7 +184,6 @@ begin
     end [ 'eax','edx','esi'];
     end [ 'eax','edx','esi'];
     { Now Dir should be filled with directory in ASCIIZ, }
     { Now Dir should be filled with directory in ASCIIZ, }
     { starting from dir[4]                               }
     { starting from dir[4]                               }
-    dir[0]:=#3;
     dir[2]:=':';
     dir[2]:=':';
     dir[3]:='\';
     dir[3]:='\';
     i:=4;
     i:=4;
@@ -199,10 +193,9 @@ begin
             { convert path name to DOS }
             { convert path name to DOS }
 			     if dir[i] in AllowDirectorySeparators then
 			     if dir[i] in AllowDirectorySeparators then
 			       dir[i]:=DirectorySeparator;
 			       dir[i]:=DirectorySeparator;
-            dir[0]:=char(i);
             inc(i);
             inc(i);
         end;
         end;
-    { upcase the string (FPC function) }
+    SetLength(dir,i-1);
     if drivenr<>0 then   { Drive was supplied. We know it }
     if drivenr<>0 then   { Drive was supplied. We know it }
         dir[1]:=chr(64+drivenr)
         dir[1]:=chr(64+drivenr)
     else
     else
@@ -217,5 +210,7 @@ begin
             end ['eax'];
             end ['eax'];
             dir[1]:=char(i);
             dir[1]:=char(i);
         end;
         end;
+    SetCodePage(dir,DefaultFileSystemCodePage,false);
+    { upcase the string (FPC function) }
     if not (FileNameCasePreserving) then dir:=upcase(dir);
     if not (FileNameCasePreserving) then dir:=upcase(dir);
 end;
 end;

+ 26 - 11
rtl/emx/sysfile.inc

@@ -40,10 +40,12 @@ begin
    end;
    end;
 end;
 end;
 
 
-procedure do_erase(p:Pchar);
-
+procedure do_erase(p:Pchar; pchangeable: boolean);
+var
+  oldp: pchar;
 begin
 begin
-    DoDirSeparators(p);
+    oldp:=p;
+    DoDirSeparators(p,pchangeable);
     asm
     asm
         movl P,%edx
         movl P,%edx
         movb $0x41,%ah
         movb $0x41,%ah
@@ -52,13 +54,18 @@ begin
         movw %ax,inoutres
         movw %ax,inoutres
     .LERASE1:
     .LERASE1:
     end ['eax', 'edx'];
     end ['eax', 'edx'];
+    if p<>oldp then
+      freemem(p);
 end;
 end;
 
 
-procedure do_rename(p1,p2:Pchar);
-
+procedure do_rename(p1,p2:Pchar; p1changeable, p2changeable: boolean);
+var
+  oldp1, oldp2 : pchar;
 begin
 begin
-    DoDirSeparators(p1);
-    DoDirSeparators(p2);
+    oldp1:=p1;
+    oldp2:=p2;
+    DoDirSeparators(p1,p1changeable);
+    DoDirSeparators(p2,p2changeable);
     asm
     asm
         movl P1, %edx
         movl P1, %edx
         movl P2, %edi
         movl P2, %edi
@@ -68,6 +75,10 @@ begin
         movw %ax,inoutres
         movw %ax,inoutres
     .LRENAME1:
     .LRENAME1:
     end ['eax', 'edx', 'edi'];
     end ['eax', 'edx', 'edi'];
+  if p1<>oldp1 then
+    freemem(p1);
+  if p2<>oldp2 then
+    freemem(p2);
 end;
 end;
 
 
 function do_read (H: THandle; Addr: pointer; Len: longint): longint; assembler;
 function do_read (H: THandle; Addr: pointer; Len: longint): longint; assembler;
@@ -254,7 +265,7 @@ begin
         end;
         end;
 end;
 end;
 
 
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
 
 
 {
 {
   filerec and textrec have both handle and mode as the first items so
   filerec and textrec have both handle and mode as the first items so
@@ -264,10 +275,10 @@ procedure do_open(var f;p:pchar;flags:longint);
   when (flags and $10000) there is no check for close (needed for textfiles)
   when (flags and $10000) there is no check for close (needed for textfiles)
 }
 }
 
 
-var Action: cardinal;
-
+var
+  Action: cardinal;
+  oldp : pchar;
 begin
 begin
-    DoDirSeparators(p);
     { close first if opened }
     { close first if opened }
     if ((flags and $10000)=0) then
     if ((flags and $10000)=0) then
         begin
         begin
@@ -309,6 +320,8 @@ begin
             end;
             end;
             exit;
             exit;
         end;
         end;
+    oldp:=p;
+    DoDirSeparators(p,pchangeable);
     Action := Action or (Flags and $FF);
     Action := Action or (Flags and $FF);
 (* DenyNone if sharing not specified. *)
 (* DenyNone if sharing not specified. *)
     if Flags and 112 = 0 then
     if Flags and 112 = 0 then
@@ -356,6 +369,8 @@ begin
                     FileRec (F).Mode := fmOutput; {fool fmappend}
                     FileRec (F).Mode := fmOutput; {fool fmappend}
                 end;
                 end;
         end;
         end;
+    if oldp<>p then
+      freemem(p);
 end;
 end;
 
 
 {$ASMMODE INTEL}
 {$ASMMODE INTEL}

+ 99 - 107
rtl/emx/sysutils.pp

@@ -26,6 +26,12 @@ uses
  Dos;
  Dos;
 
 
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_SLEEP}
+
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
 { Include platform independent interface part }
 { Include platform independent interface part }
 {$i sysutilh.inc}
 {$i sysutilh.inc}
 
 
@@ -452,7 +458,7 @@ const
                              specification for DosFindFirst call.}
                              specification for DosFindFirst call.}
 
 
 {$ASMMODE INTEL}
 {$ASMMODE INTEL}
-function FileOpen (const FileName: string; Mode: integer): longint; assembler;
+function FileOpen (const FileName: pointer; Mode: integer): longint; assembler;
 asm
 asm
  push ebx
  push ebx
 {$IFDEF REGCALL}
 {$IFDEF REGCALL}
@@ -477,21 +483,28 @@ asm
  pop ebx
  pop ebx
 end {['eax', 'ebx', 'ecx', 'edx']};
 end {['eax', 'ebx', 'ecx', 'edx']};
 
 
+function FileOpen (const FileName: rawbytestring; Mode: integer): longint;
+var
+  SystemFileName: RawByteString;
+begin
+  SystemFileName := ToSingleByteFileSystemEncodedFileName(FileName);
+  FileOpen := FileOpen(pointer(SystemFileName),Mode);
+end;
 
 
-function FileCreate (const FileName: string): longint;
+function FileCreate (const FileName: RawByteString): longint;
 begin
 begin
   FileCreate := FileCreate (FileName, ofReadWrite or faCreate or doDenyRW, 777);
   FileCreate := FileCreate (FileName, ofReadWrite or faCreate or doDenyRW, 777);
                                                        (* Sharing to DenyAll *)
                                                        (* Sharing to DenyAll *)
 end;
 end;
 
 
 
 
-function FileCreate (const FileName: string; Rights: integer): longint;
+function FileCreate (const FileName: RawByteString; Rights: integer): longint;
 begin
 begin
   FileCreate := FileCreate (FileName, ofReadWrite or faCreate or doDenyRW,
   FileCreate := FileCreate (FileName, ofReadWrite or faCreate or doDenyRW,
                                               Rights); (* Sharing to DenyAll *)
                                               Rights); (* Sharing to DenyAll *)
 end;
 end;
 
 
-function FileCreate (const FileName: string; ShareMode: integer; Rights: integer): longint; assembler;
+function FileCreate (const FileName: Pointer; ShareMode: integer; Rights: integer): longint; assembler;
 asm
 asm
  push ebx
  push ebx
 {$IFDEF REGCALL}
 {$IFDEF REGCALL}
@@ -515,6 +528,13 @@ asm
  pop ebx
  pop ebx
 end {['eax', 'ebx', 'ecx', 'edx']};
 end {['eax', 'ebx', 'ecx', 'edx']};
 
 
+function FileCreate (const FileName: RawByteString; ShareMode: integer; Rights: integer): longint;
+var
+  SystemFileName: RawByteString;
+begin
+  SystemFileName := ToSingleByteFileSystemEncodedFileName(FileName);
+  FileOpen := FileCreate(pointer(SystemFileName),ShareMode,Rights);
+end;
 
 
 function FileRead (Handle: longint; Out Buffer; Count: longint): longint;
 function FileRead (Handle: longint; Out Buffer; Count: longint): longint;
                                                                      assembler;
                                                                      assembler;
@@ -623,7 +643,7 @@ asm
 end {['eax', 'ebx', 'ecx', 'edx']};
 end {['eax', 'ebx', 'ecx', 'edx']};
 
 
 
 
-function FileAge (const FileName: string): longint;
+function FileAge (const FileName: RawByteString): longint;
 var Handle: longint;
 var Handle: longint;
 begin
 begin
     Handle := FileOpen (FileName, 0);
     Handle := FileOpen (FileName, 0);
@@ -637,10 +657,11 @@ begin
 end;
 end;
 
 
 
 
-function FileExists (const FileName: string): boolean;
+function FileExists (const FileName: RawByteString): boolean;
 var
 var
   L: longint;
   L: longint;
 begin
 begin
+  { no need to convert to DefaultFileSystemEncoding, FileGetAttr will do that }
   if FileName = '' then
   if FileName = '' then
    Result := false
    Result := false
   else
   else
@@ -658,9 +679,10 @@ type
   end;
   end;
   PSearchRec = ^SearchRec;
   PSearchRec = ^SearchRec;
 
 
-function FindFirst (const Path: string; Attr: longint; out Rslt: TSearchRec): longint;
+Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
 
 
 var
 var
+  SystemEncodedPath: RawByteString;
   SR: PSearchRec;
   SR: PSearchRec;
   FStat: PFileFindBuf3L;
   FStat: PFileFindBuf3L;
   Count: cardinal;
   Count: cardinal;
@@ -669,14 +691,15 @@ var
 begin
 begin
   if os_mode = osOS2 then
   if os_mode = osOS2 then
    begin
    begin
+    SystemEncodedPath:=ToSingleByteEncodedFileName(Path);
     New (FStat);
     New (FStat);
     Rslt.FindHandle := THandle ($FFFFFFFF);
     Rslt.FindHandle := THandle ($FFFFFFFF);
     Count := 1;
     Count := 1;
     if FSApi64 then
     if FSApi64 then
-     Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
+     Err := DosFindFirst (PChar (SystemEncodedPath), Rslt.FindHandle,
             Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandardL)
             Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandardL)
     else
     else
-     Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
+     Err := DosFindFirst (PChar (SystemEncodedPath), Rslt.FindHandle,
             Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandard);
             Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandard);
     if (Err = 0) and (Count = 0) then
     if (Err = 0) and (Count = 0) then
      Err := 18;
      Err := 18;
@@ -689,15 +712,16 @@ begin
       if FSApi64 then
       if FSApi64 then
        begin
        begin
         Rslt.Size := FStat^.FileSize;
         Rslt.Size := FStat^.FileSize;
-        Rslt.Name := FStat^.Name;
+        Name := FStat^.Name;
         Rslt.Attr := FStat^.AttrFile;
         Rslt.Attr := FStat^.AttrFile;
        end
        end
       else
       else
        begin
        begin
         Rslt.Size := PFileFindBuf3 (FStat)^.FileSize;
         Rslt.Size := PFileFindBuf3 (FStat)^.FileSize;
-        Rslt.Name := PFileFindBuf3 (FStat)^.Name;
+        Name := PFileFindBuf3 (FStat)^.Name;
         Rslt.Attr := PFileFindBuf3 (FStat)^.AttrFile;
         Rslt.Attr := PFileFindBuf3 (FStat)^.AttrFile;
        end;
        end;
+      SetCodePage(Name, DefaultFileSystemCodePage, false);
      end
      end
     else
     else
      FindClose (Rslt);
      FindClose (Rslt);
@@ -717,14 +741,15 @@ begin
       Rslt.Size := cardinal (SR^.Size);
       Rslt.Size := cardinal (SR^.Size);
       Rslt.Attr := SR^.Attr;
       Rslt.Attr := SR^.Attr;
       Rslt.ExcludeAttr := 0;
       Rslt.ExcludeAttr := 0;
-      Rslt.Name := SR^.Name;
+      Name := SR^.Name;
+      SetCodePage(Name, DefaultFileSystemCodePage, false);
      end;
      end;
     DOS.DosError := Err;
     DOS.DosError := Err;
    end;
    end;
 end;
 end;
 
 
 
 
-function FindNext (var Rslt: TSearchRec): longint;
+Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
 
 
 var
 var
   SR: PSearchRec;
   SR: PSearchRec;
@@ -749,15 +774,16 @@ begin
       if FSApi64 then
       if FSApi64 then
        begin
        begin
         Rslt.Size := FStat^.FileSize;
         Rslt.Size := FStat^.FileSize;
-        Rslt.Name := FStat^.Name;
+        Name := FStat^.Name;
         Rslt.Attr := FStat^.AttrFile;
         Rslt.Attr := FStat^.AttrFile;
        end
        end
       else
       else
        begin
        begin
         Rslt.Size := PFileFindBuf3 (FStat)^.FileSize;
         Rslt.Size := PFileFindBuf3 (FStat)^.FileSize;
-        Rslt.Name := PFileFindBuf3 (FStat)^.Name;
+        Name := PFileFindBuf3 (FStat)^.Name;
         Rslt.Attr := PFileFindBuf3 (FStat)^.AttrFile;
         Rslt.Attr := PFileFindBuf3 (FStat)^.AttrFile;
        end;
        end;
+      SetCodePage(Name, DefaultFileSystemCodePage, false);
      end;
      end;
     Dispose (FStat);
     Dispose (FStat);
    end
    end
@@ -775,29 +801,30 @@ begin
         Rslt.Size := cardinal (SR^.Size);
         Rslt.Size := cardinal (SR^.Size);
         Rslt.Attr := SR^.Attr;
         Rslt.Attr := SR^.Attr;
         Rslt.ExcludeAttr := 0;
         Rslt.ExcludeAttr := 0;
-        Rslt.Name := SR^.Name;
+        Name := SR^.Name;
+        SetCodePage(Name, DefaultFileSystemCodePage, false);
        end;
        end;
      end;
      end;
    end;
    end;
 end;
 end;
 
 
 
 
-procedure FindClose (var F: TSearchrec);
+Procedure InternalFindClose(var Handle: THandle);
 
 
 var SR: PSearchRec;
 var SR: PSearchRec;
 
 
 begin
 begin
     if os_mode = osOS2 then
     if os_mode = osOS2 then
         begin
         begin
-            DosFindClose (F.FindHandle);
+            DosFindClose (Handle);
         end
         end
     else
     else
         begin
         begin
-            SR := PSearchRec (F.FindHandle);
+            SR := PSearchRec (Handle);
             DOS.FindClose (SR^);
             DOS.FindClose (SR^);
             FreeMem (SR, SizeOf (SearchRec));
             FreeMem (SR, SizeOf (SearchRec));
         end;
         end;
-    F.FindHandle := 0;
+    Handle := 0;
 end;
 end;
 
 
 
 
@@ -878,59 +905,56 @@ asm
 end {['eax', 'edx']};
 end {['eax', 'edx']};
 
 
 
 
-function FileSetAttr (const Filename: string; Attr: longint): longint; assembler;
-asm
-{$IFDEF REGCALL}
- mov ecx, edx
- mov edx, eax
-{$ELSE REGCALL}
- mov ecx, Attr
- mov edx, FileName
-{$ENDIF REGCALL}
- mov ax, 4301h
- call syscall
- mov eax, 0
- jnc @FSetAttrEnd
- mov eax, -1
-@FSetAttrEnd:
-end {['eax', 'ecx', 'edx']};
-
-
-function DeleteFile (const FileName: string): boolean; assembler;
-asm
-{$IFDEF REGCALL}
- mov edx, eax
-{$ELSE REGCALL}
- mov edx, FileName
-{$ENDIF REGCALL}
- mov ax, 4100h
- call syscall
- mov eax, 0
- jc @FDeleteEnd
- inc eax
-@FDeleteEnd:
-end {['eax', 'edx']};
-
+function FileSetAttr (const Filename: RawByteString; Attr: longint): longint;
+var
+  SystemFileName: RawByteString;
+begin
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(Filename);
+  asm
+   mov ecx, Attr
+   mov edx, SystemFileName
+   mov ax, 4301h
+   call syscall
+   mov @result, 0
+   jnc @FSetAttrEnd
+   mov @result, -1
+  @FSetAttrEnd:
+  end ['eax', 'ecx', 'edx'];
+end;
 
 
-function RenameFile (const OldName, NewName: string): boolean; assembler;
-asm
- push edi
-{$IFDEF REGCALL}
- mov edx, eax
- mov edi, edx
-{$ELSE REGCALL}
- mov edx, OldName
- mov edi, NewName
-{$ENDIF REGCALL}
- mov ax, 5600h
- call syscall
- mov eax, 0
- jc @FRenameEnd
- inc eax
-@FRenameEnd:
- pop edi
-end {['eax', 'edx', 'edi']};
+function DeleteFile (const FileName: string): boolean;
+var
+  SystemFileName: RawByteString;
+begin
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(Filename);
+  asm
+   mov edx, SystemFileName
+   mov ax, 4100h
+   call syscall
+   mov @result, 0
+   jc @FDeleteEnd
+   moc @result, 1
+  @FDeleteEnd:
+  end ['eax', 'edx'];
+end;
 
 
+function RenameFile (const OldName, NewName: string): boolean;
+var
+  OldSystemFileName, NewSystemFileName: RawByteString;
+Begin
+  OldSystemFileName:=ToSingleByteFileSystemEncodedFileName(OldName);
+  NewSystemFileName:=ToSingleByteFileSystemEncodedFileName(NewName);
+  asm
+   mov edx, OldSystemFileName
+   mov edi, NewSystemFileName
+   mov ax, 5600h
+   call syscall
+   mov @result, 0
+   jc @FRenameEnd
+   mov @result, 1
+  @FRenameEnd:
+  end ['eax', 'edx', 'edi'];
+end;
 
 
 {****************************************************************************
 {****************************************************************************
                               Disk Functions
                               Disk Functions
@@ -1022,43 +1046,11 @@ begin
 end;
 end;
 
 
 
 
-function GetCurrentDir: string;
-begin
- GetDir (0, Result);
-end;
-
-
-function SetCurrentDir (const NewDir: string): boolean;
-begin
-{$I-}
- ChDir (NewDir);
- Result := (IOResult = 0);
-{$I+}
-end;
-
-
-function CreateDir (const NewDir: string): boolean;
-begin
-{$I-}
- MkDir (NewDir);
- Result := (IOResult = 0);
-{$I+}
-end;
-
-
-function RemoveDir (const Dir: string): boolean;
-begin
-{$I-}
- RmDir (Dir);
- Result := (IOResult = 0);
- {$I+}
-end;
-
-
-function DirectoryExists (const Directory: string): boolean;
+function DirectoryExists (const Directory: RawByteString): boolean;
 var
 var
   L: longint;
   L: longint;
 begin
 begin
+  { no need to convert to DefaultFileSystemEncoding, FileGetAttr will do that }
   if Directory = '' then
   if Directory = '' then
    Result := false
    Result := false
   else
   else
@@ -1213,7 +1205,7 @@ end;
 Function GetEnvironmentVariable(Const EnvVar : String) : String;
 Function GetEnvironmentVariable(Const EnvVar : String) : String;
 
 
 begin
 begin
-    GetEnvironmentVariable := StrPas (GetEnvPChar (EnvVar));
+    GetEnvironmentVariable := GetEnvPChar (EnvVar);
 end;
 end;
 
 
 
 
@@ -1225,7 +1217,7 @@ begin
 end;
 end;
 
 
 
 
-Function GetEnvironmentString(Index : Integer) : String;
+Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 
 
 begin
 begin
   Result:=FPCGetEnvStrFromP (EnvP, Index);
   Result:=FPCGetEnvStrFromP (EnvP, Index);

+ 24 - 0
rtl/freebsd/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 24 - 0
rtl/gba/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 4 - 4
rtl/gba/sysdir.inc

@@ -19,22 +19,22 @@
 {*****************************************************************************
 {*****************************************************************************
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
-procedure mkdir(s: pchar; len: sizeuint);[IOCheck, public, alias : 'FPC_SYS_MKDIR'];
+procedure do_mkdir(const s: rawbytestring);
 begin
 begin
 
 
 end;
 end;
 
 
-procedure rmdir(s: pchar; len: sizeuint);[IOCheck, public, alias : 'FPC_SYS_RMDIR'];
+procedure do_rmdir(const s: rawbytestring);
 begin
 begin
 
 
 end;
 end;
 
 
-procedure chdir(s: pchar; len: sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
+procedure do_chdir(const s: rawbytestring);
 begin
 begin
 
 
 end;
 end;
 
 
-procedure GetDir(DriveNr: byte; var Dir: ShortString);
+procedure do_GetDir(DriveNr: byte; var Dir: RawByteString);
 begin
 begin
 
 
 end;
 end;

+ 3 - 3
rtl/gba/sysfile.inc

@@ -27,11 +27,11 @@ begin
 
 
 end;
 end;
 
 
-procedure do_erase(p : pchar);
+procedure do_erase(p : pchar; pchangeable: boolean);
 begin
 begin
 end;
 end;
 
 
-procedure do_rename(p1,p2 : pchar);
+procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
 begin
 begin
 end;
 end;
 
 
@@ -69,7 +69,7 @@ procedure do_truncate(handle, pos: longint);
 begin
 begin
 end;
 end;
 
 
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
 begin
 begin
 end;
 end;
 
 

+ 20 - 39
rtl/gba/sysutils.pp

@@ -32,6 +32,11 @@ interface
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_OSERROR}
 {$DEFINE HAS_OSERROR}
 
 
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
 { Include platform independent interface part }
 { Include platform independent interface part }
 {$i sysutilh.inc}
 {$i sysutilh.inc}
 
 
@@ -48,7 +53,7 @@ uses
 {****************************************************************************
 {****************************************************************************
                               File Functions
                               File Functions
 ****************************************************************************}
 ****************************************************************************}
-function FileOpen(const FileName: string; Mode: Integer): LongInt;
+function FileOpen(const FileName: rawbytestring; Mode: Integer): LongInt;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
@@ -66,19 +71,19 @@ begin
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string) : LongInt;
+function FileCreate(const FileName: RawByteString) : LongInt;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string; Rights: integer): LongInt;
+function FileCreate(const FileName: RawByteString; Rights: integer): LongInt;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string; ShareMode: integer; rights : integer): LongInt;
+function FileCreate(const FileName: RawByteString; ShareMode: integer; rights : integer): LongInt;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
@@ -118,13 +123,13 @@ begin
 end;
 end;
 
 
 
 
-function DeleteFile(const FileName: string) : Boolean;
+function DeleteFile(const FileName: RawByteString) : Boolean;
 begin
 begin
   result := false;
   result := false;
 end;
 end;
 
 
 
 
-function RenameFile(const OldName, NewName: string): Boolean;
+function RenameFile(const OldName, NewName: RawByteString): Boolean;
 begin
 begin
   result := false;
   result := false;
 end;
 end;
@@ -133,41 +138,41 @@ end;
 (****** end of non portable routines ******)
 (****** end of non portable routines ******)
 
 
 
 
-Function FileAge (Const FileName : String): Longint;
+Function FileAge (Const FileName : RawByteString): Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-Function FileExists (Const FileName : String) : Boolean;
+Function FileExists (Const FileName : RawByteString) : Boolean;
 Begin
 Begin
   result := false;
   result := false;
 end;
 end;
 
 
 
 
 
 
-Function FindFirst (Const Path : String; Attr : Longint; Out Rslt : TSearchRec) : Longint;
+Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-Function FindNext (Var Rslt : TSearchRec) : Longint;
+Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
-Procedure FindClose (Var F : TSearchrec);
+Procedure InternalFindClose(var Handle: THandle);
 begin
 begin
 end;
 end;
 
 
-Function FileGetAttr (Const FileName : String) : Longint;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
@@ -197,31 +202,7 @@ Begin
 End;
 End;
 
 
 
 
-Function GetCurrentDir : String;
-begin
-  result := '';
-end;
-
-
-Function SetCurrentDir (Const NewDir : String) : Boolean;
-begin
-  result := false;
-end;
-
-
-Function CreateDir (Const NewDir : String) : Boolean;
-begin
-  result := false;
-end;
-
-
-Function RemoveDir (Const Dir : String) : Boolean;
-begin
-  result := false;
-end;
-
-
-function DirectoryExists(const Directory: string): Boolean;
+function DirectoryExists(const Directory: RawByteString): Boolean;
 begin
 begin
   result := false;
   result := false;
 end;
 end;
@@ -290,7 +271,7 @@ begin
   result := -1;
   result := -1;
 end;
 end;
 
 
-Function GetEnvironmentString(Index : Integer) : String;
+Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 begin
 begin
   result := '';
   result := '';
 end;
 end;

+ 18 - 0
rtl/go32v2/dos.pp

@@ -1083,8 +1083,17 @@ end;
 
 
 
 
 procedure getfattr(var f;var attr : word);
 procedure getfattr(var f;var attr : word);
+{$ifndef FPC_ANSI_TEXTFILEREC}
+var
+  r: rawbytestring;
+{$endif not FPC_ANSI_TEXTFILEREC}
 begin
 begin
+{$ifdef FPC_ANSI_TEXTFILEREC}
   copytodos(filerec(f).name,strlen(filerec(f).name)+1);
   copytodos(filerec(f).name,strlen(filerec(f).name)+1);
+{$else}
+  r:=ToSingleByteFileSystemEncodedFileName(filerec(f).name);
+  copytodos(pchar(r)^,length(r)+1);
+{$endif}
   dosregs.edx:=tb_offset;
   dosregs.edx:=tb_offset;
   dosregs.ds:=tb_segment;
   dosregs.ds:=tb_segment;
   if LFNSupport then
   if LFNSupport then
@@ -1101,6 +1110,10 @@ end;
 
 
 
 
 procedure setfattr(var f;attr : word);
 procedure setfattr(var f;attr : word);
+{$ifndef FPC_ANSI_TEXTFILEREC}
+var
+  r: rawbytestring;
+{$endif not FPC_ANSI_TEXTFILEREC}
 begin
 begin
   { Fail for setting VolumeId. }
   { Fail for setting VolumeId. }
   if ((attr and VolumeID)<>0) then
   if ((attr and VolumeID)<>0) then
@@ -1108,7 +1121,12 @@ begin
     doserror:=5;
     doserror:=5;
     exit;
     exit;
   end;
   end;
+{$ifdef FPC_ANSI_TEXTFILEREC}
   copytodos(filerec(f).name,strlen(filerec(f).name)+1);
   copytodos(filerec(f).name,strlen(filerec(f).name)+1);
+{$else}
+  r:=ToSingleByteFileSystemEncodedFileName(filerec(f).name);
+  copytodos(pchar(r)^,length(r)+1);
+{$endif}
   dosregs.edx:=tb_offset;
   dosregs.edx:=tb_offset;
   dosregs.ds:=tb_segment;
   dosregs.ds:=tb_segment;
   if LFNSupport then
   if LFNSupport then

+ 24 - 0
rtl/go32v2/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 28 - 24
rtl/go32v2/sysdir.inc

@@ -3,7 +3,7 @@
     Copyright (c) 1999-2000 by Florian Klaempfl and Pavel Ozerski
     Copyright (c) 1999-2000 by Florian Klaempfl and Pavel Ozerski
     member of the Free Pascal development team.
     member of the Free Pascal development team.
 
 
-    FPC Pascal system unit for the Win32 API.
+    FPC Pascal system unit for go32v2.
 
 
     See the file COPYING.FPC, included in this distribution,
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -18,18 +18,20 @@
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
 
 
-procedure DosDir(func:byte;s:pchar;len:integer);
+procedure DosDir(func:byte;s:rawbytestring);
 var
 var
   regs   : trealregs;
   regs   : trealregs;
+  len    : longint;
 begin
 begin
   DoDirSeparators(s);
   DoDirSeparators(s);
   { True DOS does not like backslashes at end
   { True DOS does not like backslashes at end
     Win95 DOS accepts this !!
     Win95 DOS accepts this !!
     but "\" and "c:\" should still be kept and accepted hopefully PM }
     but "\" and "c:\" should still be kept and accepted hopefully PM }
-  if (len>0) and (s[len-1]='\') and
-     Not ((len=1) or ((len=3) and (s[1]=':'))) then
-    s[len-1]:=#0;
-  syscopytodos(longint(s),len+1);
+  len:=length(s);
+  if (len>0) and (s[len]='\') and
+     Not ((len=1) or ((len=3) and (s[2]=':'))) then
+    s[len]:=#0;
+  syscopytodos(longint(pointer(s)),len+1);
   regs.realedx:=tb_offset;
   regs.realedx:=tb_offset;
   regs.realds:=tb_segment;
   regs.realds:=tb_segment;
   if LFNSupport then
   if LFNSupport then
@@ -41,32 +43,31 @@ begin
    GetInOutRes(lo(regs.realeax));
    GetInOutRes(lo(regs.realeax));
 end;
 end;
 
 
-Procedure MkDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_MKDIR'];
+Procedure do_MkDir(const s: rawbytestring);
 begin
 begin
- If not assigned(s) or (len=0) or (InOutRes <> 0) then
-   exit;
-  DosDir($39,s,len);
+  DosDir($39,s);
 end;
 end;
 
 
-Procedure RmDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_RMDIR'];
+Procedure do_RmDir(const s: rawbytestring);
 begin
 begin
-  if (len=1) and (s[0] = '.' ) then
-    InOutRes := 16;
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
-   exit;
-  DosDir($3a,s,len);
+  if s='.' then
+    begin
+      InOutRes := 16;
+      exit;
+    end;
+  DosDir($3a,s);
 end;
 end;
 
 
-Procedure ChDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
+Procedure do_ChDir(const s: rawbytestring);
 var
 var
   regs : trealregs;
   regs : trealregs;
+  len  : longint;
 begin
 begin
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
-   exit;
+  len:=length(s);
 { First handle Drive changes }
 { First handle Drive changes }
-  if (len>=2) and (s[1]=':') then
+  if (len>=2) and (s[2]=':') then
    begin
    begin
-     regs.realedx:=(ord(s[0]) and (not 32))-ord('A');
+     regs.realedx:=(ord(s[1]) and (not 32))-ord('A');
      regs.realeax:=$0e00;
      regs.realeax:=$0e00;
      sysrealintr($21,regs);
      sysrealintr($21,regs);
      regs.realeax:=$1900;
      regs.realeax:=$1900;
@@ -82,10 +83,10 @@ begin
        exit;
        exit;
    end;
    end;
 { do the normal dos chdir }
 { do the normal dos chdir }
-  DosDir($3b,s,len);
+  DosDir($3b,s);
 end;
 end;
 
 
-procedure GetDir (DriveNr: byte; var Dir: ShortString);
+procedure do_GetDir (DriveNr: byte; var Dir: RawByteString);
 var
 var
   temp : array[0..255] of char;
   temp : array[0..255] of char;
   i    : longint;
   i    : longint;
@@ -103,12 +104,14 @@ begin
    Begin
    Begin
      GetInOutRes (lo(regs.realeax));
      GetInOutRes (lo(regs.realeax));
      Dir := char (DriveNr + 64) + ':\';
      Dir := char (DriveNr + 64) + ':\';
+     SetCodePage (Dir,DefaultFileSystemCodePage,false);
      exit;
      exit;
    end
    end
   else
   else
    syscopyfromdos(longint(@temp),251);
    syscopyfromdos(longint(@temp),251);
 { conversion to Pascal string including slash conversion }
 { conversion to Pascal string including slash conversion }
   i:=0;
   i:=0;
+  SetLength(dir,260);
   while (temp[i]<>#0) do
   while (temp[i]<>#0) do
    begin
    begin
      if temp[i] in AllowDirectorySeparators then
      if temp[i] in AllowDirectorySeparators then
@@ -118,7 +121,8 @@ begin
    end;
    end;
   dir[2]:=':';
   dir[2]:=':';
   dir[3]:='\';
   dir[3]:='\';
-  dir[0]:=char(i+3);
+  SetLength(dir,i+3);
+  SetCodePage(dir,DefaultFileSystemCodePage,false);
 { upcase the string }
 { upcase the string }
   if not FileNameCasePreserving then
   if not FileNameCasePreserving then
    dir:=upcase(dir);
    dir:=upcase(dir);

+ 24 - 7
rtl/go32v2/sysfile.inc

@@ -54,11 +54,13 @@ begin
 end;
 end;
 
 
 
 
-procedure do_erase(p : pchar);
+procedure do_erase(p : pchar; pchangeable: boolean);
 var
 var
   regs : trealregs;
   regs : trealregs;
+  oldp : pchar;
 begin
 begin
-  DoDirSeparators(p);
+  oldp:=p;
+  DoDirSeparators(p,pchangeable);
   syscopytodos(longint(p),strlen(p)+1);
   syscopytodos(longint(p),strlen(p)+1);
   regs.realedx:=tb_offset;
   regs.realedx:=tb_offset;
   regs.realds:=tb_segment;
   regs.realds:=tb_segment;
@@ -71,15 +73,20 @@ begin
   sysrealintr($21,regs);
   sysrealintr($21,regs);
   if (regs.realflags and carryflag) <> 0 then
   if (regs.realflags and carryflag) <> 0 then
    GetInOutRes(lo(regs.realeax));
    GetInOutRes(lo(regs.realeax));
+  if p<>oldp then
+    freemem(p);
 end;
 end;
 
 
 
 
-procedure do_rename(p1,p2 : pchar);
+procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
 var
 var
   regs : trealregs;
   regs : trealregs;
+  oldp1, oldp2 : pchar;
 begin
 begin
-  DoDirSeparators(p1);
-  DoDirSeparators(p2);
+  oldp1:=p1;
+  oldp2:=p2;
+  DoDirSeparators(p1,p1changeable);
+  DoDirSeparators(p2,p2changeable);
   if strlen(p1)+strlen(p2)+3>tb_size then
   if strlen(p1)+strlen(p2)+3>tb_size then
    HandleError(217);
    HandleError(217);
   sysseg_move(get_ds,longint(p2),dos_selector,tb,strlen(p2)+1);
   sysseg_move(get_ds,longint(p2),dos_selector,tb,strlen(p2)+1);
@@ -96,6 +103,10 @@ begin
   sysrealintr($21,regs);
   sysrealintr($21,regs);
   if (regs.realflags and carryflag) <> 0 then
   if (regs.realflags and carryflag) <> 0 then
    GetInOutRes(lo(regs.realeax));
    GetInOutRes(lo(regs.realeax));
+  if p1<>oldp1 then
+    freemem(p1);
+  if p2<>oldp2 then
+    freemem(p2);
 end;
 end;
 
 
 
 
@@ -280,7 +291,7 @@ begin
 end;
 end;
 
 
 
 
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
 {
 {
   filerec and textrec have both handle and mode as the first items so
   filerec and textrec have both handle and mode as the first items so
   they could use the same routine for opening/creating.
   they could use the same routine for opening/creating.
@@ -291,8 +302,8 @@ procedure do_open(var f;p:pchar;flags:longint);
 var
 var
   regs   : trealregs;
   regs   : trealregs;
   action : longint;
   action : longint;
+  oldp : pchar;
 begin
 begin
-  DoDirSeparators(p);
 { close first if opened }
 { close first if opened }
   if ((flags and $10000)=0) then
   if ((flags and $10000)=0) then
    begin
    begin
@@ -334,6 +345,8 @@ begin
      end;
      end;
      exit;
      exit;
    end;
    end;
+  oldp:=p;
+  DoDirSeparators(p,pchangeable);
 { real dos call }
 { real dos call }
   syscopytodos(longint(p),strlen(p)+1);
   syscopytodos(longint(p),strlen(p)+1);
 {$ifndef RTLLITE}
 {$ifndef RTLLITE}
@@ -385,6 +398,8 @@ begin
   if (regs.realflags and carryflag) <> 0 then
   if (regs.realflags and carryflag) <> 0 then
     begin
     begin
       GetInOutRes(lo(regs.realeax));
       GetInOutRes(lo(regs.realeax));
+      if oldp<>p then
+        freemem(p);
       exit;
       exit;
     end
     end
   else
   else
@@ -419,6 +434,8 @@ begin
      do_seekend(filerec(f).handle);
      do_seekend(filerec(f).handle);
      filerec(f).mode:=fmoutput; {fool fmappend}
      filerec(f).mode:=fmoutput; {fool fmappend}
    end;
    end;
+  if oldp<>p then
+    freemem(p);
 end;
 end;
 
 
 
 

+ 59 - 65
rtl/go32v2/sysutils.pp

@@ -28,6 +28,12 @@ uses
   go32,dos;
   go32,dos;
 
 
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_SLEEP}
+
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
 { Include platform independent interface part }
 { Include platform independent interface part }
 {$i sysutilh.inc}
 {$i sysutilh.inc}
 
 
@@ -64,12 +70,14 @@ Type
 
 
 {  converts S to a pchar and copies it to the transfer-buffer.   }
 {  converts S to a pchar and copies it to the transfer-buffer.   }
 
 
-procedure StringToTB(const S: string);
+procedure StringToTB(const S: rawbytestring);
 var
 var
   P: pchar;
   P: pchar;
-  Len: integer;
+  Len: longint;
 begin
 begin
   Len := Length(S) + 1;
   Len := Length(S) + 1;
+  if Len > tb_size then
+    Len := tb_size;
   P := StrPCopy(StrAlloc(Len), S);
   P := StrPCopy(StrAlloc(Len), S);
   SysCopyToDos(longint(P), Len);
   SysCopyToDos(longint(P), Len);
   StrDispose(P);
   StrDispose(P);
@@ -78,7 +86,7 @@ end ;
 
 
 {  Native OpenFile function.
 {  Native OpenFile function.
    if return value <> 0 call failed.  }
    if return value <> 0 call failed.  }
-function OpenFile(const FileName: string; var Handle: longint; Mode, Action: word): longint;
+function OpenFile(const FileName: rawbytestring; var Handle: longint; Mode, Action: word): longint;
 var
 var
    Regs: registers;
    Regs: registers;
 begin
 begin
@@ -110,33 +118,37 @@ begin
 end;
 end;
 
 
 
 
-Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
+Function FileOpen (Const FileName : rawbytestring; Mode : Integer) : Longint;
 var
 var
+  SystemFileName: RawByteString;
   e: integer;
   e: integer;
-Begin
-  e := OpenFile(FileName, result, Mode, faOpen);
+begin
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  e := OpenFile(SystemFileName, result, Mode, faOpen);
   if e <> 0 then
   if e <> 0 then
     result := -1;
     result := -1;
 end;
 end;
 
 
 
 
-Function FileCreate (Const FileName : String) : Longint;
+Function FileCreate (Const FileName : RawByteString) : Longint;
 var
 var
+  SystemFileName: RawByteString;
   e: integer;
   e: integer;
 begin
 begin
-  e := OpenFile(FileName, result, ofReadWrite, faCreate or faOpenReplace);
+  SystemFileName := ToSingleByteFileSystemEncodedFileName(FileName);
+  e := OpenFile(SystemFileName, result, ofReadWrite, faCreate or faOpenReplace);
   if e <> 0 then
   if e <> 0 then
     result := -1;
     result := -1;
 end;
 end;
 
 
 
 
-Function FileCreate (Const FileName : String; ShareMode:longint; Rights : longint) : Longint;
+Function FileCreate (Const FileName : RawByteString; ShareMode:longint; Rights : longint) : Longint;
 begin
 begin
   FileCreate:=FileCreate(FileName);
   FileCreate:=FileCreate(FileName);
 end;
 end;
 
 
 
 
-Function FileCreate (Const FileName : String; Rights:longint) : Longint;
+Function FileCreate (Const FileName : RawByteString; Rights:longint) : Longint;
 begin
 begin
   FileCreate:=FileCreate(FileName);
   FileCreate:=FileCreate(FileName);
 end;
 end;
@@ -270,7 +282,7 @@ begin
 end;
 end;
 
 
 
 
-Function FileAge (Const FileName : String): Longint;
+Function FileAge (Const FileName : RawByteString): Longint;
 var Handle: longint;
 var Handle: longint;
 begin
 begin
   Handle := FileOpen(FileName, 0);
   Handle := FileOpen(FileName, 0);
@@ -284,7 +296,7 @@ begin
 end;
 end;
 
 
 
 
-function FileExists (const FileName: string): boolean;
+function FileExists (const FileName: RawByteString): boolean;
 var
 var
   L: longint;
   L: longint;
 begin
 begin
@@ -292,6 +304,7 @@ begin
    Result := false
    Result := false
   else
   else
    begin
    begin
+    { no need to convert to DefaultFileSystemEncoding, FileGetAttr will do that }
     L := FileGetAttr (FileName);
     L := FileGetAttr (FileName);
     Result := (L >= 0) and (L and (faDirectory or faVolumeID) = 0);
     Result := (L >= 0) and (L and (faDirectory or faVolumeID) = 0);
 (* Neither VolumeIDs nor directories are files. *)
 (* Neither VolumeIDs nor directories are files. *)
@@ -299,12 +312,13 @@ begin
 end;
 end;
 
 
 
 
-Function DirectoryExists (Const Directory : String) : Boolean;
+Function DirectoryExists (Const Directory : RawByteString) : Boolean;
 Var
 Var
-  Dir : String;
+  Dir : RawByteString;
   drive : byte;
   drive : byte;
   FADir, StoredIORes : longint;
   FADir, StoredIORes : longint;
 begin
 begin
+  { no need to convert to DefaultFileSystemEncoding, FileGetAttr will do that }
   Dir:=Directory;
   Dir:=Directory;
   if (length(dir)=2) and (dir[2]=':') and
   if (length(dir)=2) and (dir[2]=':') and
      ((dir[1] in ['A'..'Z']) or (dir[1] in ['a'..'z'])) then
      ((dir[1] in ['A'..'Z']) or (dir[1] in ['a'..'z'])) then
@@ -340,7 +354,7 @@ begin
 end;
 end;
 
 
 
 
-Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
+Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
 
 
 Var Sr : PSearchrec;
 Var Sr : PSearchrec;
 
 
@@ -348,6 +362,8 @@ begin
   //!! Sr := New(PSearchRec);
   //!! Sr := New(PSearchRec);
   getmem(sr,sizeof(searchrec));
   getmem(sr,sizeof(searchrec));
   Rslt.FindHandle := longint(Sr);
   Rslt.FindHandle := longint(Sr);
+  { no use in converting to defaultfilesystemcodepage, since the Dos shortstring
+    interface is called here }
   DOS.FindFirst(Path, Attr, Sr^);
   DOS.FindFirst(Path, Attr, Sr^);
   result := -DosError;
   result := -DosError;
   if result = 0 then
   if result = 0 then
@@ -356,12 +372,13 @@ begin
      Rslt.Size := Sr^.Size;
      Rslt.Size := Sr^.Size;
      Rslt.Attr := Sr^.Attr;
      Rslt.Attr := Sr^.Attr;
      Rslt.ExcludeAttr := 0;
      Rslt.ExcludeAttr := 0;
-     Rslt.Name := Sr^.Name;
+     Name := Sr^.Name;
+     SetCodePage(Name,DefaultFileSystemCodePage,False);
    end ;
    end ;
 end;
 end;
 
 
 
 
-Function FindNext (Var Rslt : TSearchRec) : Longint;
+Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
 var
 var
   Sr: PSearchRec;
   Sr: PSearchRec;
 begin
 begin
@@ -376,17 +393,18 @@ begin
         Rslt.Size := Sr^.Size;
         Rslt.Size := Sr^.Size;
         Rslt.Attr := Sr^.Attr;
         Rslt.Attr := Sr^.Attr;
         Rslt.ExcludeAttr := 0;
         Rslt.ExcludeAttr := 0;
-        Rslt.Name := Sr^.Name;
+        Name := Sr^.Name;
+        SetCodePage(Name,DefaultFileSystemCodePage,False);
       end;
       end;
    end;
    end;
 end;
 end;
 
 
 
 
-Procedure FindClose (Var F : TSearchrec);
+Procedure InternalFindClose(var Handle: THandle);
 var
 var
   Sr: PSearchRec;
   Sr: PSearchRec;
 begin
 begin
-  Sr := PSearchRec(F.FindHandle);
+  Sr := PSearchRec(Handle);
   if Sr <> nil then
   if Sr <> nil then
     begin
     begin
       //!! Dispose(Sr);
       //!! Dispose(Sr);
@@ -394,7 +412,7 @@ begin
       DOS.FindClose(SR^);
       DOS.FindClose(SR^);
       freemem(sr,sizeof(searchrec));
       freemem(sr,sizeof(searchrec));
     end;
     end;
-  F.FindHandle := 0;
+  Handle := 0;
 end;
 end;
 
 
 
 
@@ -432,11 +450,13 @@ begin
 end;
 end;
 
 
 
 
-Function FileGetAttr (Const FileName : String) : Longint;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
 var
 var
   Regs: registers;
   Regs: registers;
+  SystemFileName: RawByteString;
 begin
 begin
-  StringToTB(FileName);
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(Filename);
+  StringToTB(SystemFileName);
   Regs.Edx := tb_offset;
   Regs.Edx := tb_offset;
   Regs.Ds := tb_segment;
   Regs.Ds := tb_segment;
   if LFNSupport then
   if LFNSupport then
@@ -454,11 +474,13 @@ begin
 end;
 end;
 
 
 
 
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
 var
 var
   Regs: registers;
   Regs: registers;
+  SystemFileName: RawByteString;
 begin
 begin
-  StringToTB(FileName);
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(Filename);
+  StringToTB(SystemFileName);
   Regs.Edx := tb_offset;
   Regs.Edx := tb_offset;
   Regs.Ds := tb_segment;
   Regs.Ds := tb_segment;
   if LFNSupport then
   if LFNSupport then
@@ -477,11 +499,13 @@ begin
 end;
 end;
 
 
 
 
-Function DeleteFile (Const FileName : String) : Boolean;
+Function DeleteFile (Const FileName : RawByteString) : Boolean;
 var
 var
   Regs: registers;
   Regs: registers;
+  SystemFileName: RawByteString;
 begin
 begin
-  StringToTB(FileName);
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(Filename);
+  StringToTB(SystemFileName);
   Regs.Edx := tb_offset;
   Regs.Edx := tb_offset;
   Regs.Ds := tb_segment;
   Regs.Ds := tb_segment;
   if LFNSupport then
   if LFNSupport then
@@ -495,14 +519,17 @@ begin
 end;
 end;
 
 
 
 
-Function RenameFile (Const OldName, NewName : String) : Boolean;
+Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
 var
 var
   Regs: registers;
   Regs: registers;
-begin
-  StringToTB(OldName + #0 + NewName);
+  OldSystemFileName, NewSystemFileName: RawByteString;
+Begin
+  OldSystemFileName:=ToSingleByteFileSystemEncodedFileName(OldName);
+  NewSystemFileName:=ToSingleByteFileSystemEncodedFileName(NewName);
+  StringToTB(OldSystemFileName + #0 + NewSystemFileName);
   Regs.Edx := tb_offset;
   Regs.Edx := tb_offset;
   Regs.Ds := tb_segment;
   Regs.Ds := tb_segment;
-  Regs.Edi := tb_offset + Length(OldName) + 1;
+  Regs.Edi := tb_offset + Length(OldSystemFileName) + 1;
   Regs.Es := tb_segment;
   Regs.Es := tb_segment;
   if LFNSupport then
   if LFNSupport then
     Regs.Eax := $7156
     Regs.Eax := $7156
@@ -608,39 +635,6 @@ begin
 end;
 end;
 
 
 
 
-Function GetCurrentDir : String;
-begin
-  GetDir(0, result);
-end;
-
-
-Function SetCurrentDir (Const NewDir : String) : Boolean;
-begin
-  {$I-}
-   ChDir(NewDir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
-Function CreateDir (Const NewDir : String) : Boolean;
-begin
-  {$I-}
-   MkDir(NewDir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
-Function RemoveDir (Const Dir : String) : Boolean;
-begin
-  {$I-}
-   RmDir(Dir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
 {****************************************************************************
 {****************************************************************************
                               Time Functions
                               Time Functions
 ****************************************************************************}
 ****************************************************************************}
@@ -794,7 +788,7 @@ begin
   Result:=FPCCountEnvVar(EnvP);
   Result:=FPCCountEnvVar(EnvP);
 end;
 end;
 
 
-Function GetEnvironmentString(Index : Integer) : String;
+Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 
 
 begin
 begin
   Result:=FPCGetEnvStrFromP(Envp,Index);
   Result:=FPCGetEnvStrFromP(Envp,Index);

+ 24 - 0
rtl/haiku/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 117 - 84
rtl/inc/astrings.inc

@@ -59,6 +59,20 @@ Const
                     Internal functions, not in interface.
                     Internal functions, not in interface.
 ****************************************************************************}
 ****************************************************************************}
 
 
+{$ifndef FPC_HAS_TRANSLATEPLACEHOLDERCP}
+{$define FPC_HAS_TRANSLATEPLACEHOLDERCP}
+function TranslatePlaceholderCP(cp: TSystemCodePage): TSystemCodePage; {$ifdef SYSTEMINLINE}inline;{$endif}
+begin
+  TranslatePlaceholderCP:=cp;
+  case cp of
+    CP_OEMCP,
+    CP_ACP:
+      TranslatePlaceholderCP:=DefaultSystemCodePage;
+  end;
+end;
+{$endif FPC_HAS_TRANSLATEPLACEHOLDERCP}
+
+
 {$ifndef FPC_HAS_PCHAR_ANSISTR_INTERN_CHARMOVE}
 {$ifndef FPC_HAS_PCHAR_ANSISTR_INTERN_CHARMOVE}
 {$define FPC_HAS_PCHAR_ANSISTR_INTERN_CHARMOVE}
 {$define FPC_HAS_PCHAR_ANSISTR_INTERN_CHARMOVE}
 procedure fpc_pchar_ansistr_intern_charmove(const src: pchar; const srcindex: sizeint; var dst: rawbytestring; const dstindex, len: sizeint); {$ifdef FPC_HAS_CPSTRING}rtlproc;{$endif} {$ifdef SYSTEMINLINE}inline;{$endif}
 procedure fpc_pchar_ansistr_intern_charmove(const src: pchar; const srcindex: sizeint; var dst: rawbytestring; const dstindex, len: sizeint); {$ifdef FPC_HAS_CPSTRING}rtlproc;{$endif} {$ifdef SYSTEMINLINE}inline;{$endif}
@@ -200,15 +214,13 @@ Var
   S1CP, S2CP, DestCP: TSystemCodePage;
   S1CP, S2CP, DestCP: TSystemCodePage;
 begin
 begin
 {$ifdef FPC_HAS_CPSTRING}
 {$ifdef FPC_HAS_CPSTRING}
-  if (Pointer(DestS)=nil) then
-    DestCP:=cp
-  else
-    DestCP:=StringCodePage(DestS);
+  DestCP:=cp;
+  if DestCp=CP_NONE then
+    DestCP:=DefaultSystemCodePage;
 {$else FPC_HAS_CPSTRING}
 {$else FPC_HAS_CPSTRING}
   DestCP:=StringCodePage(DestS);
   DestCP:=StringCodePage(DestS);
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
-  if (DestCP=CP_ACP) then
-    DestCP:=DefaultSystemCodePage;
+  DestCP:=TranslatePlaceholderCP(DestCP);
   { if codepages are different then concat using unicodestring,
   { if codepages are different then concat using unicodestring,
     but avoid conversions if either addend is empty (StringCodePage will return
     but avoid conversions if either addend is empty (StringCodePage will return
     DefaultSystemCodePage in that case, which may differ from other addend/dest) }
     DefaultSystemCodePage in that case, which may differ from other addend/dest) }
@@ -216,14 +228,19 @@ begin
     S1CP:=DestCP
     S1CP:=DestCP
   else
   else
     S1CP:=StringCodePage(S1);
     S1CP:=StringCodePage(S1);
-  if (S1CP=CP_ACP) then
-    S1CP:=DefaultSystemCodePage;
+  S1CP:=TranslatePlaceholderCP(S1CP);
   if S2='' then
   if S2='' then
     S2CP:=DestCP
     S2CP:=DestCP
   else
   else
     S2CP:=StringCodePage(S2);
     S2CP:=StringCodePage(S2);
-  if (S2CP=CP_ACP) then
-    S2CP:=DefaultSystemCodePage;
+  S2CP:=TranslatePlaceholderCP(S2CP);
+{$ifdef FPC_HAS_CPSTRING}
+  { if the result is rawbytestring and both strings have the same code page,
+    keep that code page }
+  if (cp=CP_NONE) and
+     (S1CP=S2CP) then
+    DestCP:=S1CP;
+{$endif FPC_HAS_CPSTRING}
   if (S1CP<>DestCP) or (S2CP<>DestCP) then
   if (S1CP<>DestCP) or (S2CP<>DestCP) then
     begin
     begin
       ansistr_concat_complex(DestS,S1,S2,DestCP);
       ansistr_concat_complex(DestS,S1,S2,DestCP);
@@ -273,15 +290,17 @@ end;
 {$define FPC_HAS_ANSISTR_CONCAT_MULTI}
 {$define FPC_HAS_ANSISTR_CONCAT_MULTI}
 procedure fpc_AnsiStr_Concat_multi (var DestS:RawByteString;const sarr:array of RawByteString{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}); compilerproc;
 procedure fpc_AnsiStr_Concat_multi (var DestS:RawByteString;const sarr:array of RawByteString{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}); compilerproc;
 Var
 Var
-  lowstart,i  : Longint;
+  lowstart,
+  nonemptystart,
+  i           : Longint;
   p,pc        : pointer;
   p,pc        : pointer;
   Size,NewLen,
   Size,NewLen,
   OldDestLen  : SizeInt;
   OldDestLen  : SizeInt;
   destcopy    : pointer;
   destcopy    : pointer;
-  DestCP      : TSystemCodePage;
   U           : UnicodeString;
   U           : UnicodeString;
-  sameCP      : Boolean;
+  DestCP,
   tmpCP       : TSystemCodePage;
   tmpCP       : TSystemCodePage;
+  sameCP      : Boolean;
 begin
 begin
   if high(sarr)=0 then
   if high(sarr)=0 then
     begin
     begin
@@ -289,23 +308,26 @@ begin
       exit;
       exit;
     end;
     end;
 {$ifdef FPC_HAS_CPSTRING}
 {$ifdef FPC_HAS_CPSTRING}
-  if (Pointer(DestS)=nil) then
-    DestCP:=cp
-  else
-    DestCP:=StringCodePage(DestS);
+  DestCP:=cp;
+  if DestCp=CP_NONE then
+    DestCP:=DefaultSystemCodePage;
 {$else FPC_HAS_CPSTRING}
 {$else FPC_HAS_CPSTRING}
   DestCP:=StringCodePage(DestS);
   DestCP:=StringCodePage(DestS);
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
-  if (DestCP=CP_ACP) then
-    DestCP:=DefaultSystemCodePage;
+  DestCP:=TranslatePlaceholderCP(DestCP);
   sameCP:=true;
   sameCP:=true;
   lowstart:=low(sarr);
   lowstart:=low(sarr);
-  for i:=lowstart to high(sarr) do
+  { skip empty strings }
+  while (lowstart<=high(sarr)) and
+        (sarr[lowstart]='') do
+    inc(lowstart);
+  tmpCP:=TranslatePlaceholderCP(StringCodePage(sarr[lowstart]));
+  for i:=lowstart+1 to high(sarr) do
     begin
     begin
-      tmpCP:=StringCodePage(sarr[i]);
-      if tmpCP=CP_ACP then
-        tmpCP:=DefaultSystemCodePage;
-      if (DestCP<>tmpCp) then
+      { ignore the code page of empty strings, it will always be
+        DefaultSystemCodePage but it doesn't matter for the outcome }
+      if (sarr[i]<>'') and
+         (tmpCP<>TranslatePlaceholderCP(StringCodePage(sarr[i]))) then
         begin
         begin
           sameCP:=false;
           sameCP:=false;
           break;
           break;
@@ -314,48 +336,53 @@ begin
   if not sameCP then
   if not sameCP then
     begin
     begin
       U:='';
       U:='';
-      for i:=lowstart to high(sarr) do begin
-        tmpCP:=StringCodePage(sarr[i]);
-        U:=U+UnicodeString(sarr[i]);
-      end;
+      for i:=lowstart to high(sarr) do
+        if sarr[i]<>'' then
+          U:=U+UnicodeString(sarr[i]);
 
 
       DestS:='';
       DestS:='';
       widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(Pointer(U)),DestS,DestCP,Length(U));
       widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(Pointer(U)),DestS,DestCP,Length(U));
       exit;
       exit;
     end;
     end;
-
+{$ifdef FPC_HAS_CPSTRING}
+  { if the result is rawbytestring and all strings have the same code page,
+    keep that code page }
+  if cp=CP_NONE then
+    DestCP:=tmpCP;
+{$endif FPC_HAS_CPSTRING}
   destcopy:=nil;
   destcopy:=nil;
-  lowstart:=low(sarr);
-  if Pointer(DestS)=Pointer(sarr[lowstart]) then
-    inc(lowstart);
+  nonemptystart:=lowstart;
   { Check for another reuse, then we can't use
   { Check for another reuse, then we can't use
     the append optimization }
     the append optimization }
-  for i:=lowstart to high(sarr) do
+  if DestS<>'' then
     begin
     begin
-      if Pointer(DestS)=Pointer(sarr[i]) then
+      if Pointer(DestS)=Pointer(sarr[lowstart]) then
+        inc(lowstart);
+      for i:=lowstart to high(sarr) do
         begin
         begin
-          { if DestS is used somewhere in the middle of the expression,
-            we need to make sure the original string still exists after
-            we empty/modify DestS                                       }
-          destcopy:=pointer(dests);
-          fpc_AnsiStr_Incr_Ref(destcopy);
-          lowstart:=low(sarr);
-          break;
+          if Pointer(DestS)=Pointer(sarr[i]) then
+            begin
+              { if DestS is used somewhere in the middle of the expression,
+                we need to make sure the original string still exists after
+                we empty/modify DestS                                       }
+              destcopy:=pointer(dests);
+              fpc_AnsiStr_Incr_Ref(destcopy);
+              lowstart:=nonemptystart;
+              break;
+            end;
         end;
         end;
     end;
     end;
   { Start with empty DestS if we start with concatting
   { Start with empty DestS if we start with concatting
-    the first array element }
-  if lowstart=low(sarr) then
+    the first (non-empty) array element }
+  if lowstart=nonemptystart then
     DestS:='';
     DestS:='';
   OldDestLen:=length(DestS);
   OldDestLen:=length(DestS);
   { Calculate size of the result so we can do
   { Calculate size of the result so we can do
     a single call to SetLength() }
     a single call to SetLength() }
   NewLen:=0;
   NewLen:=0;
-  for i:=low(sarr) to high(sarr) do
+  for i:=nonemptystart to high(sarr) do
     inc(NewLen,length(sarr[i]));
     inc(NewLen,length(sarr[i]));
   SetLength(DestS,NewLen);
   SetLength(DestS,NewLen);
-  if (StringCodePage(DestS) <> DestCP) then
-    SetCodePage(DestS,DestCP,False);
   { Concat all strings, except the string we already
   { Concat all strings, except the string we already
     copied in DestS }
     copied in DestS }
   pc:=Pointer(DestS)+OldDestLen;
   pc:=Pointer(DestS)+OldDestLen;
@@ -369,6 +396,8 @@ begin
           inc(pc,size);
           inc(pc,size);
         end;
         end;
     end;
     end;
+  SetCodePage(DestS,tmpCP,False);
+  SetCodePage(DestS,DestCP,True);
   fpc_AnsiStr_Decr_Ref(destcopy);
   fpc_AnsiStr_Decr_Ref(destcopy);
 end;
 end;
 {$endif FPC_HAS_ANSISTR_CONCAT_MULTI}
 {$endif FPC_HAS_ANSISTR_CONCAT_MULTI}
@@ -410,11 +439,8 @@ begin
   Size:=Length(S);
   Size:=Length(S);
   if Size>0 then
   if Size>0 then
     begin
     begin
-      if (cp=CP_ACP) then
-        cp:=DefaultSystemCodePage;
-      orgcp:=StringCodePage(S);
-      if (orgcp=CP_ACP) then
-        orgcp:=DefaultSystemCodePage;
+      cp:=TranslatePlaceholderCP(cp);
+      orgcp:=TranslatePlaceholderCP(StringCodePage(S));
       if (orgcp=cp) or (orgcp=CP_NONE) then
       if (orgcp=cp) or (orgcp=CP_NONE) then
         begin
         begin
           SetLength(result,Size);
           SetLength(result,Size);
@@ -471,8 +497,7 @@ Var
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
 begin
 begin
 {$ifdef FPC_HAS_CPSTRING}
 {$ifdef FPC_HAS_CPSTRING}
-  if (cp=CP_ACP) then
-    cp:=DefaultSystemCodePage;
+  cp:=TranslatePlaceholderCP(cp);
 {$else FPC_HAS_CPSTRING}
 {$else FPC_HAS_CPSTRING}
   cp:=DefaultSystemCodePage;
   cp:=DefaultSystemCodePage;
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
@@ -499,8 +524,7 @@ var
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
 begin
 begin
 {$ifdef FPC_HAS_CPSTRING}
 {$ifdef FPC_HAS_CPSTRING}
-  if (cp=CP_ACP) then
-    cp:=DefaultSystemCodePage;
+  cp:=TranslatePlaceholderCP(cp);
 {$else FPC_HAS_CPSTRING}
 {$else FPC_HAS_CPSTRING}
   cp:=DefaultSystemCodePage;
   cp:=DefaultSystemCodePage;
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
@@ -529,8 +553,7 @@ begin
   if L > 0 then
   if L > 0 then
     begin
     begin
 {$ifdef FPC_HAS_CPSTRING}
 {$ifdef FPC_HAS_CPSTRING}
-      if (cp=CP_ACP) then
-        cp:=DefaultSystemCodePage;
+      cp:=TranslatePlaceholderCP(cp);
 {$else FPC_HAS_CPSTRING}
 {$else FPC_HAS_CPSTRING}
       cp:=DefaultSystemCodePage;
       cp:=DefaultSystemCodePage;
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
@@ -567,8 +590,7 @@ begin
   if i > 0 then
   if i > 0 then
     begin
     begin
 {$ifdef FPC_HAS_CPSTRING}
 {$ifdef FPC_HAS_CPSTRING}
-      if (cp=CP_ACP) then
-        cp:=DefaultSystemCodePage;
+      cp:=TranslatePlaceholderCP(cp);
 {$else FPC_HAS_CPSTRING}
 {$else FPC_HAS_CPSTRING}
       cp:=DefaultSystemCodePage;
       cp:=DefaultSystemCodePage;
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
@@ -628,12 +650,8 @@ begin
       result:=Length(S1);
       result:=Length(S1);
       exit;
       exit;
     end;
     end;
-  cp1:=StringCodePage(S1);
-  if cp1=CP_ACP then
-    cp1:=DefaultSystemCodePage;
-  cp2:=StringCodePage(S2);
-  if cp2=CP_ACP then
-    cp2:=DefaultSystemCodePage;
+  cp1:=TranslatePlaceholderCP(StringCodePage(S1));
+  cp2:=TranslatePlaceholderCP(StringCodePage(S2));
   if cp1=cp2 then
   if cp1=cp2 then
     begin
     begin
       Maxi:=Length(S1);
       Maxi:=Length(S1);
@@ -692,12 +710,8 @@ begin
       result:=1;
       result:=1;
       exit;
       exit;
     end;
     end;
-  cp1:=StringCodePage(S1);
-  if cp1=CP_ACP then
-    cp1:=DefaultSystemCodePage;
-  cp2:=StringCodePage(S2);
-  if cp2=CP_ACP then
-    cp2:=DefaultSystemCodePage;
+  cp1:=TranslatePlaceholderCP(StringCodePage(S1));
+  cp2:=TranslatePlaceholderCP(StringCodePage(S2));
   if cp1=cp2 then
   if cp1=cp2 then
     begin
     begin
       Maxi:=Length(S1);
       Maxi:=Length(S1);
@@ -750,6 +764,12 @@ begin
       if Pointer(S)=nil then
       if Pointer(S)=nil then
         begin
         begin
           Pointer(S):=NewAnsiString(L);
           Pointer(S):=NewAnsiString(L);
+{$ifdef FPC_HAS_CPSTRING}
+          cp:=TranslatePlaceholderCP(cp);
+          PAnsiRec(Pointer(S)-AnsiFirstOff)^.CodePage:=cp;
+{$else}
+          PAnsiRec(Pointer(S)-AnsiFirstOff)^.CodePage:=DefaultSystemCodePage;
+{$endif FPC_HAS_CPSTRING}
         end
         end
       else if PAnsiRec(Pointer(S)-AnsiFirstOff)^.Ref=1 then
       else if PAnsiRec(Pointer(S)-AnsiFirstOff)^.Ref=1 then
         begin
         begin
@@ -767,6 +787,7 @@ begin
         begin
         begin
           { Reallocation is needed... }
           { Reallocation is needed... }
           Temp:=NewAnsiString(L);
           Temp:=NewAnsiString(L);
+          PAnsiRec(Pointer(Temp)-AnsiFirstOff)^.CodePage:=PAnsiRec(Pointer(S)-AnsiFirstOff)^.CodePage;
           { also move terminating null }
           { also move terminating null }
           lens:=succ(length(s));
           lens:=succ(length(s));
           if l<lens then
           if l<lens then
@@ -777,13 +798,6 @@ begin
           fpc_ansistr_decr_ref(Pointer(s));
           fpc_ansistr_decr_ref(Pointer(s));
           Pointer(S):=Temp;
           Pointer(S):=Temp;
         end;
         end;
-{$ifdef FPC_HAS_CPSTRING}
-      if (cp=CP_ACP) then
-        cp:=DefaultSystemCodePage;
-      PAnsiRec(Pointer(S)-AnsiFirstOff)^.CodePage:=cp;
-{$else}
-      PAnsiRec(Pointer(S)-AnsiFirstOff)^.CodePage:=DefaultSystemCodePage;
-{$endif FPC_HAS_CPSTRING}
       { Force nil termination in case it gets shorter }
       { Force nil termination in case it gets shorter }
       PByte(Pointer(S)+l)^:=0;
       PByte(Pointer(S)+l)^:=0;
       PAnsiRec(Pointer(S)-AnsiFirstOff)^.Len:=l;
       PAnsiRec(Pointer(S)-AnsiFirstOff)^.Len:=l;
@@ -1280,9 +1294,7 @@ begin
    index := LS+1;
    index := LS+1;
   Dec(Index);
   Dec(Index);
   SetLength(Temp,Length(Source)+LS);
   SetLength(Temp,Length(Source)+LS);
-  cp:=StringCodePage(S);
-  if (cp=CP_ACP) then
-    cp:=DefaultSystemCodePage;
+  cp:=TranslatePlaceholderCP(StringCodePage(S));
   SetCodePage(Temp,cp,false);
   SetCodePage(Temp,cp,false);
   If Index>0 then
   If Index>0 then
     fpc_pchar_ansistr_intern_charmove(pchar(S),0,Temp,0,Index);
     fpc_pchar_ansistr_intern_charmove(pchar(S),0,Temp,0,Index);
@@ -1408,10 +1420,19 @@ procedure InternalSetCodePage(var s : RawByteString; CodePage : TSystemCodePage;
 { use this wrapper for the simple case to avoid the generation of a temp. ansistring which causes
 { use this wrapper for the simple case to avoid the generation of a temp. ansistring which causes
   extra exception frames }
   extra exception frames }
 procedure SetCodePage(var s : RawByteString; CodePage : TSystemCodePage; Convert : Boolean = True);
 procedure SetCodePage(var s : RawByteString; CodePage : TSystemCodePage; Convert : Boolean = True);
+  var
+    TranslatedCodePage,
+    TranslatedCurrentCodePage: TSystemCodePage;
   begin
   begin
-    if (S='') or (PAnsiRec(pointer(S)-AnsiFirstOff)^.CodePage=CodePage) then
-      exit
-    else if not Convert and (PAnsiRec(pointer(S)-AnsiFirstOff)^.Ref=1) then
+    if (S='') then
+      exit;
+    { if we're just replacing a placeholder code page with its actual value or
+      vice versa, we don't have to perform any conversion }
+    TranslatedCurrentCodePage:=TranslatePlaceholderCP(PAnsiRec(pointer(S)-AnsiFirstOff)^.CodePage);
+    TranslatedCodePage:=TranslatePlaceholderCP(CodePage);
+    Convert:=Convert and
+      (TranslatedCurrentCodePage<>TranslatedCodePage);
+    if not Convert and (PAnsiRec(pointer(S)-AnsiFirstOff)^.Ref=1) then
       PAnsiRec(pointer(S)-AnsiFirstOff)^.CodePage:=CodePage
       PAnsiRec(pointer(S)-AnsiFirstOff)^.CodePage:=CodePage
     else
     else
       InternalSetCodePage(S,CodePage,Convert);
       InternalSetCodePage(S,CodePage,Convert);
@@ -1424,3 +1445,15 @@ procedure SetMultiByteConversionCodePage(CodePage: TSystemCodePage);
     DefaultSystemCodePage:=CodePage;
     DefaultSystemCodePage:=CodePage;
   end;
   end;
 
 
+
+procedure SetMultiByteFileSystemCodePage(CodePage: TSystemCodePage);
+  begin
+    DefaultFileSystemCodePage:=CodePage;
+  end;
+
+
+procedure SetMultiByteRTLFileSystemCodePage(CodePage: TSystemCodePage);
+  begin
+    DefaultRTLFileSystemCodePage:=CodePage;
+  end;
+

+ 5 - 1
rtl/inc/compproc.inc

@@ -357,7 +357,11 @@ Function fpc_Char_To_UChar(const c : Char): UnicodeChar; compilerproc;
 Function fpc_UChar_To_Char(const c : UnicodeChar): Char; compilerproc;
 Function fpc_UChar_To_Char(const c : UnicodeChar): Char; compilerproc;
 Function fpc_UChar_To_UnicodeStr(const c : UnicodeChar): UnicodeString; compilerproc;
 Function fpc_UChar_To_UnicodeStr(const c : UnicodeChar): UnicodeString; compilerproc;
 Function fpc_UChar_To_AnsiStr(const c : UnicodeChar{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}): AnsiString; compilerproc;
 Function fpc_UChar_To_AnsiStr(const c : UnicodeChar{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}): AnsiString; compilerproc;
-procedure fpc_UChar_To_ShortStr(out res : shortstring;const c : WideChar) compilerproc;
+{$ifdef VER2_6}
+procedure fpc_UChar_To_ShortStr(out result : shortstring;const c : WideChar) compilerproc;
+{$else}
+function fpc_UChar_To_ShortStr(const c : WideChar): shortstring; compilerproc;
+{$endif}
 
 
 Function fpc_PWideChar_To_UnicodeStr(const p : pwidechar): unicodestring; compilerproc;
 Function fpc_PWideChar_To_UnicodeStr(const p : pwidechar): unicodestring; compilerproc;
 {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
 {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}

+ 75 - 20
rtl/inc/dynlibs.pas

@@ -20,6 +20,8 @@ unit dynlibs;
 
 
 interface
 interface
 
 
+{$i rtldefs.inc}
+
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
   Read OS-dependent interface declarations.
   Read OS-dependent interface declarations.
   ---------------------------------------------------------------------}
   ---------------------------------------------------------------------}
@@ -33,8 +35,11 @@ interface
   ---------------------------------------------------------------------}
   ---------------------------------------------------------------------}
 
 
 
 
-Function SafeLoadLibrary(const Name : AnsiString) : TLibHandle;
-Function LoadLibrary(const Name : AnsiString) : TLibHandle;
+Function SafeLoadLibrary(const Name : RawByteString) : TLibHandle;
+Function LoadLibrary(const Name : RawByteString) : TLibHandle;
+Function SafeLoadLibrary(const Name : UnicodeString) : TLibHandle;
+Function LoadLibrary(const Name : UnicodeString) : TLibHandle;
+
 Function GetProcedureAddress(Lib : TlibHandle; const ProcName : AnsiString) : Pointer;
 Function GetProcedureAddress(Lib : TlibHandle; const ProcName : AnsiString) : Pointer;
 Function UnloadLibrary(Lib : TLibHandle) : Boolean;
 Function UnloadLibrary(Lib : TLibHandle) : Boolean;
 Function GetLoadErrorStr: string;
 Function GetLoadErrorStr: string;
@@ -55,19 +60,11 @@ Implementation
 
 
 {$i dynlibs.inc}
 {$i dynlibs.inc}
 
 
-Function FreeLibrary(Lib : TLibHandle) : Boolean;
-
-begin
-  Result:=UnloadLibrary(lib);
-end;
-
-Function GetProcAddress(Lib : TlibHandle; const ProcName : AnsiString) : Pointer;
-
-begin
-  Result:=GetProcedureAddress(Lib,Procname);
-end;
-
-Function SafeLoadLibrary(const Name : AnsiString) : TLibHandle;
+{$ifndef FPCRTL_FILESYSTEM_TWO_BYTE_API}
+Function DoSafeLoadLibrary(const Name : RawByteString) : TLibHandle;
+{$else not FPCRTL_FILESYSTEM_TWO_BYTE_API}
+Function DoSafeLoadLibrary(const Name : UnicodeString) : TLibHandle;
+{$endif not FPCRTL_FILESYSTEM_TWO_BYTE_API}
 {$if defined(cpui386) or defined(cpux86_64)}
 {$if defined(cpui386) or defined(cpux86_64)}
   var
   var
     fpucw : Word;
     fpucw : Word;
@@ -82,11 +79,7 @@ Function SafeLoadLibrary(const Name : AnsiString) : TLibHandle;
 {$endif cpui386}
 {$endif cpui386}
         ssecw:=GetSSECSR;
         ssecw:=GetSSECSR;
 {$endif}
 {$endif}
-{$if defined(windows) or defined(win32)}
-      Result:=LoadLibraryA(PChar(Name));
-{$else}
-      Result:=loadlibrary(Name);
-{$endif}
+      Result:=doloadlibrary(Name);
       finally
       finally
 {$if defined(cpui386) or defined(cpux86_64)}
 {$if defined(cpui386) or defined(cpux86_64)}
       Set8087CW(fpucw);
       Set8087CW(fpucw);
@@ -98,5 +91,67 @@ Function SafeLoadLibrary(const Name : AnsiString) : TLibHandle;
     end;
     end;
   end;
   end;
 
 
+{$ifndef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+Function SafeLoadLibrary(const Name : RawByteString) : TLibHandle;
+begin
+  Result:=DoSafeLoadLibrary(UnicodeString(Name));
+end;
+
+Function LoadLibrary(const Name : RawByteString) : TLibHandle;
+begin
+  Result:=DoLoadLibrary(UnicodeString(Name));
+end;
+
+{$else not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+Function SafeLoadLibrary(const Name : RawByteString) : TLibHandle;
+begin
+  Result:=DoSafeLoadLibrary(ToSingleByteFileSystemEncodedFileName(Name));
+end;
+
+Function LoadLibrary(const Name : RawByteString) : TLibHandle;
+begin
+  Result:=DoLoadLibrary(ToSingleByteFileSystemEncodedFileName(Name));
+end;
+{$endif not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+
+{$ifndef FPCRTL_FILESYSTEM_TWO_BYTE_API}
+Function SafeLoadLibrary(const Name : UnicodeString) : TLibHandle;
+begin
+  Result:=DoSafeLoadLibrary(ToSingleByteFileSystemEncodedFileName(Name));
+end;
+
+Function LoadLibrary(const Name : UnicodeString) : TLibHandle;
+begin
+  Result:=DoLoadLibrary(ToSingleByteFileSystemEncodedFileName(Name));
+end;
+
+{$else not FPCRTL_FILESYSTEM_TWO_BYTE_API}
+
+Function SafeLoadLibrary(const Name : UnicodeString) : TLibHandle;
+begin
+  Result:=DoSafeLoadLibrary(Name);
+end;
+
+Function LoadLibrary(const Name : UnicodeString) : TLibHandle;
+begin
+  Result:=DoLoadLibrary(Name);
+end;
+{$endif not FPCRTL_FILESYSTEM_TWO_BYTE_API}
+
+
+Function FreeLibrary(Lib : TLibHandle) : Boolean;
+
+begin
+  Result:=UnloadLibrary(lib);
+end;
+
+Function GetProcAddress(Lib : TlibHandle; const ProcName : AnsiString) : Pointer;
+
+begin
+  Result:=GetProcedureAddress(Lib,Procname);
+end;
+
 
 
 end.
 end.

+ 6 - 6
rtl/inc/exeinfo.pp

@@ -71,11 +71,11 @@ uses
 
 
   var
   var
     Tmm: TMemoryBasicInformation;
     Tmm: TMemoryBasicInformation;
-{$ifdef wince}
+{$ifdef FPC_OS_UNICODE}
     TST: array[0..Max_Path] of WideChar;
     TST: array[0..Max_Path] of WideChar;
-{$else wince}
+{$else}
     TST: array[0..Max_Path] of Char;
     TST: array[0..Max_Path] of Char;
-{$endif wince}
+{$endif FPC_OS_UNICODE}
   procedure GetModuleByAddr(addr: pointer; var baseaddr: pointer; var filename: string);
   procedure GetModuleByAddr(addr: pointer; var baseaddr: pointer; var filename: string);
     begin
     begin
       baseaddr:=nil;
       baseaddr:=nil;
@@ -86,11 +86,11 @@ uses
           baseaddr:=Tmm.AllocationBase;
           baseaddr:=Tmm.AllocationBase;
           TST[0]:= #0;
           TST[0]:= #0;
           GetModuleFileName(THandle(Tmm.AllocationBase), TST, Length(TST));
           GetModuleFileName(THandle(Tmm.AllocationBase), TST, Length(TST));
-{$ifdef wince}
+{$ifdef FPC_OS_UNICODE}
           filename:= String(PWideChar(@TST));
           filename:= String(PWideChar(@TST));
-{$else wince}
+{$else}
           filename:= String(PChar(@TST));
           filename:= String(PChar(@TST));
-{$endif wince}
+{$endif FPC_OS_UNICODE}
         end;
         end;
     end;
     end;
 
 

+ 126 - 23
rtl/inc/fexpand.inc

@@ -50,7 +50,25 @@
  {$DEFINE FPC_FEXPAND_UPDIR_HELPER}
  {$DEFINE FPC_FEXPAND_UPDIR_HELPER}
 {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
 {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
 
 
-procedure GetDirIO (DriveNr: byte; var Dir: String);
+{ this code is used both in sysutils and in the dos unit, and the dos
+  unit does not have a charinset routine }
+{$if not defined(FPC_FEXPAND_SYSUTILS) and not defined(FPC_FEXPAND_HAS_CHARINSET)}
+{$define FPC_FEXPAND_HAS_CHARINSET}
+type
+  TFExpandSysCharSet = set of ansichar;
+
+Function CharInSet(Ch:AnsiChar;Const CSet : TFExpandSysCharSet) : Boolean; inline;
+begin
+  CharInSet:=ch in CSet;
+end;
+
+Function CharInSet(Ch:WideChar;Const CSet : TFExpandSysCharSet) : Boolean;
+begin
+  CharInSet:=(Ch<=#$FF) and (ansichar(byte(ch)) in CSet);
+end;
+{$endif}
+
+procedure GetDirIO (DriveNr: byte; var Dir: {$IF defined(FPC_FEXPAND_SYSUTILS) and not defined(SYSUTILSUNICODE)}RawByteString{$else}PathStr{$endif});
 
 
 (* GetDirIO is supposed to return the root of the given drive   *)
 (* GetDirIO is supposed to return the root of the given drive   *)
 (* in case of an error for compatibility of FExpand with TP/BP. *)
 (* in case of an error for compatibility of FExpand with TP/BP. *)
@@ -67,7 +85,7 @@ end;
 
 
 {$IFDEF FPC_FEXPAND_VOLUMES}
 {$IFDEF FPC_FEXPAND_VOLUMES}
  {$IFNDEF FPC_FEXPAND_NO_DEFAULT_PATHS}
  {$IFNDEF FPC_FEXPAND_NO_DEFAULT_PATHS}
-procedure GetDirIO (const VolumeName: OpenString; var Dir: string);
+procedure GetDirIO (const VolumeName: OpenString; var Dir: {$IF defined(FPC_FEXPAND_SYSUTILS) and not defined(SYSUTILSUNICODE)}RawByteString{$else}PathStr{$endif});
 
 
 var
 var
   OldInOutRes: word;
   OldInOutRes: word;
@@ -110,7 +128,7 @@ const
     RootNotNeeded = false;
     RootNotNeeded = false;
 {$ENDIF FPC_FEXPAND_UNC}
 {$ENDIF FPC_FEXPAND_UNC}
 
 
-var S, Pa, Dirs: PathStr;
+var S, Pa, Dirs, TmpS: {$IF defined(FPC_FEXPAND_SYSUTILS) and not defined(SYSUTILSUNICODE)}RawByteString{$else}PathStr{$endif};
     I, J: longint;
     I, J: longint;
 
 
 begin
 begin
@@ -119,18 +137,31 @@ begin
 {$ENDIF FPC_FEXPAND_UNC}
 {$ENDIF FPC_FEXPAND_UNC}
 
 
 (* First convert the path to uppercase if appropriate for current platform. *)
 (* First convert the path to uppercase if appropriate for current platform. *)
+{$IF defined(FPC_FEXPAND_SYSUTILS) and not defined(SYSUTILSUNICODE)}
+    { for sysutils/rawbytestring, process everything in
+      DefaultFileSystemCodePage to prevent risking data loss that may be
+      relevant when the file name is used }
+    if FileNameCasePreserving then
+        Pa := ToSingleByteFileSystemEncodedFileName (Path)
+    else
+        Pa := UpCase (ToSingleByteFileSystemEncodedFileName (Path));
+{$ELSE FPC_FEXPAND_SYSUTILS and not SYSUTILSUNICODE}
     if FileNameCasePreserving then
     if FileNameCasePreserving then
         Pa := Path
         Pa := Path
     else
     else
         Pa := UpCase (Path);
         Pa := UpCase (Path);
+{$ENDIF FPC_FEXPAND_SYSUTILS and not SYSUTILSUNICODE}
 
 
+{ already done before this routine is called from sysutils }
+{$IFNDEF FPC_FEXPAND_SYSUTILS}
 (* Allow both '/' and '\' as directory separators *)
 (* Allow both '/' and '\' as directory separators *)
 (* by converting all to the native one.           *)
 (* by converting all to the native one.           *)
 {$warnings off}
 {$warnings off}
 	  for I := 1 to Length (Pa) do
 	  for I := 1 to Length (Pa) do
-	    if Pa [I] in AllowDirectorySeparators  then
+	    if CharInSet(Pa [I], AllowDirectorySeparators)  then
 	      Pa [I] := DirectorySeparator;
 	      Pa [I] := DirectorySeparator;
 {$warnings on}
 {$warnings on}
+{$ENDIF not FPC_FEXPAND_SYSUTILS}
 
 
 (* PathStart is amount of characters to strip to get beginning *)
 (* PathStart is amount of characters to strip to get beginning *)
 (* of path without volume/drive specification.                 *)
 (* of path without volume/drive specification.                 *)
@@ -153,7 +184,11 @@ begin
                       ((Pa [2] = DirectorySeparator) or (Length (Pa) = 1)) then
                       ((Pa [2] = DirectorySeparator) or (Length (Pa) = 1)) then
         begin
         begin
  {$IFDEF FPC_FEXPAND_SYSUTILS}
  {$IFDEF FPC_FEXPAND_SYSUTILS}
-            S := GetEnvironmentVariable ('HOME');
+   {$IFDEF SYSUTILSUNICODE}
+            S := PathStr(GetEnvironmentVariable ('HOME'));
+   {$ELSE SYSUTILSUNICODE}
+            S := ToSingleByteFileSystemEncodedFileName(GetEnvironmentVariable ('HOME'));
+   {$ENDIF SYSUTILSUNICODE}
  {$ELSE FPC_FEXPAND_SYSUTILS}
  {$ELSE FPC_FEXPAND_SYSUTILS}
   {$IFDEF FPC_FEXPAND_GETENV_PCHAR}
   {$IFDEF FPC_FEXPAND_GETENV_PCHAR}
             S := StrPas (GetEnv ('HOME'));
             S := StrPas (GetEnv ('HOME'));
@@ -176,7 +211,7 @@ begin
 {$IFDEF FPC_FEXPAND_VOLUMES}
 {$IFDEF FPC_FEXPAND_VOLUMES}
     if PathStart > 1 then
     if PathStart > 1 then
 {$ELSE FPC_FEXPAND_VOLUMES}
 {$ELSE FPC_FEXPAND_VOLUMES}
-    if (Length (Pa) > 1) and (Pa [1] in ['A'..'Z', 'a'..'z']) and
+    if (Length (Pa) > 1) and CharInSet(Pa [1], ['A'..'Z', 'a'..'z']) and
       (Pa [2] = DriveSeparator) and (DriveSeparator <> DirectorySeparator) then
       (Pa [2] = DriveSeparator) and (DriveSeparator <> DirectorySeparator) then
 {$ENDIF FPC_FEXPAND_VOLUMES}
 {$ENDIF FPC_FEXPAND_VOLUMES}
         begin
         begin
@@ -189,7 +224,7 @@ begin
             GetDirIO (Copy (Pa, 1, PathStart - 2), S);
             GetDirIO (Copy (Pa, 1, PathStart - 2), S);
   {$ELSE FPC_FEXPAND_VOLUMES}
   {$ELSE FPC_FEXPAND_VOLUMES}
             { Always uppercase driveletter }
             { Always uppercase driveletter }
-            if (Pa [1] in ['a'..'z']) then
+            if CharInSet(Pa [1], ['a'..'z']) then
                 Pa [1] := Chr (Ord (Pa [1]) and not ($20));
                 Pa [1] := Chr (Ord (Pa [1]) and not ($20));
             GetDirIO (Ord (Pa [1]) - Ord ('A') + 1, S);
             GetDirIO (Ord (Pa [1]) - Ord ('A') + 1, S);
   {$ENDIF FPC_FEXPAND_VOLUMES}
   {$ENDIF FPC_FEXPAND_VOLUMES}
@@ -212,19 +247,38 @@ begin
                         begin
                         begin
                             { remove ending slash if it already exists }
                             { remove ending slash if it already exists }
                             if S [Length (S)] = DirectorySeparator then
                             if S [Length (S)] = DirectorySeparator then
-                               SetLength(S,Length(s)-1);
+                               SetLength(S,Length(S)-1);
+{$IFDEF FPC_FEXPAND_SYSUTILS}
+                            { not "Pa := S + DirectorySeparator + ..." because
+                              that will convert the result to
+                              DefaultSystemCodePage in case of RawByteString due
+                              to DirectorySeparator being an ansichar }
+                            TmpS := S;
+                            SetLength(TmpS, Length(TmpS) + 1);
+                            TmpS[Length(TmpS)] := DirectorySeparator;
+                            Pa := TmpS +
+                              Copy (Pa, PathStart, Length (Pa) - PathStart + 1)
+{$ELSE FPC_FEXPAND_SYSUTILS}
                             Pa := S + DirectorySeparator +
                             Pa := S + DirectorySeparator +
                               Copy (Pa, PathStart, Length (Pa) - PathStart + 1)
                               Copy (Pa, PathStart, Length (Pa) - PathStart + 1)
+{$ENDIF FPC_FEXPAND_SYSUTILS}
                         end
                         end
                     else
                     else
+                      begin
+                        TmpS := DriveSeparator + DirectorySeparator;
+  {$IF defined(FPC_FEXPAND_SYSUTILS) and not defined(SYSUTILSUNICODE)}
+                        SetCodePage(TmpS, DefaultFileSystemCodePage, false);
+  {$ENDIF FPC_FEXPAND_SYSUTILS and not SYSUTILSUNICODE}
+
   {$IFDEF FPC_FEXPAND_VOLUMES}
   {$IFDEF FPC_FEXPAND_VOLUMES}
-                        Pa := Copy (Pa, 1, PathStart - 2) + DriveSeparator
-                           + DirectorySeparator +
+                        Pa := Copy (Pa, 1, PathStart - 2) + TmpS +
                               Copy (Pa, PathStart, Length (Pa) - PathStart + 1)
                               Copy (Pa, PathStart, Length (Pa) - PathStart + 1)
   {$ELSE FPC_FEXPAND_VOLUMES}
   {$ELSE FPC_FEXPAND_VOLUMES}
-                        Pa := Pa [1] + DriveSeparator + DirectorySeparator +
+                        { copy() instead of Pa[1] to preserve string code page }
+                        Pa := Copy (Pa, 1, 1) + TmpS +
                               Copy (Pa, PathStart, Length (Pa) - PathStart + 1)
                               Copy (Pa, PathStart, Length (Pa) - PathStart + 1)
   {$ENDIF FPC_FEXPAND_VOLUMES}
   {$ENDIF FPC_FEXPAND_VOLUMES}
+                      end
  {$ENDIF FPC_FEXPAND_NO_DEFAULT_PATHS}
  {$ENDIF FPC_FEXPAND_NO_DEFAULT_PATHS}
         end
         end
     else
     else
@@ -277,8 +331,17 @@ begin
                                 {...or not even that one}
                                 {...or not even that one}
                                     PathStart := 2
                                     PathStart := 2
                                 else
                                 else
-                                    Pa := Pa + DirectorySeparator                            else
-                                if PathStart < Length (Pa) then
+                                  begin
+    {$IFDEF FPC_FEXPAND_SYSUTILS}
+                                    { no string concatenation to prevent code page
+                                      conversion for RawByteString }
+                                    SetLength(Pa, Length(Pa) + 1);
+                                    Pa[Length(Pa)] := DirectorySeparator
+    {$ELSE FPC_FEXPAND_SYSUTILS}
+                                    Pa := Pa + DirectorySeparator;
+    {$ENDIF FPC_FEXPAND_SYSUTILS}
+                                  end
+                                else if PathStart < Length (Pa) then
                                 {We have a resource name as well}
                                 {We have a resource name as well}
                                     begin
                                     begin
                                         RootNotNeeded := true;
                                         RootNotNeeded := true;
@@ -291,8 +354,8 @@ begin
                         end
                         end
                     else
                     else
   {$ENDIF FPC_FEXPAND_UNC}
   {$ENDIF FPC_FEXPAND_UNC}
-  {$IFDEF FPC_FEXPAND_VOLUMES}
                         begin
                         begin
+  {$IFDEF FPC_FEXPAND_VOLUMES}
                             I := Pos (DriveSeparator, S);
                             I := Pos (DriveSeparator, S);
    {$IFDEF FPC_FEXPAND_DIRSEP_IS_UPDIR}
    {$IFDEF FPC_FEXPAND_DIRSEP_IS_UPDIR}
     {$IFDEF FPC_FEXPAND_DRIVESEP_IS_ROOT}
     {$IFDEF FPC_FEXPAND_DRIVESEP_IS_ROOT}
@@ -302,13 +365,20 @@ begin
                             Pa := Copy (S, 1, I) + Pa;
                             Pa := Copy (S, 1, I) + Pa;
                             PathStart := I;
                             PathStart := I;
    {$ELSE FPC_FEXPAND_DIRSEP_IS_UPDIR}
    {$ELSE FPC_FEXPAND_DIRSEP_IS_UPDIR}
-                            Pa := Copy (S, 1, Pred (I)) + DriveSeparator + Pa;
+                            TmpS := Copy (S, 1, Pred (I));
+                            SetLength(TmpS, Length(TmpS) + 1);
+                            TmpS[Length(TmpS)] := DriveSeparator;
+                            Pa := TmpS + Pa;
                             PathStart := Succ (I);
                             PathStart := Succ (I);
    {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
    {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
-                        end;
   {$ELSE FPC_FEXPAND_VOLUMES}
   {$ELSE FPC_FEXPAND_VOLUMES}
-                        Pa := S [1] + DriveSeparator + Pa;
+                            TmpS := S[1] + DriveSeparator;
+  {$IF defined(FPC_FEXPAND_SYSUTILS) and not defined(SYSUTILSUNICODE)}
+                            SetCodePage(TmpS, DefaultFileSystemCodePage, false);
+  {$ENDIF FPC_FEXPAND_SYSUTILS and not SYSUTILSUNICODE}
+                            Pa := TmpS + Pa;
   {$ENDIF FPC_FEXPAND_VOLUMES}
   {$ENDIF FPC_FEXPAND_VOLUMES}
+                        end;
                 end
                 end
             else
             else
  {$ENDIF FPC_FEXPAND_DRIVES}
  {$ENDIF FPC_FEXPAND_DRIVES}
@@ -328,18 +398,42 @@ begin
                     (* with an empty string for compatibility, except *)
                     (* with an empty string for compatibility, except *)
                     (* for platforms where this is invalid.           *)
                     (* for platforms where this is invalid.           *)
                     if Length (Pa) = 0 then
                     if Length (Pa) = 0 then
-{$IFDEF FPC_FEXPAND_DIRSEP_IS_UPDIR}
-                        Pa := S
-{$ELSE FPC_FEXPAND_DIRSEP_IS_UPDIR}
-                        Pa := S + DirectorySeparator
-{$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
+                      begin
+                        Pa := S;
+{$IFNDEF FPC_FEXPAND_DIRSEP_IS_UPDIR}
+  {$IFDEF FPC_FEXPAND_SYSUTILS}
+                        { no string concatenation to prevent code page
+                          conversion for RawByteString }
+                        SetLength(Pa, Length(Pa) + 1);
+                        Pa[Length(Pa)] := DirectorySeparator
+  {$ELSE FPC_FEXPAND_SYSUTILS}
+                        Pa := Pa + DirectorySeparator;
+  {$ENDIF FPC_FEXPAND_SYSUTILS}
+{$ENDIF not FPC_FEXPAND_DIRSEP_IS_UPDIR}
+                      end
                     else
                     else
 {$IFDEF FPC_FEXPAND_UPDIR_HELPER}
 {$IFDEF FPC_FEXPAND_UPDIR_HELPER}
                         if Pa [1] = DirectorySeparator then
                         if Pa [1] = DirectorySeparator then
                             Pa := S + Pa
                             Pa := S + Pa
                         else
                         else
 {$ENDIF FPC_FEXPAND_UPDIR_HELPER}
 {$ENDIF FPC_FEXPAND_UPDIR_HELPER}
-                        Pa := S + DirectorySeparator + Pa;
+                          begin
+{$IFDEF FPC_FEXPAND_SYSUTILS}
+                            { not "Pa := S + DirectorySeparator + Pa" because
+                              that will convert the result to
+                              DefaultSystemCodePage in case of RawByteString due
+                              to DirectorySeparator being an ansichar. Don't
+                              always use this code because in case of
+                              truncation with shortstrings the result will be
+                              different }
+                            TmpS := S;
+                            SetLength(TmpS, Length(TmpS) + 1);
+                            TmpS[Length(TmpS)] := DirectorySeparator;
+                            Pa := TmpS + Pa;
+{$ELSE FPC_FEXPAND_SYSUTILS}
+                            Pa := S + DirectorySeparator + Pa
+{$ENDIF FPC_FEXPAND_SYSUTILS}
+                          end;
         end;
         end;
 
 
     {Get string of directories to only process relative references on this one}
     {Get string of directories to only process relative references on this one}
@@ -477,7 +571,16 @@ begin
             Pa := Copy (Pa, 1, PathStart);
             Pa := Copy (Pa, 1, PathStart);
 {$IFNDEF FPC_FEXPAND_DRIVESEP_IS_ROOT}
 {$IFNDEF FPC_FEXPAND_DRIVESEP_IS_ROOT}
             if Pa [PathStart] <> DirectorySeparator then
             if Pa [PathStart] <> DirectorySeparator then
+              begin
+  {$IFDEF FPC_FEXPAND_SYSUTILS}
+                { no string concatenation to prevent code page
+                  conversion for RawByteString }
+                SetLength(Pa, Length(Pa) + 1);
+                Pa[Length(Pa)] := DirectorySeparator
+  {$ELSE FPC_FEXPAND_SYSUTILS}
                 Pa := Pa + DirectorySeparator;
                 Pa := Pa + DirectorySeparator;
+  {$ENDIF FPC_FEXPAND_SYSUTILS}
+              end
 {$ENDIF FPC_FEXPAND_DRIVESEP_IS_ROOT}
 {$ENDIF FPC_FEXPAND_DRIVESEP_IS_ROOT}
         end
         end
     else
     else

+ 175 - 35
rtl/inc/file.inc

@@ -18,35 +18,85 @@
 type
 type
   UnTypedFile=File;
   UnTypedFile=File;
 
 
-Procedure Assign(out f:File;const Name:string);
+procedure InitFile(var f : file);
+begin
+  FillChar(f,SizeOf(FileRec),0);
+  FileRec(f).Handle:=UnusedHandle;
+  FileRec(f).mode:=fmClosed;
+end;
+
+
+{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
+Procedure Assign(out f:File;const Name: UnicodeString);
 {
 {
   Assign Name to file f so it can be used with the file routines
   Assign Name to file f so it can be used with the file routines
 }
 }
 Begin
 Begin
-  FillChar(f,SizeOf(FileRec),0);
-  FileRec(f).Handle:=UnusedHandle;
-  FileRec(f).mode:=fmClosed;
-  Move(Name[1],FileRec(f).Name,Length(Name));
+  InitFile(F);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(Name);
+{$else FPC_ANSI_TEXTFILEREC}
+  FileRec(f).Name:=Name;
+{$endif FPC_ANSI_TEXTFILEREC}
+  { null terminate, since the name array is regularly used as p(wide)char }
+  FileRec(f).Name[high(FileRec(f).Name)]:=#0;
 End;
 End;
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
 
 
 
 
-Procedure Assign(out f:File;p:pchar);
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Procedure Assign(out f:File;const Name: RawByteString);
 {
 {
   Assign Name to file f so it can be used with the file routines
   Assign Name to file f so it can be used with the file routines
 }
 }
-begin
-  Assign(f,StrPas(p));
-end;
-
+Begin
+  InitFile(F);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  { ensure the characters in the record's filename are encoded correctly }
+  FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(Name);
+{$else FPC_ANSI_TEXTFILEREC}
+  FileRec(f).Name:=Name;
+{$endif FPC_ANSI_TEXTFILEREC}
+  { null terminate, since the name array is regularly used as p(wide)char }
+  FileRec(f).Name[high(FileRec(f).Name)]:=#0;
+End;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 
-Procedure Assign(out f:File;c:char);
+Procedure Assign(out f:File;const Name: ShortString);
 {
 {
   Assign Name to file f so it can be used with the file routines
   Assign Name to file f so it can be used with the file routines
 }
 }
-begin
-  Assign(f,string(c));
-end;
+Begin
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+  Assign(f,AnsiString(Name));
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
+  InitFile(f);
+  { warning: no encoding support }
+  FileRec(f).Name:=Name;
+  { null terminate, since the name array is regularly used as p(wide)char }
+  FileRec(f).Name[high(FileRec(f).Name)]:=#0;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
+End;
 
 
+Procedure Assign(out f:File;const p: PAnsiChar);
+Begin
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+  Assign(f,AnsiString(p));
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
+  { no use in making this the one that does the work, since the name field is
+    limited to 255 characters anyway }
+  Assign(f,strpas(p));
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
+End;
+
+Procedure Assign(out f:File;const c: AnsiChar);
+Begin
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+  Assign(f,AnsiString(c));
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
+  Assign(f,ShortString(c));
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
+End;
 
 
 Procedure Rewrite(var f:File;l:Longint);[IOCheck];
 Procedure Rewrite(var f:File;l:Longint);[IOCheck];
 {
 {
@@ -69,7 +119,7 @@ Begin
   else
   else
    Begin
    Begin
      { Reopen with filemode 2, to be Tp compatible (PFV) }
      { Reopen with filemode 2, to be Tp compatible (PFV) }
-     Do_Open(f,PChar(@FileRec(f).Name),$1002);
+     Do_Open(f,PFileTextRecChar(@FileRec(f).Name),$1002,false);
      FileRec(f).RecSize:=l;
      FileRec(f).RecSize:=l;
    End;
    End;
 End;
 End;
@@ -95,7 +145,7 @@ Begin
    InOutRes:=2
    InOutRes:=2
   else
   else
    Begin
    Begin
-     Do_Open(f,PChar(@FileRec(f).Name),Filemode);
+     Do_Open(f,PFileTextRecChar(@FileRec(f).Name),Filemode,false);
      FileRec(f).RecSize:=l;
      FileRec(f).RecSize:=l;
    End;
    End;
 End;
 End;
@@ -383,44 +433,134 @@ Begin
   If InOutRes <> 0 then
   If InOutRes <> 0 then
    exit;
    exit;
   If FileRec(f).mode=fmClosed Then
   If FileRec(f).mode=fmClosed Then
-   Do_Erase(PChar(@FileRec(f).Name));
+   Do_Erase(PFileTextRecChar(@FileRec(f).Name),false);
 End;
 End;
 
 
 
 
-Procedure Rename(var f : File;p:pchar);[IOCheck];
+Procedure Rename(var f : File; const S : UnicodeString);[IOCheck];
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+var
+  fs: RawByteString;
+{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
 Begin
 Begin
-  If InOutRes <> 0 then
-   exit;
-  If FileRec(f).mode=fmClosed Then
-   Begin
-     Do_Rename(PChar(@FileRec(f).Name),p);
-     { check error code of do_rename }
-     If InOutRes = 0 then
-        Move(p^,FileRec(f).Name,StrLen(p)+1);
-   End;
+  If (InOutRes<>0) or
+     (FileRec(f).mode<>fmClosed) then
+    exit;
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  { it's slightly faster to convert the unicodestring here to rawbytestring
+    than doing it in do_rename(), because here we still know the length }
+  fs:=ToSingleByteFileSystemEncodedFileName(s);
+  Do_Rename(PFileTextRecChar(@FileRec(f).Name),PAnsiChar(fs),false,true);
+  If InOutRes=0 then
+     FileRec(f).Name:=fs
+{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  Do_Rename(PFileTextRecChar(@FileRec(f).Name),PUnicodeChar(S),false,false);
+  If InOutRes=0 then
+{$ifdef FPC_ANSI_TEXTFILEREC}
+    FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(s);
+{$else FPC_ANSI_TEXTFILEREC}
+    FileRec(f).Name:=s
+{$endif FPC_ANSI_TEXTFILEREC}
+{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
 End;
 End;
 
 
 
 
-Procedure Rename(var f : File;const s : string);[IOCheck];
+Procedure Rename(var f : File;const s : RawByteString);[IOCheck];
+var
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  fs: RawByteString;
+  pdst: PAnsiChar;
+{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  fs: UnicodeString;
+  pdst: PUnicodeChar;
+{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  dstchangeable: boolean;
+Begin
+  If (InOutRes<>0) or
+     (FileRec(f).mode<>fmClosed) then
+    exit;
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  dstchangeable:=false;
+  pdst:=PAnsiChar(s);
+  if StringCodePage(s)<>DefaultFileSystemCodePage then
+    begin
+      fs:=ToSingleByteFileSystemEncodedFileName(s);
+      pdst:=PAnsiChar(fs);
+      dstchangeable:=true;
+    end
+  else
+    fs:=s;
+{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+   { it's slightly faster to convert the rawbytestring here to unicodestring
+     than doing it in do_rename, because here we still know the length }
+   fs:=unicodestring(s);
+   pdst:=PUnicodeChar(fs);
+   dstchangeable:=true;
+{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  Do_Rename(PFileTextRecChar(@FileRec(f).Name),pdst,false,dstchangeable);
+  If InOutRes=0 then
+{$if defined(FPC_ANSI_TEXTFILEREC) and not defined(FPCRTL_FILESYSTEM_SINGLE_BYTE_API)}
+    FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(fs)
+{$else FPC_ANSI_TEXTFILEREC and not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+    FileRec(f).Name:=fs
+{$endif FPC_ANSI_TEXTFILEREC and not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+End;
+
+
+Procedure Rename(var f : File;const s : ShortString);[IOCheck];
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Begin
+  Rename(f,AnsiString(s));
+End;
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
 var
 var
   p : array[0..255] Of Char;
   p : array[0..255] Of Char;
 Begin
 Begin
-  If InOutRes <> 0 then
-   exit;
   Move(s[1],p,Length(s));
   Move(s[1],p,Length(s));
   p[Length(s)]:=#0;
   p[Length(s)]:=#0;
   Rename(f,Pchar(@p));
   Rename(f,Pchar(@p));
 End;
 End;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 
 
 
-Procedure Rename(var f : File;c : char);[IOCheck];
+Procedure Rename(var f:File;const p : PAnsiChar);[IOCheck];
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Begin
+  Rename(f,AnsiString(p));
+End;
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
 var
 var
-  p : array[0..1] Of Char;
+  len: SizeInt
+Begin
+  If InOutRes<>0 then
+    exit;
+  If FileRec(f).mode=fmClosed Then
+    Begin
+      Do_Rename(PFileTextRecChar(@FileRec(f).Name),p,false);
+      { check error code of do_rename }
+      If InOutRes=0 then
+        begin
+          len:=min(StrLen(p),high(FileRec(f).Name));
+          Move(p^,FileRec(f).Name,len);
+          FileRec(f).Name[len]:=#0;
+        end;
+    End;
+End;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
+
+
+Procedure Rename(var f:File;const c : AnsiChar);[IOCheck];
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Begin
+  Rename(f,AnsiString(c));
+End;
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
+var
+  p : array[0..1] Of AnsiChar;
 Begin
 Begin
-  If InOutRes <> 0 then
-   exit;
   p[0]:=c;
   p[0]:=c;
   p[1]:=#0;
   p[1]:=#0;
-  Rename(f,Pchar(@p));
+  Rename(f,PAnsiChar(@p));
 End;
 End;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 

+ 1 - 1
rtl/inc/filerec.inc

@@ -35,6 +35,6 @@ type
     RecSize   : SizeInt;
     RecSize   : SizeInt;
     _private  : array[1..3 * SizeOf(SizeInt) + 5 * SizeOf (pointer)] of byte;
     _private  : array[1..3 * SizeOf(SizeInt) + 5 * SizeOf (pointer)] of byte;
     UserData  : array[1..32] of byte;
     UserData  : array[1..32] of byte;
-    name      : array[0..filerecnamelength] of char;
+    name      : array[0..filerecnamelength] of TFileTextRecChar;
   End;
   End;
 
 

+ 1 - 1
rtl/inc/objects.pp

@@ -1389,7 +1389,7 @@ BEGIN
      Begin                        { Check status okay }
      Begin                        { Check status okay }
      If (Handle = InvalidHandle) Then
      If (Handle = InvalidHandle) Then
         Begin                      { File not open }
         Begin                      { File not open }
-          Assign(FileInfo,FName);
+          Assign(FileInfo,@FName);
           { Handle the mode }
           { Handle the mode }
           if OpenMode =stCreate then
           if OpenMode =stCreate then
             Begin
             Begin

+ 312 - 43
rtl/inc/system.inc

@@ -57,18 +57,6 @@ Const
                                 Local types
                                 Local types
 ****************************************************************************}
 ****************************************************************************}
 
 
-{
-  TextRec and FileRec are put in a separate file to make it available to other
-  units without putting it explicitly in systemh.
-  This way we keep TP compatibility, and the TextRec definition is available
-  for everyone who needs it.
-}
-{$ifdef FPC_HAS_FEATURE_FILEIO}
-{$i filerec.inc}
-{$endif FPC_HAS_FEATURE_FILEIO}
-
-{$i textrec.inc}
-
 {$ifdef FPC_HAS_FEATURE_EXITCODE}
 {$ifdef FPC_HAS_FEATURE_EXITCODE}
   {$ifdef FPC_OBJFPC_EXTENDED_IF}
   {$ifdef FPC_OBJFPC_EXTENDED_IF}
     {$if High(errorcode)<>maxExitCode}
     {$if High(errorcode)<>maxExitCode}
@@ -1430,13 +1418,49 @@ end;
 
 
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 { Allow slash and backslash as separators }
 { Allow slash and backslash as separators }
-procedure DoDirSeparators(p:Pchar);
+procedure DoDirSeparators(var p: pchar; inplace: boolean = true);
 var
 var
   i : longint;
   i : longint;
+  len : sizeint;
+  newp : pchar;
 begin
 begin
-  for i:=0 to strlen(p) do
+  len:=length(p);
+  newp:=nil;
+  for i:=0 to len do
     if p[i] in AllowDirectorySeparators then
     if p[i] in AllowDirectorySeparators then
-      p[i]:=DirectorySeparator;
+      begin
+        if not inplace and
+           not assigned(newp) then
+          begin
+            getmem(newp,len+1);
+            move(p^,newp^,len+1);
+            p:=newp;
+          end;
+        p[i]:=DirectorySeparator;
+      end;
+end;
+
+procedure DoDirSeparators(var p: pwidechar; inplace: boolean = true);
+var
+  i : longint;
+  len : sizeint;
+  newp : pwidechar;
+begin
+  len:=length(p);
+  newp:=nil;
+  for i:=0 to len do
+    if (ord(p[i])<255) and
+       (ansichar(ord(p[i])) in AllowDirectorySeparators) then
+      begin
+        if not inplace and
+           not assigned(newp) then
+          begin
+            getmem(newp,(len+1)*2);
+            move(p^,newp^,(len+1)*2);
+            p:=newp;
+          end;
+        p[i]:=DirectorySeparator;
+      end;
 end;
 end;
 
 
 procedure DoDirSeparators(var p:shortstring);
 procedure DoDirSeparators(var p:shortstring);
@@ -1447,11 +1471,129 @@ begin
     if p[i] in AllowDirectorySeparators then
     if p[i] in AllowDirectorySeparators then
       p[i]:=DirectorySeparator;
       p[i]:=DirectorySeparator;
 end;
 end;
+
+
+procedure DoDirSeparators(var ps:RawByteString);
+var
+  i : longint;
+  p : pchar;
+  unique : boolean;
+begin
+  unique:=false;
+  for i:=1 to length(ps) do
+    if ps[i] in AllowDirectorySeparators then
+      begin
+        if not unique then
+          begin
+            uniquestring(ps);
+            p:=pchar(ps);
+            unique:=true;
+          end;
+        p[i-1]:=DirectorySeparator;
+      end;
+end;
+
+procedure DoDirSeparators(var ps:UnicodeString);
+var
+  i : longint;
+  p : pwidechar;
+  unique : boolean;
+begin
+  unique:=false;
+  for i:=1 to length(ps) do
+    if ps[i] in AllowDirectorySeparators then
+      begin
+        if not unique then
+          begin
+            uniquestring(ps);
+            p:=pwidechar(ps);
+            unique:=true;
+          end;
+        p[i-1]:=DirectorySeparator;
+      end;
+end;
+
 {$endif FPC_HAS_FEATURE_FILEIO}
 {$endif FPC_HAS_FEATURE_FILEIO}
 
 
 { OS dependent low level file functions }
 { OS dependent low level file functions }
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 {$i sysfile.inc}
 {$i sysfile.inc}
+
+{$ifndef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+{$ifdef FPC_ANSI_TEXTFILEREC}
+procedure do_open(var f; p: pansichar; flags: longint; pchangeable: boolean);
+var
+  u: UnicodeString;
+begin
+  widestringmanager.Ansi2UnicodeMoveProc(p,DefaultFileSystemCodePage,u,length(p));
+  do_open(f,pwidechar(u),flags,true);
+end;
+
+procedure do_erase(p: pansichar; pchangeable: boolean);
+var
+  u: UnicodeString;
+begin
+  widestringmanager.Ansi2UnicodeMoveProc(p,DefaultFileSystemCodePage,u,length(p));
+  do_erase(pwidechar(u),true);
+end;
+
+procedure do_rename(src, dst: pansichar; srcchangeable, dstchangeable: boolean);
+var
+  usrc, udst: UnicodeString;
+begin
+  widestringmanager.Ansi2UnicodeMoveProc(src,DefaultFileSystemCodePage,usrc,length(src));
+  widestringmanager.Ansi2UnicodeMoveProc(dst,DefaultFileSystemCodePage,udst,length(dst));
+  do_rename(pwidechar(usrc),pwidechar(udst),true,true);
+end;
+
+procedure do_rename(src: pansichar; dst: pwidechar; srcchangeable, dstchangeable: boolean);
+var
+  usrc: UnicodeString;
+begin
+  widestringmanager.Ansi2UnicodeMoveProc(src,DefaultFileSystemCodePage,usrc,length(src));
+  do_rename(pwidechar(usrc),dst,true,dstchangeable);
+end;
+{$endif FPC_ANSI_TEXTFILEREC}
+{$endif not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+
+{$ifndef FPCRTL_FILESYSTEM_TWO_BYTE_API}
+{$ifndef FPC_ANSI_TEXTFILEREC}
+procedure do_open(var f; p: pwidechar; flags: longint; pchangeable: boolean);
+var
+  s: RawByteString;
+begin
+  widestringmanager.Unicode2AnsiMoveProc(p,s,DefaultFileSystemCodePage,length(p));
+  do_open(f,pansichar(s),flags,true);
+end;
+
+procedure do_erase(p: pwidechar; pchangeable: boolean);
+var
+  s: RawByteString;
+begin
+  widestringmanager.Unicode2AnsiMoveProc(p,s,DefaultFileSystemCodePage,length(p));
+  do_erase(pansichar(s),true);
+end;
+
+procedure do_rename(src, dst: pwidechar; srcchangeable, dstchangeable: boolean);
+var
+  rsrc, rdst: RawByteString;
+begin
+  widestringmanager.Unicode2AnsiMoveProc(src,rsrc,DefaultFileSystemCodePage,length(src));
+  widestringmanager.Unicode2AnsiMoveProc(dst,rdst,DefaultFileSystemCodePage,length(dst));
+  do_rename(pansichar(rsrc),pansichar(rdst),true,true);
+end;
+
+procedure do_rename(src: pwidechar; dst: pansichar; srcchangeable, dstchangeable: boolean);
+var
+  rsrc: RawByteString;
+begin
+  widestringmanager.Unicode2AnsiMoveProc(src,rsrc,DefaultFileSystemCodePage,length(src));
+  do_rename(pansichar(rsrc),dst,true,dstchangeable);
+end;
+{$endif not FPC_ANSI_TEXTFILEREC}
+{$endif not FPCRTL_FILESYSTEM_TWO_BYTE_API}
+
 {$endif FPC_HAS_FEATURE_FILEIO}
 {$endif FPC_HAS_FEATURE_FILEIO}
 
 
 { Text file }
 { Text file }
@@ -1473,55 +1615,182 @@ end;
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 { OS dependent dir functions }
 { OS dependent dir functions }
 {$i sysdir.inc}
 {$i sysdir.inc}
-{$endif FPC_HAS_FEATURE_FILEIO}
 
 
-{$if defined(FPC_HAS_FEATURE_FILEIO) and defined(FPC_HAS_FEATURE_ANSISTRINGS)}
-Procedure getdir(drivenr:byte;Var dir:ansistring);
-{ this is needed to also allow ansistrings, the shortstring version is
-  OS dependent }
+
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+
+{$ifndef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+procedure do_getdir(drivenr : byte;var dir : rawbytestring);
 var
 var
-  s : shortstring;
+  u: unicodestring;
 begin
 begin
-  getdir(drivenr,s);
-  dir:=s;
+  Do_getdir(drivenr,u);
+  widestringmanager.Unicode2AnsiMoveProc(pwidechar(u),dir,DefaultRTLFileSystemCodePage,length(u));
 end;
 end;
+{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+Procedure MkDir(Const s: RawByteString);[IOCheck];
+Begin
+  If (s='') or (InOutRes <> 0) then
+   exit;
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  Do_mkdir(ToSingleByteFileSystemEncodedFileName(S));
+{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  Do_mkdir(S);
 {$endif}
 {$endif}
+end;
 
 
-{$if defined(FPC_HAS_FEATURE_FILEIO)}
 
 
-Procedure MkDir(Const s: String);
-Var
-  Buffer: Array[0..255] of Char;
+Procedure RmDir(Const s: RawByteString);[IOCheck];
 Begin
 Begin
   If (s='') or (InOutRes <> 0) then
   If (s='') or (InOutRes <> 0) then
    exit;
    exit;
-  Move(s[1], Buffer, Length(s));
-  Buffer[Length(s)] := #0;
-  MkDir(@buffer[0],length(s));
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  Do_rmdir(ToSingleByteFileSystemEncodedFileName(S));
+{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  Do_rmdir(S);
+{$endif}
 End;
 End;
 
 
-Procedure RmDir(Const s: String);
-Var
-  Buffer: Array[0..255] of Char;
+
+Procedure ChDir(Const s: RawByteString);[IOCheck];
 Begin
 Begin
   If (s='') or (InOutRes <> 0) then
   If (s='') or (InOutRes <> 0) then
    exit;
    exit;
-  Move(s[1], Buffer, Length(s));
-  Buffer[Length(s)] := #0;
-  RmDir(@buffer[0],length(s));
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  Do_chdir(ToSingleByteFileSystemEncodedFileName(S));
+{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  Do_chdir(S);
+{$endif}
 End;
 End;
 
 
-Procedure ChDir(Const s: String);
-Var
-  Buffer: Array[0..255] of Char;
+
+Procedure getdir(drivenr:byte;Var dir:rawbytestring);
+begin
+  Do_getdir(drivenr,dir);
+  { we should return results in the DefaultRTLFileSystemCodePage -> convert if
+    necessary }
+  setcodepage(dir,DefaultRTLFileSystemCodePage,true);
+end;
+
+{ the generic shortstring ones are only implemented elsewhere for systems *not*
+  supporting ansi/unicodestrings; for now assume there are no systems that
+  support unicodestrings but not ansistrings }
+
+{ avoid double string conversions }
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+function GetDirStrFromShortstring(const s: shortstring): RawByteString;
+begin
+  GetDirStrFromShortstring:=ToSingleByteFileSystemEncodedFileName(ansistring(s));
+end;
+{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+function GetDirStrFromShortstring(const s: shortstring): UnicodeString;
+begin
+  GetDirStrFromShortstring:=s;
+end;
+{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+Procedure MkDir(Const s: shortstring);[IOCheck];
 Begin
 Begin
   If (s='') or (InOutRes <> 0) then
   If (s='') or (InOutRes <> 0) then
    exit;
    exit;
-  Move(s[1], Buffer, Length(s));
-  Buffer[Length(s)] := #0;
-  ChDir(@buffer[0],length(s));
+  Do_mkdir(GetDirStrFromShortstring(S));
 End;
 End;
-{$endif}
+
+
+Procedure RmDir(Const s: shortstring);[IOCheck];
+Begin
+  If (s='') or (InOutRes <> 0) then
+   exit;
+  Do_rmdir(GetDirStrFromShortstring(S));
+End;
+
+
+Procedure ChDir(Const s: shortstring);[IOCheck];
+Begin
+  If (s='') or (InOutRes <> 0) then
+   exit;
+  Do_chdir(GetDirStrFromShortstring(S));
+End;
+
+
+Procedure getdir(drivenr:byte;Var dir:shortstring);
+var
+  s: rawbytestring;
+begin
+  Do_getdir(drivenr,s);
+  if length(s)<=high(dir) then
+    dir:=s
+  else
+    inoutres:=3;
+end;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
+
+
+{$if defined(FPC_HAS_FEATURE_WIDESTRINGS)}
+
+{$ifndef FPCRTL_FILESYSTEM_TWO_BYTE_API}
+{ overloads required for mkdir/rmdir/chdir to ensure that the string is
+  converted to the right code page }
+procedure do_mkdir(const s: unicodestring); {$ifdef SYSTEMINLINE}inline;{$endif}
+begin
+  do_mkdir(ToSingleByteFileSystemEncodedFileName(s));
+end;
+
+
+procedure do_rmdir(const s: unicodestring); {$ifdef SYSTEMINLINE}inline;{$endif}
+begin
+  do_rmdir(ToSingleByteFileSystemEncodedFileName(s));
+end;
+
+
+procedure do_chdir(const s: unicodestring); {$ifdef SYSTEMINLINE}inline;{$endif}
+begin
+  do_chdir(ToSingleByteFileSystemEncodedFileName(s));
+end;
+
+
+procedure do_getdir(drivenr : byte;var dir : unicodestring);
+var
+  s: rawbytestring;
+begin
+  Do_getdir(drivenr,s);
+  dir:=s;
+end;
+{$endif FPCRTL_FILESYSTEM_TWO_BYTE_API}
+
+Procedure MkDir(Const s: UnicodeString);[IOCheck];
+Begin
+  if (s='') or (InOutRes <> 0) then
+   exit;
+  Do_mkdir(S);
+End;
+
+
+Procedure RmDir(Const s: UnicodeString);[IOCheck];
+Begin
+  if (s='') or (InOutRes <> 0) then
+   exit;
+  Do_rmdir(S);
+End;
+
+
+Procedure ChDir(Const s: UnicodeString);[IOCheck];
+Begin
+  if (s='') or (InOutRes <> 0) then
+   exit;
+  Do_chdir(S);
+End;
+
+
+Procedure getdir(drivenr:byte;Var dir:unicodestring);
+begin
+  Do_getdir(drivenr,dir);
+end;
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
+
+{$endif FPC_HAS_FEATURE_FILEIO}
+
 
 
 {*****************************************************************************
 {*****************************************************************************
                             Resources support
                             Resources support

+ 99 - 37
rtl/inc/systemh.inc

@@ -84,6 +84,17 @@
                          Global Types and Constants
                          Global Types and Constants
 ****************************************************************************}
 ****************************************************************************}
 
 
+{ some values which are used in RTL for TSystemCodePage type }
+const
+  CP_ACP     = 0;     // default to ANSI code page
+  CP_OEMCP   = 1;     // default to OEM (console) code page
+  CP_UTF16   = 1200;  // utf-16
+  CP_UTF16BE = 1201;  // unicodeFFFE
+  CP_UTF7    = 65000; // utf-7
+  CP_UTF8    = 65001; // utf-8
+  CP_ASCII   = 20127; // us-ascii
+  CP_NONE    = $FFFF; // rawbytestring encoding
+
 Type
 Type
   { The compiler has all integer types defined internally. Here
   { The compiler has all integer types defined internally. Here
     we define only aliases }
     we define only aliases }
@@ -380,17 +391,6 @@ Type
   PPChar              = ^PChar;
   PPChar              = ^PChar;
   PPPChar             = ^PPChar;
   PPPChar             = ^PPChar;
 
 
-{ some values which are used in RTL for TSystemCodePage type }
-const
-  CP_ACP     = 0;     // default to ANSI code page
-  CP_UTF16   = 1200;  // utf-16
-  CP_UTF16BE = 1201;  // unicodeFFFE
-  CP_UTF7    = 65000; // utf-7
-  CP_UTF8    = 65001; // utf-8
-  CP_ASCII   = 20127; // us-ascii
-  CP_NONE    = $FFFF; // rawbytestring encoding
-
-type
   { AnsiChar is equivalent of Char, so we need
   { AnsiChar is equivalent of Char, so we need
     to use type renamings }
     to use type renamings }
   TAnsiChar           = Char;
   TAnsiChar           = Char;
@@ -505,18 +505,39 @@ type
 
 
   TSystemCodePage     = Word;
   TSystemCodePage     = Word;
 
 
-  { Needed for fpc_get_output }
-  PText               = ^Text;
+{$ifdef VER2_6}
+  { the size of textrec/filerec is hardcoded in the 2.6 compiler binary }
+  {$define FPC_ANSI_TEXTFILEREC}
+{$endif}
+  TFileTextRecChar    = {$ifdef FPC_ANSI_TEXTFILEREC}AnsiChar{$else}UnicodeChar{$endif};
+  PFileTextRecChar    = ^TFileTextRecChar;
 
 
   TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR);
   TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR);
 
 
 { procedure type }
 { procedure type }
   TProcedure  = Procedure;
   TProcedure  = Procedure;
 
 
-{ platform dependent types }
+{ platform-dependent types }
 {$i sysosh.inc}
 {$i sysosh.inc}
 
 
+{ platform-dependent defines }
+{$i rtldefs.inc}
+
+{*****************************************************************************
+                   TextRec/FileRec exported to allow compiler to take size
+*****************************************************************************}
+
+{$ifdef FPC_HAS_FEATURE_FILEIO}
+{$i filerec.inc}
+{$endif FPC_HAS_FEATURE_FILEIO}
+
+{$i textrec.inc}
+
+
 type
 type
+  { Needed for fpc_get_output }
+  PText               = ^Text;
+
   TEntryInformation = record
   TEntryInformation = record
     InitFinalTable : Pointer;
     InitFinalTable : Pointer;
     ThreadvarTablesTable : Pointer;
     ThreadvarTablesTable : Pointer;
@@ -639,6 +660,13 @@ var
 
 
   DefaultSystemCodePage,
   DefaultSystemCodePage,
   DefaultUnicodeCodePage,
   DefaultUnicodeCodePage,
+  { the code page to use when sending paths/file names to OS file system API
+    calls using single byte strings, and to interpret the results gotten back
+    from such API calls }
+  DefaultFileSystemCodePage,
+  { the code page to use to return file names from single byte file system calls
+    in the RTL that return ansistrings (by default, same as a above) }
+  DefaultRTLFileSystemCodePage,
   UTF8CompareLocale : TSystemCodePage;
   UTF8CompareLocale : TSystemCodePage;
 
 
 
 
@@ -1066,6 +1094,8 @@ function StringElementSize(const S : RawByteString): Word; overload;
 function StringRefCount(const S : RawByteString): SizeInt; overload;
 function StringRefCount(const S : RawByteString): SizeInt; overload;
 procedure SetCodePage(var s : RawByteString; CodePage : TSystemCodePage; Convert : Boolean = True);
 procedure SetCodePage(var s : RawByteString; CodePage : TSystemCodePage; Convert : Boolean = True);
 procedure SetMultiByteConversionCodePage(CodePage: TSystemCodePage);
 procedure SetMultiByteConversionCodePage(CodePage: TSystemCodePage);
+procedure SetMultiByteFileSystemCodePage(CodePage: TSystemCodePage);
+procedure SetMultiByteRTLFileSystemCodePage(CodePage: TSystemCodePage);
 {$endif FPC_HAS_FEATURE_ANSISTRINGS}
 {$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 
 
 
@@ -1086,9 +1116,20 @@ procedure SetMultiByteConversionCodePage(CodePage: TSystemCodePage);
 ****************************************************************************}
 ****************************************************************************}
 
 
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 {$ifdef FPC_HAS_FEATURE_FILEIO}
-Procedure Assign(out f:File;const Name:string);
-Procedure Assign(out f:File;p:pchar);
-Procedure Assign(out f:File;c:char);
+Procedure Assign(out f:File;const Name: ShortString);
+Procedure Assign(out f:File;const p: PAnsiChar);
+Procedure Assign(out f:File;const c: AnsiChar);
+Procedure Rename(var f:File;const s : ShortString);
+Procedure Rename(var f:File;const p : PAnsiChar);
+Procedure Rename(var f:File;const c : AnsiChar);
+{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
+Procedure Assign(out f:File;const Name: UnicodeString);
+Procedure Rename(var f:File;const s : UnicodeString);
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Procedure Assign(out f:File;const Name: RawByteString);
+Procedure Rename(var f:File;const s : RawByteString);
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 Procedure Rewrite(var f:File;l:Longint);
 Procedure Rewrite(var f:File;l:Longint);
 Procedure Rewrite(var f:File);
 Procedure Rewrite(var f:File);
 Procedure Reset(var f:File;l:Longint);
 Procedure Reset(var f:File;l:Longint);
@@ -1111,9 +1152,6 @@ Function  FileSize(var f:File):Int64;
 Procedure Seek(var f:File;Pos:Int64);
 Procedure Seek(var f:File;Pos:Int64);
 Function  EOF(var f:File):Boolean;
 Function  EOF(var f:File):Boolean;
 Procedure Erase(var f:File);
 Procedure Erase(var f:File);
-Procedure Rename(var f:File;const s:string);
-Procedure Rename(var f:File;p:pchar);
-Procedure Rename(var f:File;c:char);
 Procedure Truncate (var F:File);
 Procedure Truncate (var F:File);
 {$endif FPC_HAS_FEATURE_FILEIO}
 {$endif FPC_HAS_FEATURE_FILEIO}
 
 
@@ -1123,9 +1161,15 @@ Procedure Truncate (var F:File);
 ****************************************************************************}
 ****************************************************************************}
 
 
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 {$ifdef FPC_HAS_FEATURE_FILEIO}
-Procedure Assign(out f:TypedFile;const Name:string);
-Procedure Assign(out f:TypedFile;p:pchar);
-Procedure Assign(out f:TypedFile;c:char);
+Procedure Assign(out f:TypedFile;const Name:shortstring);
+Procedure Assign(out f:TypedFile;const p:PAnsiChar);
+Procedure Assign(out f:TypedFile;const c:AnsiChar);
+{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
+Procedure Assign(out f:TypedFile;const Name:unicodestring);
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Procedure Assign(out f:TypedFile;const Name:rawbytestring);
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 Procedure Reset(var f : TypedFile);   [INTERNPROC: fpc_in_Reset_TypedFile];
 Procedure Reset(var f : TypedFile);   [INTERNPROC: fpc_in_Reset_TypedFile];
 Procedure Rewrite(var f : TypedFile); [INTERNPROC: fpc_in_Rewrite_TypedFile];
 Procedure Rewrite(var f : TypedFile); [INTERNPROC: fpc_in_Rewrite_TypedFile];
 {$endif FPC_HAS_FEATURE_FILEIO}
 {$endif FPC_HAS_FEATURE_FILEIO}
@@ -1135,18 +1179,26 @@ Procedure Rewrite(var f : TypedFile); [INTERNPROC: fpc_in_Rewrite_TypedFile];
 ****************************************************************************}
 ****************************************************************************}
 
 
 {$ifdef FPC_HAS_FEATURE_TEXTIO}
 {$ifdef FPC_HAS_FEATURE_TEXTIO}
-Procedure Assign(out t:Text;const s:string);
-Procedure Assign(out t:Text;p:pchar);
-Procedure Assign(out t:Text;c:char);
+Procedure Assign(out t:Text;const s:shortstring);
+Procedure Rename(var t:Text;const s:shortstring);
+Procedure Assign(out t:Text;const p:PAnsiChar);
+Procedure Rename(var t:Text;const p:PAnsiChar);
+Procedure Assign(out t:Text;const c:AnsiChar);
+Procedure Rename(var t:Text;const c:AnsiChar);
+{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
+Procedure Assign(out t:Text;const s:unicodestring);
+Procedure Rename(var t:Text;const s:unicodestring);
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Procedure Rename(var t:Text;const s:rawbytestring);
+Procedure Assign(out t:Text;const s:rawbytestring);
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 Procedure Close(var t:Text);
 Procedure Close(var t:Text);
 Procedure Rewrite(var t:Text);
 Procedure Rewrite(var t:Text);
 Procedure Reset(var t:Text);
 Procedure Reset(var t:Text);
 Procedure Append(var t:Text);
 Procedure Append(var t:Text);
 Procedure Flush(var t:Text);
 Procedure Flush(var t:Text);
 Procedure Erase(var t:Text);
 Procedure Erase(var t:Text);
-Procedure Rename(var t:Text;const s:string);
-Procedure Rename(var t:Text;p:pchar);
-Procedure Rename(var t:Text;c:char);
 Function  EOF(var t:Text):Boolean;
 Function  EOF(var t:Text):Boolean;
 Function  EOF:Boolean;
 Function  EOF:Boolean;
 Function  EOLn(var t:Text):Boolean;
 Function  EOLn(var t:Text):Boolean;
@@ -1166,19 +1218,29 @@ procedure SetTextCodePage(var T: Text; CodePage: TSystemCodePage);
                             Directory Management
                             Directory Management
 ****************************************************************************}
 ****************************************************************************}
 
 
-
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 {$ifdef FPC_HAS_FEATURE_FILEIO}
-Procedure chdir(const s:string); overload;
-Procedure mkdir(const s:string); overload;
-Procedure rmdir(const s:string); overload;
-// the pchar versions are exported via alias for use in objpas
-
-Procedure getdir(drivenr:byte;var dir:shortstring);
+Procedure chdir(const s:shortstring); overload;
+Procedure mkdir(const s:shortstring); overload;
+Procedure rmdir(const s:shortstring); overload;
+Procedure getdir(drivenr:byte;var dir:shortstring);overload;
 {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
 {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
-Procedure getdir(drivenr:byte;var dir:ansistring);
+Procedure chdir(const s:rawbytestring); overload;
+Procedure mkdir(const s:rawbytestring); overload;
+Procedure rmdir(const s:rawbytestring); overload;
+// defaultrtlfilesystemcodepage is returned here
+Procedure getdir(drivenr:byte;var dir: rawbytestring);overload;{$ifdef FPC_HAS_CPSTRING}rtlproc;{$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_FEATURE_ANSISTRINGS}
 {$endif FPC_HAS_FEATURE_ANSISTRINGS}
+{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
+Procedure chdir(const s:unicodestring); overload;
+Procedure mkdir(const s:unicodestring); overload;
+Procedure rmdir(const s:unicodestring); overload;
+Procedure getdir(drivenr:byte;var dir: unicodestring);overload;
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
+
 {$endif FPC_HAS_FEATURE_FILEIO}
 {$endif FPC_HAS_FEATURE_FILEIO}
 
 
+
+
 {*****************************************************************************
 {*****************************************************************************
                              Miscellaneous
                              Miscellaneous
 *****************************************************************************}
 *****************************************************************************}

+ 173 - 33
rtl/inc/text.inc

@@ -57,7 +57,7 @@ Begin
      exit;
      exit;
    end;
    end;
   End;
   End;
-  Do_Open(t,PChar(@t.Name),Flags);
+  Do_Open(t,PFileTextRecChar(@t.Name),Flags,False);
   t.CloseFunc:=@FileCloseFunc;
   t.CloseFunc:=@FileCloseFunc;
   t.FlushFunc:=nil;
   t.FlushFunc:=nil;
   if t.Mode=fmInput then
   if t.Mode=fmInput then
@@ -74,9 +74,9 @@ Begin
    end;
    end;
 End;
 End;
 
 
+Procedure InitText(Var t : Text);
 
 
-Procedure Assign(out t:Text;const s:String);
-Begin
+begin
   FillChar(t,SizeOf(TextRec),0);
   FillChar(t,SizeOf(TextRec),0);
 { only set things that are not zero }
 { only set things that are not zero }
   TextRec(t).Handle:=UnusedHandle;
   TextRec(t).Handle:=UnusedHandle;
@@ -89,20 +89,74 @@ Begin
     tlbsCRLF: TextRec(t).LineEnd := #13#10;
     tlbsCRLF: TextRec(t).LineEnd := #13#10;
     tlbsCR: TextRec(t).LineEnd := #13;
     tlbsCR: TextRec(t).LineEnd := #13;
   End;
   End;
-  Move(s[1],TextRec(t).Name,Length(s));
-End;
+end;
 
 
 
 
-Procedure Assign(out t:Text;p:pchar);
+{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
+Procedure Assign(out t:Text;const s : UnicodeString);
 begin
 begin
-  Assign(t,StrPas(p));
+  InitText(t);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  TextRec(t).Name:=ToSingleByteFileSystemEncodedFileName(S);
+{$else FPC_ANSI_TEXTFILEREC}
+  TextRec(t).Name:=S;
+{$endif FPC_ANSI_TEXTFILEREC}
+  { null terminate, since the name array is regularly used as p(wide)char }
+  TextRec(t).Name[high(TextRec(t).Name)]:=#0;
 end;
 end;
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
 
 
 
 
-Procedure Assign(out t:Text;c:char);
-begin
-  Assign(t,string(c));
-end;
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Procedure Assign(out t:Text;const s: RawByteString);
+Begin
+  InitText(t);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  { ensure the characters in the record's filename are encoded correctly }
+  TextRec(t).Name:=ToSingleByteFileSystemEncodedFileName(S);
+{$else FPC_ANSI_TEXTFILEREC}
+  TextRec(t).Name:=S;
+{$endif FPC_ANSI_TEXTFILEREC}
+  { null terminate, since the name array is regularly used as p(wide)char }
+  TextRec(t).Name[high(TextRec(t).Name)]:=#0;
+End;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
+
+
+Procedure Assign(out t:Text;const s: ShortString);
+Begin
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+  Assign(t,AnsiString(s));
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
+  InitText(t);
+  { warning: no encoding support }
+  TextRec(t).Name:=s;
+  { null terminate, since the name array is regularly used as p(wide)char }
+  TextRec(t).Name[high(TextRec(t).Name)]:=#0;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
+End;
+
+
+Procedure Assign(out t:Text;const p: PAnsiChar);
+Begin
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+  Assign(t,AnsiString(p));
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
+  { no use in making this the one that does the work, since the name field is
+    limited to 255 characters anyway }
+  Assign(t,strpas(p));
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
+End;
+
+
+Procedure Assign(out t:Text;const c: AnsiChar);
+Begin
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+  Assign(t,AnsiString(c));
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
+  Assign(t,ShortString(c));
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
+End;
 
 
 
 
 Procedure Close(var t : Text);[IOCheck];
 Procedure Close(var t : Text);[IOCheck];
@@ -148,8 +202,7 @@ Begin
   TextRec(t).bufend:=0;
   TextRec(t).bufend:=0;
   {$ifdef FPC_HAS_CPSTRING}
   {$ifdef FPC_HAS_CPSTRING}
   { if no codepage is yet assigned then assign default ansi codepage }
   { if no codepage is yet assigned then assign default ansi codepage }
-  if TextRec(t).CodePage=CP_ACP then
-    TextRec(t).CodePage:=DefaultSystemCodePage;
+  TextRec(t).CodePage:=TranslatePlaceholderCP(TextRec(t).CodePage);
   {$endif}
   {$endif}
   FileFunc(TextRec(t).OpenFunc)(TextRec(t));
   FileFunc(TextRec(t).OpenFunc)(TextRec(t));
   { reset the mode to closed when an error has occured }
   { reset the mode to closed when an error has occured }
@@ -205,47 +258,134 @@ Begin
   If InOutRes <> 0 then
   If InOutRes <> 0 then
    exit;
    exit;
   If TextRec(t).mode=fmClosed Then
   If TextRec(t).mode=fmClosed Then
-   Do_Erase(PChar(@TextRec(t).Name));
+   Do_Erase(PFileTextRecChar(@TextRec(t).Name),false);
 End;
 End;
 
 
 
 
-Procedure Rename(var t : text;p:pchar);[IOCheck];
+Procedure Rename(var t : Text;const s : unicodestring);[IOCheck];
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+var
+  fs: RawByteString;
+{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
 Begin
 Begin
-  If InOutRes <> 0 then
-   exit;
-  If TextRec(t).mode=fmClosed Then
-   Begin
-     Do_Rename(PChar(@TextRec(t).Name),p);
-     { check error code of do_rename }
-     If InOutRes = 0 then
-         Move(p^,TextRec(t).Name,StrLen(p)+1);
-   End;
+  If (InOutRes<>0) or
+     (TextRec(t).mode<>fmClosed) then
+    exit;
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  { it's slightly faster to convert the unicodestring here to rawbytestring
+    than doing it in do_rename(), because here we still know the length }
+  fs:=ToSingleByteFileSystemEncodedFileName(s);
+  Do_Rename(PFileTextRecChar(@TextRec(t).Name),PAnsiChar(fs),false,true);
+  If InOutRes=0 then
+     TextRec(t).Name:=fs
+{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  Do_Rename(PFileTextRecChar(@TextRec(t).Name),PUnicodeChar(S),false,false);
+  If InOutRes=0 then
+{$ifdef FPC_ANSI_TEXTTextRec}
+    TextRec(t).Name:=ToSingleByteFileSystemEncodedFileName(s);
+{$else FPC_ANSI_TEXTFILEREC}
+    TextRec(t).Name:=s
+{$endif FPC_ANSI_TEXTFILEREC}
+{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
 End;
 End;
 
 
 
 
-Procedure Rename(var t : Text;const s : string);[IOCheck];
+Procedure Rename(var t : Text;const s : rawbytestring);[IOCheck];
+var
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  fs: RawByteString;
+  pdst: PAnsiChar;
+{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  fs: UnicodeString;
+  pdst: PUnicodeChar;
+{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  dstchangeable: boolean;
+Begin
+  If (InOutRes<>0) or
+     (TextRec(t).mode<>fmClosed) then
+    exit;
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  dstchangeable:=false;
+  pdst:=PAnsiChar(s);
+  if StringCodePage(s)<>DefaultFileSystemCodePage then
+    begin
+      fs:=ToSingleByteFileSystemEncodedFileName(s);
+      pdst:=PAnsiChar(fs);
+      dstchangeable:=true;
+    end
+  else
+    fs:=s;
+{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+   { it's slightly faster to convert the rawbytestring here to unicodestring
+     than doing it in do_rename, because here we still know the length }
+   fs:=unicodestring(s);
+   pdst:=PUnicodeChar(fs);
+   dstchangeable:=true;
+{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  Do_Rename(PFileTextRecChar(@TextRec(t).Name),pdst,false,dstchangeable);
+  If InOutRes=0 then
+{$if defined(FPC_ANSI_TEXTTextRec) and not defined(FPCRTL_FILESYSTEM_SINGLE_BYTE_API)}
+    TextRec(t).Name:=ToSingleByteFileSystemEncodedFileName(fs)
+{$else FPC_ANSI_TEXTTextRec and not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+    TextRec(t).Name:=fs
+{$endif FPC_ANSI_TEXTTextRec and not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+End;
+
+
+Procedure Rename(var t : Text;const s : ShortString);[IOCheck];
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Begin
+  Rename(t,AnsiString(s));
+End;
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
 var
 var
   p : array[0..255] Of Char;
   p : array[0..255] Of Char;
 Begin
 Begin
-  If InOutRes <> 0 then
-   exit;
   Move(s[1],p,Length(s));
   Move(s[1],p,Length(s));
   p[Length(s)]:=#0;
   p[Length(s)]:=#0;
   Rename(t,Pchar(@p));
   Rename(t,Pchar(@p));
 End;
 End;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 
+Procedure Rename(var t:Text;const p:PAnsiChar);
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Begin
+  Rename(t,AnsiString(p));
+End;
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
+var
+  len: SizeInt
+Begin
+  If InOutRes<>0 then
+    exit;
+  If TextRec(t).mode=fmClosed Then
+    Begin
+      Do_Rename(PFileTextRecChar(@TextRec(t).Name),p,false);
+      { check error code of do_rename }
+      If InOutRes=0 then
+        begin
+          len:=min(StrLen(p),high(TextRec(t).Name));
+          Move(p^,TextRec(t).Name,len);
+          TextRec(t).Name[len]:=#0;
+        end;
+    End;
+End;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 
-Procedure Rename(var t : Text;c : char);[IOCheck];
+Procedure Rename(var t : Text;const c : AnsiChar);[IOCheck];
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Begin
+  Rename(t,AnsiString(c));
+End;
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
 var
 var
-  p : array[0..1] Of Char;
+  p : array[0..1] Of AnsiChar;
 Begin
 Begin
-  If InOutRes <> 0 then
-   exit;
   p[0]:=c;
   p[0]:=c;
   p[1]:=#0;
   p[1]:=#0;
-  Rename(t,Pchar(@p));
+  Rename(t,PAnsiChar(@p));
 End;
 End;
-
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 
 Function Eof(Var t: Text): Boolean;[IOCheck];
 Function Eof(Var t: Text): Boolean;[IOCheck];
 Begin
 Begin

+ 4 - 2
rtl/inc/textrec.inc

@@ -29,7 +29,9 @@ const
 {$endif CPUAVR}
 {$endif CPUAVR}
 type
 type
   TLineEndStr = string [3];
   TLineEndStr = string [3];
-  TextBuf = array[0..TextRecBufSize-1] of char;
+  TextBuf = array[0..TextRecBufSize-1] of ansichar;
+  TTextBuf = TextBuf;
+
   { using packed makes the compiler to generate ugly code on some CPUs, further
   { using packed makes the compiler to generate ugly code on some CPUs, further
     using packed causes the compiler to handle arrays of text wrongly, see  see tw0754 e.g. on arm  }
     using packed causes the compiler to handle arrays of text wrongly, see  see tw0754 e.g. on arm  }
   TextRec = {$ifdef VER2_6} packed {$endif} Record
   TextRec = {$ifdef VER2_6} packed {$endif} Record
@@ -45,7 +47,7 @@ type
     flushfunc,
     flushfunc,
     closefunc : codepointer;
     closefunc : codepointer;
     UserData  : array[1..32] of byte;
     UserData  : array[1..32] of byte;
-    name      : array[0..textrecnamelength-1] of char;
+    name      : array[0..textrecnamelength-1] of TFileTextRecChar;
     LineEnd   : TLineEndStr;
     LineEnd   : TLineEndStr;
     buffer    : textbuf;
     buffer    : textbuf;
 {$ifdef FPC_HAS_CPSTRING}
 {$ifdef FPC_HAS_CPSTRING}

+ 24 - 16
rtl/inc/typefile.inc

@@ -15,48 +15,56 @@
                     subroutines for typed file handling
                     subroutines for typed file handling
 ****************************************************************************}
 ****************************************************************************}
 
 
-Procedure Assign(out f:TypedFile;const Name:string);
+{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
+Procedure Assign(out f:TypedFile;const Name: UnicodeString);
 {
 {
   Assign Name to file f so it can be used with the file routines
   Assign Name to file f so it can be used with the file routines
 }
 }
 Begin
 Begin
-  FillChar(f,SizeOF(FileRec),0);
-  FileRec(f).Handle:=UnusedHandle;
-  FileRec(f).mode:=fmClosed;
-  Move(Name[1],FileRec(f).Name,Length(Name));
+  Assign(UnTypedFile(f),Name);
 End;
 End;
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
 
 
 
 
-Procedure Assign(out f:TypedFile;p:pchar);
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Procedure Assign(out f:TypedFile;const Name: RawByteString);
 {
 {
   Assign Name to file f so it can be used with the file routines
   Assign Name to file f so it can be used with the file routines
 }
 }
-begin
-  Assign(f,StrPas(p));
-end;
+Begin
+  Assign(UnTypedFile(f),Name);
+End;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 
 
 
-Procedure Assign(out f:TypedFile;c:char);
+Procedure Assign(out f:TypedFile;const Name: ShortString);
 {
 {
   Assign Name to file f so it can be used with the file routines
   Assign Name to file f so it can be used with the file routines
 }
 }
-begin
-  Assign(f,string(c));
+Begin
+  Assign(UnTypedFile(f),Name);
+End;
+
+
+Procedure Assign(out f:TypedFile;const p:PAnsiChar);
+Begin
+  Assign(UnTypedFile(f),p);
 end;
 end;
 
 
 
 
+Procedure Assign(out f:TypedFile;const c:AnsiChar);
+Begin
+  Assign(UnTypedFile(f),c);
+end;
+
 Procedure fpc_reset_typed(var f : TypedFile;Size : Longint);[Public,IOCheck, Alias:'FPC_RESET_TYPED']; compilerproc;
 Procedure fpc_reset_typed(var f : TypedFile;Size : Longint);[Public,IOCheck, Alias:'FPC_RESET_TYPED']; compilerproc;
 Begin
 Begin
-  If InOutRes <> 0 then
-   exit;
   Reset(UnTypedFile(f),Size);
   Reset(UnTypedFile(f),Size);
 End;
 End;
 
 
 
 
 Procedure fpc_rewrite_typed(var f : TypedFile;Size : Longint);[Public,IOCheck, Alias:'FPC_REWRITE_TYPED']; compilerproc;
 Procedure fpc_rewrite_typed(var f : TypedFile;Size : Longint);[Public,IOCheck, Alias:'FPC_REWRITE_TYPED']; compilerproc;
 Begin
 Begin
-  If InOutRes <> 0 then
-   exit;
   Rewrite(UnTypedFile(f),Size);
   Rewrite(UnTypedFile(f),Size);
 End;
 End;
 
 

+ 8 - 3
rtl/inc/ustringh.inc

@@ -53,9 +53,10 @@ procedure DefaultAnsi2UnicodeMove(source:pchar;cp : TSystemCodePage;var dest:uni
 
 
 Type
 Type
   TStandardCodePageEnum = (
   TStandardCodePageEnum = (
-    scpAnsi,          // system Ansi code page (GetACP on windows)
-    scpConsoleInput,  // system console input code page (GetConsoleCP on windows)
-    scpConsoleOutput  // system console output code page (GetConsoleOutputCP on windows)
+    scpAnsi,                 // system Ansi code page (GetACP on windows)
+    scpConsoleInput,         // system console input code page (GetConsoleCP on windows)
+    scpConsoleOutput,        // system console output code page (GetConsoleOutputCP on windows)
+    scpFileSystemSingleByte  // file system code page used by single byte OS FileSystem APIs (GetACP on Windows),
   );
   );
 
 
 {$ifndef FPC_HAS_BUILTIN_WIDESTR_MANAGER}
 {$ifndef FPC_HAS_BUILTIN_WIDESTR_MANAGER}
@@ -144,3 +145,7 @@ Procedure SetUnicodeStringManager (Const New : TUnicodeStringManager; Var Old: T
 function StringElementSize(const S : UnicodeString): Word; overload;
 function StringElementSize(const S : UnicodeString): Word; overload;
 function StringRefCount(const S : UnicodeString): SizeInt; overload;
 function StringRefCount(const S : UnicodeString): SizeInt; overload;
 function StringCodePage(const S : UnicodeString): TSystemCodePage; overload;
 function StringCodePage(const S : UnicodeString): TSystemCodePage; overload;
+
+Function ToSingleByteFileSystemEncodedFileName(const Str: UnicodeString): RawByteString;
+Function ToSingleByteFileSystemEncodedFileName(const arr: array of widechar): RawByteString;
+Function ToSingleByteFileSystemEncodedFileName(const Str: RawByteString): RawByteString;

+ 50 - 15
rtl/inc/ustrings.inc

@@ -70,7 +70,7 @@ begin
   setlength(dest,len);
   setlength(dest,len);
   if not assigned(pointer(dest)) then
   if not assigned(pointer(dest)) then
     exit;
     exit;
-  PAnsiRec(dest)^.CodePage:=cp;
+  SetCodePage(dest,cp,false);
   p:=pointer(dest);         {SetLength guarantees that dest is unique}
   p:=pointer(dest);         {SetLength guarantees that dest is unique}
   for i:=1 to len do
   for i:=1 to len do
     begin
     begin
@@ -124,7 +124,13 @@ function DefaultCodePointLength(const Str: PChar; MaxLookAead: PtrInt): Ptrint;
 function DefaultGetStandardCodePage(const stdcp: TStandardCodePageEnum): TSystemCodePage;
 function DefaultGetStandardCodePage(const stdcp: TStandardCodePageEnum): TSystemCodePage;
   begin
   begin
     { don't raise an exception here. We need this for text file handling }
     { don't raise an exception here. We need this for text file handling }
-    Result:=DefaultSystemCodePage;
+    if stdcp<>scpFileSystemSingleByte then
+      Result:=DefaultSystemCodePage
+    else
+      { we could return UTF-8 here in case of FPCRTL_FILESYSTEM_UTF8, but
+        without a fully functional widestring manager that will probably cause
+        more problems that it solves }
+      Result:=DefaultFileSystemCodePage
   end;
   end;
 
 
 Procedure GetUnicodeStringManager (Var Manager : TUnicodeStringManager);
 Procedure GetUnicodeStringManager (Var Manager : TUnicodeStringManager);
@@ -306,8 +312,7 @@ begin
   Size:=Length(S2);
   Size:=Length(S2);
   if Size>0 then
   if Size>0 then
   begin
   begin
-    if (cp=CP_ACP) then
-      cp:=DefaultSystemCodePage;
+    cp:=TranslatePlaceholderCP(cp);
     widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(Pointer(S2)),result,cp,Size);
     widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(Pointer(S2)),result,cp,Size);
   end;
   end;
 end;
 end;
@@ -328,9 +333,7 @@ begin
   Size:=Length(S2);
   Size:=Length(S2);
   if Size>0 then
   if Size>0 then
   begin
   begin
-    cp:=StringCodePage(S2);
-    if (cp=CP_ACP) then
-      cp:=DefaultSystemCodePage;
+    cp:=TranslatePlaceholderCP(StringCodePage(S2));
     widestringmanager.Ansi2UnicodeMoveProc(PChar(S2),cp,result,Size);
     widestringmanager.Ansi2UnicodeMoveProc(PChar(S2),cp,result,Size);
   end;
   end;
 end;
 end;
@@ -595,7 +598,11 @@ end;
 
 
 {$ifndef FPC_HAS_UCHAR_TO_SHORTSTR}
 {$ifndef FPC_HAS_UCHAR_TO_SHORTSTR}
 {$define FPC_HAS_UCHAR_TO_SHORTSTR}
 {$define FPC_HAS_UCHAR_TO_SHORTSTR}
-procedure fpc_UChar_To_ShortStr(out res : shortstring;const c : WideChar) compilerproc;
+{$ifdef VER2_6}
+procedure fpc_UChar_To_ShortStr(out result : shortstring;const c : WideChar); compilerproc;
+{$else}
+function fpc_UChar_To_ShortStr(const c : WideChar): shortstring; compilerproc;
+{$endif}
 {
 {
   Converts a WideChar to a ShortString;
   Converts a WideChar to a ShortString;
 }
 }
@@ -603,7 +610,7 @@ var
   s: ansistring;
   s: ansistring;
 begin
 begin
   widestringmanager.Wide2AnsiMoveProc(@c,s,DefaultSystemCodePage,1);
   widestringmanager.Wide2AnsiMoveProc(@c,s,DefaultSystemCodePage,1);
-  res:=s;
+  result:=s;
 end;
 end;
 {$endif FPC_HAS_UCHAR_TO_SHORTSTR}
 {$endif FPC_HAS_UCHAR_TO_SHORTSTR}
 
 
@@ -635,8 +642,7 @@ begin
 {$ifndef FPC_HAS_CPSTRING}
 {$ifndef FPC_HAS_CPSTRING}
   cp:=DefaultSystemCodePage;
   cp:=DefaultSystemCodePage;
 {$endif FPC_HAS_CPSTRING}     
 {$endif FPC_HAS_CPSTRING}     
-  if (cp=CP_ACP) then
-    cp:=DefaultSystemCodePage;
+  cp:=TranslatePlaceholderCP(cp);
   widestringmanager.Unicode2AnsiMoveProc(@c, fpc_UChar_To_AnsiStr, cp, 1);
   widestringmanager.Unicode2AnsiMoveProc(@c, fpc_UChar_To_AnsiStr, cp, 1);
 end;
 end;
 {$endif FPC_HAS_UCHAR_TO_ANSISTR}
 {$endif FPC_HAS_UCHAR_TO_ANSISTR}
@@ -943,14 +949,18 @@ Procedure fpc_UnicodeStr_SetLength(Var S : UnicodeString; l : SizeInt);[Public,A
 Var
 Var
   Temp : Pointer;
   Temp : Pointer;
   movelen: SizeInt;
   movelen: SizeInt;
-  lens, lena : SizeUInt;
+  nl,lens, lena : SizeUInt;
 begin
 begin
+  nl:=l;
+{$IFDEF VER2_6}
+  nl:=nl*2;
+{$ENDIF}
    if (l>0) then
    if (l>0) then
     begin
     begin
       if Pointer(S)=nil then
       if Pointer(S)=nil then
         begin
         begin
           { Need a complete new string...}
           { Need a complete new string...}
-          Pointer(s):=NewUnicodeString(l);
+          Pointer(s):=NewUnicodeString(nl);
         end
         end
       else
       else
         if (PUnicodeRec(Pointer(S)-UnicodeFirstOff)^.Ref = 1) then
         if (PUnicodeRec(Pointer(S)-UnicodeFirstOff)^.Ref = 1) then
@@ -967,7 +977,7 @@ begin
       else
       else
         begin
         begin
           { Reallocation is needed... }
           { Reallocation is needed... }
-          Temp:=NewUnicodeString(L);
+          Temp:=NewUnicodeString(nL);
           if Length(S)>0 then
           if Length(S)>0 then
             begin
             begin
               if l < succ(length(s)) then
               if l < succ(length(s)) then
@@ -982,7 +992,7 @@ begin
         end;
         end;
       { Force nil termination in case it gets shorter }
       { Force nil termination in case it gets shorter }
       PWord(Pointer(S)+l*sizeof(UnicodeChar))^:=0;
       PWord(Pointer(S)+l*sizeof(UnicodeChar))^:=0;
-      PUnicodeRec(Pointer(S)-UnicodeFirstOff)^.Len:=l;
+      PUnicodeRec(Pointer(S)-UnicodeFirstOff)^.Len:=nl;
     end
     end
   else  { length=0, deallocate the string }
   else  { length=0, deallocate the string }
     fpc_unicodestr_decr_ref (Pointer(S));
     fpc_unicodestr_decr_ref (Pointer(S));
@@ -2275,3 +2285,28 @@ procedure initunicodestringmanager;
   end;
   end;
 {$endif FPC_HAS_BUILTIN_WIDESTR_MANAGER}
 {$endif FPC_HAS_BUILTIN_WIDESTR_MANAGER}
 
 
+
+{$ifndef FPC_HAS_TOSINGLEBYTEFILESYSTEMENCODEDFILENAME_UNICODESTRING}
+{$define FPC_HAS_TOSINGLEBYTEFILESYSTEMENCODEDFILENAME_UNICODESTRING}
+Function ToSingleByteFileSystemEncodedFileName(const Str: UnicodeString): RawByteString;
+Begin
+  widestringmanager.Unicode2AnsiMoveProc(punicodechar(Str),Result,
+    DefaultFileSystemCodePage,Length(Str));
+End;
+{$endif FPC_HAS_TOSINGLEBYTEFILESYSTEMENCODEDFILENAME_UNICODESTRING}
+
+
+{$ifndef FPC_HAS_TOSINGLEBYTEFILESYSTEMENCODEDFILENAME_UNICODECHARARRAY}
+{$define FPC_HAS_TOSINGLEBYTEFILESYSTEMENCODEDFILENAME_UNICODECHARARRAY}
+Function ToSingleByteFileSystemEncodedFileName(const arr: array of widechar): RawByteString;
+Begin
+  widestringmanager.Unicode2AnsiMoveProc(@arr[0],Result,
+    DefaultFileSystemCodePage,length(pwidechar(@arr[0])));
+End;
+{$endif FPC_HAS_TOSINGLEBYTEFILESYSTEMENCODEDFILENAME_UNICODECHARARRAY}
+
+Function ToSingleByteFileSystemEncodedFileName(const Str: RawByteString): RawByteString;
+Begin
+  Result:=Str;
+  SetCodePage(Result,DefaultFileSystemCodePage,True);
+End;

+ 24 - 0
rtl/inc/uuchar.pp

@@ -21,7 +21,31 @@ interface
     char = widechar;
     char = widechar;
     pchar = pwidechar;
     pchar = pwidechar;
 
 
+
+{$ifdef FPC_HAS_FEATURE_COMMANDARGS}
+Function ParamStr(Param: Longint): UnicodeString;
+{$endif FPC_HAS_FEATURE_COMMANDARGS}
+
 implementation
 implementation
 
 
+{$ifdef FPC_HAS_FEATURE_COMMANDARGS}
+Function ParamStr(Param: Longint): UnicodeString;
+  begin
+  {
+    Paramstr(0) should return the name of the binary.
+    Since this functionality is included in the system unit,
+    we fetch it from there.
+    Normally, pathnames are less than 255 chars anyway,
+    so this will work correct in 99% of all cases.
+    In time, the system unit should get a GetExeName call.
+  }
+    if (Param=0) then
+      Paramstr:=System.Paramstr(0)
+    else if (Param>0) and (Param<argc) then
+      paramstr:=UnicodeString(Argv[Param])
+    else
+      paramstr:='';
+  end;
+{$endif FPC_HAS_FEATURE_COMMANDARGS}
 
 
 end.
 end.

+ 2 - 5
rtl/inc/wstrings.inc

@@ -194,8 +194,7 @@ begin
   Size:=Length(S2);
   Size:=Length(S2);
   if Size>0 then
   if Size>0 then
   begin
   begin
-    if (cp=CP_ACP) then
-      cp:=DefaultSystemCodePage;
+    cp:=TranslatePlaceholderCP(cp);
     widestringmanager.Wide2AnsiMoveProc(PWideChar(Pointer(S2)),result,cp,Size);
     widestringmanager.Wide2AnsiMoveProc(PWideChar(Pointer(S2)),result,cp,Size);
   end;
   end;
 end;
 end;
@@ -213,9 +212,7 @@ begin
   Size:=Length(S2);
   Size:=Length(S2);
   if Size>0 then
   if Size>0 then
   begin
   begin
-    cp:=StringCodePage(S2);
-    if (cp=CP_ACP) then
-      cp:=DefaultSystemCodePage;
+    cp:=TranslatePlaceholderCP(StringCodePage(S2));
     widestringmanager.Ansi2WideMoveProc(PChar(S2),cp,result,Size);
     widestringmanager.Ansi2WideMoveProc(PChar(S2),cp,result,Size);
   end;
   end;
 end;
 end;

+ 73 - 55
rtl/java/jastrings.inc

@@ -17,6 +17,18 @@
 { This will release some functions for special shortstring support }
 { This will release some functions for special shortstring support }
 { define EXTRAANSISHORT}
 { define EXTRAANSISHORT}
 
 
+{$define FPC_HAS_TRANSLATEPLACEHOLDERCP}
+function TranslatePlaceholderCP(cp: TSystemCodePage): TSystemCodePage; {$ifdef SYSTEMINLINE}inline;{$endif}
+begin
+  TranslatePlaceholderCP:=cp;
+  case cp of
+    CP_OEMCP,
+    CP_ACP:
+      TranslatePlaceholderCP:=DefaultSystemCodePage;
+  end;
+end;
+
+
 constructor AnsistringClass.Create(len: longint; cp: TSystemCodePage);
 constructor AnsistringClass.Create(len: longint; cp: TSystemCodePage);
 begin
 begin
   fElementSize:=1;
   fElementSize:=1;
@@ -146,7 +158,7 @@ end;
 
 
 function AnsistringClass.toUnicodeString: unicodestring;
 function AnsistringClass.toUnicodeString: unicodestring;
 begin
 begin
-  widestringmanager.Ansi2UnicodeMoveProc(pchar(fdata),fCodePage,result,system.length(fdata)-1);
+  widestringmanager.Ansi2UnicodeMoveProc(pchar(fdata),TranslatePlaceholderCP(fCodePage),result,system.length(fdata)-1);
 end;
 end;
 
 
 
 
@@ -302,11 +314,8 @@ begin
   Size:=Length(S);
   Size:=Length(S);
   if Size>0 then
   if Size>0 then
     begin
     begin
-      if (cp=CP_ACP) then
-        cp:=DefaultSystemCodePage;
-      orgcp:=StringCodePage(S);
-      if (orgcp=CP_ACP) then
-        orgcp:=DefaultSystemCodePage;
+      cp:=TranslatePlaceholderCP(cp);
+      orgcp:=TranslatePlaceholderCP(StringCodePage(S));
       if (orgcp=cp) or (orgcp=CP_NONE) then
       if (orgcp=cp) or (orgcp=CP_NONE) then
         begin
         begin
           result:=RawByteString(AnsistringClass.Create(S,cp));
           result:=RawByteString(AnsistringClass.Create(S,cp));
@@ -325,16 +334,17 @@ Function fpc_AnsiStr_To_AnsiStr (const S : RawByteString;cp : TSystemCodePage):
 {$define FPC_HAS_ANSISTR_CONCAT_MULTI}
 {$define FPC_HAS_ANSISTR_CONCAT_MULTI}
 procedure fpc_AnsiStr_Concat_multi (var DestS:RawByteString;const sarr:array of RawByteString{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}); compilerproc;
 procedure fpc_AnsiStr_Concat_multi (var DestS:RawByteString;const sarr:array of RawByteString{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}); compilerproc;
 Var
 Var
-  lowstart,i  : Longint;
+  lowstart,
+  nonemptystart,
+  i           : Longint;
   p           : pointer;
   p           : pointer;
   Size,NewLen,
   Size,NewLen,
   OldDestLen  : SizeInt;
   OldDestLen  : SizeInt;
   destcopy    : RawByteString;
   destcopy    : RawByteString;
-  DestCP      : TSystemCodePage;
   U           : UnicodeString;
   U           : UnicodeString;
-  sameCP      : Boolean;
-  tmpStr      : RawByteString;
+  DestCP      : TSystemCodePage;
   tmpCP       : TSystemCodePage;
   tmpCP       : TSystemCodePage;
+  sameCP      : Boolean;
 begin
 begin
   if high(sarr)=0 then
   if high(sarr)=0 then
     begin
     begin
@@ -342,23 +352,26 @@ begin
       exit;
       exit;
     end;
     end;
 {$ifdef FPC_HAS_CPSTRING}
 {$ifdef FPC_HAS_CPSTRING}
-  if (Pointer(DestS)=nil) then
-    DestCP:=cp
-  else
-    DestCP:=StringCodePage(DestS);
+  DestCP:=cp;
+  if DestCp=CP_NONE then
+    DestCP:=DefaultSystemCodePage;
 {$else FPC_HAS_CPSTRING}
 {$else FPC_HAS_CPSTRING}
   DestCP:=StringCodePage(DestS);
   DestCP:=StringCodePage(DestS);
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
-  if (DestCP=CP_ACP) then
-    DestCP:=DefaultSystemCodePage;
+  DestCP:=TranslatePlaceholderCP(DestCP);
   sameCP:=true;
   sameCP:=true;
   lowstart:=low(sarr);
   lowstart:=low(sarr);
-  for i:=lowstart to high(sarr) do
+  { skip empty strings }
+  while (lowstart<=high(sarr)) and
+        (sarr[lowstart]='') do
+    inc(lowstart);
+  tmpCP:=TranslatePlaceholderCP(StringCodePage(sarr[lowstart]));
+  for i:=lowstart+1 to high(sarr) do
     begin
     begin
-      tmpCP:=StringCodePage(sarr[i]);
-      if tmpCP=CP_ACP then
-        tmpCP:=DefaultSystemCodePage;
-      if (DestCP<>tmpCp) then
+      { ignore the code page of empty strings, it will always be
+        DefaultSystemCodePage but it doesn't matter for the outcome }
+      if (sarr[i]<>'') and
+         (tmpCP<>TranslatePlaceholderCP(StringCodePage(sarr[i]))) then
         begin
         begin
           sameCP:=false;
           sameCP:=false;
           break;
           break;
@@ -367,43 +380,44 @@ begin
   if not sameCP then
   if not sameCP then
     begin
     begin
       U:='';
       U:='';
-      for i:=lowstart to high(sarr) do begin
-        tmpCP:=StringCodePage(sarr[i]);
-        if (tmpCP=CP_ACP) then
-          begin
-            tmpStr:=sarr[i];
-            SetCodePage(tmpStr,DefaultSystemCodePage,False);
-            U:=U+UnicodeString(tmpStr);
-          end
-        else
+      for i:=lowstart to high(sarr) do
+        if sarr[i]<>'' then
           U:=U+UnicodeString(sarr[i]);
           U:=U+UnicodeString(sarr[i]);
-      end;
 
 
       DestS:='';
       DestS:='';
       widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(JLString(U).toCharArray),DestS,DestCP,Length(U));
       widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(JLString(U).toCharArray),DestS,DestCP,Length(U));
       exit;
       exit;
     end;
     end;
-
-  lowstart:=low(sarr);
-  if Pointer(DestS)=Pointer(sarr[lowstart]) then
-    inc(lowstart);
+  {$ifdef FPC_HAS_CPSTRING}
+    { if the result is rawbytestring and all strings have the same code page,
+      keep that code page }
+    if cp=CP_NONE then
+      DestCP:=tmpCP;
+  {$endif FPC_HAS_CPSTRING}
+
+  nonemptystart:=lowstart;
   { Check for another reuse, then we can't use
   { Check for another reuse, then we can't use
     the append optimization }
     the append optimization }
-  for i:=lowstart to high(sarr) do
+  if DestS<>'' then
     begin
     begin
-      if Pointer(DestS)=Pointer(sarr[i]) then
+      if Pointer(DestS)=Pointer(sarr[lowstart]) then
+        inc(lowstart);
+      for i:=lowstart to high(sarr) do
         begin
         begin
-          { if DestS is used somewhere in the middle of the expression,
-            we need to make sure the original string still exists after
-            we empty/modify DestS -- not necessary on JVM platform, ansistrings
-            are not explicitly refrence counted there }
-          lowstart:=low(sarr);
-          break;
+          if Pointer(DestS)=Pointer(sarr[i]) then
+            begin
+              { if DestS is used somewhere in the middle of the expression,
+                we need to make sure the original string still exists after
+                we empty/modify DestS -- not necessary on JVM platform, ansistrings
+                are not explicitly refrence counted there }
+              lowstart:=nonemptystart;
+              break;
+            end;
         end;
         end;
     end;
     end;
   { Start with empty DestS if we start with concatting
   { Start with empty DestS if we start with concatting
-    the first array element }
-  if lowstart=low(sarr) then
+    the first (non-empty) array element }
+  if lowstart=nonemptystart then
     DestS:='';
     DestS:='';
   OldDestLen:=length(DestS);
   OldDestLen:=length(DestS);
   { Calculate size of the result so we can do
   { Calculate size of the result so we can do
@@ -412,8 +426,6 @@ begin
   for i:=low(sarr) to high(sarr) do
   for i:=low(sarr) to high(sarr) do
     inc(NewLen,length(sarr[i]));
     inc(NewLen,length(sarr[i]));
   SetLength(DestS,NewLen);
   SetLength(DestS,NewLen);
-  if (StringCodePage(DestS) <> DestCP) then
-    SetCodePage(DestS,DestCP,False);
   { Concat all strings, except the string we already
   { Concat all strings, except the string we already
     copied in DestS }
     copied in DestS }
   NewLen:=OldDestLen;
   NewLen:=OldDestLen;
@@ -427,6 +439,11 @@ begin
           inc(NewLen,size);
           inc(NewLen,size);
         end;
         end;
     end;
     end;
+  if NewLen<>0 then
+    begin
+      SetCodePage(DestS,tmpCP,False);
+      SetCodePage(DestS,DestCP,True);
+    end;
 end;
 end;
 
 
 
 
@@ -468,8 +485,7 @@ begin
   if L > 0 then
   if L > 0 then
     begin
     begin
 {$ifdef FPC_HAS_CPSTRING}
 {$ifdef FPC_HAS_CPSTRING}
-      if (cp=CP_ACP) then
-        cp:=DefaultSystemCodePage;
+      cp:=TranslatePlaceholderCP(cp);
 {$else FPC_HAS_CPSTRING}
 {$else FPC_HAS_CPSTRING}
       cp:=DefaultSystemCodePage;
       cp:=DefaultSystemCodePage;
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
@@ -552,10 +568,11 @@ begin
   else
   else
     begin
     begin
       r1:=S1;
       r1:=S1;
-      if (cp1=CP_ACP) then
+      cp1:=TranslatePlaceholderCP(cp1);
+      if (cp1<>StringCodePage(r1)) then
         SetCodePage(r1,DefaultSystemCodePage,false);
         SetCodePage(r1,DefaultSystemCodePage,false);
       r2:=S2;
       r2:=S2;
-      if (cp2=CP_ACP) then
+      if (cp2<>StringCodePage(r2)) then
         SetCodePage(r2,DefaultSystemCodePage,false);
         SetCodePage(r2,DefaultSystemCodePage,false);
       //convert them to utf8 then compare
       //convert them to utf8 then compare
       SetCodePage(r1,65001);
       SetCodePage(r1,65001);
@@ -599,10 +616,12 @@ begin
   if cp1<>cp2 then
   if cp1<>cp2 then
     begin
     begin
       r1:=S1;
       r1:=S1;
-      if (cp1=CP_ACP) then
+      cp1:=TranslatePlaceholderCP(cp1);
+      if (cp1<>StringCodePage(r1)) then
         SetCodePage(r1,DefaultSystemCodePage,false);
         SetCodePage(r1,DefaultSystemCodePage,false);
       r2:=S2;
       r2:=S2;
-      if (cp2=CP_ACP) then
+      cp2:=TranslatePlaceholderCP(cp2);
+      if (cp2<>StringCodePage(r2)) then
         SetCodePage(r2,DefaultSystemCodePage,false);
         SetCodePage(r2,DefaultSystemCodePage,false);
       //convert them to utf8 then compare
       //convert them to utf8 then compare
       SetCodePage(r1,65001);
       SetCodePage(r1,65001);
@@ -631,8 +650,7 @@ var
   oldlen: longint;
   oldlen: longint;
   result: RawByteString;
   result: RawByteString;
 begin
 begin
-  if (cp=CP_ACP) then
-    cp:=DefaultSystemCodePage;
+  cp:=TranslatePlaceholderCP(cp);
   { no explicit reference counting possible -> can't reuse S because we don't
   { no explicit reference counting possible -> can't reuse S because we don't
     know how many references exist to it }
     know how many references exist to it }
   result:=RawByteString(AnsistringClass.Create(l,cp));
   result:=RawByteString(AnsistringClass.Create(l,cp));

+ 2 - 2
rtl/java/jcompproc.inc

@@ -36,7 +36,7 @@ procedure fpc_Shortstr_SetLength(var s:shortstring;len:SizeInt); compilerproc;
 //procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer); compilerproc;
 //procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer); compilerproc;
 procedure fpc_shortstr_to_shortstr(out res:shortstring; const sstr: shortstring); compilerproc;
 procedure fpc_shortstr_to_shortstr(out res:shortstring; const sstr: shortstring); compilerproc;
 { JVM-specific }
 { JVM-specific }
-procedure fpc_Char_To_ShortStr(out res : shortstring;const c : AnsiChar) compilerproc;
+function fpc_Char_To_ShortStr(const c : AnsiChar): ShortString; compilerproc;
 
 
 
 
 procedure fpc_shortstr_concat(var dests:shortstring;const s1,s2:shortstring);compilerproc;
 procedure fpc_shortstr_concat(var dests:shortstring;const s1,s2:shortstring);compilerproc;
@@ -285,7 +285,7 @@ Function fpc_Char_To_UChar(const c : AnsiChar): UnicodeChar; compilerproc;
 Function fpc_UChar_To_Char(const c : UnicodeChar): AnsiChar; compilerproc;
 Function fpc_UChar_To_Char(const c : UnicodeChar): AnsiChar; compilerproc;
 Function fpc_UChar_To_UnicodeStr(const c : UnicodeChar): UnicodeString; compilerproc;
 Function fpc_UChar_To_UnicodeStr(const c : UnicodeChar): UnicodeString; compilerproc;
 Function fpc_UChar_To_AnsiStr(const c : UnicodeChar{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}): AnsiString; compilerproc;
 Function fpc_UChar_To_AnsiStr(const c : UnicodeChar{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}): AnsiString; compilerproc;
-procedure fpc_UChar_To_ShortStr(out res : shortstring;const c : UnicodeChar) compilerproc;
+function fpc_UChar_To_ShortStr(const c : UnicodeChar): shortstring; compilerproc;
 
 
 Function fpc_PWideChar_To_UnicodeStr(const p : pwidechar): unicodestring; compilerproc;
 Function fpc_PWideChar_To_UnicodeStr(const p : pwidechar): unicodestring; compilerproc;
 {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
 {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}

+ 3 - 3
rtl/java/jsstrings.inc

@@ -220,13 +220,13 @@ end;
 
 
 
 
 {$define FPC_HAS_CHAR_TO_SHORTSTR}
 {$define FPC_HAS_CHAR_TO_SHORTSTR}
-procedure fpc_Char_To_ShortStr(out res : shortstring;const c : AnsiChar) compilerproc;
+function fpc_Char_To_ShortStr(const c : AnsiChar): shortstring; compilerproc;
 {
 {
   Converts an AnsiChar to a ShortString;
   Converts an AnsiChar to a ShortString;
 }
 }
 begin
 begin
-  setlength(res,1);
-  ShortstringClass(@res).fdata[0]:=c;
+  setlength(result,1);
+  ShortstringClass(@result).fdata[0]:=c;
 end;
 end;
 
 
 
 

+ 8 - 0
rtl/java/jsystemh_types.inc

@@ -295,6 +295,7 @@ Type
 { some values which are used in RTL for TSystemCodePage type }
 { some values which are used in RTL for TSystemCodePage type }
 const
 const
   CP_ACP     = 0;     // default to ANSI code page
   CP_ACP     = 0;     // default to ANSI code page
+  CP_OEMCP   = 1;     // default to OEM (console) code page
   CP_UTF16   = 1200;  // utf-16
   CP_UTF16   = 1200;  // utf-16
   CP_UTF16BE = 1201;  // unicodeFFFE
   CP_UTF16BE = 1201;  // unicodeFFFE
   CP_UTF7    = 65000; // utf-7
   CP_UTF7    = 65000; // utf-7
@@ -533,6 +534,13 @@ var
 
 
   DefaultSystemCodePage,
   DefaultSystemCodePage,
   DefaultUnicodeCodePage,
   DefaultUnicodeCodePage,
+  { the code page to use when sending paths/file names to OS file system API
+    calls using single byte strings, and to interpret the results gotten back
+    from such API calls }
+  DefaultFileSystemCodePage,
+  { the code page to use to return file names from single byte file system calls
+    in the RTL that return ansistrings (by default, same as a above) }
+  DefaultRTLFileSystemCodePage,
   UTF8CompareLocale : TSystemCodePage;
   UTF8CompareLocale : TSystemCodePage;
 
 
 
 

+ 20 - 10
rtl/java/justrings.inc

@@ -122,8 +122,7 @@ Function fpc_UnicodeStr_To_AnsiStr (const S2 : UnicodeString{$ifdef FPC_HAS_CPST
 Var
 Var
   Size : SizeInt;
   Size : SizeInt;
 begin
 begin
-  if (cp=CP_ACP) then
-    cp:=DefaultSystemCodePage;
+  cp:=TranslatePlaceholderCP(cp);
   { avoid codepage conversion -- why isn't the result rawbytestring? }
   { avoid codepage conversion -- why isn't the result rawbytestring? }
   pointer(result):=pointer(AnsistringClass.Create(s2,cp));
   pointer(result):=pointer(AnsistringClass.Create(s2,cp));
 end;
 end;
@@ -185,8 +184,7 @@ begin
   if (p=nil) or
   if (p=nil) or
      (p^=#0) then
      (p^=#0) then
     exit;
     exit;
-  if (cp=CP_ACP) then
-    cp:=DefaultSystemCodePage;
+  cp:=TranslatePlaceholderCP(cp);
   pointer(result):=pointer(AnsistringClass.Create(unicodestring(p),cp));
   pointer(result):=pointer(AnsistringClass.Create(unicodestring(p),cp));
 end;
 end;
 
 
@@ -317,14 +315,13 @@ var
   arr: array[0..0] of unicodechar;
   arr: array[0..0] of unicodechar;
 begin
 begin
   arr[0]:=c;
   arr[0]:=c;
-  if (cp=CP_ACP) then
-    cp:=DefaultSystemCodePage;
+  cp:=TranslatePlaceholderCP(cp);
   widestringmanager.Unicode2AnsiMoveProc(punicodechar(@arr), RawByteString(fpc_UChar_To_AnsiStr), cp, 1);
   widestringmanager.Unicode2AnsiMoveProc(punicodechar(@arr), RawByteString(fpc_UChar_To_AnsiStr), cp, 1);
 end;
 end;
 
 
 
 
 {$define FPC_HAS_UCHAR_TO_SHORTSTR}
 {$define FPC_HAS_UCHAR_TO_SHORTSTR}
-procedure fpc_UChar_To_ShortStr(out res : shortstring;const c : UnicodeChar) compilerproc;
+function fpc_UChar_To_ShortStr(const c : UnicodeChar): shortstring; compilerproc;
 {
 {
   Converts a UnicodeChar to a AnsiString;
   Converts a UnicodeChar to a AnsiString;
 }
 }
@@ -332,7 +329,7 @@ var
   u: unicodestring;
   u: unicodestring;
 begin
 begin
   u:=c;
   u:=c;
-  res:=u;
+  result:=u;
 end;
 end;
 
 
 
 
@@ -351,8 +348,7 @@ begin
 {$ifndef FPC_HAS_CPSTRING}
 {$ifndef FPC_HAS_CPSTRING}
   cp:=DefaultSystemCodePage;
   cp:=DefaultSystemCodePage;
 {$endif FPC_HAS_CPSTRING}
 {$endif FPC_HAS_CPSTRING}
-  if (cp=CP_ACP) then
-    cp:=DefaultSystemCodePage;
+  cp:=TranslatePlaceholderCP(cp);
   arr[0]:=c;
   arr[0]:=c;
   widestringmanager.Unicode2AnsiMoveProc(punicodechar(@arr[0]), fpc_UChar_To_AnsiStr, cp, 1);
   widestringmanager.Unicode2AnsiMoveProc(punicodechar(@arr[0]), fpc_UChar_To_AnsiStr, cp, 1);
 end;
 end;
@@ -906,6 +902,18 @@ function StringCodePage(const S : UnicodeString): TSystemCodePage;
       result:=DefaultUnicodeCodePage;
       result:=DefaultUnicodeCodePage;
   end;
   end;
 
 
+{$define FPC_HAS_TOSINGLEBYTEFILESYSTEMENCODEDFILENAME_UNICODESTRING}
+Function ToSingleByteFileSystemEncodedFileName(const Str: UnicodeString): RawByteString;
+Begin
+  result:=AnsiString(AnsistringClass.Create(Str,DefaultFileSystemCodePage));
+End;
+
+{$define FPC_HAS_TOSINGLEBYTEFILESYSTEMENCODEDFILENAME_UNICODECHARARRAY}
+Function ToSingleByteFileSystemEncodedFileName(const arr: array of widechar): RawByteString;
+Begin
+  result:=AnsiString(AnsistringClass.Create(arr,DefaultFileSystemCodePage));
+End;
+
 
 
 { helpers for converting between Windows and Java code page identifiers }
 { helpers for converting between Windows and Java code page identifiers }
 
 
@@ -1009,6 +1017,8 @@ class constructor TUnicodeStringManager.ClassCreate;
       stdin etc, so setting this to utf-8 or so won't help) }
       stdin etc, so setting this to utf-8 or so won't help) }
     if DefaultSystemCodePage=65535 then
     if DefaultSystemCodePage=65535 then
       DefaultSystemCodePage:=20127;
       DefaultSystemCodePage:=20127;
+    DefaultFileSystemCodePage:=DefaultSystemCodePage;
+    DefaultRTLFileSystemCodePage:=DefaultFileSystemCodePage;
     DefaultUnicodeCodePage:=CP_UTF16BE;
     DefaultUnicodeCodePage:=CP_UTF16BE;
   end;
   end;
 
 

+ 24 - 0
rtl/java/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 24 - 0
rtl/linux/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 10 - 2
rtl/macos/dos.pp

@@ -803,7 +803,11 @@ End;
       paramBlock: CInfoPBRec;
       paramBlock: CInfoPBRec;
 
 
   begin
   begin
-    DosError := PathArgToFSSpec(StrPas(filerec(f).name), spec);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+    DosError := PathArgToFSSpec(filerec(f).name, spec);
+{$else}
+    DosError := PathArgToFSSpec(ToSingleByteFileSystemEncodedFileName(filerec(f).name), spec);
+{$endif}
     if (DosError = 0) or (DosError = 2) then
     if (DosError = 0) or (DosError = 2) then
       begin
       begin
         DosError := DoFindOne(spec, paramBlock);
         DosError := DoFindOne(spec, paramBlock);
@@ -822,7 +826,11 @@ End;
       macfiletime: UInt32;
       macfiletime: UInt32;
 
 
   begin
   begin
-    DosError := PathArgToFSSpec(StrPas(filerec(f).name), spec);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+    DosError := PathArgToFSSpec(filerec(f).name, spec);
+{$else}
+    DosError := PathArgToFSSpec(ToSingleByteFileSystemEncodedFileName(filerec(f).name), spec);
+{$endif}
     if (DosError = 0) or (DosError = 2) then
     if (DosError = 0) or (DosError = 2) then
       begin
       begin
         DosError := DoFindOne(spec, paramBlock);
         DosError := DoFindOne(spec, paramBlock);

+ 24 - 0
rtl/macos/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 7 - 21
rtl/macos/sysdir.inc

@@ -18,16 +18,14 @@
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
 
 
-procedure mkdir(const s:string);[IOCheck];
+procedure do_mkdir(const s: rawbytestring);
 var
 var
   spec: FSSpec;
   spec: FSSpec;
   createdDirID: Longint;
   createdDirID: Longint;
   err: OSErr;
   err: OSErr;
   res: Integer;
   res: Integer;
 begin
 begin
-  If (s='') or (InOutRes <> 0) then
-    exit;
-
+  { TODO: convert PathArgToFSSpec (and the routines it calls) to rawbytestring }
   res:= PathArgToFSSpec(s, spec);
   res:= PathArgToFSSpec(s, spec);
   if (res = 0) or (res = 2) then
   if (res = 0) or (res = 2) then
     begin
     begin
@@ -38,7 +36,7 @@ begin
     InOutRes:=res;
     InOutRes:=res;
 end;
 end;
 
 
-procedure rmdir(const s:string);[IOCheck];
+procedure do_rmdir(const s: rawbytestring);
 
 
 var
 var
   spec: FSSpec;
   spec: FSSpec;
@@ -46,9 +44,6 @@ var
   res: Integer;
   res: Integer;
 
 
 begin
 begin
-  If (s='') or (InOutRes <> 0) then
-    exit;
-
   res:= PathArgToFSSpec(s, spec);
   res:= PathArgToFSSpec(s, spec);
 
 
   if (res = 0) then
   if (res = 0) then
@@ -65,15 +60,12 @@ begin
     InOutRes:=res;
     InOutRes:=res;
 end;
 end;
 
 
-procedure chdir(const s:string);[IOCheck];
+procedure do_chdir(const s: rawbytestring);
 var
 var
   spec, newDirSpec: FSSpec;
   spec, newDirSpec: FSSpec;
   err: OSErr;
   err: OSErr;
   res: Integer;
   res: Integer;
 begin
 begin
-  if (s='') or (InOutRes <> 0) then
-    exit;
-
   res:= PathArgToFSSpec(s, spec);
   res:= PathArgToFSSpec(s, spec);
   if (res = 0) or (res = 2) then
   if (res = 0) or (res = 2) then
     begin
     begin
@@ -98,22 +90,16 @@ begin
     InOutRes:=res;
     InOutRes:=res;
 end;
 end;
 
 
-procedure getDir (DriveNr: byte; var Dir: ShortString);
+procedure do_getDir (DriveNr: byte; var Dir: RawByteString);
 
 
 var
 var
-  fullPath: AnsiString;
   pathHandleSize: Longint;
   pathHandleSize: Longint;
 
 
 begin
 begin
-  if FSpGetFullPath(workingDirectorySpec, fullPath, false) <> noErr then
+  if FSpGetFullPath(workingDirectorySpec, Dir, false) <> noErr then
     Halt(3);  {exit code 3 according to MPW}
     Halt(3);  {exit code 3 according to MPW}
 
 
-  if Length(fullPath) <= 255 then {because dir is ShortString}
-    InOutRes := 0
-  else
-    InOutRes := 1; //TODO Exchange to something better
-
-  dir:= fullPath;
+  SetCodePage(Dir,DefaultFileSystemCodePage,false);
 end;
 end;
 
 
 
 

+ 3 - 3
rtl/macos/sysfile.inc

@@ -40,7 +40,7 @@ begin
   {$endif}
   {$endif}
 end;
 end;
 
 
-procedure do_erase(p : pchar);
+procedure do_erase(p : pchar; pchangeable: boolean);
 
 
 var
 var
   spec: FSSpec;
   spec: FSSpec;
@@ -63,7 +63,7 @@ begin
     InOutRes:=res;
     InOutRes:=res;
 end;
 end;
 
 
-procedure do_rename(p1,p2 : pchar);
+procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
 var
 var
   s1,s2: AnsiString;
   s1,s2: AnsiString;
 begin
 begin
@@ -196,7 +196,7 @@ begin
   {$endif}
   {$endif}
 end;
 end;
 
 
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
 {
 {
   filerec and textrec have both handle and mode as the first items so
   filerec and textrec have both handle and mode as the first items so
   they could use the same routine for opening/creating.
   they could use the same routine for opening/creating.

+ 33 - 58
rtl/macos/sysutils.pp

@@ -44,6 +44,11 @@ type
                 exactMatch: Boolean;
                 exactMatch: Boolean;
   end;
   end;
 
 
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
 { Include platform independent interface part }
 { Include platform independent interface part }
 {$i sysutilh.inc}
 {$i sysutilh.inc}
 
 
@@ -66,12 +71,13 @@ uses
                               File Functions
                               File Functions
 ****************************************************************************}
 ****************************************************************************}
 
 
-Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
+Function FileOpen (Const FileName : rawbytestring; Mode : Integer) : Longint;
 
 
 Var LinuxFlags : longint;
 Var LinuxFlags : longint;
-
-BEGIN
+    SystemFileName: RawByteString;
+begin
   (* TODO fix
   (* TODO fix
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
   LinuxFlags:=0;
   LinuxFlags:=0;
   Case (Mode and 3) of
   Case (Mode and 3) of
     0 : LinuxFlags:=LinuxFlags or Open_RdOnly;
     0 : LinuxFlags:=LinuxFlags or Open_RdOnly;
@@ -84,7 +90,7 @@ BEGIN
 end;
 end;
 
 
 
 
-Function FileCreate (Const FileName : String) : Longint;
+Function FileCreate (Const FileName : RawByteString) : Longint;
 
 
 begin
 begin
   (* TODO fix
   (* TODO fix
@@ -93,7 +99,7 @@ begin
 end;
 end;
 
 
 
 
-Function FileCreate (Const FileName : String;Rights : Longint) : Longint;
+Function FileCreate (Const FileName : RawByteString;Rights : Longint) : Longint;
 
 
 Var LinuxFlags : longint;
 Var LinuxFlags : longint;
 
 
@@ -109,7 +115,7 @@ BEGIN
   *)
   *)
 end;
 end;
 
 
-Function FileCreate (Const FileName : String;ShareMode : Longint; Rights : Longint) : Longint;
+Function FileCreate (Const FileName : RawByteString;ShareMode : Longint; Rights : Longint) : Longint;
 
 
 Var LinuxFlags : longint;
 Var LinuxFlags : longint;
 
 
@@ -179,7 +185,7 @@ begin
   *)
   *)
 end;
 end;
 
 
-Function FileAge (Const FileName : String): Longint;
+Function FileAge (Const FileName : RawByteString): Longint;
 
 
   (*
   (*
 Var Info : Stat;
 Var Info : Stat;
@@ -199,7 +205,7 @@ begin
 end;
 end;
 
 
 
 
-Function FileExists (Const FileName : String) : Boolean;
+Function FileExists (Const FileName : RawByteString) : Boolean;
 
 
   (*
   (*
 Var Info : Stat;
 Var Info : Stat;
@@ -212,7 +218,7 @@ begin
 end;
 end;
 
 
 
 
-Function DirectoryExists (Const Directory : String) : Boolean;
+Function DirectoryExists (Const Directory : RawByteString) : Boolean;
 
 
   (*
   (*
 Var Info : Stat;
 Var Info : Stat;
@@ -289,7 +295,7 @@ end;
 *)
 *)
 
 
 
 
-procedure DoFind (var F: TSearchRec; firstTime: Boolean);
+procedure DoFind (var F: TSearchRec; var retname: RawByteString; firstTime: Boolean);
 
 
   var
   var
     err: OSErr;
     err: OSErr;
@@ -323,7 +329,8 @@ begin
           attr := GetFileAttrFromPB(Rslt.paramBlock);
           attr := GetFileAttrFromPB(Rslt.paramBlock);
           if ((Attr and not(searchAttr)) = 0) then
           if ((Attr and not(searchAttr)) = 0) then
             begin
             begin
-              name := s;
+              retname := s;
+              SetCodePage(retname, DefaultFileSystemCodePage, false);
               UpperString(s, true);
               UpperString(s, true);
 
 
               if FNMatch(Rslt.searchFSSpec.name, s) then
               if FNMatch(Rslt.searchFSSpec.name, s) then
@@ -339,13 +346,11 @@ begin
 end;
 end;
 
 
 
 
-Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
+Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
   var
   var
     s: Str255;
     s: Str255;
 
 
 begin
 begin
-  fillchar(Rslt, sizeof(Rslt), 0);
-
   if path = '' then
   if path = '' then
     begin
     begin
       Result := 3;
       Result := 3;
@@ -355,10 +360,12 @@ begin
   {We always also search for readonly and archive, regardless of Attr.}
   {We always also search for readonly and archive, regardless of Attr.}
   Rslt.searchAttr := (Attr or (archive or readonly));
   Rslt.searchAttr := (Attr or (archive or readonly));
 
 
+  { TODO: convert PathArgToFSSpec (and the routines it calls) to rawbytestring }
   Result := PathArgToFSSpec(path, Rslt.searchFSSpec);
   Result := PathArgToFSSpec(path, Rslt.searchFSSpec);
   with Rslt do
   with Rslt do
     if (Result = 0) or (Result = 2) then
     if (Result = 0) or (Result = 2) then
       begin
       begin
+        { FIXME: SearchSpec is a shortstring -> ignores encoding }
         SearchSpec := path;
         SearchSpec := path;
         NamePos := Length(path) - Length(searchFSSpec.name);
         NamePos := Length(path) - Length(searchFSSpec.name);
 
 
@@ -372,6 +379,7 @@ begin
                 if ((Attr and not(searchAttr)) = 0) then
                 if ((Attr and not(searchAttr)) = 0) then
                   begin
                   begin
                     name := searchFSSpec.name;
                     name := searchFSSpec.name;
+                    SetCodePage(name, DefaultFileSystemCodePage, false);
                     size := GetFileSizeFromPB(paramBlock);
                     size := GetFileSizeFromPB(paramBlock);
                     time := MacTimeToDosPackedTime(paramBlock.ioFlMdDat);
                     time := MacTimeToDosPackedTime(paramBlock.ioFlMdDat);
                   end
                   end
@@ -389,23 +397,23 @@ begin
             UpperString(s, true);
             UpperString(s, true);
             Rslt.searchFSSpec.name := s;
             Rslt.searchFSSpec.name := s;
 
 
-            DoFind(Rslt, true);
+            DoFind(Rslt, name, true);
           end;
           end;
       end;
       end;
 end;
 end;
 
 
 
 
-Function FindNext (Var Rslt : TSearchRec) : Longint;
+Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
 
 
 begin
 begin
   if F.exactMatch then
   if F.exactMatch then
     Result := 18
     Result := 18
   else
   else
-    Result:=DoFind (Rslt);
+    Result:=DoFind (Rslt, Name, false);
 end;
 end;
 
 
 
 
-Procedure FindClose (Var F : TSearchrec);
+Procedure InternalFindClose (var Handle: THandle; var FindData: TFindData);
 
 
   (*
   (*
 Var
 Var
@@ -414,7 +422,7 @@ Var
 
 
 begin
 begin
   (* TODO fix
   (* TODO fix
-  GlobSearchRec:=PGlobSearchRec(F.FindHandle);
+  GlobSearchRec:=PGlobSearchRec(Handle);
   GlobFree (GlobSearchRec^.GlobHandle);
   GlobFree (GlobSearchRec^.GlobHandle);
   Dispose(GlobSearchRec);
   Dispose(GlobSearchRec);
   *)
   *)
@@ -446,7 +454,7 @@ begin
 end;
 end;
 
 
 
 
-Function FileGetAttr (Const FileName : String) : Longint;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
 
 
   (*
   (*
 Var Info : Stat;
 Var Info : Stat;
@@ -462,14 +470,14 @@ begin
 end;
 end;
 
 
 
 
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
 
 
 begin
 begin
   Result:=-1;
   Result:=-1;
 end;
 end;
 
 
 
 
-Function DeleteFile (Const FileName : String) : Boolean;
+Function DeleteFile (Const FileName : RawByteString) : Boolean;
 
 
 begin
 begin
   (* TODO fix
   (* TODO fix
@@ -478,7 +486,7 @@ begin
 end;
 end;
 
 
 
 
-Function RenameFile (Const OldName, NewName : String) : Boolean;
+Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
 
 
 begin
 begin
   (* TODO fix
   (* TODO fix
@@ -558,39 +566,6 @@ Begin
   *)
   *)
 End;
 End;
 
 
-Function GetCurrentDir : String;
-begin
-  GetDir (0,Result);
-end;
-
-
-Function SetCurrentDir (Const NewDir : String) : Boolean;
-begin
-  {$I-}
-   ChDir(NewDir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
-Function CreateDir (Const NewDir : String) : Boolean;
-begin
-  {$I-}
-   MkDir(NewDir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
-Function RemoveDir (Const Dir : String) : Boolean;
-begin
-  {$I-}
-   RmDir(Dir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
 {****************************************************************************
 {****************************************************************************
                               Misc Functions
                               Misc Functions
 ****************************************************************************}
 ****************************************************************************}
@@ -660,7 +635,7 @@ Function GetEnvironmentVariable(Const EnvVar : String) : String;
 
 
 begin
 begin
   (* TODO fix
   (* TODO fix
-  Result:=StrPas(Unix.Getenv(PChar(EnvVar)));
+  Result:=Unix.Getenv(PChar(EnvVar));
   *)
   *)
 end;
 end;
 
 
@@ -671,7 +646,7 @@ begin
   Result:=0;
   Result:=0;
 end;
 end;
 
 
-Function GetEnvironmentString(Index : Integer) : String;
+Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 
 
 begin
 begin
   // Result:=FPCGetEnvStrFromP(Envp,Index);
   // Result:=FPCGetEnvStrFromP(Envp,Index);

+ 28 - 6
rtl/morphos/dos.pp

@@ -725,7 +725,11 @@ var
 begin
 begin
     DosError:=0;
     DosError:=0;
     FTime := 0;
     FTime := 0;
-    Str := StrPas(filerec(f).name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+    Str := strpas(filerec(f).Name);
+{$else}
+    Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+{$endif}
     DoDirSeparators(Str);
     DoDirSeparators(Str);
     FLock := dosLock(Str, SHARED_LOCK);
     FLock := dosLock(Str, SHARED_LOCK);
     IF FLock <> 0 then begin
     IF FLock <> 0 then begin
@@ -756,7 +760,11 @@ end;
     FLock: longint;
     FLock: longint;
   Begin
   Begin
     new(DateStamp);
     new(DateStamp);
-    Str := StrPas(filerec(f).name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+    Str := strpas(filerec(f).Name);
+{$else}
+    Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+{$endif}
     DoDirSeparators(str);
     DoDirSeparators(str);
     { Check first of all, if file exists }
     { Check first of all, if file exists }
     FLock := dosLock(Str, SHARED_LOCK);
     FLock := dosLock(Str, SHARED_LOCK);
@@ -788,7 +796,11 @@ begin
     DosError:=0;
     DosError:=0;
     flags:=0;
     flags:=0;
     New(info);
     New(info);
-    Str := StrPas(filerec(f).name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+    Str := strpas(filerec(f).Name);
+{$else}
+    Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+{$endif}
     DoDirSeparators(str);
     DoDirSeparators(str);
     { open with shared lock to check if file exists }
     { open with shared lock to check if file exists }
     MyLock:=dosLock(Str,SHARED_LOCK);
     MyLock:=dosLock(Str,SHARED_LOCK);
@@ -825,7 +837,17 @@ procedure setfattr(var f; attr : word);
 var
 var
   flags: longint;
   flags: longint;
   tmpLock : longint;
   tmpLock : longint;
-begin
+{$ifndef FPC_ANSI_TEXTFILEREC}
+  r : rawbytestring;
+{$endif not FPC_ANSI_TEXTFILEREC}
+  p : pchar;
+begin
+{$ifdef FPC_ANSI_TEXTFILEREC}
+    p := @filerec(f).Name;
+{$else}
+    r := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+    p := pchar(r);
+{$endif}
   DosError:=0;
   DosError:=0;
   flags:=FIBF_WRITE;
   flags:=FIBF_WRITE;
 
 
@@ -836,10 +858,10 @@ begin
   { converts the path (KB) }
   { converts the path (KB) }
 
 
   { create a shared lock on the file }
   { create a shared lock on the file }
-  tmpLock:=Lock(filerec(f).name,SHARED_LOCK);
+  tmpLock:=Lock(p,SHARED_LOCK);
   if tmpLock <> 0 then begin
   if tmpLock <> 0 then begin
     Unlock(tmpLock);
     Unlock(tmpLock);
-    if not SetProtection(filerec(f).name,flags) then DosError:=5;
+    if not SetProtection(p,flags) then DosError:=5;
   end else
   end else
     DosError:=3;
     DosError:=3;
 end;
 end;

+ 24 - 0
rtl/morphos/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 22 - 19
rtl/morphos/sysdir.inc

@@ -17,15 +17,14 @@
 {*****************************************************************************
 {*****************************************************************************
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
-Procedure MkDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_MKDIR'];
+Procedure do_MkDir(const s: rawbytestring);
 var
 var
-  tmpStr : array[0..255] of char;
+  tmpStr : rawbytestring;
   tmpLock: LongInt;
   tmpLock: LongInt;
 begin
 begin
   checkCTRLC;
   checkCTRLC;
-  if not assigned(s) or (len=0) or (InOutRes<>0) then exit;
-  tmpStr:=PathConv(strpas(s))+#0;
-  tmpLock:=dosCreateDir(@tmpStr);
+  tmpStr:=PathConv(s);
+  tmpLock:=dosCreateDir(pchar(tmpStr));
   if tmpLock=0 then begin
   if tmpLock=0 then begin
     dosError2InOut(IoErr);
     dosError2InOut(IoErr);
     exit;
     exit;
@@ -33,34 +32,35 @@ begin
   UnLock(tmpLock);
   UnLock(tmpLock);
 end;
 end;
 
 
-Procedure RmDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_RMDIR'];
+Procedure do_RmDir(const s: rawbytestring);
 var
 var
-  tmpStr : array[0..255] of Char;
+  tmpStr : rawbytestring;
 begin
 begin
   checkCTRLC;
   checkCTRLC;
-  if not assigned(s) or (len=0) then exit;
-  if (s='.') then InOutRes:=16;
-  If (s='') or (InOutRes<>0) then exit;
-  tmpStr:=PathConv(strpas(s))+#0;
-  if not dosDeleteFile(@tmpStr) then
+  if (s='.') then
+    begin
+      InOutRes:=16;
+      exit;
+    end;
+  tmpStr:=PathConv(s);
+  if not dosDeleteFile(pchar(tmpStr)) then
     dosError2InOut(IoErr);
     dosError2InOut(IoErr);
 end;
 end;
 
 
-Procedure ChDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
+Procedure do_ChDir(const s: rawbytestring);
 var
 var
-  tmpStr : array[0..255] of Char;
+  tmpStr : rawbytestring;
   tmpLock: LongInt;
   tmpLock: LongInt;
   FIB    : PFileInfoBlock;
   FIB    : PFileInfoBlock;
 begin
 begin
   checkCTRLC;
   checkCTRLC;
-  if not assigned(s) or (len=0) or (InOutRes<>0) then exit;
-  tmpStr:=PathConv(strpas(s))+#0;
+  tmpStr:=PathConv(s);
   tmpLock:=0;
   tmpLock:=0;
 
 
   { Changing the directory is a pretty complicated affair }
   { Changing the directory is a pretty complicated affair }
   {   1) Obtain a lock on the directory                   }
   {   1) Obtain a lock on the directory                   }
   {   2) CurrentDir the lock                              }
   {   2) CurrentDir the lock                              }
-  tmpLock:=Lock(@tmpStr,SHARED_LOCK);
+  tmpLock:=Lock(pchar(tmpStr),SHARED_LOCK);
   if tmpLock=0 then begin
   if tmpLock=0 then begin
     dosError2InOut(IoErr);
     dosError2InOut(IoErr);
     exit;
     exit;
@@ -83,7 +83,7 @@ begin
   if assigned(FIB) then dispose(FIB);
   if assigned(FIB) then dispose(FIB);
 end;
 end;
 
 
-procedure GetDir (DriveNr: byte; var Dir: ShortString);
+procedure do_GetDir (DriveNr: byte; var Dir: RawByteString);
 var tmpbuf: array[0..255] of char;
 var tmpbuf: array[0..255] of char;
 begin
 begin
   checkCTRLC;
   checkCTRLC;
@@ -91,5 +91,8 @@ begin
   if not GetCurrentDirName(tmpbuf,256) then
   if not GetCurrentDirName(tmpbuf,256) then
     dosError2InOut(IoErr)
     dosError2InOut(IoErr)
   else
   else
-    Dir:=strpas(tmpbuf);
+    begin
+      Dir:=tmpbuf;
+      SetCodePage(Dir,DefaultFileSystemCodePage,false);
+    end;
 end;
 end;

+ 3 - 3
rtl/morphos/sysfile.inc

@@ -171,7 +171,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure do_erase(p : pchar);
+procedure do_erase(p : pchar; pchangeable: boolean);
 var
 var
   tmpStr: array[0..255] of Char;
   tmpStr: array[0..255] of Char;
 begin
 begin
@@ -181,7 +181,7 @@ begin
     dosError2InOut(IoErr);
     dosError2InOut(IoErr);
 end;
 end;
 
 
-procedure do_rename(p1,p2 : pchar);
+procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
 { quite stack-effective code, huh? :) damn path conversions... (KB) }
 { quite stack-effective code, huh? :) damn path conversions... (KB) }
 var
 var
   tmpStr1: array[0..255] of Char;
   tmpStr1: array[0..255] of Char;
@@ -311,7 +311,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
 {
 {
   filerec and textrec have both handle and mode as the first items so
   filerec and textrec have both handle and mode as the first items so
   they could use the same routine for opening/creating.
   they could use the same routine for opening/creating.

+ 35 - 0
rtl/morphos/sysos.inc

@@ -137,5 +137,40 @@ begin
 end;
 end;
 
 
 
 
+{ Converts an Unix-like path to Amiga-like path }
+function PathConv(const path: rawbytestring): rawbytestring; alias: 'PATHCONVRBS'; [public];
+var tmppos: longint;
+begin
+  { check for short paths }
+  if length(path)<=2 then begin
+    if (path='.') or (path='./') then PathConv:='' else
+    if path='..' then PathConv:='/' else
+    if path='*' then PathConv:='#?'
+    else PathConv:=path;
+  end else begin
+    { convert parent directories }
+    PathConv:=path;
+    tmppos:=pos('../',PathConv);
+    while tmppos<>0 do begin
+      { delete .. to have / as parent dir sign }
+      delete(PathConv,tmppos,2);
+      tmppos:=pos('../',PathConv);
+    end;
+    { convert current directories }
+    tmppos:=pos('./',PathConv);
+    while tmppos<>0 do begin
+      { delete ./ since we doesn't need to sign current directory }
+      delete(PathConv,tmppos,2);
+      tmppos:=pos('./',PathConv);
+    end;
+    { convert wildstart to #? }
+    tmppos:=pos('*',PathConv);
+    while tmppos<>0 do begin
+      delete(PathConv,tmppos,1);
+      insert('#?',PathConv,tmppos);
+      tmppos:=pos('*',PathConv);
+    end;
+  end;
+end;
 
 
 
 

+ 56 - 76
rtl/morphos/sysutils.pp

@@ -28,6 +28,12 @@ interface
 {$DEFINE OS_FILESETDATEBYNAME}
 {$DEFINE OS_FILESETDATEBYNAME}
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_OSERROR}
 {$DEFINE HAS_OSERROR}
+
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
 { Include platform independent interface part }
 { Include platform independent interface part }
 {$i sysutilh.inc}
 {$i sysutilh.inc}
 
 
@@ -58,6 +64,7 @@ uses dos,sysconst;
 
 
 { * Followings are implemented in the system unit! * }
 { * Followings are implemented in the system unit! * }
 function PathConv(path: shortstring): shortstring; external name 'PATHCONV';
 function PathConv(path: shortstring): shortstring; external name 'PATHCONV';
+function PathConv(path: RawByteString): shortstring; external name 'PATHCONVRBS';
 procedure AddToList(var l: Pointer; h: LongInt); external name 'ADDTOLIST';
 procedure AddToList(var l: Pointer; h: LongInt); external name 'ADDTOLIST';
 function RemoveFromList(var l: Pointer; h: LongInt): boolean; external name 'REMOVEFROMLIST';
 function RemoveFromList(var l: Pointer; h: LongInt): boolean; external name 'REMOVEFROMLIST';
 function CheckInList(var l: Pointer; h: LongInt): pointer; external name 'CHECKINLIST';
 function CheckInList(var l: Pointer; h: LongInt): pointer; external name 'CHECKINLIST';
@@ -126,14 +133,14 @@ end;
 
 
 (****** non portable routines ******)
 (****** non portable routines ******)
 
 
-function FileOpen(const FileName: string; Mode: Integer): LongInt;
+function FileOpen(const FileName: rawbytestring; Mode: Integer): LongInt;
 var
 var
+  SystemFileName: RawByteString;
   dosResult: LongInt;
   dosResult: LongInt;
-  tmpStr   : array[0..255] of char;
 begin
 begin
+  SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
   {$WARNING FIX ME! To do: FileOpen Access Modes}
   {$WARNING FIX ME! To do: FileOpen Access Modes}
-  tmpStr:=PathConv(FileName)+#0;
-  dosResult:=Open(@tmpStr,MODE_OLDFILE);
+  dosResult:=Open(PChar(SystemFileName),MODE_OLDFILE);
   if dosResult=0 then
   if dosResult=0 then
     dosResult:=-1
     dosResult:=-1
   else
   else
@@ -184,33 +191,33 @@ begin
 end;
 end;
 
 
 
 
-function FileSetDate(const FileName: string; Age: LongInt) : LongInt;
+function FileSetDate(const FileName: RawByteString; Age: LongInt) : LongInt;
 var
 var
   tmpDateStamp: TDateStamp;
   tmpDateStamp: TDateStamp;
-  tmpName: array[0..255] of char;
+  SystemFileName: RawByteString;
 begin
 begin
   result:=0;
   result:=0;
-  tmpName:=PathConv(FileName)+#0;
+  SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
   tmpDateStamp:=DateTimeToAmigaDateStamp(FileDateToDateTime(Age));
   tmpDateStamp:=DateTimeToAmigaDateStamp(FileDateToDateTime(Age));
-  if not SetFileDate(@tmpName,@tmpDateStamp) then begin
+  if not SetFileDate(PChar(SystemFileName),@tmpDateStamp) then begin
     IoErr(); // dump the error code for now (TODO)
     IoErr(); // dump the error code for now (TODO)
     result:=-1;
     result:=-1;
   end;
   end;
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string) : LongInt;
+function FileCreate(const FileName: RawByteString) : LongInt;
 var
 var
+  SystemFileName: RawByteString;
   dosResult: LongInt;
   dosResult: LongInt;
-  tmpStr   : array[0..255] of char;
 begin
 begin
   dosResult:=-1;
   dosResult:=-1;
 
 
   { Open file in MODDE_READWRITE, then truncate it by hand rather than
   { Open file in MODDE_READWRITE, then truncate it by hand rather than
     opening it in MODE_NEWFILE, because that returns an exclusive lock 
     opening it in MODE_NEWFILE, because that returns an exclusive lock 
     so some operations might fail with it (KB) }
     so some operations might fail with it (KB) }
-  tmpStr:=PathConv(FileName)+#0;
-  dosResult:=Open(@tmpStr,MODE_READWRITE);
+  SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
+  dosResult:=Open(PChar(SystemFileName),MODE_READWRITE);
   if dosResult = 0 then exit;
   if dosResult = 0 then exit;
 
 
   if SetFileSize(dosResult, 0, OFFSET_BEGINNING) = 0 then 
   if SetFileSize(dosResult, 0, OFFSET_BEGINNING) = 0 then 
@@ -223,13 +230,13 @@ begin
   FileCreate:=dosResult;
   FileCreate:=dosResult;
 end;
 end;
 
 
-function FileCreate(const FileName: string; Rights: integer): LongInt;
+function FileCreate(const FileName: RawByteString; Rights: integer): LongInt;
 begin
 begin
   {$WARNING FIX ME! To do: FileCreate Access Modes}
   {$WARNING FIX ME! To do: FileCreate Access Modes}
   FileCreate:=FileCreate(FileName);
   FileCreate:=FileCreate(FileName);
 end;
 end;
 
 
-function FileCreate(const FileName: string; ShareMode: integer; Rights : integer): LongInt;
+function FileCreate(const FileName: RawByteString; ShareMode: integer; Rights : integer): LongInt;
 begin
 begin
   {$WARNING FIX ME! To do: FileCreate Access Modes}
   {$WARNING FIX ME! To do: FileCreate Access Modes}
   FileCreate:=FileCreate(FileName);
   FileCreate:=FileCreate(FileName);
@@ -304,33 +311,31 @@ begin
 end;
 end;
 
 
 
 
-function DeleteFile(const FileName: string) : Boolean;
+function DeleteFile(const FileName: RawByteString) : Boolean;
 var
 var
-  tmpStr: array[0..255] of char;
+  SystemFileName: RawByteString;
 begin
 begin
-  tmpStr:=PathConv(FileName)+#0;
-
-  DeleteFile:=dosDeleteFile(@tmpStr);
+  SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
+  DeleteFile:=dosDeleteFile(PChar(SystemFileName));
 end;
 end;
 
 
 
 
-function RenameFile(const OldName, NewName: string): Boolean;
+function RenameFile(const OldName, NewName: RawByteString): Boolean;
 var
 var
-  tmpOldName, tmpNewName: array[0..255] of char;
+  OldSystemFileName, NewSystemFileName: RawByteString;
 begin
 begin
-  tmpOldName:=PathConv(OldName)+#0;
-  tmpNewName:=PathConv(NewName)+#0;
-
-  RenameFile:=dosRename(tmpOldName, tmpNewName);
+  OldSystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(OldName));
+  NewSystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(NewName));
+  RenameFile:=dosRename(PChar(OldSystemFileName), PChar(NewSystemFileName));
 end;
 end;
 
 
 
 
 (****** end of non portable routines ******)
 (****** end of non portable routines ******)
 
 
 
 
-function FileAge (const FileName : String): Longint;
+function FileAge (const FileName : RawByteString): Longint;
 var
 var
-  tmpName: String;
+  tmpName: RawByteString;
   tmpLock: Longint;
   tmpLock: Longint;
   tmpFIB : PFileInfoBlock;
   tmpFIB : PFileInfoBlock;
   tmpDateTime: TDateTime;
   tmpDateTime: TDateTime;
@@ -338,7 +343,7 @@ var
 
 
 begin
 begin
   validFile:=false;
   validFile:=false;
-  tmpName := PathConv(FileName);
+  tmpName := PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
   tmpLock := dosLock(tmpName, SHARED_LOCK);
   tmpLock := dosLock(tmpName, SHARED_LOCK);
 
 
   if (tmpLock <> 0) then begin
   if (tmpLock <> 0) then begin
@@ -357,16 +362,15 @@ begin
 end;
 end;
 
 
 
 
-function FileExists (const FileName : String) : Boolean;
+function FileExists (const FileName : RawByteString) : Boolean;
 var
 var
-  tmpName: String;
   tmpLock: LongInt;
   tmpLock: LongInt;
   tmpFIB : PFileInfoBlock;
   tmpFIB : PFileInfoBlock;
-
+  SystemFileName: RawByteString;
 begin
 begin
   result:=false;
   result:=false;
-  tmpName := PathConv(FileName);
-  tmpLock := dosLock(tmpName, SHARED_LOCK);
+  SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(FileName));
+  tmpLock := dosLock(PChar(SystemFileName), SHARED_LOCK);
 
 
   if (tmpLock <> 0) then begin
   if (tmpLock <> 0) then begin
     new(tmpFIB);
     new(tmpFIB);
@@ -378,15 +382,15 @@ begin
 end;
 end;
 
 
 
 
-function FindFirst(const Path: String; Attr : Longint; out Rslt: TSearchRec): Longint;
+Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
 var
 var
-  tmpStr: array[0..255] of Char;
+  tmpStr: RawByteString;
   Anchor: PAnchorPath;
   Anchor: PAnchorPath;
   tmpDateTime: TDateTime;
   tmpDateTime: TDateTime;
   validDate: boolean;
   validDate: boolean;
 begin
 begin
   result:=-1; { We emulate Linux/Unix behaviour, and return -1 on errors. }
   result:=-1; { We emulate Linux/Unix behaviour, and return -1 on errors. }
-  tmpStr:=PathConv(path)+#0;
+  tmpStr:=PathConv(ToSingleByteFileSystemEncodedFileName(Path));
 
 
   { $1e = faHidden or faSysFile or faVolumeID or faDirectory }
   { $1e = faHidden or faSysFile or faVolumeID or faDirectory }
   Rslt.ExcludeAttr := (not Attr) and ($1e);
   Rslt.ExcludeAttr := (not Attr) and ($1e);
@@ -395,11 +399,12 @@ begin
   new(Anchor);
   new(Anchor);
   FillChar(Anchor^,sizeof(TAnchorPath),#0);
   FillChar(Anchor^,sizeof(TAnchorPath),#0);
 
 
-  if MatchFirst(@tmpStr,Anchor)<>0 then exit;
+  if MatchFirst(pchar(tmpStr),Anchor)<>0 then exit;
   Rslt.FindHandle := longint(Anchor);
   Rslt.FindHandle := longint(Anchor);
 
 
   with Anchor^.ap_Info do begin
   with Anchor^.ap_Info do begin
-    Rslt.Name := StrPas(fib_FileName);
+    Name := fib_FileName;
+    SetCodePage(Name,DefaultFileSystemCodePage,False);
 
 
     Rslt.Size := fib_Size;
     Rslt.Size := fib_Size;
     Rslt.Time := DateTimeToFileDate(AmigaFileDateToDateTime(fib_Date,validDate));
     Rslt.Time := DateTimeToFileDate(AmigaFileDateToDateTime(fib_Date,validDate));
@@ -417,7 +422,7 @@ begin
 end;
 end;
 
 
 
 
-function FindNext (var Rslt : TSearchRec): Longint;
+Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
 var
 var
   Anchor: PAnchorPath;
   Anchor: PAnchorPath;
   validDate: boolean;
   validDate: boolean;
@@ -429,7 +434,8 @@ begin
   if MatchNext(Anchor) <> 0 then exit;
   if MatchNext(Anchor) <> 0 then exit;
 
 
   with Anchor^.ap_Info do begin
   with Anchor^.ap_Info do begin
-    Rslt.Name := StrPas(fib_FileName);
+    Name := fib_FileName;
+    SetCodePage(Name,DefaultFileSystemCodePage,False);
     Rslt.Size := fib_Size;
     Rslt.Size := fib_Size;
     Rslt.Time := DateTimeToFileDate(AmigaFileDateToDateTime(fib_Date,validDate));
     Rslt.Time := DateTimeToFileDate(AmigaFileDateToDateTime(fib_Date,validDate));
     if not validDate then exit;
     if not validDate then exit;
@@ -445,20 +451,21 @@ begin
 end;
 end;
 
 
 
 
-procedure FindClose(var f: TSearchRec);
+Procedure InternalFindClose(var Handle: THandle);
 var
 var
   Anchor: PAnchorPath;
   Anchor: PAnchorPath;
 begin
 begin
-  Anchor:=PAnchorPath(f.FindHandle);
+  Anchor:=PAnchorPath(Handle);
   if not assigned(Anchor) then exit;
   if not assigned(Anchor) then exit;
   MatchEnd(Anchor);
   MatchEnd(Anchor);
   Dispose(Anchor);
   Dispose(Anchor);
+  Handle:=THandle(nil);
 end;
 end;
 
 
 
 
 (****** end of non portable routines ******)
 (****** end of non portable routines ******)
 
 
-Function FileGetAttr (Const FileName : String) : Longint;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
 var
 var
  F: file;
  F: file;
  attr: word;
  attr: word;
@@ -472,7 +479,7 @@ begin
 end;
 end;
 
 
 
 
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
 var
 var
  F: file;
  F: file;
 begin
 begin
@@ -534,44 +541,17 @@ Begin
   DiskSize := dos.DiskSize(Drive);
   DiskSize := dos.DiskSize(Drive);
 End;
 End;
 
 
-function GetCurrentDir : String;
-begin
-  GetDir (0,Result);
-end;
-
-
-Function SetCurrentDir (Const NewDir : String) : Boolean;
-begin
-  ChDir(NewDir);
-  result := (IOResult = 0);
-end;
-
-
-Function CreateDir (Const NewDir : String) : Boolean;
-begin
-  MkDir(NewDir);
-  result := (IOResult = 0);
-end;
-
-
-Function RemoveDir (Const Dir : String) : Boolean;
-begin
-  RmDir(Dir);
-  result := (IOResult = 0);
-end;
-
-
-function DirectoryExists(const Directory: string): Boolean;
+function DirectoryExists(const Directory: RawByteString): Boolean;
 var
 var
-  tmpStr : String;
   tmpLock: LongInt;
   tmpLock: LongInt;
   FIB    : PFileInfoBlock;
   FIB    : PFileInfoBlock;
+  SystemFileName: RawByteString;
 begin
 begin
   result:=false;
   result:=false;
   if (Directory='') or (InOutRes<>0) then exit;
   if (Directory='') or (InOutRes<>0) then exit;
-  tmpStr:=PathConv(Directory);
+  SystemFileName:=PathConv(ToSingleByteFileSystemEncodedFileName(Directory));
 
 
-  tmpLock:=dosLock(tmpStr,SHARED_LOCK);
+  tmpLock:=dosLock(PChar(SystemFileName),SHARED_LOCK);
   if tmpLock=0 then exit;
   if tmpLock=0 then exit;
 
 
   FIB:=nil; new(FIB);
   FIB:=nil; new(FIB);
@@ -654,7 +634,7 @@ begin
   Result:=Dos.envCount;
   Result:=Dos.envCount;
 end;
 end;
 
 
-Function GetEnvironmentString(Index : Integer) : String;
+Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 
 
 begin
 begin
   // Result:=FPCGetEnvStrFromP(Envp,Index);
   // Result:=FPCGetEnvStrFromP(Envp,Index);

+ 26 - 4
rtl/msdos/dos.pp

@@ -902,9 +902,20 @@ end;
 
 
 
 
 procedure getfattr(var f;var attr : word);
 procedure getfattr(var f;var attr : word);
+var
+  path: pchar;
+{$ifndef FPC_ANSI_TEXTFILEREC}
+  r: rawbytestring;
+{$endif not FPC_ANSI_TEXTFILEREC}
 begin
 begin
-  dosregs.dx:=Ofs(filerec(f).name);
-  dosregs.ds:=Seg(filerec(f).name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  path:=@filerec(f).Name;
+{$else}
+  r:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+  path:=pchar(r);
+{$endif}
+  dosregs.dx:=Ofs(path^);
+  dosregs.ds:=Seg(path^);
   if LFNSupport then
   if LFNSupport then
    begin
    begin
      dosregs.ax:=$7143;
      dosregs.ax:=$7143;
@@ -919,6 +930,11 @@ end;
 
 
 
 
 procedure setfattr(var f;attr : word);
 procedure setfattr(var f;attr : word);
+var
+  path: pchar;
+{$ifndef FPC_ANSI_TEXTFILEREC}
+  r: rawbytestring;
+{$endif not FPC_ANSI_TEXTFILEREC}
 begin
 begin
   { Fail for setting VolumeId. }
   { Fail for setting VolumeId. }
   if ((attr and VolumeID)<>0) then
   if ((attr and VolumeID)<>0) then
@@ -926,8 +942,14 @@ begin
     doserror:=5;
     doserror:=5;
     exit;
     exit;
   end;
   end;
-  dosregs.dx:=Ofs(filerec(f).name);
-  dosregs.ds:=Seg(filerec(f).name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  path:=@filerec(f).Name;
+{$else}
+  r:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
+  path:=pchar(r);
+{$endif}
+  dosregs.dx:=Ofs(path);
+  dosregs.ds:=Seg(path);
   if LFNSupport then
   if LFNSupport then
    begin
    begin
      dosregs.ax:=$7143;
      dosregs.ax:=$7143;

+ 24 - 0
rtl/msdos/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 28 - 24
rtl/msdos/sysdir.inc

@@ -18,19 +18,21 @@
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
 
 
-procedure DosDir(func:byte;s:pchar;len:integer);
+procedure DosDir(func:byte;s: rawbytestring);
 var
 var
   regs   : Registers;
   regs   : Registers;
+  len    : Longint;
 begin
 begin
   DoDirSeparators(s);
   DoDirSeparators(s);
   { True DOS does not like backslashes at end
   { True DOS does not like backslashes at end
     Win95 DOS accepts this !!
     Win95 DOS accepts this !!
     but "\" and "c:\" should still be kept and accepted hopefully PM }
     but "\" and "c:\" should still be kept and accepted hopefully PM }
-  if (len>0) and (s[len-1]='\') and
-     Not ((len=1) or ((len=3) and (s[1]=':'))) then
-    s[len-1]:=#0;
-  regs.DX:=Ofs(s^);
-  regs.DS:=Seg(s^);
+  len:=length(s);
+  if (len>0) and (s[len]='\') and
+     Not ((len=1) or ((len=3) and (s[2]=':'))) then
+    s[len]:=#0;
+  regs.DX:=Ofs(s[1]);
+  regs.DS:=Seg(s[1]);
   if LFNSupport then
   if LFNSupport then
    regs.AX:=$7100+func
    regs.AX:=$7100+func
   else
   else
@@ -40,32 +42,31 @@ begin
    GetInOutRes(regs.AX);
    GetInOutRes(regs.AX);
 end;
 end;
 
 
-Procedure MkDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_MKDIR'];
+Procedure do_MkDir(const s: rawbytestring);
 begin
 begin
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
-    exit;
-   DosDir($39,s,len);
+   DosDir($39,s);
 end;
 end;
 
 
-Procedure RmDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_RMDIR'];
+Procedure do_RmDir(const s: rawbytestring);
 begin
 begin
-  if (len=1) and (s[0] = '.' ) then
-    InOutRes := 16;
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
-   exit;
-  DosDir($3a,s,len);
+  if s='.' then
+    begin
+      InOutRes:=16;
+      exit;
+    end;
+  DosDir($3a,s);
 end;
 end;
 
 
-Procedure ChDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
+Procedure do_ChDir(const s: rawbytestring);
 var
 var
   regs : Registers;
   regs : Registers;
+  len  : Longint;
 begin
 begin
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
-   exit;
+  len:=Length(s);
 { First handle Drive changes }
 { First handle Drive changes }
-  if (len>=2) and (s[1]=':') then
+  if (len>=2) and (s[2]=':') then
    begin
    begin
-     regs.DX:=(ord(s[0]) and (not 32))-ord('A');
+     regs.DX:=(ord(s[1]) and (not 32))-ord('A');
      regs.AX:=$0e00;
      regs.AX:=$0e00;
      MsDos(regs);
      MsDos(regs);
      regs.AX:=$1900;
      regs.AX:=$1900;
@@ -81,10 +82,10 @@ begin
        exit;
        exit;
    end;
    end;
 { do the normal dos chdir }
 { do the normal dos chdir }
-  DosDir($3b,s,len);
+  DosDir($3b,s);
 end;
 end;
 
 
-procedure GetDir (DriveNr: byte; var Dir: ShortString);
+procedure do_GetDir (DriveNr: byte; var Dir: RawByteString);
 var
 var
   temp : array[0..260] of char;
   temp : array[0..260] of char;
   i    : longint;
   i    : longint;
@@ -102,12 +103,14 @@ begin
    Begin
    Begin
      GetInOutRes (regs.AX);
      GetInOutRes (regs.AX);
      Dir := char (DriveNr + 64) + ':\';
      Dir := char (DriveNr + 64) + ':\';
+     SetCodePage (Dir,DefaultFileSystemCodePage,false);
      exit;
      exit;
    end
    end
   else
   else
     temp[252] := #0;  { to avoid shortstring buffer overflow }
     temp[252] := #0;  { to avoid shortstring buffer overflow }
 { conversion to Pascal string including slash conversion }
 { conversion to Pascal string including slash conversion }
   i:=0;
   i:=0;
+  SetLength(dir,260);
   while (temp[i]<>#0) do
   while (temp[i]<>#0) do
    begin
    begin
      if temp[i] in AllowDirectorySeparators then
      if temp[i] in AllowDirectorySeparators then
@@ -117,7 +120,8 @@ begin
    end;
    end;
   dir[2]:=':';
   dir[2]:=':';
   dir[3]:='\';
   dir[3]:='\';
-  dir[0]:=char(i+3);
+  SetLength(dir,i+3);
+  SetCodePage (dir,DefaultFileSystemCodePage,false);
 { upcase the string }
 { upcase the string }
   if not FileNameCasePreserving then
   if not FileNameCasePreserving then
    dir:=upcase(dir);
    dir:=upcase(dir);

+ 24 - 7
rtl/msdos/sysfile.inc

@@ -54,11 +54,13 @@ begin
 end;
 end;
 
 
 
 
-procedure do_erase(p : pchar);
+procedure do_erase(p : pchar; pchangeable: boolean);
 var
 var
   regs : Registers;
   regs : Registers;
+  oldp : pchar;
 begin
 begin
-  DoDirSeparators(p);
+  oldp:=p;
+  DoDirSeparators(p,pchangeable);
   regs.DX:=Ofs(p^);
   regs.DX:=Ofs(p^);
   regs.DS:=Seg(p^);
   regs.DS:=Seg(p^);
   if LFNSupport then
   if LFNSupport then
@@ -70,15 +72,20 @@ begin
   MsDos(regs);
   MsDos(regs);
   if (regs.Flags and fCarry) <> 0 then
   if (regs.Flags and fCarry) <> 0 then
    GetInOutRes(regs.AX);
    GetInOutRes(regs.AX);
+  if p<>oldp then
+    freemem(p);
 end;
 end;
 
 
 
 
-procedure do_rename(p1,p2 : pchar);
+procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
 var
 var
   regs : Registers;
   regs : Registers;
+  oldp1, oldp2 : pchar;
 begin
 begin
-  DoDirSeparators(p1);
-  DoDirSeparators(p2);
+  oldp1:=p1;
+  oldp2:=p2;
+  DoDirSeparators(p1,p1changeable);
+  DoDirSeparators(p2,p2changeable);
   regs.DS:=Seg(p1^);
   regs.DS:=Seg(p1^);
   regs.DX:=Ofs(p1^);
   regs.DX:=Ofs(p1^);
   regs.ES:=Seg(p2^);
   regs.ES:=Seg(p2^);
@@ -91,6 +98,10 @@ begin
   MsDos(regs);
   MsDos(regs);
   if (regs.Flags and fCarry) <> 0 then
   if (regs.Flags and fCarry) <> 0 then
    GetInOutRes(regs.AX);
    GetInOutRes(regs.AX);
+  if p1<>oldp1 then
+    freemem(p1);
+  if p2<>oldp2 then
+    freemem(p2);
 end;
 end;
 
 
 
 
@@ -229,7 +240,7 @@ begin
     Increase_file_handle_count:=true;
     Increase_file_handle_count:=true;
 end;
 end;
 
 
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
 {
 {
   filerec and textrec have both handle and mode as the first items so
   filerec and textrec have both handle and mode as the first items so
   they could use the same routine for opening/creating.
   they could use the same routine for opening/creating.
@@ -240,8 +251,8 @@ procedure do_open(var f;p:pchar;flags:longint);
 var
 var
   regs   : Registers;
   regs   : Registers;
   action : longint;
   action : longint;
+  oldp : pchar;
 begin
 begin
-  DoDirSeparators(p);
 { close first if opened }
 { close first if opened }
   if ((flags and $10000)=0) then
   if ((flags and $10000)=0) then
    begin
    begin
@@ -283,6 +294,8 @@ begin
      end;
      end;
      exit;
      exit;
    end;
    end;
+  oldp:=p;
+  DoDirSeparators(p,pchangeable);
 {$ifndef RTLLITE}
 {$ifndef RTLLITE}
   if LFNSupport then
   if LFNSupport then
    begin
    begin
@@ -332,6 +345,8 @@ begin
   if (regs.Flags and fCarry) <> 0 then
   if (regs.Flags and fCarry) <> 0 then
     begin
     begin
       GetInOutRes(regs.AX);
       GetInOutRes(regs.AX);
+      if oldp<>p then
+        freemem(p);
       exit;
       exit;
     end
     end
   else
   else
@@ -366,6 +381,8 @@ begin
      do_seekend(filerec(f).handle);
      do_seekend(filerec(f).handle);
      filerec(f).mode:=fmoutput; {fool fmappend}
      filerec(f).mode:=fmoutput; {fool fmappend}
    end;
    end;
+  if oldp<>p then
+    freemem(p);
 end;
 end;
 
 
 
 

+ 27 - 54
rtl/msdos/sysutils.pp

@@ -28,6 +28,12 @@ uses
   {go32,}dos;
   {go32,}dos;
 
 
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_SLEEP}
+
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
 { Include platform independent interface part }
 { Include platform independent interface part }
 {$i sysutilh.inc}
 {$i sysutilh.inc}
 
 
@@ -78,7 +84,7 @@ end ;}
 
 
 {  Native OpenFile function.
 {  Native OpenFile function.
    if return value <> 0 call failed.  }
    if return value <> 0 call failed.  }
-function OpenFile(const FileName: string; var Handle: THandle; Mode, Action: word): longint;
+function OpenFile(const FileName: RawByteString; var Handle: THandle; Mode, Action: word): longint;
 var
 var
    Regs: registers;
    Regs: registers;
 begin
 begin
@@ -110,7 +116,7 @@ begin
 end;
 end;
 
 
 
 
-Function FileOpen (Const FileName : string; Mode : Integer) : THandle;
+Function FileOpen (Const FileName : RawByteString; Mode : Integer) : THandle;
 var
 var
   e: integer;
   e: integer;
 Begin
 Begin
@@ -120,7 +126,7 @@ Begin
 end;
 end;
 
 
 
 
-Function FileCreate (Const FileName : String) : THandle;
+Function FileCreate (Const FileName : RawByteString) : THandle;
 var
 var
   e: integer;
   e: integer;
 begin
 begin
@@ -130,13 +136,13 @@ begin
 end;
 end;
 
 
 
 
-Function FileCreate (Const FileName : String; ShareMode:longint; Rights : longint) : THandle;
+Function FileCreate (Const FileName : RawByteString; ShareMode:longint; Rights : longint) : THandle;
 begin
 begin
   FileCreate:=FileCreate(FileName);
   FileCreate:=FileCreate(FileName);
 end;
 end;
 
 
 
 
-Function FileCreate (Const FileName : String; Rights:longint) : THandle;
+Function FileCreate (Const FileName : RawByteString; Rights:longint) : THandle;
 begin
 begin
   FileCreate:=FileCreate(FileName);
   FileCreate:=FileCreate(FileName);
 end;
 end;
@@ -270,7 +276,7 @@ begin
 end;
 end;
 
 
 
 
-Function FileAge (Const FileName : String): Longint;
+Function FileAge (Const FileName : RawByteString): Longint;
 var Handle: longint;
 var Handle: longint;
 begin
 begin
   Handle := FileOpen(FileName, 0);
   Handle := FileOpen(FileName, 0);
@@ -284,7 +290,7 @@ begin
 end;
 end;
 
 
 
 
-function FileExists (const FileName: string): boolean;
+function FileExists (const FileName: RawByteString): boolean;
 var
 var
   L: longint;
   L: longint;
 begin
 begin
@@ -299,9 +305,9 @@ begin
 end;
 end;
 
 
 
 
-Function DirectoryExists (Const Directory : String) : Boolean;
+Function DirectoryExists (Const Directory : RawByteString) : Boolean;
 Var
 Var
-  Dir : String;
+  Dir : RawByteString;
   drive : byte;
   drive : byte;
   FADir, StoredIORes : longint;
   FADir, StoredIORes : longint;
 begin
 begin
@@ -340,7 +346,7 @@ begin
 end;
 end;
 
 
 
 
-Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
+Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
 
 
 Var Sr : PSearchrec;
 Var Sr : PSearchrec;
 
 
@@ -356,12 +362,12 @@ begin
      Rslt.Size := Sr^.Size;
      Rslt.Size := Sr^.Size;
      Rslt.Attr := Sr^.Attr;
      Rslt.Attr := Sr^.Attr;
      Rslt.ExcludeAttr := 0;
      Rslt.ExcludeAttr := 0;
-     Rslt.Name := Sr^.Name;
+     Name := Sr^.Name;
    end ;
    end ;
 end;
 end;
 
 
 
 
-Function FindNext (Var Rslt : TSearchRec) : Longint;
+Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
 var
 var
   Sr: PSearchRec;
   Sr: PSearchRec;
 begin
 begin
@@ -376,17 +382,17 @@ begin
         Rslt.Size := Sr^.Size;
         Rslt.Size := Sr^.Size;
         Rslt.Attr := Sr^.Attr;
         Rslt.Attr := Sr^.Attr;
         Rslt.ExcludeAttr := 0;
         Rslt.ExcludeAttr := 0;
-        Rslt.Name := Sr^.Name;
+        Name := Sr^.Name;
       end;
       end;
    end;
    end;
 end;
 end;
 
 
 
 
-Procedure FindClose (Var F : TSearchrec);
+Procedure InternalFindClose(var Handle: THandle);
 var
 var
   Sr: PSearchRec;
   Sr: PSearchRec;
 begin
 begin
-  Sr := PSearchRec(F.FindHandle);
+  Sr := PSearchRec(Handle);
   if Sr <> nil then
   if Sr <> nil then
     begin
     begin
       //!! Dispose(Sr);
       //!! Dispose(Sr);
@@ -394,7 +400,7 @@ begin
       DOS.FindClose(SR^);
       DOS.FindClose(SR^);
       freemem(sr,sizeof(searchrec));
       freemem(sr,sizeof(searchrec));
     end;
     end;
-  F.FindHandle := 0;
+  Handle := 0;
 end;
 end;
 
 
 
 
@@ -432,7 +438,7 @@ begin
 end;
 end;
 
 
 
 
-Function FileGetAttr (Const FileName : String) : Longint;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
 var
 var
   Regs: registers;
   Regs: registers;
 begin
 begin
@@ -453,7 +459,7 @@ begin
 end;
 end;
 
 
 
 
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
 var
 var
   Regs: registers;
   Regs: registers;
 begin
 begin
@@ -475,7 +481,7 @@ begin
 end;
 end;
 
 
 
 
-Function DeleteFile (Const FileName : String) : Boolean;
+Function DeleteFile (Const FileName : RawByteString) : Boolean;
 var
 var
   Regs: registers;
   Regs: registers;
 begin
 begin
@@ -492,7 +498,7 @@ begin
 end;
 end;
 
 
 
 
-Function RenameFile (Const OldName, NewName : String) : Boolean;
+Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
 var
 var
   Regs: registers;
   Regs: registers;
 begin
 begin
@@ -607,39 +613,6 @@ begin
 end;
 end;
 
 
 
 
-Function GetCurrentDir : String;
-begin
-  GetDir(0, result);
-end;
-
-
-Function SetCurrentDir (Const NewDir : String) : Boolean;
-begin
-  {$I-}
-   ChDir(NewDir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
-Function CreateDir (Const NewDir : String) : Boolean;
-begin
-  {$I-}
-   MkDir(NewDir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
-Function RemoveDir (Const Dir : String) : Boolean;
-begin
-  {$I-}
-   RmDir(Dir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
 {****************************************************************************
 {****************************************************************************
                               Time Functions
                               Time Functions
 ****************************************************************************}
 ****************************************************************************}
@@ -794,7 +767,7 @@ begin
   Result:=FPCCountEnvVar(EnvP);
   Result:=FPCCountEnvVar(EnvP);
 end;
 end;
 
 
-Function GetEnvironmentString(Index : Integer) : String;
+Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 
 
 begin
 begin
   Result:=FPCGetEnvStrFromP(Envp,Index);
   Result:=FPCGetEnvStrFromP(Envp,Index);

+ 148 - 146
rtl/nativent/Makefile

@@ -345,442 +345,442 @@ endif
 OBJPASDIR=$(RTL)/objpas
 OBJPASDIR=$(RTL)/objpas
 WINDOWS_SOURCE_FILES=$(addprefix $(WININC)/,$(addsuffix .inc,$(WINDOWS_FILES)))
 WINDOWS_SOURCE_FILES=$(addprefix $(WININC)/,$(addsuffix .inc,$(WINDOWS_FILES)))
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-android)
 ifeq ($(FULL_TARGET),i386-android)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-aix)
 ifeq ($(FULL_TARGET),powerpc-aix)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
 ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
 ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),arm-android)
 ifeq ($(FULL_TARGET),arm-android)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-aix)
 ifeq ($(FULL_TARGET),powerpc64-aix)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),mips-linux)
 ifeq ($(FULL_TARGET),mips-linux)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),jvm-java)
 ifeq ($(FULL_TARGET),jvm-java)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),jvm-android)
 ifeq ($(FULL_TARGET),jvm-android)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
-override TARGET_UNITS+=system uuchar objpas iso7185 buildrtl
+override TARGET_UNITS+=system uuchar objpas iso7185 cpall buildrtl
 endif
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-win32)
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-os2)
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-beos)
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netware)
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-emx)
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-wince)
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
 ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-android)
 ifeq ($(FULL_TARGET),i386-android)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
 ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc-aix)
 ifeq ($(FULL_TARGET),powerpc-aix)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
 ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
 ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),arm-linux)
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),arm-darwin)
 ifeq ($(FULL_TARGET),arm-darwin)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),arm-wince)
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),arm-gba)
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),arm-nds)
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),arm-android)
 ifeq ($(FULL_TARGET),arm-android)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),powerpc64-aix)
 ifeq ($(FULL_TARGET),powerpc64-aix)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),mips-linux)
 ifeq ($(FULL_TARGET),mips-linux)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),jvm-java)
 ifeq ($(FULL_TARGET),jvm-java)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),jvm-android)
 ifeq ($(FULL_TARGET),jvm-android)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
-override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
+override TARGET_IMPLICITUNITS+=ndk ndkutils ddk ctypes strings matrix rtlconsts sysconst sysutils math types strutils dateutils varutils variants typinfo fgl classes convutils stdconvs $(CPU_UNITS) charset ucomplex getopts fmtbcd cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256 cp1257 cp1258 cp437 cp646 cp850 cp866 cp874 cp932 cp936 cp949 cp950 cp8859_1 cp8859_5
 endif
 endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
 override TARGET_RSTS+=math varutils typinfo variants classes dateutils sysconst
 override TARGET_RSTS+=math varutils typinfo variants classes dateutils sysconst
@@ -2601,3 +2601,5 @@ macpas$(PPUEXT) : $(INC)/macpas.pp objpas$(PPUEXT) buildrtl$(PPUEXT)
 	$(COMPILER) $(INC)/macpas.pp $(REDIR)
 	$(COMPILER) $(INC)/macpas.pp $(REDIR)
 buildrtl$(PPUEXT): buildrtl.pp system$(PPUEXT) objpas$(PPUEXT)
 buildrtl$(PPUEXT): buildrtl.pp system$(PPUEXT) objpas$(PPUEXT)
 	$(COMPILER) -Fi$(OBJPASDIR)/sysutils -Fi$(OBJPASDIR)/classes -Fu$(PROCINC) -I$(OBJPASDIR) -Fi$(DDKINC) -I$(INC) -Fu$(INC) -Fu$(OBJPASDIR) buildrtl
 	$(COMPILER) -Fi$(OBJPASDIR)/sysutils -Fi$(OBJPASDIR)/classes -Fu$(PROCINC) -I$(OBJPASDIR) -Fi$(DDKINC) -I$(INC) -Fu$(INC) -Fu$(OBJPASDIR) buildrtl
+cpall$(PPUEXT): $(RTL)/charmaps/cpall.pas system$(PPUEXT) objpas$(PPUEXT)
+	$(COMPILER) -Fu$(INC) -Fi$(RTL)/charmaps $(RTL)/charmaps/cpall.pas

+ 5 - 2
rtl/nativent/Makefile.fpc

@@ -8,7 +8,7 @@ main=rtl
 [target]
 [target]
 loaders=
 loaders=
 #units=system objpas macpas iso7185 buildrtl lineinfo lnfodwrf
 #units=system objpas macpas iso7185 buildrtl lineinfo lnfodwrf
-units=system uuchar objpas iso7185 buildrtl
+units=system uuchar objpas iso7185 cpall buildrtl
 implicitunits=ndk ndkutils ddk \
 implicitunits=ndk ndkutils ddk \
       ctypes strings \
       ctypes strings \
 #      heaptrc
 #      heaptrc
@@ -17,7 +17,7 @@ implicitunits=ndk ndkutils ddk \
 #      dos crt objects \
 #      dos crt objects \
       rtlconsts sysconst sysutils math types \
       rtlconsts sysconst sysutils math types \
       strutils dateutils varutils variants typinfo fgl classes \
       strutils dateutils varutils variants typinfo fgl classes \
-      convutils stdconvs $(CPU_UNITS) charset cpall ucomplex getopts \
+      convutils stdconvs $(CPU_UNITS) charset ucomplex getopts \
 #      sockets printer \
 #      sockets printer \
 #      video mouse keyboard
 #      video mouse keyboard
        fmtbcd \
        fmtbcd \
@@ -124,3 +124,6 @@ macpas$(PPUEXT) : $(INC)/macpas.pp objpas$(PPUEXT) buildrtl$(PPUEXT)
 
 
 buildrtl$(PPUEXT): buildrtl.pp system$(PPUEXT) objpas$(PPUEXT)
 buildrtl$(PPUEXT): buildrtl.pp system$(PPUEXT) objpas$(PPUEXT)
         $(COMPILER) -Fi$(OBJPASDIR)/sysutils -Fi$(OBJPASDIR)/classes -Fu$(PROCINC) -I$(OBJPASDIR) -Fi$(DDKINC) -I$(INC) -Fu$(INC) -Fu$(OBJPASDIR) buildrtl
         $(COMPILER) -Fi$(OBJPASDIR)/sysutils -Fi$(OBJPASDIR)/classes -Fu$(PROCINC) -I$(OBJPASDIR) -Fi$(DDKINC) -I$(INC) -Fu$(INC) -Fu$(OBJPASDIR) buildrtl
+
+cpall$(PPUEXT): $(RTL)/charmaps/cpall.pas system$(PPUEXT) objpas$(PPUEXT)
+        $(COMPILER) -Fu$(INC) -Fi$(RTL)/charmaps $(RTL)/charmaps/cpall.pas

+ 2 - 2
rtl/nativent/ndkutils.pas

@@ -24,7 +24,7 @@ uses
 
 
 // Helpers for converting Pascal string types to NT's UNICODE_STRING
 // Helpers for converting Pascal string types to NT's UNICODE_STRING
 procedure ShortStrToNTStr(aStr: ShortString; var aNTStr: UNICODE_STRING);
 procedure ShortStrToNTStr(aStr: ShortString; var aNTStr: UNICODE_STRING);
-procedure AnsiStrToNTStr(const aStr: String; var aNTStr: UNICODE_STRING);
+procedure AnsiStrToNTStr(const aStr: RawByteString; var aNTStr: UNICODE_STRING);
 procedure UnicodeStrToNtStr(const aStr: UnicodeString;
 procedure UnicodeStrToNtStr(const aStr: UnicodeString;
     var aNTStr: UNICODE_STRING);
     var aNTStr: UNICODE_STRING);
 procedure PCharToNTStr(aStr: PChar; aLen: Cardinal; var aNTStr: UNICODE_STRING);
 procedure PCharToNTStr(aStr: PChar; aLen: Cardinal; var aNTStr: UNICODE_STRING);
@@ -53,7 +53,7 @@ begin
   aNTStr.MaximumLength := aNTStr.Length;
   aNTStr.MaximumLength := aNTStr.Length;
 end;
 end;
 
 
-procedure AnsiStrToNTStr(const aStr: String; var aNTStr: UNICODE_STRING);
+procedure AnsiStrToNTStr(const aStr: RawByteString; var aNTStr: UNICODE_STRING);
 var
 var
   buf: PWideChar;
   buf: PWideChar;
   i: Integer;
   i: Integer;

+ 24 - 0
rtl/nativent/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 16 - 15
rtl/nativent/sysdir.inc

@@ -17,7 +17,7 @@
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
 
 
-procedure MkDir(s: pchar; len: sizeuint); [IOCheck, public, alias : 'FPC_SYS_MKDIR'];
+procedure do_MkDir(const s: UnicodeString);
 var
 var
   objattr: TObjectAttributes;
   objattr: TObjectAttributes;
   name: TNtUnicodeString;
   name: TNtUnicodeString;
@@ -25,10 +25,7 @@ var
   iostatus: TIOStatusBlock;
   iostatus: TIOStatusBlock;
   h: THandle;
   h: THandle;
 begin
 begin
-  if not Assigned(s) or (len <= 1) or (InOutRes <> 0) then
-    Exit;
-
-  SysPCharToNtStr(name, s, len);
+  SysUnicodeStringToNtStr(name, s);
 
 
   { first we try to create a directory object }
   { first we try to create a directory object }
   SysInitializeObjectAttributes(objattr, @name, OBJ_PERMANENT, 0, Nil);
   SysInitializeObjectAttributes(objattr, @name, OBJ_PERMANENT, 0, Nil);
@@ -61,7 +58,7 @@ begin
   SysFreeNtStr(name);
   SysFreeNtStr(name);
 end;
 end;
 
 
-procedure RmDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_RMDIR'];
+procedure do_RmDir(const s: UnicodeString);
 var
 var
   ntstr: TNtUnicodeString;
   ntstr: TNtUnicodeString;
   objattr: TObjectAttributes;
   objattr: TObjectAttributes;
@@ -70,14 +67,18 @@ var
   disp: TFileDispositionInformation;
   disp: TFileDispositionInformation;
   res: LongInt;
   res: LongInt;
 begin
 begin
-  if (len = 1) and (s^ = '.') then
-    InOutRes := 16;
-  if not assigned(s) or (len = 0) or (InOutRes <> 0) then
-    Exit;
-  if (len = 2) and (s[0] = '.') and (s[1] = '.') then
-    InOutRes := 5;
+  if s = '.' then
+    begin
+      InOutRes := 16;
+      exit;
+    end;
+  if s = '..' then
+    begin
+      InOutRes := 5;
+      exit;
+    end;
 
 
-  SysPCharToNtStr(ntstr, s, len);
+  SysUnicodeStringToNtStr(ntstr, s);
   SysInitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   SysInitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
 
 
   res := NtOpenDirectoryObject(@h, STANDARD_RIGHTS_REQUIRED, @objattr);
   res := NtOpenDirectoryObject(@h, STANDARD_RIGHTS_REQUIRED, @objattr);
@@ -115,13 +116,13 @@ begin
   Errno2InoutRes;
   Errno2InoutRes;
 end;
 end;
 
 
-procedure ChDir(s: pchar; len: sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
+procedure do_ChDir(const s: UnicodeString);
 begin
 begin
   { for now this is not supported }
   { for now this is not supported }
   InOutRes := 3;
   InOutRes := 3;
 end;
 end;
 
 
-procedure GetDir(DriveNr: byte; var Dir: ShortString);
+procedure do_GetDir(DriveNr: byte; var Dir: UnicodeString);
 begin
 begin
   { for now we return simply the root directory }
   { for now we return simply the root directory }
   Dir := DirectorySeparator;
   Dir := DirectorySeparator;

+ 26 - 11
rtl/nativent/sysfile.inc

@@ -34,7 +34,7 @@ begin
 end;
 end;
 
 
 
 
-procedure do_erase(p : pchar);
+procedure do_erase(p : pwidechar; pchangeable: boolean);
 var
 var
   ntstr: TNtUnicodeString;
   ntstr: TNtUnicodeString;
   objattr: TObjectAttributes;
   objattr: TObjectAttributes;
@@ -42,11 +42,13 @@ var
   h: THandle;
   h: THandle;
   disp: TFileDispositionInformation;
   disp: TFileDispositionInformation;
   res: LongInt;
   res: LongInt;
+  oldp: pwidechar;
 begin
 begin
   InoutRes := 4;
   InoutRes := 4;
-  DoDirSeparators(p);
+  oldp:=p;
+  DoDirSeparators(p,pchangeable);
 
 
-  SysPCharToNtStr(ntstr, p, 0);
+  SysPWideCharToNtStr(ntstr, p, 0);
   SysInitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   SysInitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
 
 
   res := NtCreateFile(@h, NT_DELETE or NT_SYNCHRONIZE, @objattr, @iostatus, Nil,
   res := NtCreateFile(@h, NT_DELETE or NT_SYNCHRONIZE, @objattr, @iostatus, Nil,
@@ -71,10 +73,12 @@ begin
 
 
   SysFreeNtStr(ntstr);
   SysFreeNtStr(ntstr);
   Errno2InoutRes;
   Errno2InoutRes;
+  if p<>oldp then
+    freemem(p);
 end;
 end;
 
 
 
 
-procedure do_rename(p1,p2 : pchar);
+procedure do_rename(p1,p2 : pwidechar; p1changeable, p2changeable: boolean);
 var
 var
   h: THandle;
   h: THandle;
   objattr: TObjectAttributes;
   objattr: TObjectAttributes;
@@ -82,12 +86,14 @@ var
   dest, src: TNtUnicodeString;
   dest, src: TNtUnicodeString;
   renameinfo: PFileRenameInformation;
   renameinfo: PFileRenameInformation;
   res: LongInt;
   res: LongInt;
+  oldp1, oldp2 : pwidechar;
 begin
 begin
-  DoDirSeparators(p1);
-  DoDirSeparators(p2);
+  oldp1:=p1;
+  oldp2:=p2;
 
 
   { check whether the destination exists first }
   { check whether the destination exists first }
-  SysPCharToNtStr(dest, p2, 0);
+  DoDirSeparators(p2,p2changeable);
+  SysPWideCharToNtStr(dest, p2, 0);
   SysInitializeObjectAttributes(objattr, @dest, 0, 0, Nil);
   SysInitializeObjectAttributes(objattr, @dest, 0, 0, Nil);
 
 
   res := NtCreateFile(@h, 0, @objattr, @iostatus, Nil, 0,
   res := NtCreateFile(@h, 0, @objattr, @iostatus, Nil, 0,
@@ -99,7 +105,8 @@ begin
     errno := 5;
     errno := 5;
     Errno2InoutRes;
     Errno2InoutRes;
   end else begin
   end else begin
-    SysPCharToNtStr(src, p1, 0);
+    DoDirSeparators(p1,p1changeable);
+    SysPWideCharToNtStr(src, p1, 0);
     SysInitializeObjectAttributes(objattr, @src, 0, 0, Nil);
     SysInitializeObjectAttributes(objattr, @src, 0, 0, Nil);
 
 
     res := NtCreateFile(@h, GENERIC_ALL or NT_SYNCHRONIZE or FILE_READ_ATTRIBUTES,
     res := NtCreateFile(@h, GENERIC_ALL or NT_SYNCHRONIZE or FILE_READ_ATTRIBUTES,
@@ -138,6 +145,10 @@ begin
   end;
   end;
 
 
   SysFreeNtStr(dest);
   SysFreeNtStr(dest);
+  if p1<>oldp1 then
+    freemem(p1);
+  if p2<>oldp2 then
+    freemem(p2);
 end;
 end;
 
 
 
 
@@ -292,7 +303,7 @@ begin
 end;
 end;
 
 
 
 
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pwidechar;flags:longint; pchangeable: boolean);
 {
 {
   filerec and textrec have both handle and mode as the first items so
   filerec and textrec have both handle and mode as the first items so
   they could use the same routine for opening/creating.
   they could use the same routine for opening/creating.
@@ -306,8 +317,8 @@ var
   iostatus: TIoStatusBlock;
   iostatus: TIoStatusBlock;
   ntstr: TNtUnicodeString;
   ntstr: TNtUnicodeString;
   res: LongInt;
   res: LongInt;
+  oldp : pwidechar;
 begin
 begin
-  DoDirSeparators(p);
   { close first if opened }
   { close first if opened }
   if ((flags and $10000)=0) then
   if ((flags and $10000)=0) then
    begin
    begin
@@ -378,7 +389,9 @@ begin
      exit;
      exit;
    end;
    end;
 
 
-  SysPCharToNtStr(ntstr, p, 0);
+  oldp:=p;
+  DoDirSeparators(p,pchangeable);
+  SysPWideCharToNtStr(ntstr, p, 0);
 
 
   SysInitializeObjectAttributes(objattr, @ntstr, OBJ_INHERIT, 0, Nil);
   SysInitializeObjectAttributes(objattr, @ntstr, OBJ_INHERIT, 0, Nil);
 
 
@@ -399,4 +412,6 @@ begin
     errno := res;
     errno := res;
     Errno2InoutRes;
     Errno2InoutRes;
   end;
   end;
+  if oldp<>p then
+    freemem(p);
 end;
 end;

+ 25 - 1
rtl/nativent/sysos.inc

@@ -368,10 +368,34 @@ begin
   aNtStr.Length := aLen * SizeOf(WideChar);
   aNtStr.Length := aLen * SizeOf(WideChar);
   aNtStr.MaximumLength := aNtStr.Length;
   aNtStr.MaximumLength := aNtStr.Length;
   aNtStr.Buffer := GetMem(aNtStr.Length);
   aNtStr.Buffer := GetMem(aNtStr.Length);
-  for i := 0 to aLen do
+  for i := 0 to aLen-1 do
     aNtStr.Buffer[i] := aText[i];
     aNtStr.Buffer[i] := aText[i];
 end;
 end;
 
 
+procedure SysPWideCharToNtStr(var aNtStr: TNtUnicodeString; aText: PWideChar;
+  aLen: LongWord);
+var
+  i: Integer;
+begin
+  if (aLen = 0) and (aText <> Nil) and (aText^ <> #0) then
+    aLen := Length(aText);
+  aNtStr.Length := aLen * SizeOf(WideChar);
+  aNtStr.MaximumLength := aNtStr.Length;
+  aNtStr.Buffer := GetMem(aNtStr.Length);
+  Move(aText[0],aNtStr.Buffer[0],aLen);
+end;
+
+procedure SysUnicodeStringToNtStr(var aNtStr: TNtUnicodeString; const s: UnicodeString);
+var
+  i: Integer;
+begin
+  aNtStr.Length := Length(s) * SizeOf(WideChar);
+  aNtStr.MaximumLength := aNtStr.Length;
+  aNtStr.Buffer := GetMem(aNtStr.Length);
+  if aNtStr.Length<>0 then
+    Move(s[1],aNtStr.Buffer[0],aNtStr.Length);
+end;
+
 procedure SysFreeNtStr(var aNtStr: TNtUnicodeString);
 procedure SysFreeNtStr(var aNtStr: TNtUnicodeString);
 begin
 begin
   if aNtStr.Buffer <> Nil then begin
   if aNtStr.Buffer <> Nil then begin

+ 239 - 157
rtl/nativent/sysutils.pp

@@ -30,7 +30,7 @@ uses
 
 
 type
 type
   TNativeNTFindData = record
   TNativeNTFindData = record
-    SearchSpec: String;
+    SearchSpec: UnicodeString;
     NamePos: LongInt;
     NamePos: LongInt;
     Handle: THandle;
     Handle: THandle;
     IsDirObj: Boolean;
     IsDirObj: Boolean;
@@ -39,6 +39,12 @@ type
     LastRes: NTSTATUS;
     LastRes: NTSTATUS;
   end;
   end;
 
 
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API (actually it's
+  unicodestring, but that's not yet implemented) }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
 { Include platform independent interface part }
 { Include platform independent interface part }
 {$i sysutilh.inc}
 {$i sysutilh.inc}
 
 
@@ -56,7 +62,7 @@ implementation
                               File Functions
                               File Functions
 ****************************************************************************}
 ****************************************************************************}
 
 
-function FileOpen(const FileName : string; Mode : Integer) : THandle;
+function FileOpen(const FileName : UnicodeString; Mode : Integer) : THandle;
 const
 const
   AccessMode: array[0..2] of ACCESS_MASK  = (
   AccessMode: array[0..2] of ACCESS_MASK  = (
     GENERIC_READ,
     GENERIC_READ,
@@ -73,7 +79,7 @@ var
   objattr: OBJECT_ATTRIBUTES;
   objattr: OBJECT_ATTRIBUTES;
   iostatus: IO_STATUS_BLOCK;
   iostatus: IO_STATUS_BLOCK;
 begin
 begin
-  AnsiStrToNtStr(FileName, ntstr);
+  UnicodeStrToNtStr(FileName, ntstr);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   NtCreateFile(@Result, AccessMode[Mode and 3] or NT_SYNCHRONIZE, @objattr,
   NtCreateFile(@Result, AccessMode[Mode and 3] or NT_SYNCHRONIZE, @objattr,
     @iostatus, Nil, FILE_ATTRIBUTE_NORMAL, ShareMode[(Mode and $F0) shr 4],
     @iostatus, Nil, FILE_ATTRIBUTE_NORMAL, ShareMode[(Mode and $F0) shr 4],
@@ -82,19 +88,19 @@ begin
 end;
 end;
 
 
 
 
-function FileCreate(const FileName : String) : THandle;
+function FileCreate(const FileName : UnicodeString) : THandle;
 begin
 begin
   FileCreate := FileCreate(FileName, fmShareDenyNone, 0);
   FileCreate := FileCreate(FileName, fmShareDenyNone, 0);
 end;
 end;
 
 
 
 
-function FileCreate(const FileName : String; Rights: longint) : THandle;
+function FileCreate(const FileName : UnicodeString; Rights: longint) : THandle;
 begin
 begin
   FileCreate := FileCreate(FileName, fmShareDenyNone, Rights);
   FileCreate := FileCreate(FileName, fmShareDenyNone, Rights);
 end;
 end;
 
 
 
 
-function FileCreate(const FileName : String; ShareMode : longint; Rights: longint) : THandle;
+function FileCreate(const FileName : UnicodeString; ShareMode : longint; Rights: longint) : THandle;
 const
 const
   ShareModeFlags: array[0..4] of ULONG = (
   ShareModeFlags: array[0..4] of ULONG = (
                0,
                0,
@@ -108,7 +114,7 @@ var
   iostatus: IO_STATUS_BLOCK;
   iostatus: IO_STATUS_BLOCK;
   res: NTSTATUS;
   res: NTSTATUS;
 begin
 begin
-  AnsiStrToNTStr(FileName, ntstr);
+  UnicodeStrToNtStr(FileName, ntstr);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   NtCreateFile(@Result, GENERIC_READ or GENERIC_WRITE or NT_SYNCHRONIZE,
   NtCreateFile(@Result, GENERIC_READ or GENERIC_WRITE or NT_SYNCHRONIZE,
     @objattr, @iostatus, Nil, FILE_ATTRIBUTE_NORMAL,
     @objattr, @iostatus, Nil, FILE_ATTRIBUTE_NORMAL,
@@ -305,14 +311,14 @@ begin
   aNtTime.QuadPart := local.QuadPart + bias.QuadPart;
   aNtTime.QuadPart := local.QuadPart + bias.QuadPart;
 end;
 end;
 
 
-function FileAge(const FileName: String): Longint;
+function FileAge(const FileName: UnicodeString): Longint;
 begin
 begin
   { TODO }
   { TODO }
   Result := -1;
   Result := -1;
 end;
 end;
 
 
 
 
-function FileExists(const FileName: String): Boolean;
+function FileExists(const FileName: UnicodeString): Boolean;
 var
 var
   ntstr: UNICODE_STRING;
   ntstr: UNICODE_STRING;
   objattr: OBJECT_ATTRIBUTES;
   objattr: OBJECT_ATTRIBUTES;
@@ -320,7 +326,7 @@ var
   iostatus: IO_STATUS_BLOCK;
   iostatus: IO_STATUS_BLOCK;
   h: THandle;
   h: THandle;
 begin
 begin
-  AnsiStrToNtStr(FileName, ntstr);
+  UnicodeStrToNtStr(FileName, ntstr);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   res := NtOpenFile(@h, FILE_READ_ATTRIBUTES or NT_SYNCHRONIZE, @objattr,
   res := NtOpenFile(@h, FILE_READ_ATTRIBUTES or NT_SYNCHRONIZE, @objattr,
            @iostatus, FILE_SHARE_READ or FILE_SHARE_WRITE,
            @iostatus, FILE_SHARE_READ or FILE_SHARE_WRITE,
@@ -333,7 +339,7 @@ begin
 end;
 end;
 
 
 
 
-function DirectoryExists(const Directory : String) : Boolean;
+function DirectoryExists(const Directory : UnicodeString) : Boolean;
 var
 var
   ntstr: UNICODE_STRING;
   ntstr: UNICODE_STRING;
   objattr: OBJECT_ATTRIBUTES;
   objattr: OBJECT_ATTRIBUTES;
@@ -341,7 +347,7 @@ var
   iostatus: IO_STATUS_BLOCK;
   iostatus: IO_STATUS_BLOCK;
   h: THandle;
   h: THandle;
 begin
 begin
-  AnsiStrToNtStr(Directory, ntstr);
+  UnicodeStrToNtStr(Directory, ntstr);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
 
 
   { first test wether this is a object directory }
   { first test wether this is a object directory }
@@ -364,80 +370,193 @@ begin
   FreeNtStr(ntstr);
   FreeNtStr(ntstr);
 end;
 end;
 
 
-{ copied from rtl/unix/sysutils.pp }
-Function FNMatch(const Pattern,Name:string):Boolean;
+{ copied from rtl/unix/sysutils.pp and adapted to UTF-16 }
+Function FNMatch(const Pattern,Name:UnicodeString):Boolean;
 Var
 Var
   LenPat,LenName : longint;
   LenPat,LenName : longint;
 
 
+  function NameUtf16CodePointLen(index: longint): longint;
+    begin
+      { see https://en.wikipedia.org/wiki/UTF-16#Description for details }
+      Result:=1;
+      { valid surrogate pair? }
+      if (Name[index]>=#$D800) and
+         (Name[index]<=#$DBFF) then
+        begin
+          if (index+1<=LenName) and
+             (Name[index+1]>=#$DC00) and
+             (Name[index+1]<=#$DFFF) then
+            inc(Result)
+          else
+            exit;
+        end;
+      { combining diacritics?
+          1) U+0300 - U+036F
+          2) U+1DC0 - U+1DFF
+          3) U+20D0 - U+20FF
+          4) U+FE20 - U+FE2F
+      }
+      while (index+Result+1<=LenName) and
+            ((word(ord(Name[index+Result+1])-$0300) <= word($036F-$0300)) or
+             (word(ord(Name[index+Result+1])-$1DC0) <= word($1DFF-$1DC0)) or
+             (word(ord(Name[index+Result+1])-$20D0) <= word($20FF-$20D0)) or
+             (word(ord(Name[index+Result+1])-$FE20) <= word($FE2F-$FE20))) do
+        begin
+          inc(Result)
+        end;
+    end;
+
+    procedure GoToLastByteOfUtf16CodePoint(var j: longint);
+    begin
+      { Take one less, because we have to stop at the last word of the sequence.
+      }
+      inc(j,NameUtf16CodePointLen(j)-1);
+    end;
+
+  { input:
+      i: current position in pattern (start of utf-16 code point)
+      j: current position in name (start of utf-16 code point)
+      update_i_j: should i and j be changed by the routine or not
+
+    output:
+      i: if update_i_j, then position of last matching part of code point in
+         pattern, or first non-matching code point in pattern. Otherwise the
+         same value as on input.
+      j: if update_i_j, then position of last matching part of code point in
+         name, or first non-matching code point in name. Otherwise the
+         same value as on input.
+      result: true if match, false if no match
+  }
+  function CompareUtf16CodePoint(var i,j: longint; update_i_j: boolean): Boolean;
+    var
+      words,
+      new_i,
+      new_j: longint;
+    begin
+      words:=NameUtf16CodePointLen(j);
+      new_i:=i;
+      new_j:=j;
+      { ensure that a part of an UTF-8 codepoint isn't interpreted
+        as '*' or '?' }
+      repeat
+        dec(words);
+        Result:=
+          (new_j<=LenName) and
+          (new_i<=LenPat) and
+          (Pattern[new_i]=Name[new_j]);
+        inc(new_i);
+        inc(new_j);
+      until not(Result) or
+            (words=0);
+      if update_i_j then
+        begin
+          i:=new_i;
+          j:=new_j;
+        end;
+    end;
+
+
   Function DoFNMatch(i,j:longint):Boolean;
   Function DoFNMatch(i,j:longint):Boolean;
   Var
   Var
     Found : boolean;
     Found : boolean;
   Begin
   Begin
-  Found:=true;
-  While Found and (i<=LenPat) Do
-   Begin
-     Case Pattern[i] of
-      '?' : Found:=(j<=LenName);
-      '*' : Begin
-            {find the next character in pattern, different of ? and *}
-              while Found do
-                begin
-                inc(i);
-                if i>LenPat then Break;
-                case Pattern[i] of
-                  '*' : ;
-                  '?' : begin
-                          if j>LenName then begin DoFNMatch:=false; Exit; end;
+    Found:=true;
+    While Found and (i<=LenPat) Do
+     Begin
+       Case Pattern[i] of
+        '?' :
+          begin
+            Found:=(j<=LenName);
+            GoToLastByteOfUtf16CodePoint(j);
+          end;
+        '*' : Begin
+              {find the next character in pattern, different of ? and *}
+                while Found do
+                  begin
+                    inc(i);
+                    if i>LenPat then
+                      Break;
+                    case Pattern[i] of
+                      '*' : ;
+                      '?' : begin
+                              if j>LenName then
+                                begin
+                                  DoFNMatch:=false;
+                                  Exit;
+                                end;
+                              GoToLastByteOfUtf16CodePoint(j);
+                              inc(j);
+                            end;
+                      else
+                        Found:=false;
+                      end;
+                 end;
+                Assert((i>LenPat) or ( (Pattern[i]<>'*') and (Pattern[i]<>'?') ));
+                { Now, find in name the character which i points to, if the * or
+                  ? wasn't the last character in the pattern, else, use up all
+                  the chars in name }
+                Found:=false;
+                if (i<=LenPat) then
+                  begin
+                    repeat
+                      {find a letter (not only first !) which maches pattern[i]}
+                      while (j<=LenName) and
+                            ((name[j]<>pattern[i]) or
+                             not CompareUtf16CodePoint(i,j,false)) do
+                        begin
+                          GoToLastByteOfUtf16CodePoint(j);
                           inc(j);
                           inc(j);
                         end;
                         end;
+                      if (j<LenName) then
+                        begin
+                          { while positions i/j have already been checked, we have to
+                            ensure that we don't split a code point }
+                          if DoFnMatch(i,j) then
+                            begin
+                              i:=LenPat;
+                              j:=LenName;{we can stop}
+                              Found:=true;
+                              Break;
+                            end
+                          { We didn't find one, need to look further }
+                          else
+                            begin
+                              GoToLastByteOfUtf16CodePoint(j);
+                              inc(j);
+                            end;
+                        end
+                      else if j=LenName then
+                        begin
+                          Found:=true;
+                          Break;
+                        end;
+                      { This 'until' condition must be j>LenName, not j>=LenName.
+                        That's because when we 'need to look further' and
+                        j = LenName then loop must not terminate. }
+                    until (j>LenName);
+                  end
                 else
                 else
-                  Found:=false;
-                end;
-               end;
-              Assert((i>LenPat) or ( (Pattern[i]<>'*') and (Pattern[i]<>'?') ));
-            {Now, find in name the character which i points to, if the * or ?
-             wasn't the last character in the pattern, else, use up all the
-             chars in name}
-              Found:=false;
-              if (i<=LenPat) then
-              begin
-                repeat
-                  {find a letter (not only first !) which maches pattern[i]}
-                  while (j<=LenName) and (name[j]<>pattern[i]) do
-                    inc (j);
-                  if (j<LenName) then
-                  begin
-                    if DoFnMatch(i+1,j+1) then
-                    begin
-                      i:=LenPat;
-                      j:=LenName;{we can stop}
-                      Found:=true;
-                      Break;
-                    end else
-                      inc(j);{We didn't find one, need to look further}
-                  end else
-                  if j=LenName then
                   begin
                   begin
+                    j:=LenName;{we can stop}
                     Found:=true;
                     Found:=true;
-                    Break;
                   end;
                   end;
-                  { This 'until' condition must be j>LenName, not j>=LenName.
-                    That's because when we 'need to look further' and
-                    j = LenName then loop must not terminate. }
-                until (j>LenName);
-              end else
-              begin
-                j:=LenName;{we can stop}
-                Found:=true;
               end;
               end;
-            end;
-     else {not a wildcard character in pattern}
-       Found:=(j<=LenName) and (pattern[i]=name[j]);
+        #$D800..#$DBFF:
+          begin
+            { ensure that a part of an UTF-16 codepoint isn't matched with
+              '*' or '?' }
+            Found:=CompareUtf16CodePoint(i,j,true);
+            { at this point, either Found is false (and we'll stop), or
+              both pattern[i] and name[j] are the end of the current code
+              point and equal }
+          end
+       else {not a wildcard character in pattern}
+         Found:=(j<=LenName) and (pattern[i]=name[j]);
+       end;
+       inc(i);
+       inc(j);
      end;
      end;
-     inc(i);
-     inc(j);
-   end;
-  DoFnMatch:=Found and (j>LenName);
+    DoFnMatch:=Found and (j>LenName);
   end;
   end;
 
 
 Begin {start FNMatch}
 Begin {start FNMatch}
@@ -447,7 +566,7 @@ Begin {start FNMatch}
 End;
 End;
 
 
 
 
-function FindGetFileInfo(const s: String; var f: TSearchRec): Boolean;
+function FindGetFileInfo(const s: UnicodeString; var f: TAbstractSearchRec; var Name: UnicodeString): Boolean;
 var
 var
   ntstr: UNICODE_STRING;
   ntstr: UNICODE_STRING;
   objattr: OBJECT_ATTRIBUTES;
   objattr: OBJECT_ATTRIBUTES;
@@ -455,14 +574,13 @@ var
   h: THandle;
   h: THandle;
   iostatus: IO_STATUS_BLOCK;
   iostatus: IO_STATUS_BLOCK;
   attr: LongInt;
   attr: LongInt;
-  filename: String;
+  filename: UnicodeString;
   isfileobj: Boolean;
   isfileobj: Boolean;
-  buf: array of Byte;
   objinfo: OBJECT_BASIC_INFORMATION;
   objinfo: OBJECT_BASIC_INFORMATION;
   fileinfo: FILE_BASIC_INFORMATION;
   fileinfo: FILE_BASIC_INFORMATION;
   time: LongInt;
   time: LongInt;
 begin
 begin
-  AnsiStrToNtStr(s, ntstr);
+  UnicodeStrToNtStr(s, ntstr);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
 
 
   filename := ExtractFileName(s);
   filename := ExtractFileName(s);
@@ -545,7 +663,7 @@ begin
   end;
   end;
 
 
   if (attr and not f.FindData.SearchAttr) = 0 then begin
   if (attr and not f.FindData.SearchAttr) = 0 then begin
-    f.Name := filename;
+    Name := filename;
     f.Attr := attr;
     f.Attr := attr;
     f.Size := 0;
     f.Size := 0;
 {$ifndef FPUNONE}
 {$ifndef FPUNONE}
@@ -564,21 +682,24 @@ begin
 end;
 end;
 
 
 
 
-procedure FindClose(var F: TSearchrec);
+Procedure InternalFindClose (var Handle: THandle; var FindData: TFindData);
 begin
 begin
-  if f.FindData.Handle <> 0 then
-    NtClose(f.FindData.Handle);
+  if FindData.Handle <> 0 then
+    begin
+      NtClose(FindData.Handle);
+      FindData.Handle:=0;
+    end;
 end;
 end;
 
 
 
 
-function FindNext(var Rslt: TSearchRec): LongInt;
+Function InternalFindNext (Var Rslt : TAbstractSearchRec; var Name: UnicodeString) : Longint;
 {
 {
   re-opens dir if not already in array and calls FindGetFileInfo
   re-opens dir if not already in array and calls FindGetFileInfo
 }
 }
 Var
 Var
-  DirName  : String;
+  DirName  : UnicodeString;
   FName,
   FName,
-  SName    : string;
+  SName    : UnicodeString;
   Found,
   Found,
   Finished : boolean;
   Finished : boolean;
   ntstr: UNICODE_STRING;
   ntstr: UNICODE_STRING;
@@ -590,7 +711,7 @@ Var
   dirinfo: POBJECT_DIRECTORY_INFORMATION;
   dirinfo: POBJECT_DIRECTORY_INFORMATION;
   filedirinfo: PFILE_DIRECTORY_INFORMATION;
   filedirinfo: PFILE_DIRECTORY_INFORMATION;
   pc: PChar;
   pc: PChar;
-  name: AnsiString;
+  filename: UnicodeString;
   iostatus: IO_STATUS_BLOCK;
   iostatus: IO_STATUS_BLOCK;
 begin
 begin
   { TODO : relative directories }
   { TODO : relative directories }
@@ -606,13 +727,13 @@ begin
 
 
   if Rslt.FindData.Handle = 0 then begin
   if Rslt.FindData.Handle = 0 then begin
     if Rslt.FindData.NamePos > 1 then
     if Rslt.FindData.NamePos > 1 then
-      name := Copy(Rslt.FindData.SearchSpec, 1, Rslt.FindData.NamePos - 1)
+      filename := Copy(Rslt.FindData.SearchSpec, 1, Rslt.FindData.NamePos - 1)
     else
     else
     if Rslt.FindData.NamePos = 1 then
     if Rslt.FindData.NamePos = 1 then
-      name := Copy(Rslt.FindData.SearchSpec, 1, 1)
+      filename := Copy(Rslt.FindData.SearchSpec, 1, 1)
     else
     else
-      name := Rslt.FindData.SearchSpec;
-    AnsiStrToNtStr(name, ntstr);
+      filename := Rslt.FindData.SearchSpec;
+    UnicodeStrToNtStr(filename, ntstr);
     InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
     InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
 
 
     res := NtOpenDirectoryObject(@Rslt.FindData.Handle,
     res := NtOpenDirectoryObject(@Rslt.FindData.Handle,
@@ -664,14 +785,7 @@ begin
       Rslt.FindData.LastRes := res;
       Rslt.FindData.LastRes := res;
       if dirinfo^.Name.Length > 0 then begin
       if dirinfo^.Name.Length > 0 then begin
         SetLength(FName, dirinfo^.Name.Length div 2);
         SetLength(FName, dirinfo^.Name.Length div 2);
-        pc := PChar(FName);
-        for i := 0 to dirinfo^.Name.Length div 2 - 1 do begin
-          if dirinfo^.Name.Buffer[i] < #256 then
-            pc^ := AnsiChar(Byte(dirinfo^.Name.Buffer[i]))
-          else
-            pc^ := '?';
-          pc := pc + 1;
-        end;
+        move(dirinfo^.Name.Buffer[0],FName[1],dirinfo^.Name.Length);
 {$ifdef debug_findnext}
 {$ifdef debug_findnext}
         Write(FName, ' (');
         Write(FName, ' (');
         for i := 0 to dirinfo^.TypeName.Length div 2 - 1 do
         for i := 0 to dirinfo^.TypeName.Length div 2 - 1 do
@@ -685,21 +799,14 @@ begin
         FName := '';
         FName := '';
     end else begin
     end else begin
       SetLength(FName, filedirinfo^.FileNameLength div 2);
       SetLength(FName, filedirinfo^.FileNameLength div 2);
-      pc := PChar(FName);
-      for i := 0 to filedirinfo^.FileNameLength div 2 - 1 do begin
-        if filedirinfo^.FileName[i] < #256 then
-          pc^ := AnsiChar(Byte(filedirinfo^.FileName[i]))
-        else
-          pc^ := '?';
-        pc := pc + 1;
-      end;
+      move(filedirinfo^.FileName[0],FName[1],filedirinfo^.FileNameLength);
     end;
     end;
     if FName = '' then
     if FName = '' then
       Finished := True
       Finished := True
     else begin
     else begin
       if FNMatch(SName, FName) then begin
       if FNMatch(SName, FName) then begin
         Found := FindGetFileInfo(Copy(Rslt.FindData.SearchSpec, 1,
         Found := FindGetFileInfo(Copy(Rslt.FindData.SearchSpec, 1,
-                   Rslt.FindData.NamePos) + FName, Rslt);
+                   Rslt.FindData.NamePos) + FName, Rslt, Name);
         if Found then begin
         if Found then begin
           Result := 0;
           Result := 0;
           Exit;
           Exit;
@@ -710,19 +817,18 @@ begin
 end;
 end;
 
 
 
 
-function FindFirst(const Path: String; Attr: Longint; out Rslt: TSearchRec): Longint;
+Function InternalFindFirst (Const Path : UnicodeString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name : UnicodeString) : Longint;
 {
 {
   opens dir and calls FindNext if needed.
   opens dir and calls FindNext if needed.
 }
 }
 Begin
 Begin
   Result := -1;
   Result := -1;
-  FillChar(Rslt, SizeOf(Rslt), 0);
   if Path = '' then
   if Path = '' then
     Exit;
     Exit;
   Rslt.FindData.SearchAttr := Attr;
   Rslt.FindData.SearchAttr := Attr;
   {Wildcards?}
   {Wildcards?}
   if (Pos('?', Path) = 0) and (Pos('*', Path) = 0) then begin
   if (Pos('?', Path) = 0) and (Pos('*', Path) = 0) then begin
-    if FindGetFileInfo(Path, Rslt) then
+    if FindGetFileInfo(Path, Rslt, Name) then
       Result := 0;
       Result := 0;
   end else begin
   end else begin
     {Create Info}
     {Create Info}
@@ -732,10 +838,10 @@ Begin
         and (Rslt.FindData.SearchSpec[Rslt.FindData.NamePos] <> DirectorySeparator)
         and (Rslt.FindData.SearchSpec[Rslt.FindData.NamePos] <> DirectorySeparator)
         do
         do
       Dec(Rslt.FindData.NamePos);
       Dec(Rslt.FindData.NamePos);
-    Result := FindNext(Rslt);
+    Result := InternalFindNext(Rslt,Name);
   end;
   end;
   if Result <> 0 then
   if Result <> 0 then
-    FindClose(Rslt);
+    InternalFindClose(Rslt.FindHandle,Rslt.FindData);
 end;
 end;
 
 
 
 
@@ -779,14 +885,14 @@ begin
 end;
 end;
 
 
 
 
-function FileGetAttr(const FileName: String): Longint;
+function FileGetAttr(const FileName: UnicodeString): Longint;
 var
 var
   objattr: OBJECT_ATTRIBUTES;
   objattr: OBJECT_ATTRIBUTES;
   info: FILE_NETWORK_OPEN_INFORMATION;
   info: FILE_NETWORK_OPEN_INFORMATION;
   res: NTSTATUS;
   res: NTSTATUS;
   ntstr: UNICODE_STRING;
   ntstr: UNICODE_STRING;
 begin
 begin
-  AnsiStrToNtStr(FileName, ntstr);
+  UnicodeStrToNtStr(FileName, ntstr);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
 
 
   res := NtQueryFullAttributesFile(@objattr, @info);
   res := NtQueryFullAttributesFile(@objattr, @info);
@@ -799,7 +905,7 @@ begin
 end;
 end;
 
 
 
 
-function FileSetAttr(const Filename: String; Attr: LongInt): Longint;
+function FileSetAttr(const Filename: UnicodeString; Attr: LongInt): Longint;
 var
 var
   h: THandle;
   h: THandle;
   objattr: OBJECT_ATTRIBUTES;
   objattr: OBJECT_ATTRIBUTES;
@@ -808,7 +914,7 @@ var
   res: NTSTATUS;
   res: NTSTATUS;
   iostatus: IO_STATUS_BLOCK;
   iostatus: IO_STATUS_BLOCK;
 begin
 begin
-  AnsiStrToNtStr(Filename, ntstr);
+  UnicodeStrToNtStr(Filename, ntstr);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   res := NtOpenFile(@h,
   res := NtOpenFile(@h,
            NT_SYNCHRONIZE or FILE_READ_ATTRIBUTES or FILE_WRITE_ATTRIBUTES,
            NT_SYNCHRONIZE or FILE_READ_ATTRIBUTES or FILE_WRITE_ATTRIBUTES,
@@ -834,7 +940,7 @@ begin
 end;
 end;
 
 
 
 
-function DeleteFile(const FileName: String): Boolean;
+function DeleteFile(const FileName: UnicodeString): Boolean;
 var
 var
   h: THandle;
   h: THandle;
   objattr: OBJECT_ATTRIBUTES;
   objattr: OBJECT_ATTRIBUTES;
@@ -843,7 +949,7 @@ var
   res: NTSTATUS;
   res: NTSTATUS;
   iostatus: IO_STATUS_BLOCK;
   iostatus: IO_STATUS_BLOCK;
 begin
 begin
-  AnsiStrToNtStr(Filename, ntstr);
+  UnicodeStrToNtStr(Filename, ntstr);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   InitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
   res := NtOpenFile(@h, NT_DELETE, @objattr, @iostatus,
   res := NtOpenFile(@h, NT_DELETE, @objattr, @iostatus,
            FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
            FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
@@ -865,7 +971,7 @@ begin
 end;
 end;
 
 
 
 
-function RenameFile(const OldName, NewName: String): Boolean;
+function RenameFile(const OldName, NewName: UnicodeString): Boolean;
 var
 var
   h: THandle;
   h: THandle;
   objattr: OBJECT_ATTRIBUTES;
   objattr: OBJECT_ATTRIBUTES;
@@ -875,7 +981,7 @@ var
   res: LongInt;
   res: LongInt;
 begin
 begin
   { check whether the destination exists first }
   { check whether the destination exists first }
-  AnsiStrToNtStr(NewName, dest);
+  UnicodeStrToNtStr(NewName, dest);
   InitializeObjectAttributes(objattr, @dest, 0, 0, Nil);
   InitializeObjectAttributes(objattr, @dest, 0, 0, Nil);
 
 
   res := NtCreateFile(@h, 0, @objattr, @iostatus, Nil, 0,
   res := NtCreateFile(@h, 0, @objattr, @iostatus, Nil, 0,
@@ -886,7 +992,7 @@ begin
     NtClose(h);
     NtClose(h);
     Result := False;
     Result := False;
   end else begin
   end else begin
-    AnsiStrToNtStr(OldName, src);
+    UnicodeStrToNtStr(OldName, src);
     InitializeObjectAttributes(objattr, @src, 0, 0, Nil);
     InitializeObjectAttributes(objattr, @src, 0, 0, Nil);
 
 
     res := NtCreateFile(@h,
     res := NtCreateFile(@h,
@@ -945,39 +1051,6 @@ begin
 end;
 end;
 
 
 
 
-function GetCurrentDir: String;
-begin
-  GetDir(0, result);
-end;
-
-
-function SetCurrentDir(const NewDir: String): Boolean;
-begin
-{$I-}
-  ChDir(NewDir);
-{$I+}
-  Result := IOResult = 0;
-end;
-
-
-function CreateDir(const NewDir: String): Boolean;
-begin
-{$I-}
-  MkDir(NewDir);
-{$I+}
-  Result := IOResult = 0;
-end;
-
-
-function RemoveDir(const Dir: String): Boolean;
-begin
-{$I-}
-  RmDir(Dir);
-{$I+}
-  Result := IOResult = 0;
-end;
-
-
 {****************************************************************************
 {****************************************************************************
                               Time Functions
                               Time Functions
 ****************************************************************************}
 ****************************************************************************}
@@ -1047,7 +1120,7 @@ function wstrlen(p: PWideChar): SizeInt; external name 'FPC_PWIDECHAR_LENGTH';
 
 
 function GetEnvironmentVariable(const EnvVar: String): String;
 function GetEnvironmentVariable(const EnvVar: String): String;
 var
 var
-   s : string;
+   s, upperenvvar : UTF8String;
    i : longint;
    i : longint;
    hp: pwidechar;
    hp: pwidechar;
    len: sizeint;
    len: sizeint;
@@ -1055,15 +1128,19 @@ begin
    { TODO : test once I know how to execute processes }
    { TODO : test once I know how to execute processes }
    Result:='';
    Result:='';
    hp:=PPEB(CurrentPEB)^.ProcessParameters^.Environment;
    hp:=PPEB(CurrentPEB)^.ProcessParameters^.Environment;
+   { first convert to UTF-8, then uppercase in order to avoid potential data
+     loss }
+   upperenvvar:=EnvVar;
+   upperenvvar:=UpperCase(upperenvvar);
    while hp^<>#0 do
    while hp^<>#0 do
      begin
      begin
         len:=UnicodeToUTF8(Nil, hp, 0);
         len:=UnicodeToUTF8(Nil, hp, 0);
         SetLength(s,len);
         SetLength(s,len);
         UnicodeToUTF8(PChar(s), hp, len);
         UnicodeToUTF8(PChar(s), hp, len);
-        //s:=strpas(hp);
         i:=pos('=',s);
         i:=pos('=',s);
-        if uppercase(copy(s,1,i-1))=upcase(envvar) then
+        if uppercase(copy(s,1,i-1))=upperenvvar then
           begin
           begin
+             { copy() returns a rawbytestring -> will keep UTF-8 encoding }
              Result:=copy(s,i+1,length(s)-i);
              Result:=copy(s,i+1,length(s)-i);
              break;
              break;
           end;
           end;
@@ -1086,7 +1163,7 @@ begin
       end;
       end;
 end;
 end;
 
 
-function GetEnvironmentString(Index: Integer): String;
+function GetEnvironmentString(Index: Integer): {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 var
 var
   hp : pwidechar;
   hp : pwidechar;
   len: sizeint;
   len: sizeint;
@@ -1097,14 +1174,19 @@ begin
     begin
     begin
     while (hp^<>#0) and (Index>1) do
     while (hp^<>#0) and (Index>1) do
       begin
       begin
-      Dec(Index);
-      hp:=hp+wstrlen(hp)+1;
+        Dec(Index);
+        hp:=hp+wstrlen(hp)+1;
       end;
       end;
     If (hp^<>#0) then
     If (hp^<>#0) then
       begin
       begin
+{$ifdef FPC_RTL_UNICODE}
+        Result:=hp;
+{$else}
         len:=UnicodeToUTF8(Nil, hp, 0);
         len:=UnicodeToUTF8(Nil, hp, 0);
         SetLength(Result, len);
         SetLength(Result, len);
         UnicodeToUTF8(PChar(Result), hp, len);
         UnicodeToUTF8(PChar(Result), hp, len);
+        SetCodePage(RawByteString(Result),CP_UTF8,false);
+{$endif}
       end;
       end;
     end;
     end;
 end;
 end;

+ 24 - 0
rtl/nds/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 4 - 7
rtl/nds/sysdir.inc

@@ -19,25 +19,22 @@
 {*****************************************************************************
 {*****************************************************************************
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
-procedure mkdir(s: pchar; len: sizeuint);[IOCheck, public, alias : 'FPC_SYS_MKDIR'];
+procedure do_mkdir(const s: rawbytestring);
 begin
 begin
-  if not assigned(s) or (len=0) or (InOutRes<>0) then exit;
 
 
 end;
 end;
 
 
-procedure rmdir(s: pchar; len: sizeuint);[IOCheck, public, alias : 'FPC_SYS_RMDIR'];
+procedure do_rmdir(const s: rawbytestring);
 begin
 begin
-  if not assigned(s) or (len=0) then exit;
 
 
 end;
 end;
 
 
-procedure chdir(s: pchar; len: sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
+procedure do_chdir(const s: rawbytestring);
 begin
 begin
-  if not assigned(s) or (len=0) then exit;
 
 
 end;
 end;
 
 
-procedure GetDir(DriveNr: byte; var Dir: ShortString);
+procedure do_GetDir(DriveNr: byte; var Dir: RawByteString);
 begin
 begin
 
 
 end;
 end;

+ 3 - 3
rtl/nds/sysfile.inc

@@ -88,7 +88,7 @@ begin
     InOutRes := 0;
     InOutRes := 0;
 end;
 end;
 
 
-procedure do_erase(p: pchar);
+procedure do_erase(p: pchar; pchangeable: boolean);
 var
 var
   res: longint;
   res: longint;
 begin
 begin
@@ -100,7 +100,7 @@ begin
     InOutRes := 0;  
     InOutRes := 0;  
 end;
 end;
 
 
-procedure do_rename(p1, p2: pchar);
+procedure do_rename(p1, p2: pchar; p1changeable, p2changeable: boolean);
 var
 var
   res: longint;
   res: longint;
 begin
 begin
@@ -209,7 +209,7 @@ begin
     InOutRes := 0;  
     InOutRes := 0;  
 end;
 end;
 
 
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
 {
 {
   filerec and textrec have both handle and mode as the first items so
   filerec and textrec have both handle and mode as the first items so
   they could use the same routine for opening/creating.
   they could use the same routine for opening/creating.

+ 52 - 48
rtl/nds/sysutils.pp

@@ -29,6 +29,11 @@ interface
 { force ansistrings }
 { force ansistrings }
 {$H+}
 {$H+}
 
 
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
 { Include platform independent interface part }
 { Include platform independent interface part }
 {$i sysutilh.inc}
 {$i sysutilh.inc}
 
 
@@ -44,10 +49,12 @@ uses
 {****************************************************************************
 {****************************************************************************
                               File Functions
                               File Functions
 ****************************************************************************}
 ****************************************************************************}
-function FileOpen(const FileName: string; Mode: Integer): LongInt;
+function FileOpen(const FileName: rawbytestring; Mode: Integer): LongInt;
 var
 var
   NDSFlags: longint;
   NDSFlags: longint;
+  SystemFileName: RawByteString;
 begin
 begin
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
   NDSFlags := 0;
   NDSFlags := 0;
 
 
   case (Mode and (fmOpenRead or fmOpenWrite or fmOpenReadWrite)) of
   case (Mode and (fmOpenRead or fmOpenWrite or fmOpenReadWrite)) of
@@ -55,7 +62,7 @@ begin
     fmOpenWrite : NDSFlags := NDSFlags or O_WrOnly;
     fmOpenWrite : NDSFlags := NDSFlags or O_WrOnly;
     fmOpenReadWrite : NDSFlags := NDSFlags or O_RdWr;
     fmOpenReadWrite : NDSFlags := NDSFlags or O_RdWr;
   end;
   end;
-  FileOpen := _open(pchar(FileName), NDSFlags);
+  FileOpen := _open(pchar(SystemFileName), NDSFlags);
 end;
 end;
 
 
 
 
@@ -71,19 +78,25 @@ begin
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string) : LongInt;
+function FileCreate(const FileName: RawByteString) : LongInt;
+var
+  SystemFileName: RawByteString;
 begin
 begin
-  FileCreate:=_open(pointer(FileName), O_RdWr or O_Creat or O_Trunc);
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  FileCreate:=_open(pointer(SystemFileName), O_RdWr or O_Creat or O_Trunc);
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string; Rights: integer): LongInt;
+function FileCreate(const FileName: RawByteString; Rights: integer): LongInt;
+var
+  SystemFileName: RawByteString;
 begin
 begin
-  FileCreate:=_Open(pointer(FileName),O_RdWr or O_Creat or O_Trunc,Rights);
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  FileCreate:=_Open(pointer(SystemFileName),O_RdWr or O_Creat or O_Trunc,Rights);
 end;
 end;
 
 
 
 
-function FileCreate(const FileName: string; ShareMode : Integer; Rights: integer): LongInt;
+function FileCreate(const FileName: RawByteString; ShareMode : Integer; Rights: integer): LongInt;
 begin
 begin
   result := FileCreate(FileName, Rights);
   result := FileCreate(FileName, Rights);
 end;
 end;
@@ -127,66 +140,81 @@ begin
 end;
 end;
 
 
 
 
-function DeleteFile(const FileName: string) : Boolean;
+function DeleteFile(const FileName: RawByteString) : Boolean;
+var
+  SystemFileName: RawByteString;
 begin
 begin
-  Result := _UnLink(pointer(FileName))>= 0;
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  Result := _UnLink(pointer(SystemFileName))>= 0;
 end;
 end;
 
 
 
 
-function RenameFile(const OldName, NewName: string): Boolean;
+function RenameFile(const OldName, NewName: RawByteString): Boolean;
+var
+  OldSystemFileName, NewSystemFileName: RawByteString;
 begin
 begin
-  RenameFile := _Rename(pointer(OldNAme), pointer(NewName)) >= 0;
+  OldSystemFileName:=ToSingleByteFileSystemEncodedFileName(OldName);
+  NewSystemFileName:=ToSingleByteFileSystemEncodedFileName(NewName);
+  RenameFile := _Rename(pointer(OldSystemFileName), pointer(NewSystemFileName)) >= 0;
 end;
 end;
 
 
 
 
 (****** end of non portable routines ******)
 (****** end of non portable routines ******)
 
 
 
 
-Function FileAge (Const FileName : String): Longint;
+Function FileAge (Const FileName : RawByteString): Longint;
 var 
 var 
   info: Stat;
   info: Stat;
+  SystemFileName: RawByteString;
 begin
 begin
-  if (_stat(pchar(FileName), Info) < 0) or S_ISDIR(info.st_mode) then
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  if (_stat(pchar(SystemFileName), Info) < 0) or S_ISDIR(info.st_mode) then
     exit(-1)
     exit(-1)
   else 
   else 
     Result := (info.st_mtime);
     Result := (info.st_mtime);
 end;
 end;
 
 
 
 
-Function FileExists (Const FileName : String) : Boolean;
+Function FileExists (Const FileName : RawByteString) : Boolean;
+var
+  SystemFileName: RawByteString;
 begin
 begin
-  FileExists := _Access(pointer(filename), F_OK) = 0;
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  FileExists := _Access(pointer(SystemFileName), F_OK) = 0;
 end;
 end;
 
 
 
 
 
 
-Function FindFirst (Const Path : String; Attr : Longint; Out Rslt : TSearchRec) : Longint;
+Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
 
 
-Function FindNext (Var Rslt : TSearchRec) : Longint;
+Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
 
 
-Procedure FindClose (Var F : TSearchrec);
+Procedure InternalFindClose(var Handle: Pointer);
 begin
 begin
 
 
 end;
 end;
 
 
-Function FileGetAttr (Const FileName : String) : Longint;
-Var Info : TStat;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
+var
+  Info : TStat;
+  SystemFileName: RawByteString;
 begin
 begin
-  If _stat(pchar(FileName), Info) <> 0 then
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  If _stat(pchar(SystemFileName), Info) <> 0 then
     Result := -1
     Result := -1
   Else
   Else
     Result := (Info.st_mode shr 16) and $ffff;
     Result := (Info.st_mode shr 16) and $ffff;
 end;
 end;
 
 
 
 
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
 begin
 begin
   result := -1;
   result := -1;
 end;
 end;
@@ -216,31 +244,7 @@ Begin
 End;
 End;
 
 
 
 
-Function GetCurrentDir : String;
-begin
-  result := '';
-end;
-
-
-Function SetCurrentDir (Const NewDir : String) : Boolean;
-begin
-  result := false;
-end;
-
-
-Function CreateDir (Const NewDir : String) : Boolean;
-begin
-  result := false;
-end;
-
-
-Function RemoveDir (Const Dir : String) : Boolean;
-begin
-  result := false;
-end;
-
-
-function DirectoryExists(const Directory: string): Boolean;
+function DirectoryExists(const Directory: RawByteString): Boolean;
 begin
 begin
   result := false;
   result := false;
 end;
 end;
@@ -285,7 +289,7 @@ begin
   result := -1;
   result := -1;
 end;
 end;
 
 
-Function GetEnvironmentString(Index : Integer) : String;
+Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 begin
 begin
   result := '';
   result := '';
 end;
 end;

+ 24 - 0
rtl/netbsd/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 3 - 3
rtl/netware/dynlibs.inc

@@ -36,10 +36,10 @@ Const
 
 
 Uses nwserv;
 Uses nwserv;
 
 
-Function LoadLibrary(const Name : AnsiString) : TlibHandle;
-var args : array[0..1] of pchar;
+Function DoLoadLibrary(const Name : RawByteString) : TlibHandle;
+var args : array[0..1] of PAnsiChar;
 begin
 begin
-  args[0] := pchar(Name);
+  args[0] := PAnsiChar(Name);
   args[1] := nil;
   args[1] := nil;
   Result:=spawnvp(P_NOWAIT,@args,nil);
   Result:=spawnvp(P_NOWAIT,@args,nil);
 end;
 end;

+ 24 - 0
rtl/netware/rtldefs.inc

@@ -0,0 +1,24 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by Free Pascal development team
+
+    This file contains platform-specific defines that are used in
+    multiple RTL units.
+
+    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.
+
+ **********************************************************************}
+
+{ the single byte OS APIs always use UTF-8 }
+{ define FPCRTL_FILESYSTEM_UTF8}
+
+{ The OS supports a single byte file system operations API that we use }
+{$define FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+
+{ The OS supports a two byte file system operations API that we use }
+{ define FPCRTL_FILESYSTEM_TWO_BYTE_API}

+ 13 - 13
rtl/netware/sysdir.inc

@@ -17,12 +17,10 @@
                            Directory Handling
                            Directory Handling
 *****************************************************************************}
 *****************************************************************************}
 
 
-Procedure MkDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_MKDIR'];
+Procedure do_MkDir(s: rawbytestring);
 var
 var
     Rc : longint;
     Rc : longint;
 begin
 begin
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
-    exit;
   DoDirSeparators(s);
   DoDirSeparators(s);
   Rc := _mkdir(pchar(s));
   Rc := _mkdir(pchar(s));
   if Rc <> 0 then
   if Rc <> 0 then
@@ -30,13 +28,14 @@ begin
 end;
 end;
 
 
 
 
-procedure RmDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_RMDIR'];
+procedure do_RmDir(s: rawbytestring);
 var Rc : longint;
 var Rc : longint;
 begin
 begin
-  if (len=1) and (s^ = '.' ) then
-    InOutRes := 16;
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
-    exit;
+  if s = '.' then
+    begin
+      InOutRes := 16;
+      exit;
+    end;
   DoDirSeparators(s);
   DoDirSeparators(s);
   Rc := _rmdir(pchar(s));
   Rc := _rmdir(pchar(s));
   if Rc <> 0 then
   if Rc <> 0 then
@@ -44,17 +43,17 @@ begin
 end;
 end;
 
 
 
 
-procedure ChDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
+procedure do_ChDir(s: rawbytestring);
 var RC: longint;
 var RC: longint;
 begin
 begin
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
-    exit;
+  DoDirSeparators(s);
   RC := _chdir (pchar(s));
   RC := _chdir (pchar(s));
   if Rc <> 0 then
   if Rc <> 0 then
     SetFileError(Rc);
     SetFileError(Rc);
 end;
 end;
 
 
-procedure getdir(drivenr : byte;var dir : shortstring);
+
+procedure do_getdir(drivenr : byte;var dir : rawbytestring);
 VAR P : ARRAY [0..255] OF CHAR;
 VAR P : ARRAY [0..255] OF CHAR;
     i : LONGINT;
     i : LONGINT;
 begin
 begin
@@ -63,8 +62,8 @@ begin
   i := _strlen (P);
   i := _strlen (P);
   if i > 0 then
   if i > 0 then
   begin
   begin
+    SetLength (dir, i);
     Move (P, dir[1], i);
     Move (P, dir[1], i);
-    BYTE(dir[0]) := i;
     DoDirSeparators(dir);
     DoDirSeparators(dir);
     // fix / after volume, the compiler needs that
     // fix / after volume, the compiler needs that
     // normaly root of a volumes is SERVERNAME/SYS:, change that
     // normaly root of a volumes is SERVERNAME/SYS:, change that
@@ -73,6 +72,7 @@ begin
     if (i > 0) then
     if (i > 0) then
       if i = Length (dir) then dir := dir + '/' else
       if i = Length (dir) then dir := dir + '/' else
       if dir [i+1] <> '/' then insert ('/',dir,i+1);
       if dir [i+1] <> '/' then insert ('/',dir,i+1);
+    SetCodePage (dir,DefaultFileSystemCodePage,false);
   END ELSE
   END ELSE
     InOutRes := 1;
     InOutRes := 1;
 end;
 end;

+ 3 - 3
rtl/netware/sysfile.inc

@@ -80,7 +80,7 @@ begin
     InOutRes := 0;
     InOutRes := 0;
 end;
 end;
 
 
-procedure do_erase(p : pchar);
+procedure do_erase(p : pchar; pchangeable: boolean);
 VAR res : LONGINT;
 VAR res : LONGINT;
 begin
 begin
   res := _unlink (p);
   res := _unlink (p);
@@ -90,7 +90,7 @@ begin
     InOutRes := 0;
     InOutRes := 0;
 end;
 end;
 
 
-procedure do_rename(p1,p2 : pchar);
+procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
 VAR res : LONGINT;
 VAR res : LONGINT;
 begin
 begin
   res := _rename (p1,p2);
   res := _rename (p1,p2);
@@ -189,7 +189,7 @@ begin
 end;
 end;
 
 
 // mostly stolen from syslinux
 // mostly stolen from syslinux
-procedure do_open(var f;p:pchar;flags:longint);
+procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
 {
 {
   filerec and textrec have both handle and mode as the first items so
   filerec and textrec have both handle and mode as the first items so
   they could use the same routine for opening/creating.
   they could use the same routine for opening/creating.

+ 61 - 67
rtl/netware/sysutils.pp

@@ -29,6 +29,11 @@ uses DOS;
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_SLEEP}
 {$DEFINE HAS_OSERROR}
 {$DEFINE HAS_OSERROR}
 
 
+{ used OS file system APIs use ansistring }
+{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+{ OS has an ansistring/single byte environment variable API }
+{$define SYSUTILS_HAS_ANSISTR_ENVVAR_IMPL}
+
 TYPE
 TYPE
   TNetwareFindData =
   TNetwareFindData =
   RECORD
   RECORD
@@ -85,35 +90,38 @@ implementation
                               File Functions
                               File Functions
 ****************************************************************************}
 ****************************************************************************}
 
 
-Function FileOpen (Const FileName : string; Mode : Integer) : THandle;
+Function FileOpen (Const FileName : rawbytestring; Mode : Integer) : THandle;
 VAR NWOpenFlags : longint;
 VAR NWOpenFlags : longint;
-BEGIN
+    SystemFileName: RawByteString;
+begin
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
   NWOpenFlags:=0;
   NWOpenFlags:=0;
   Case (Mode and 3) of
   Case (Mode and 3) of
     0 : NWOpenFlags:=NWOpenFlags or O_RDONLY;
     0 : NWOpenFlags:=NWOpenFlags or O_RDONLY;
     1 : NWOpenFlags:=NWOpenFlags or O_WRONLY;
     1 : NWOpenFlags:=NWOpenFlags or O_WRONLY;
     2 : NWOpenFlags:=NWOpenFlags or O_RDWR;
     2 : NWOpenFlags:=NWOpenFlags or O_RDWR;
   end;
   end;
-  FileOpen := _open (pchar(FileName),NWOpenFlags,0);
+  FileOpen := _open (pchar(SystemFileName),NWOpenFlags,0);
 
 
   //!! We need to set locking based on Mode !!
   //!! We need to set locking based on Mode !!
 end;
 end;
 
 
 
 
-Function FileCreate (Const FileName : String) : THandle;
-
+Function FileCreate (Const FileName : RawByteString) : THandle;
+VAR SystemFileName: RawByteString;
 begin
 begin
-  FileCreate:=_open(Pchar(FileName),O_RdWr or O_Creat or O_Trunc,0);
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  FileCreate:=_open(Pchar(SystemFileName),O_RdWr or O_Creat or O_Trunc,0);
 end;
 end;
 
 
-Function FileCreate (Const FileName : String; Rights:longint) : THandle;
+Function FileCreate (Const FileName : RawByteString; Rights:longint) : THandle;
 
 
 begin
 begin
   FileCreate:=FileCreate (FileName);
   FileCreate:=FileCreate (FileName);
 end;
 end;
 
 
 
 
-Function FileCreate (Const FileName : String; ShareMode: Longint; Rights:longint) : THandle;
+Function FileCreate (Const FileName : RawByteString; ShareMode: Longint; Rights:longint) : THandle;
 
 
 begin
 begin
   FileCreate:=FileCreate (FileName);
   FileCreate:=FileCreate (FileName);
@@ -205,15 +213,17 @@ begin
 end;
 end;
 
 
 
 
-Function FileExists (Const FileName : String) : Boolean;
+Function FileExists (Const FileName : RawByteString) : Boolean;
 VAR Info : NWStatBufT;
 VAR Info : NWStatBufT;
+    SystemFileName: RawByteString;
 begin
 begin
-  FileExists:=(_stat(pchar(filename),Info) = 0);
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  FileExists:=(_stat(pchar(SystemFileName),Info) = 0);
 end;
 end;
 
 
 
 
 
 
-PROCEDURE find_setfields (VAR f : TsearchRec);
+PROCEDURE find_setfields (VAR f : TsearchRec; VAR Name : RawByteString);
 VAR T : Dos.DateTime;
 VAR T : Dos.DateTime;
 BEGIN
 BEGIN
   WITH F DO
   WITH F DO
@@ -225,21 +235,25 @@ BEGIN
       UnpackTime(FindData.EntryP^.d_time + (LONGINT (FindData.EntryP^.d_date) SHL 16), T);
       UnpackTime(FindData.EntryP^.d_time + (LONGINT (FindData.EntryP^.d_date) SHL 16), T);
       time := DateTimeToFileDate(EncodeDate(T.Year,T.Month,T.day)+EncodeTime(T.Hour,T.Min,T.Sec,0));
       time := DateTimeToFileDate(EncodeDate(T.Year,T.Month,T.day)+EncodeTime(T.Hour,T.Min,T.Sec,0));
       size := FindData.EntryP^.d_size;
       size := FindData.EntryP^.d_size;
-      name := strpas (FindData.EntryP^.d_nameDOS);
+      name := FindData.EntryP^.d_nameDOS;
+      SetCodePage(name, DefaultFileSystemCodePage, false);
     END ELSE
     END ELSE
     BEGIN
     BEGIN
-      FillChar (f,SIZEOF(f),0);
+      name := '';
     END;
     END;
   END;
   END;
 END;
 END;
 
 
 
 
 
 
-Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
+Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint;
+var
+  SystemEncodedPath: RawByteString;
 begin
 begin
   IF path = '' then
   IF path = '' then
     exit (18);
     exit (18);
-  Rslt.FindData.DirP := _opendir (pchar(Path));
+  SystemEncodedPath := ToSingleByteEncodedFileName (Path);
+  Rslt.FindData.DirP := _opendir (pchar(SystemEncodedPath));
   IF Rslt.FindData.DirP = NIL THEN
   IF Rslt.FindData.DirP = NIL THEN
     exit (18);
     exit (18);
   IF attr <> faAnyFile THEN
   IF attr <> faAnyFile THEN
@@ -253,13 +267,13 @@ begin
     result := 18;
     result := 18;
   end else
   end else
   begin
   begin
-    find_setfields (Rslt);
+    find_setfields (Rslt,Name);
     result := 0;
     result := 0;
   end;
   end;
 end;
 end;
 
 
 
 
-Function FindNext (Var Rslt : TSearchRec) : Longint;
+Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint;
 
 
 begin
 begin
   IF Rslt.FindData.Magic <> $AD01 THEN
   IF Rslt.FindData.Magic <> $AD01 THEN
@@ -267,14 +281,14 @@ begin
   Rslt.FindData.EntryP := _readdir (Rslt.FindData.DirP);
   Rslt.FindData.EntryP := _readdir (Rslt.FindData.DirP);
   IF Rslt.FindData.EntryP = NIL THEN
   IF Rslt.FindData.EntryP = NIL THEN
     exit (18);
     exit (18);
-  find_setfields (Rslt);
+  find_setfields (Rslt,Name);
   result := 0;
   result := 0;
 end;
 end;
 
 
 
 
-Procedure FindClose (Var F : TSearchrec);
+Procedure InternalFindClose (var Handle: THandle; var FindData: TFindData);
 begin
 begin
-  IF F.FindData.Magic = $AD01 THEN
+  IF FindData.Magic = $AD01 THEN
   BEGIN
   BEGIN
     IF F.FindData.DirP <> NIL THEN
     IF F.FindData.DirP <> NIL THEN
       _closedir (F.FindData.DirP);
       _closedir (F.FindData.DirP);
@@ -313,38 +327,48 @@ begin
 end;
 end;
 
 
 
 
-Function FileGetAttr (Const FileName : String) : Longint;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
 Var Info : NWStatBufT;
 Var Info : NWStatBufT;
+    SystemFileName: RawByteString;
 begin
 begin
-  If _stat (pchar(FileName),Info) <> 0 then
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  If _stat (pchar(SystemFileName),Info) <> 0 then
     Result:=-1
     Result:=-1
   Else
   Else
     Result := Info.st_attr AND $FFFF;
     Result := Info.st_attr AND $FFFF;
 end;
 end;
 
 
 
 
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
 VAR MS : NWModifyStructure;
 VAR MS : NWModifyStructure;
+    SystemFileName: RawByteString;
 begin
 begin
+  { The Attr parameter is not used! }
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
   FillChar (MS, SIZEOF (MS), 0);
   FillChar (MS, SIZEOF (MS), 0);
-  if _ChangeDirectoryEntry (PChar (Filename), MS, MFileAtrributesBit, 0) <> 0 then
+  if _ChangeDirectoryEntry (PChar (SystemFilename), MS, MFileAtrributesBit, 0) <> 0 then
     result := -1
     result := -1
   else
   else
     result := 0;
     result := 0;
 end;
 end;
 
 
 
 
-Function DeleteFile (Const FileName : String) : Boolean;
-
+Function DeleteFile (Const FileName : RawByteString) : Boolean;
+var
+  SystemFileName: RawByteString;
 begin
 begin
-  Result:= (_UnLink (pchar(FileName)) = 0);
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  Result:= (_UnLink (pchar(SystemFileName)) = 0);
 end;
 end;
 
 
 
 
-Function RenameFile (Const OldName, NewName : String) : Boolean;
-
+Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
+var
+  OldSystemFileName, NewSystemFileName: RawByteString;
 begin
 begin
-  RenameFile:=(_rename(pchar(OldName),pchar(NewName)) = 0);
+  OldSystemFileName:=ToSingleByteFileSystemEncodedFileName(OldName);
+  NewSystemFileName:=ToSingleByteFileSystemEncodedFileName(NewName);
+  RenameFile:=(_rename(pchar(OldSystemFileName),pchar(NewSystemFileName)) = 0);
 end;
 end;
 
 
 
 
@@ -416,43 +440,13 @@ Begin
 End;
 End;
 
 
 
 
-Function GetCurrentDir : String;
-begin
-  GetDir (0,Result);
-end;
-
-
-Function SetCurrentDir (Const NewDir : String) : Boolean;
-begin
-  {$I-}
-   ChDir(NewDir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
-Function CreateDir (Const NewDir : String) : Boolean;
-begin
-  {$I-}
-   MkDir(NewDir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
-Function RemoveDir (Const Dir : String) : Boolean;
-begin
-  {$I-}
-   RmDir(Dir);
-  {$I+}
-  result := (IOResult = 0);
-end;
-
-
 function DirectoryExists (const Directory: string): boolean;
 function DirectoryExists (const Directory: string): boolean;
-VAR Info : NWStatBufT;
+var
+  Info : NWStatBufT;
+  SystemFileName: RawByteString;
 begin
 begin
-  If _stat (pchar(Directory),Info) <> 0 then
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(Directory);
+  If _stat (pchar(SystemFileName),Info) <> 0 then
     exit(false)
     exit(false)
   else
   else
     Exit ((Info.st_attr and faDirectory) <> 0);
     Exit ((Info.st_attr and faDirectory) <> 0);
@@ -523,7 +517,7 @@ end;
 Function GetEnvironmentVariable(Const EnvVar : String) : String;
 Function GetEnvironmentVariable(Const EnvVar : String) : String;
 
 
 begin
 begin
-  Result:=StrPas(_getenv(PChar(EnvVar)));
+  Result:=_getenv(PChar(EnvVar));
 end;
 end;
 
 
 Function GetEnvironmentVariableCount : Integer;
 Function GetEnvironmentVariableCount : Integer;
@@ -533,7 +527,7 @@ begin
   Result:=0;
   Result:=0;
 end;
 end;
 
 
-Function GetEnvironmentString(Index : Integer) : String;
+Function GetEnvironmentString(Index : Integer) : {$ifdef FPC_RTL_UNICODE}UnicodeString{$else}AnsiString{$endif};
 
 
 begin
 begin
   // Result:=FPCGetEnvStrFromP(Envp,Index);
   // Result:=FPCGetEnvStrFromP(Envp,Index);

+ 24 - 3
rtl/netwlibc/dos.pp

@@ -553,10 +553,21 @@ end;
 
 
 
 
 procedure getfattr(var f;var attr : word);
 procedure getfattr(var f;var attr : word);
-VAR StatBuf : TStat;
+var
+  StatBuf : TStat;
+{$ifndef FPC_ANSI_TEXTFILEREC}
+  r: rawbytestring;
+{$endif not FPC_ANSI_TEXTFILEREC}
+  p: pchar;
 begin
 begin
   doserror := 0;
   doserror := 0;
-  if Fpstat (@textrec(f).name, StatBuf) = 0 then
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  p := @filerec(f).name;
+{$else FPC_ANSI_TEXTFILEREC}
+  r := ToSingleByteFileSystemEncodedFileName(filerec(f).name);
+  p := pchar(r);
+{$endif FPC_ANSI_TEXTFILEREC}
+  if Fpstat (p, StatBuf) = 0 then
     attr := nwattr2dosattr (StatBuf.st_mode)
     attr := nwattr2dosattr (StatBuf.st_mode)
   else
   else
   begin
   begin
@@ -570,8 +581,18 @@ procedure setfattr(var f;attr : word);
 var
 var
   StatBuf : TStat;
   StatBuf : TStat;
   newMode : longint;
   newMode : longint;
+{$ifndef FPC_ANSI_TEXTFILEREC}
+  r: rawbytestring;
+{$endif not FPC_ANSI_TEXTFILEREC}
+  p: pchar;
 begin
 begin
-  if Fpstat (@textrec(f).name,StatBuf) = 0 then
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  p := @filerec(f).name;
+{$else FPC_ANSI_TEXTFILEREC}
+  r := ToSingleByteFileSystemEncodedFileName(filerec(f).name);
+  p := pchar(r);
+{$endif FPC_ANSI_TEXTFILEREC}
+  if Fpstat (p,StatBuf) = 0 then
   begin
   begin
     newmode := StatBuf.st_mode and ($FFFF0000 - M_A_RDONLY-M_A_HIDDEN-M_A_SYSTEM-M_A_ARCH); {only this can be set by dos unit}
     newmode := StatBuf.st_mode and ($FFFF0000 - M_A_RDONLY-M_A_HIDDEN-M_A_SYSTEM-M_A_ARCH); {only this can be set by dos unit}
     newmode := newmode or M_A_BITS_SIGNIFICANT;  {set netware attributes}
     newmode := newmode or M_A_BITS_SIGNIFICANT;  {set netware attributes}

+ 2 - 2
rtl/netwlibc/dynlibs.inc

@@ -35,10 +35,10 @@ Const
 
 
 uses libc;
 uses libc;
 
 
-Function LoadLibrary(const Name : AnsiString) : TLibHandle;
+Function DoLoadLibrary(const Name : RawByteString) : TLibHandle;
 
 
 begin
 begin
-  Result:=dlopen(Pchar(Name),RTLD_LAZY);
+  Result:=dlopen(PAnsiChar(Name),RTLD_LAZY);
 end;
 end;
 
 
 Function GetProcedureAddress(Lib : TLibHandle; const ProcName : AnsiString) : Pointer;
 Function GetProcedureAddress(Lib : TLibHandle; const ProcName : AnsiString) : Pointer;

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