Browse Source

* Unicode RTL and packages compile

git-svn-id: branches/unicode@24715 -
michael 12 years ago
parent
commit
209aa73d58

+ 1 - 0
.gitattributes

@@ -8539,6 +8539,7 @@ rtl/objpas/sysconst.pp 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/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/fina.inc svneol=native#text/plain
 rtl/objpas/sysutils/finah.inc svneol=native#text/plain

+ 2 - 0
compiler/options.pas

@@ -2807,6 +2807,8 @@ begin
   def_system_macro('FPC_HAS_CEXTENDED');
   def_system_macro('FPC_HAS_RESSTRINITS');
 
+  def_system_macro('FPC_HAS_SYSTEMFILEREC');
+
 { these cpus have an inline rol/ror implementaion }
 {$ifdef cpurox}
   def_system_macro('FPC_HAS_INTERNAL_ROX');

+ 38 - 15
compiler/symdef.pas

@@ -133,6 +133,7 @@ interface
           procedure deref;override;
           function  GetTypeName:string;override;
           function  getmangledparaname:TSymStr;override;
+          function  size:asizeint;override;
           procedure setsize;
        end;
 
@@ -2559,7 +2560,6 @@ implementation
          inherited create(filedef);
          filetyp:=ft_text;
          typedfiledef:=nil;
-         setsize;
       end;
 
 
@@ -2568,7 +2568,6 @@ implementation
          inherited create(filedef);
          filetyp:=ft_untyped;
          typedfiledef:=nil;
-         setsize;
       end;
 
 
@@ -2577,7 +2576,6 @@ implementation
          inherited create(filedef);
          filetyp:=ft_typed;
          typedfiledef:=def;
-         setsize;
       end;
 
 
@@ -2589,7 +2587,6 @@ implementation
            ppufile.getderef(typedfiledefderef)
          else
            typedfiledef:=nil;
-         setsize;
       end;
 
 
@@ -2622,56 +2619,82 @@ implementation
         if filetyp=ft_typed then
           typedfiledef:=tdef(typedfiledefderef.resolve);
       end;
-
+      
+    function  tfiledef.size:asizeint;
+    
+    begin
+      if savesize=0 then
+        Setsize;
+      size:=savesize;    
+    end;
+
+const 
+{$ifdef FPC_RTL_UNICODE}
+      wideextra  = 256; // difference between n chars and n widechars
+      widesmall  =  16;
+{$else}
+      wideextra  =  0;
+      widesmall  =  0;
+{$endif}
 
     procedure tfiledef.setsize;
       begin
+{$ifdef FPC_HAS_SYSTEMFILEREC}
+       case filetyp of
+         ft_text    : savesize:=search_system_type('TEXTREC').typedef.size;
+         ft_typed,
+         ft_untyped : savesize:=search_system_type('FILEREC').typedef.size;
+         end;
+{$else}
 {$ifdef cpu64bitaddr}
         case filetyp of
           ft_text :
             if target_info.system in [system_x86_64_win64,system_ia64_win64] then
-              savesize:=640
+              savesize:=640+wideextra
             else
-              savesize:=632;
+              savesize:=632+wideextra;
           ft_typed,
           ft_untyped :
             if target_info.system in [system_x86_64_win64,system_ia64_win64] then
-              savesize:=376
+              savesize:=376+wideextra
             else
-              savesize:=368;
+              savesize:=368+wideextra;
         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 }
+            savesize:=596+wideextra; { keep this dividable by 4 for proper alignment of arrays of text, see tw0754 e.g. on arm }
           ft_typed,
           ft_untyped :
-            savesize:=332;
+            savesize:=332+wideextra;
         end;
 {$endif cpu32bitaddr}
 {$ifdef cpu16bitaddr}
         case filetyp of
           ft_text :
             {$ifdef avr}
-              savesize:=96;
+              savesize:=96+widesmall;
             {$else avr}
-              savesize:=576;
+              savesize:=576+wideextra;
             {$endif avr}
           ft_typed,
           ft_untyped :
             {$ifdef avr}
-              savesize:=76;
+              savesize:=76+widesmall;
             {$else avr}
-              savesize:=316;
+              savesize:=316+wideextra;
             {$endif avr}
         end;
 {$endif cpu16bitaddr}
+{$endif}
       end;
 
 
     procedure tfiledef.ppuwrite(ppufile:tcompilerppufile);
       begin
+         if savesize=0 then
+            internalerror(201305131);
          inherited ppuwrite(ppufile);
          ppufile.putbyte(byte(filetyp));
          if filetyp=ft_typed then

+ 12 - 0
rtl/inc/astrings.inc

@@ -1413,3 +1413,15 @@ procedure SetMultiByteConversionCodePage(CodePage: TSystemCodePage);
     DefaultSystemCodePage:=CodePage;
   end;
 
+
+procedure SetMultiByteFileSystemCodePage(CodePage: TSystemCodePage);
+  begin
+    DefaultFileSystemCodePage:=CodePage;
+  end;
+
+
+procedure SetMultiByteRTLFileSystemCodePage(CodePage: TSystemCodePage);
+  begin
+    DefaultRTLFileSystemCodePage:=CodePage;
+  end;
+

+ 9 - 0
rtl/inc/dos.inc

@@ -286,3 +286,12 @@ end;
 
 {$ENDIF HAS_FEXPAND}
 
+{$ifdef FPC_UNICODE_RTL}
+procedure getdir(drivenr:byte;var dir: pathstr);
+var s : ansistring;
+begin
+   s:=dir;
+   system.getdir(drivenr,s);
+   dir:=s;
+end;
+{$endif}

+ 3 - 1
rtl/inc/dosh.inc

@@ -145,4 +145,6 @@ Function  GetMsCount: int64;
  particular meaning - it can be e.g. amount of milliseconds since computer
  startup on DOS-like x86 platforms, derived from Unix time on Unix etc.}
 
-
+{$ifdef FPC_UNICODE_RTL}
+procedure GetDir(Drivenr:Byte;var Dir: PathStr);
+{$endif}

+ 4 - 3
rtl/inc/fexpand.inc

@@ -50,13 +50,14 @@
  {$DEFINE FPC_FEXPAND_UPDIR_HELPER}
 {$ENDIF FPC_FEXPAND_DIRSEP_IS_UPDIR}
 
-procedure GetDirIO (DriveNr: byte; var Dir: String);
+procedure GetDirIO (DriveNr: byte; var Dir: PathStr);
 
 (* GetDirIO is supposed to return the root of the given drive   *)
 (* in case of an error for compatibility of FExpand with TP/BP. *)
 
 var
   OldInOutRes: word;
+
 begin
   OldInOutRes := InOutRes;
   InOutRes := 0;
@@ -67,14 +68,14 @@ end;
 
 {$IFDEF FPC_FEXPAND_VOLUMES}
  {$IFNDEF FPC_FEXPAND_NO_DEFAULT_PATHS}
-procedure GetDirIO (const VolumeName: OpenString; var Dir: string);
+procedure GetDirIO (const VolumeName: OpenString; var Dir: PathStr);
 
 var
   OldInOutRes: word;
 begin
   OldInOutRes := InOutRes;
   InOutRes := 0;
-  GetDir (VolumeName, Dir);
+  GetDir (VolumeName, dir);
   InOutRes := OldInOutRes;
 end;
  {$ENDIF FPC_FEXPAND_NO_DEFAULT_PATHS}

+ 78 - 25
rtl/inc/file.inc

@@ -18,35 +18,50 @@
 type
   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_UNICODE_RTL}
+Procedure Assign(out f:File;const Name: UnicodeString);
 {
   Assign Name to file f so it can be used with the file routines
 }
 Begin
-  FillChar(f,SizeOf(FileRec),0);
-  FileRec(f).Handle:=UnusedHandle;
-  FileRec(f).mode:=fmClosed;
-  Move(Name[1],FileRec(f).Name,Length(Name));
+  InitFile(F);
+  FileRec(f).Name:=Name;
 End;
 
-
-Procedure Assign(out f:File;p:pchar);
+Procedure Assign(out f:File;const Name: RawByteString);
 {
   Assign Name to file f so it can be used with the file routines
 }
+Begin
+  InitFile(F);
+  FileRec(f).Name:=Name;
+End;
+{$ELSE}
+
+Procedure Assign(out f:File;p:pchar);
 begin
   Assign(f,StrPas(p));
 end;
 
-
 Procedure Assign(out f:File;c:char);
-{
-  Assign Name to file f so it can be used with the file routines
-}
 begin
   Assign(f,string(c));
 end;
 
+Procedure Assign(out f:File;const Name:string);
+Begin
+  initfile(f);
+  Move(Name[1],FileRec(f).Name,Length(Name));
+End;
+{$ENDIF}
 
 Procedure Rewrite(var f:File;l:Longint);[IOCheck];
 {
@@ -69,7 +84,11 @@ Begin
   else
    Begin
      { Reopen with filemode 2, to be Tp compatible (PFV) }
+{$IFDEF FPC_UNICODE_RTL}
+     Do_Open(f,UnicodeString(FileRec(f).Name),$1002);
+{$ELSE}
      Do_Open(f,PChar(@FileRec(f).Name),$1002);
+{$ENDIF}
      FileRec(f).RecSize:=l;
    End;
 End;
@@ -95,7 +114,11 @@ Begin
    InOutRes:=2
   else
    Begin
-     Do_Open(f,PChar(@FileRec(f).Name),Filemode);
+{$IFDEF FPC_UNICODE_RTL}
+     Do_Open(f,UnicodeString(FileRec(f).Name),Filemode);
+{$ELSE}
+     Do_Open(f,PChar(@FileRec(f).Name),FileMode);
+{$ENDIF}
      FileRec(f).RecSize:=l;
    End;
 End;
@@ -383,36 +406,65 @@ Begin
   If InOutRes <> 0 then
    exit;
   If FileRec(f).mode=fmClosed Then
-   Do_Erase(PChar(@FileRec(f).Name));
+{$IFDEF FPC_UNICODE_RTL}
+   Do_Erase(UnicodeString(FileRec(f).Name));
+{$ELSE}
+   Do_Erase(pchar(@FileRec(f).Name));
+{$ENDIF}
 End;
 
 
-Procedure Rename(var f : File;p:pchar);[IOCheck];
+{$IFDEF FPC_UNICODE_RTL}
+Procedure Rename(var f : File; const S : UnicodeString);[IOCheck];
+
 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;
+  Do_Rename(FileRec(f).Name,S);
+  If InOutRes = 0 then
+     FileRec(f).Name:=S
+End;
+
+
+Procedure Rename(var f : File;const s : rawbytestring);[IOCheck];
+
+Begin
+  If InOutRes <> 0 then
+   exit;
+  Do_Rename(FileRec(f).Name,S);
+  If InOutRes = 0 then
+     FileRec(f).Name:=S
 End;
 
+{$ELSE}
+
+Procedure Rename(var f : File;p:pchar);[IOCheck];
 
+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;
+End;
+ 
+ 
 Procedure Rename(var f : File;const s : string);[IOCheck];
 var
   p : array[0..255] Of Char;
 Begin
-  If InOutRes <> 0 then
-   exit;
+   If InOutRes <> 0 then
+    exit;
   Move(s[1],p,Length(s));
   p[Length(s)]:=#0;
   Rename(f,Pchar(@p));
 End;
-
-
+ 
+ 
 Procedure Rename(var f : File;c : char);[IOCheck];
 var
   p : array[0..1] Of Char;
@@ -423,4 +475,5 @@ Begin
   p[1]:=#0;
   Rename(f,Pchar(@p));
 End;
+{$ENDIF}
 

+ 1 - 1
rtl/inc/filerec.inc

@@ -35,6 +35,6 @@ type
     RecSize   : SizeInt;
     _private  : array[1..3 * SizeOf(SizeInt) + 5 * SizeOf (pointer)] of byte;
     UserData  : array[1..32] of byte;
-    name      : array[0..filerecnamelength] of char;
+    name      : array[0..filerecnamelength] of {$IFDEF FPC_UNICODE_RTL} unicodechar {$ELSE} char {$ENDIF};
   End;
 

+ 89 - 12
rtl/inc/system.inc

@@ -63,11 +63,13 @@ Const
   This way we keep TP compatibility, and the TextRec definition is available
   for everyone who needs it.
 }
+{$ifndef FPC_HAS_SYSTEMFILEREC}
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 {$i filerec.inc}
 {$endif FPC_HAS_FEATURE_FILEIO}
 
 {$i textrec.inc}
+{$endif}
 
 {$ifdef FPC_HAS_FEATURE_EXITCODE}
   {$ifdef FPC_OBJFPC_EXTENDED_IF}
@@ -1437,7 +1439,16 @@ begin
       p[i]:=DirectorySeparator;
 end;
 
-procedure DoDirSeparators(var p:shortstring);
+procedure DoDirSeparators(var p:RawByteString);
+var
+  i : longint;
+begin
+  for i:=1 to length(p) do
+    if p[i] in AllowDirectorySeparators then
+      p[i]:=DirectorySeparator;
+end;
+
+procedure DoDirSeparators(var p:UnicodeString);
 var
   i : longint;
 begin
@@ -1445,6 +1456,7 @@ begin
     if p[i] in AllowDirectorySeparators then
       p[i]:=DirectorySeparator;
 end;
+
 {$endif FPC_HAS_FEATURE_FILEIO}
 
 { OS dependent low level file functions }
@@ -1471,22 +1483,22 @@ end;
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 { OS dependent dir functions }
 {$i sysdir.inc}
-{$endif FPC_HAS_FEATURE_FILEIO}
 
-{$if defined(FPC_HAS_FEATURE_FILEIO) and defined(FPC_HAS_FEATURE_ANSISTRINGS)}
+{$IFNDEF FPC_UNICODE_RTL}
+
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
 Procedure getdir(drivenr:byte;Var dir:ansistring);
-{ this is needed to also allow ansistrings, the shortstring version is
-  OS dependent }
+
+ { this is needed to also allow ansistrings, the shortstring version is
+   OS dependent }
 var
   s : shortstring;
 begin
   getdir(drivenr,s);
   dir:=s;
 end;
-{$endif}
-
-{$if defined(FPC_HAS_FEATURE_FILEIO)}
 
+{$endif}
 Procedure MkDir(Const s: String);
 Var
   Buffer: Array[0..255] of Char;
@@ -1495,7 +1507,7 @@ Begin
    exit;
   Move(s[1], Buffer, Length(s));
   Buffer[Length(s)] := #0;
-  MkDir(@buffer[0],length(s));
+  do_MkDir(@buffer[0],length(s));
 End;
 
 Procedure RmDir(Const s: String);
@@ -1506,20 +1518,85 @@ Begin
    exit;
   Move(s[1], Buffer, Length(s));
   Buffer[Length(s)] := #0;
-  RmDir(@buffer[0],length(s));
+  do_RmDir(@buffer[0],length(s));
 End;
 
 Procedure ChDir(Const s: String);
 Var
   Buffer: Array[0..255] of Char;
+
 Begin
   If (s='') or (InOutRes <> 0) then
    exit;
   Move(s[1], Buffer, Length(s));
   Buffer[Length(s)] := #0;
-  ChDir(@buffer[0],length(s));
+  do_ChDir(@buffer[0],length(s));
 End;
-{$endif}
+
+{$ELSE}
+
+// UNICODE Implementation
+
+Procedure getdir(drivenr:byte;Var dir: unicodestring);
+begin
+  do_getdir(drivenr,dir);
+end;
+
+Procedure getdir(drivenr:byte;Var dir: rawbytestring);
+begin
+  do_getdir(drivenr,dir);
+end;
+
+Procedure MkDir(Const s: RawByteString);
+
+Begin
+  If (s='') or (InOutRes <> 0) then
+   exit;
+  Do_mkdir(S);
+End;
+
+Procedure MkDir(Const s: UnicodeString);
+
+Begin
+  If (s='') or (InOutRes <> 0) then
+   exit;
+  Do_mkdir(S);
+End;
+
+Procedure RmDir(Const s: RawByteString);
+
+Begin
+  If (s='') or (InOutRes <> 0) then
+   exit;
+  Do_rmdir(S);
+End;
+
+Procedure RmDir(Const s: UnicodeString);
+
+Begin
+  If (s='') or (InOutRes <> 0) then
+   exit;
+  Do_rmdir(S);
+End;
+
+Procedure ChDir(Const s: RawByteString);
+
+Begin
+  If (s='') or (InOutRes <> 0) then
+   exit;
+  Do_chdir(S);
+End;
+
+Procedure ChDir(Const s: UnicodeString);
+
+Begin
+  If (s='') or (InOutRes <> 0) then
+   exit;
+  Do_chdir(S);
+End;
+{$ENDIF}
+
+{$ENDIF}
 
 {*****************************************************************************
                             Resources support

+ 81 - 21
rtl/inc/systemh.inc

@@ -84,6 +84,16 @@
                          Global Types and Constants
 ****************************************************************************}
 
+{ 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
   { The compiler has all integer types defined internally. Here
     we define only aliases }
@@ -331,17 +341,6 @@ Type
   PPChar              = ^PChar;
   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
     to use type renamings }
   TAnsiChar           = Char;
@@ -442,8 +441,6 @@ type
 
   TSystemCodePage     = Word;
 
-  { Needed for fpc_get_output }
-  PText               = ^Text;
 
   TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR);
 
@@ -453,7 +450,23 @@ type
 { platform dependent types }
 {$i sysosh.inc}
 
+{*****************************************************************************
+                   TextRec/FileRec exported to allow compiler to take size
+*****************************************************************************}
+
+{$ifdef FPC_HAS_SYSTEMFILEREC}
+{$ifdef FPC_HAS_FEATURE_FILEIO}
+{$i filerec.inc}
+{$endif FPC_HAS_FEATURE_FILEIO}
+
+{$i textrec.inc}
+{$endif}
+
+
 type
+  { Needed for fpc_get_output }
+  PText               = ^Text;
+
   TEntryInformation = record
     InitFinalTable : Pointer;
     ThreadvarTablesTable : Pointer;
@@ -574,6 +587,13 @@ var
 
   DefaultSystemCodePage,
   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;
 
 
@@ -1001,6 +1021,8 @@ function StringElementSize(const S : RawByteString): Word; overload;
 function StringRefCount(const S : RawByteString): SizeInt; overload;
 procedure SetCodePage(var s : RawByteString; CodePage : TSystemCodePage; Convert : Boolean = True);
 procedure SetMultiByteConversionCodePage(CodePage: TSystemCodePage);
+procedure SetMultiByteFileSystemCodePage(CodePage: TSystemCodePage);
+procedure SetMultiByteRTLFileSystemCodePage(CodePage: TSystemCodePage);
 {$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 
@@ -1021,9 +1043,19 @@ procedure SetMultiByteConversionCodePage(CodePage: TSystemCodePage);
 ****************************************************************************}
 
 {$ifdef FPC_HAS_FEATURE_FILEIO}
+{$IFNDEF FPC_UNICODE_RTL}
 Procedure Assign(out f:File;const Name:string);
 Procedure Assign(out f:File;p:pchar);
 Procedure Assign(out f:File;c:char);
+Procedure Rename(var f:File;const s:string);
+Procedure Rename(var f:File;p:pchar);
+Procedure Rename(var f:File;c:char);
+{$ELSE}
+Procedure Assign(out f:File;const Name: UnicodeString);
+Procedure Assign(out f:File;const Name: RawByteString);
+Procedure Rename(var f:File;const s : UnicodeString);
+Procedure Rename(var f:File;const s : RawByteString);
+{$ENDIF}
 Procedure Rewrite(var f:File;l:Longint);
 Procedure Rewrite(var f:File);
 Procedure Reset(var f:File;l:Longint);
@@ -1046,9 +1078,6 @@ Function  FileSize(var f:File):Int64;
 Procedure Seek(var f:File;Pos:Int64);
 Function  EOF(var f:File):Boolean;
 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);
 {$endif FPC_HAS_FEATURE_FILEIO}
 
@@ -1058,9 +1087,14 @@ Procedure Truncate (var F:File);
 ****************************************************************************}
 
 {$ifdef FPC_HAS_FEATURE_FILEIO}
+{$IFNDEF FPC_UNICODE_RTL}
 Procedure Assign(out f:TypedFile;const Name:string);
 Procedure Assign(out f:TypedFile;p:pchar);
 Procedure Assign(out f:TypedFile;c:char);
+{$ELSE}
+Procedure Assign(out f:TypedFile;const Name:unicodestring);
+Procedure Assign(out f:TypedFile;const Name:rawbytestring);
+{$ENDIF}
 Procedure Reset(var f : TypedFile);   [INTERNPROC: fpc_in_Reset_TypedFile];
 Procedure Rewrite(var f : TypedFile); [INTERNPROC: fpc_in_Rewrite_TypedFile];
 {$endif FPC_HAS_FEATURE_FILEIO}
@@ -1070,18 +1104,25 @@ Procedure Rewrite(var f : TypedFile); [INTERNPROC: fpc_in_Rewrite_TypedFile];
 ****************************************************************************}
 
 {$ifdef FPC_HAS_FEATURE_TEXTIO}
+{$IFNDEF FPC_UNICODE_RTL}
 Procedure Assign(out t:Text;const s:string);
 Procedure Assign(out t:Text;p:pchar);
 Procedure Assign(out t:Text;c:char);
+Procedure Rename(var t:Text;const s:string);
+Procedure Rename(var t:Text;p:pchar);
+Procedure Rename(var t:Text;c:char);
+{$ELSE}
+Procedure Assign(out t:Text;const s:unicodestring);
+Procedure Assign(out t:Text;const s:rawbytestring);
+Procedure Rename(var t:Text;const s:unicodestring);
+Procedure Rename(var t:Text;const s:rawbytestring);
+{$ENDIF}
 Procedure Close(var t:Text);
 Procedure Rewrite(var t:Text);
 Procedure Reset(var t:Text);
 Procedure Append(var t:Text);
 Procedure Flush(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:Boolean;
 Function  EOLn(var t:Text):Boolean;
@@ -1103,15 +1144,25 @@ procedure SetTextCodePage(var T: Text; CodePage: TSystemCodePage);
 
 
 {$ifdef FPC_HAS_FEATURE_FILEIO}
+{$IFNDEF FPC_UNICODE_RTL}
 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);
 {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
 Procedure getdir(drivenr:byte;var dir:ansistring);
 {$endif FPC_HAS_FEATURE_ANSISTRINGS}
+{$ELSE}
+Procedure chdir(const s:unicodestring); overload;
+Procedure mkdir(const s:unicodestring); overload;
+Procedure rmdir(const s:unicodestring); overload;
+Procedure chdir(const s:rawbytestring); overload;
+Procedure mkdir(const s:rawbytestring); overload;
+Procedure rmdir(const s:rawbytestring); overload;
+
+Procedure getdir(drivenr:byte;var dir: unicodestring);
+Procedure getdir(drivenr:byte;var dir: rawbytestring);rtlproc; // defaultrtlfilesystemcodepage is used here
+{$ENDIF}
 {$endif FPC_HAS_FEATURE_FILEIO}
 
 {*****************************************************************************
@@ -1214,7 +1265,12 @@ Const
 Procedure Error(RunTimeError : TRunTimeError);
 {$ifdef FPC_HAS_FEATURE_COMMANDARGS}
 Function  Paramcount:Longint;
+
+{$IFDEF FPC_UNICODE_RTL}
+Function  ParamStr(l:Longint):unicodestring;
+{$ELSE}
 Function  ParamStr(l:Longint):string;
+{$ENDIF}
 {$endif FPC_HAS_FEATURE_COMMANDARGS}
 
 Procedure Dump_Stack(var f : text;bp:pointer;addr : pointer = nil);
@@ -1351,3 +1407,7 @@ const
 {$ifdef fpdocsystem}
 {$i system.fpd}
 {$endif}
+
+
+
+

+ 60 - 10
rtl/inc/text.inc

@@ -57,7 +57,11 @@ Begin
      exit;
    end;
   End;
-  Do_Open(t,PChar(@t.Name),Flags);
+{$IFDEF FPC_UNICODE_RTL}
+  Do_Open(t,unicodestring(t.Name),Flags);
+{$ELSE FPC_UNICODE_RTL}
+  Do_Open(t,pchar(@t.Name),Flags);
+{$ENDIF FPC_UNICODE_RTL}
   t.CloseFunc:=@FileCloseFunc;
   t.FlushFunc:=nil;
   if t.Mode=fmInput then
@@ -74,9 +78,9 @@ Begin
    end;
 End;
 
+Procedure InitText(Var t : Text);
 
-Procedure Assign(out t:Text;const s:String);
-Begin
+begin
   FillChar(t,SizeOf(TextRec),0);
 { only set things that are not zero }
   TextRec(t).Handle:=UnusedHandle;
@@ -89,21 +93,42 @@ Begin
     tlbsCRLF: TextRec(t).LineEnd := #13#10;
     tlbsCR: TextRec(t).LineEnd := #13;
   End;
-  Move(s[1],TextRec(t).Name,Length(s));
+end;
+
+{$IFDEF FPC_UNICODE_RTL}
+Procedure Assign(out t:Text;const s : UnicodeString);
+
+begin
+  InitText(t);
+  TextRec(t).Name:=S;
+end;
+
+Procedure Assign(out t:Text;const s: RawByteString);
+Begin
+  InitText(t);
+  TextRec(t).Name:=S;
 End;
+{$ELSE}
 
+Procedure Assign(out t:Text;const s:String);
+Begin
+  InitText(T);
+  Move(s[1],TextRec(t).Name,Length(s));
+end;
 
 Procedure Assign(out t:Text;p:pchar);
 begin
   Assign(t,StrPas(p));
+  InitText(t);
 end;
 
-
 Procedure Assign(out t:Text;c:char);
 begin
   Assign(t,string(c));
 end;
 
+{$ENDIF}
+
 
 Procedure Close(var t : Text);[IOCheck];
 Begin
@@ -205,9 +230,35 @@ Begin
   If InOutRes <> 0 then
    exit;
   If TextRec(t).mode=fmClosed Then
-   Do_Erase(PChar(@TextRec(t).Name));
+{$IFDEF FPC_UNICODE_RTL}
+   Do_Erase(unicodestring(TextRec(t).Name));
+{$ELSE FPC_UNICODE_RTL}
+   Do_Erase(@TextRec(t).Name);
+{$ENDIF FPC_UNICODE_RTL}
 End;
 
+{$IFDEF FPC_UNICODE_RTL}
+
+Procedure Rename(var t : Text;const s : unicodestring);[IOCheck];
+
+Begin
+  If InOutRes <> 0 then
+   exit;
+  Do_Rename(TextRec(T).Name,S);
+  if InoutRes=0 then
+    TextRec(T).Name:=S;
+End;
+
+Procedure Rename(var t : Text;const s : rawbytestring);[IOCheck];
+Begin
+  If InOutRes <> 0 then
+   exit;
+  Do_Rename(TextRec(T).Name,S);
+  if InoutRes=0 then
+    TextRec(T).Name:=S;
+End;
+
+{$ELSE FPC_UNICODE_RTL}
 
 Procedure Rename(var t : text;p:pchar);[IOCheck];
 Begin
@@ -222,7 +273,6 @@ Begin
    End;
 End;
 
-
 Procedure Rename(var t : Text;const s : string);[IOCheck];
 var
   p : array[0..255] Of Char;
@@ -234,18 +284,18 @@ Begin
   Rename(t,Pchar(@p));
 End;
 
-
 Procedure Rename(var t : Text;c : char);[IOCheck];
 var
   p : array[0..1] Of Char;
 Begin
   If InOutRes <> 0 then
-   exit;
+    exit;
   p[0]:=c;
   p[1]:=#0;
   Rename(t,Pchar(@p));
 End;
 
+{$ENDIF FPC_UNICODE_RTL}
 
 Function Eof(Var t: Text): Boolean;[IOCheck];
 Begin
@@ -2071,7 +2121,7 @@ end;
 {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
 procedure WriteStrUnicode(var t: textrec);
 var
-  temp: ansistring;
+  temp: AnsiString;
   str: punicodestring;
 begin
   if (t.bufpos=0) then

+ 4 - 2
rtl/inc/textrec.inc

@@ -29,7 +29,9 @@ const
 {$endif CPUAVR}
 type
   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 causes the compiler to handle arrays of text wrongly, see  see tw0754 e.g. on arm  }
   TextRec = {$ifdef VER2_6} packed {$endif} Record
@@ -45,7 +47,7 @@ type
     flushfunc,
     closefunc : pointer;
     UserData  : array[1..32] of byte;
-    name      : array[0..textrecnamelength-1] of char;
+    name      : array[0..textrecnamelength-1] of {$IFDEF FPC_UNICODE_RTL} unicodechar {$ELSE} char {$ENDIF};
     LineEnd   : TLineEndStr;
     buffer    : textbuf;
 {$ifdef FPC_HAS_CPSTRING}

+ 33 - 12
rtl/inc/typefile.inc

@@ -15,35 +15,56 @@
                     subroutines for typed file handling
 ****************************************************************************}
 
-Procedure Assign(out f:TypedFile;const Name:string);
+Procedure InitTypedFile(Var F : TypedFile);
+
+begin
+  FillChar(f,SizeOF(FileRec),0);
+  FileRec(f).Handle:=UnusedHandle;
+  FileRec(f).mode:=fmClosed;
+end;
+
+{$IFDEF FPC_UNICODE_RTL}
+Procedure Assign(out f:TypedFile;const Name:unicodestring);
 {
   Assign Name to file f so it can be used with the file routines
 }
 Begin
-  FillChar(f,SizeOF(FileRec),0);
-  FileRec(f).Handle:=UnusedHandle;
-  FileRec(f).mode:=fmClosed;
-  Move(Name[1],FileRec(f).Name,Length(Name));
+  InitTypedFile(F);
+  FileRec(f).Name:=Name;
 End;
 
-
-Procedure Assign(out f:TypedFile;p:pchar);
+Procedure Assign(out f:TypedFile;const Name: rawbytestring);
 {
   Assign Name to file f so it can be used with the file routines
 }
+Begin
+  InitTypedFile(F);
+  FileRec(f).Name:=Name;
+End;
+{$ELSE}
+Procedure Assign(out f:TypedFile;const Name:string);
+{
+  Assign Name to file f so it can be used with the file routines
+}
+Begin
+   FillChar(f,SizeOF(FileRec),0);
+   FileRec(f).Handle:=UnusedHandle;
+   FileRec(f).mode:=fmClosed;
+  Move(Name[1],FileRec(f).Name,Length(Name));
+end;
+ 
+Procedure Assign(out f:TypedFile;p:pchar);
 begin
   Assign(f,StrPas(p));
 end;
 
-
-Procedure Assign(out f:TypedFile;c:char);
-{
-  Assign Name to file f so it can be used with the file routines
-}
+Procedure Assign(out f:TypedFile;c : char);
 begin
   Assign(f,string(c));
 end;
 
+{$ENDIF}
+
 
 Procedure fpc_reset_typed(var f : TypedFile;Size : Longint);[Public,IOCheck, Alias:'FPC_RESET_TYPED']; compilerproc;
 Begin

+ 7 - 3
rtl/inc/ustringh.inc

@@ -53,9 +53,10 @@ procedure DefaultAnsi2UnicodeMove(source:pchar;cp : TSystemCodePage;var dest:uni
 
 Type
   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}
@@ -144,3 +145,6 @@ Procedure SetUnicodeStringManager (Const New : TUnicodeStringManager; Var Old: T
 function StringElementSize(const S : UnicodeString): Word; overload;
 function StringRefCount(const S : UnicodeString): SizeInt; overload;
 function StringCodePage(const S : UnicodeString): TSystemCodePage; overload;
+
+Function ToSingleByteFileSystemEncodedFileName(const Str: UnicodeString): RawByteString;
+Function ToSingleByteFileSystemEncodedFileName(const Str: RawByteString): RawByteString;

+ 20 - 1
rtl/inc/ustrings.inc

@@ -124,7 +124,13 @@ function DefaultCodePointLength(const Str: PChar; MaxLookAead: PtrInt): Ptrint;
 function DefaultGetStandardCodePage(const stdcp: TStandardCodePageEnum): TSystemCodePage;
   begin
     { 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;
 
 Procedure GetUnicodeStringManager (Var Manager : TUnicodeStringManager);
@@ -2275,3 +2281,16 @@ procedure initunicodestringmanager;
   end;
 {$endif FPC_HAS_BUILTIN_WIDESTR_MANAGER}
 
+
+Function ToSingleByteFileSystemEncodedFileName(const Str: UnicodeString): RawByteString;
+Begin
+  widestringmanager.Unicode2AnsiMoveProc(punicodechar(Str),Result,
+    DefaultFileSystemCodePage,Length(Str));
+End;
+
+
+Function ToSingleByteFileSystemEncodedFileName(const Str: RawByteString): RawByteString;
+Begin
+  Result:=Str;
+  SetCodePage(Result,DefaultFileSystemCodePage,True);
+End;

+ 4 - 0
rtl/linux/system.pp

@@ -121,7 +121,11 @@ end;}
 var
  execpathstr : shortstring;
 
+{$IFDEF FPC_UNICODE_RTL}
+function paramstr(l: longint) : unicodestring;
+{$ELSE}
 function paramstr(l: longint) : string;
+{$ENDIF}
  begin
    { stricly conforming POSIX applications  }
    { have the executing filename as argv[0] }

+ 57 - 8
rtl/objpas/objpas.pp

@@ -60,34 +60,48 @@ Var
 {$ifdef FPC_HAS_FEATURE_FILEIO}
     { Untyped file support }
 
+     {$ifdef FPC_UNICODE_RTL}
+     Procedure AssignFile(out f:File;const Name:UnicodeString);
+     Procedure AssignFile(out f:File;const Name:RawByteString);
+     {$else}
      Procedure AssignFile(out f:File;const Name:string);
      Procedure AssignFile(out f:File;p:pchar);
      Procedure AssignFile(out f:File;c:char);
+     {$endif}
      Procedure CloseFile(var f:File);
 {$endif FPC_HAS_FEATURE_FILEIO}
 
 {$ifdef FPC_HAS_FEATURE_TEXTIO}
      { Text file support }
+     {$ifdef FPC_UNICODE_RTL}
+     Procedure AssignFile(out f:Text;const Name:UnicodeString);
+     Procedure AssignFile(out f:Text;const Name:RawByteString);
+     {$else}
      Procedure AssignFile(out t:Text;const s:string);
      Procedure AssignFile(out t:Text;p:pchar);
      Procedure AssignFile(out t:Text;c:char);
+     {$endif}
      Procedure CloseFile(Var t:Text);
 {$endif FPC_HAS_FEATURE_TEXTIO}
 
 {$ifdef FPC_HAS_FEATURE_FILEIO}
      { Typed file supoort }
-
+     {$ifdef FPC_UNICODE_RTL}
+     Procedure AssignFile(out f:TypedFile;const Name:UnicodeString);
+     Procedure AssignFile(out f:TypedFile;const Name:RawByteString);
+     {$else}
      Procedure AssignFile(out f:TypedFile;const Name:string);
      Procedure AssignFile(out f:TypedFile;p:pchar);
      Procedure AssignFile(out f:TypedFile;c:char);
+     {$endif}
 {$endif FPC_HAS_FEATURE_FILEIO}
 
-{$ifdef FPC_HAS_FEATURE_COMMANDARGS}
+{$if defined(FPC_HAS_FEATURE_COMMANDARGS) and not defined(FPC_UNICODE_RTL)}
      { ParamStr should return also an ansistring }
      Function ParamStr(Param : Integer) : Ansistring;
 {$endif FPC_HAS_FEATURE_COMMANDARGS}
 
-{$if defined(FPC_HAS_FEATURE_FILEIO) and defined(FPC_HAS_FEATURE_ANSISTRINGS)}
+{$if defined(FPC_HAS_FEATURE_FILEIO) and defined(FPC_HAS_FEATURE_ANSISTRINGS) and not defined(FPC_UNICODE_RTL)}
      Procedure MkDir(s:ansistring);overload;
      Procedure RmDir(s:ansistring);overload;
      Procedure ChDir(s:ansistring);overload;
@@ -130,20 +144,30 @@ Var
 ****************************************************************************}
 
 {$ifdef FPC_HAS_FEATURE_FILEIO}
+{$ifndef FPC_UNICODE_RTL}
 Procedure MkDirpchar(s: pchar;len:sizeuint);[IOCheck]; external name 'FPC_SYS_MKDIR';
 Procedure ChDirpchar(s: pchar;len:sizeuint);[IOCheck]; external name 'FPC_SYS_CHDIR';
 Procedure RmDirpchar(s: pchar;len:sizeuint);[IOCheck]; external name 'FPC_SYS_RMDIR';
+{$endif}
 
 { Untyped file support }
+{$ifdef FPC_UNICODE_RTL}
+Procedure AssignFile(out f:File;const Name:RawBytestring);
+begin
+  System.Assign (F,Name);
+end;
 
+Procedure AssignFile(out f:File;const Name:UnicodeString);
+begin
+  System.Assign (F,Name);
+end;
+{$else}
 Procedure AssignFile(out f:File;const Name:string);
-
 begin
   System.Assign (F,Name);
 end;
 
 Procedure AssignFile(out f:File;p:pchar);
-
 begin
   System.Assign (F,P);
 end;
@@ -153,7 +177,7 @@ Procedure AssignFile(out f:File;c:char);
 begin
   System.Assign (F,C);
 end;
-
+{$endif}
 Procedure CloseFile(Var f:File); [IOCheck];
 
 begin
@@ -165,6 +189,18 @@ end;
 {$ifdef FPC_HAS_FEATURE_TEXTIO}
 { Text file support }
 
+{$ifdef FPC_UNICODE_RTL}
+Procedure AssignFile(out f:Text;const Name:RawBytestring);
+begin
+  System.Assign (F,Name);
+end;
+
+Procedure AssignFile(out f:Text;const Name:UnicodeString);
+begin
+  System.Assign (F,Name);
+end;
+{$else}
+
 Procedure AssignFile(out t:Text;const s:string);
 
 begin
@@ -182,6 +218,7 @@ Procedure AssignFile(out t:Text;c:char);
 begin
   System.Assign (T,C);
 end;
+{$endif}
 
 Procedure CloseFile(Var t:Text); [IOCheck];
 
@@ -194,6 +231,17 @@ end;
 {$ifdef FPC_HAS_FEATURE_FILEIO}
 { Typed file support }
 
+{$ifdef FPC_UNICODE_RTL}
+Procedure AssignFile(out f:TypedFile;const Name:RawBytestring);
+begin
+  System.Assign (F,Name);
+end;
+
+Procedure AssignFile(out f:TypedFile;const Name:UnicodeString);
+begin
+  System.Assign (F,Name);
+end;
+{$else}
 Procedure AssignFile(out f:TypedFile;const Name:string);
 
 begin
@@ -211,9 +259,10 @@ Procedure AssignFile(out f:TypedFile;c:char);
 begin
   system.Assign (F,C);
 end;
+{$endif}
 {$endif FPC_HAS_FEATURE_FILEIO}
 
-{$ifdef FPC_HAS_FEATURE_COMMANDARGS}
+{$if defined(FPC_HAS_FEATURE_COMMANDARGS) and not defined(FPC_UNICODE_RTL)}
 Function ParamStr(Param : Integer) : Ansistring;
 
 Var Len : longint;
@@ -244,7 +293,7 @@ end;
 {$endif FPC_HAS_FEATURE_COMMANDARGS}
 
 
-{$if defined(FPC_HAS_FEATURE_FILEIO) and defined(FPC_HAS_FEATURE_ANSISTRINGS)}
+{$if defined(FPC_HAS_FEATURE_FILEIO) and defined(FPC_HAS_FEATURE_ANSISTRINGS) and not defined(FPC_UNICODE_RTL)}
 { xxDirPChar procedures can adjust directory separators in supplied string (at least
   Windows implementation does so). Therefore full copy of argument is needed,
   just passing by value isn't enough because it won't copy a string literal. }

+ 413 - 0
rtl/objpas/sysutils/filutil.inc

@@ -0,0 +1,413 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2012 by the Free Pascal development team
+
+    File utility calls
+
+    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.
+
+ **********************************************************************}
+
+
+
+{$ifndef SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
+Function FileOpen (Const FileName : unicodestring; Mode : Integer) : THandle;
+begin
+  Result:=FileOpen(ToSingleByteFileSystemEncodedFileName(FileName),Mode);
+end;
+
+
+Function FileCreate (Const FileName : UnicodeString) : THandle;
+begin
+  Result:=FileCreate(ToSingleByteFileSystemEncodedFileName(FileName));
+end;
+
+
+Function FileCreate (Const FileName : UnicodeString; Rights : Integer) : THandle;
+begin
+  Result:=FileCreate(ToSingleByteFileSystemEncodedFileName(FileName),Rights);
+end;
+
+
+Function FileCreate (Const FileName : UnicodeString; ShareMode : Integer; Rights : Integer) : THandle;
+begin
+  Result:=FileCreate(ToSingleByteFileSystemEncodedFileName(FileName),ShareMode,Rights);
+end;
+
+Function FileAge (Const FileName : UnicodeString): Longint;
+begin
+  Result:=FileAge(ToSingleByteFileSystemEncodedFileName(FileName));
+end;
+
+Function FileExists (Const FileName : UnicodeString) : Boolean;
+
+begin
+  Result:=FileExists(ToSingleByteFileSystemEncodedFileName(FileName));
+end;
+
+Function DirectoryExists (Const Directory : UnicodeString) : Boolean;
+begin
+  Result:=DirectoryExists(ToSingleByteFileSystemEncodedFileName(Directory));
+end;
+
+Function FileGetAttr (Const FileName : UnicodeString) : Longint;
+begin
+  Result:=FileGetAttr(ToSingleByteFileSystemEncodedFileName(FileName));  
+end;
+
+Function FileSetAttr (Const Filename : UnicodeString; Attr: longint) : Longint;
+begin
+  Result:=FileSetAttr(ToSingleByteFileSystemEncodedFileName(FileName),Attr);
+end;
+
+
+Function DeleteFile (Const FileName : UnicodeString) : Boolean;
+begin
+  Result:=DeleteFile(ToSingleByteFileSystemEncodedFileName(FileName));
+end;
+
+
+Function RenameFile (Const OldName, NewName : UnicodeString) : Boolean;
+
+begin
+  Result:=RenameFile(ToSingleByteFileSystemEncodedFileName(OldName),
+                     ToSingleByteFileSystemEncodedFileName(NewName));
+end;
+
+Function FileIsReadOnly(const FileName: UnicodeString): Boolean;
+
+begin
+  Result:=FileIsReadOnly(ToSingleByteFileSystemEncodedFileName(FileName));
+end;
+
+Function FileSetDate (Const FileName : UnicodeString;Age : Longint) : Longint;
+
+begin
+  Result:=FileSetDate(ToSingleByteFileSystemEncodedFileName(FileName),Age);
+end;
+
+function FileAge(const FileName: RawByteString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
+   
+Var
+  Info : TSearchRec;
+  A : Integer;
+      
+begin
+  for A:=1 to Length(FileName) do
+    If (FileName[A] in ['?','*']) then
+      Exit(False);
+  A:=0;
+  if Not FollowLink then
+    A:=A or faSymLink;
+  Result:=FindFirst(FileName,A,Info)=0;
+  If Result then 
+    FileDateTime:=FileDatetoDateTime (Info.Time);
+  FindClose(Info);
+end;
+
+Function FileAge(const FileName: UnicodeString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
+begin
+  Result:=FileAge(ToSingleByteFileSystemEncodedFileName(FileName),FileDateTime,FollowLink);
+end;
+
+Function FileSearch (Const Name, DirList : UnicodeString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : UnicodeString;
+
+begin
+  Result:=UnicodeString(FileSearch(ToSingleByteFileSystemEncodedFileName(Name),
+                                   ToSingleByteFileSystemEncodedFileName(Dirlist),Options));
+end;
+
+
+Function FileSearch (Const Name, DirList : UnicodeString; ImplicitCurrentDir : Boolean) : UnicodeString;
+
+begin
+  Result:=UnicodeString(FileSearch(ToSingleByteFileSystemEncodedFileName(Name),
+                                   ToSingleByteFileSystemEncodedFileName(DirList),ImplicitCurrentDir));
+end;
+
+    
+Function ExeSearch (Const Name : UnicodeString; Const DirList : UnicodeString ='' ) : UnicodeString;
+
+begin
+  Result:=UnicodeString(ExeSearch(ToSingleByteFileSystemEncodedFileName(Name),
+                                  ToSingleByteFileSystemEncodedFileName(Dirlist)));
+end;
+
+
+{$endif}
+
+{$ifndef SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+Function FileOpen (Const FileName : rawbytestring; Mode : Integer) : THandle;
+begin
+  Result:=FileOpen(UnicodeString(FileName),Mode);
+end;
+
+
+Function FileCreate (Const FileName : RawByteString) : THandle;
+begin
+  Result:=FileCreate(UnicodeString(FileName));
+end;
+
+
+Function FileCreate (Const FileName : RawByteString; Rights : Integer) : THandle;
+begin
+  Result:=FileCreate(UnicodeString(FileName),Rights);
+end;
+
+
+Function FileCreate (Const FileName : RawByteString; ShareMode : Integer; Rights : Integer) : THandle;
+begin
+  Result:=FileCreate(UnicodeString(FileName),ShareMode,Rights);
+end;
+
+Function FileAge (Const FileName : RawByteString): Longint;
+begin
+  Result:=FileAge(UnicodeString(FileName));
+end;
+
+Function FileExists (Const FileName : RawByteString) : Boolean;
+
+begin
+  Result:=FileExists(UnicodeString(FileName));
+end;
+
+Function DirectoryExists (Const Directory : RawByteString) : Boolean;
+begin
+  Result:=DirectoryExists(UnicodeString(Directory));
+end;
+
+Function FindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TSearchRec) : Longint;
+
+begin
+  Result:=FindFirst(unicodestring(path),attr,rslt);
+end;
+
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
+begin
+  Result:=FileGetAttr(unicodestring(FileName));  
+end;
+
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
+begin
+  Result:=FileSetAttr(unicodestring(FileName),Attr);
+end;
+
+Function DeleteFile (Const FileName : RawByteString) : Boolean;
+begin
+  Result:=DeleteFile(UnicodeString(FileName));
+end;
+
+Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
+
+begin
+  Result:=RenameFile(UnicodeString(OldName),UnicodeString(NewName));
+end;
+
+Function FileIsReadOnly(const FileName: RawByteString): Boolean;
+
+begin
+  Result:=FileIsReadOnly(UnicodeString(FileName));
+end;
+
+Function FileSetDate (Const FileName : RawByteString;Age : Longint) : Longint;
+
+begin
+  Result:=FileSetDate(UnicodeString(FileName),Age);
+end;
+
+function FileAge(const FileName: UnicodeString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
+   
+Var
+  Info : TSearchRec;
+  A : Integer;
+      
+begin
+  for A:=1 to Length(FileName) do
+    If (FileName[A] in ['?','*']) then
+      Exit(False);
+  A:=0;
+  if Not FollowLink then
+    A:=A or faSymLink;
+  Result:=FindFirst(FileName,A,Info)=0;
+  If Result then 
+    FileDateTime:=FileDatetoDateTime (Info.Time);
+  FindClose(Info);
+end;
+
+Function FileAge(const FileName: RawbyteString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
+begin
+  Result:=FileAge(UnicodeString(FileName),FileDateTime,FollowLink);
+end;
+
+
+Function FileSearch (Const Name, DirList : RawByteString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : RawByteString;
+
+begin
+  Result:=ToSingleByteFileSystemEncodedFileName(FileSearch(UnicodeString(Name),UnicodeString(Dirlist),Options));
+end;
+
+Function FileSearch (Const Name, DirList : UnicodeString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : UnicodeString;
+Var
+  I : longint;
+  Temp : UnicodeString;
+
+begin
+  Result:=Name;
+  temp:=SetDirSeparators(DirList);
+  // Start with checking the file in the current directory
+  If (sfoImplicitCurrentDir in Options) and (Result <> '') and FileExists(Result) Then
+    exit;
+  while True do begin
+    If Temp = '' then
+      Break; // No more directories to search - fail
+    I:=pos(PathSeparator,Temp);
+    If I<>0 then
+      begin
+        Result:=Copy (Temp,1,i-1);
+        system.Delete(Temp,1,I);
+      end
+    else
+      begin
+        Result:=Temp;
+        Temp:='';
+      end;
+    If Result<>'' then
+      begin
+      If (sfoStripQuotes in Options) and (Result[1]='"') and (Result[Length(Result)]='"') then
+        Result:=Copy(Result,2,Length(Result)-2);
+      if (Result<>'') then
+        Result:=IncludeTrailingPathDelimiter(Result)+name;
+      end;
+    If (Result <> '') and FileExists(Result) Then
+      exit;
+  end;
+  result:='';
+end;
+
+Function FileSearch (Const Name, DirList : RawByteString; ImplicitCurrentDir : Boolean) : RawByteString;
+
+begin
+  Result:=ToSingleByteFileSystemEncodedFileName(FileSearch(UnicodeString(Name),UnicodeString(DirList),ImplicitCurrentDir));
+end;
+
+Function FileSearch (Const Name, DirList : UnicodeString; ImplicitCurrentDir : Boolean) : UnicodeString;
+
+begin
+  if ImplicitCurrentDir then
+    Result:=FileSearch(Name,DirList,[sfoImplicitCurrentDir])
+  else  
+    Result:=FileSearch(Name,DirList,[]);
+end;
+    
+Function ExeSearch (Const Name : RawByteString; Const DirList : RawByteString ='' ) : RawByteString;
+
+begin
+  Result:=ToSingleByteFileSystemEncodedFileName(ExeSearch(UnicodeString(Name),UnicodeString(Dirlist));
+end;
+
+Function ExeSearch (Const Name : UnicodeString; Const DirList : UnicodeString ='' ) : UnicodeString;
+
+Var
+  D : UnicodeString;
+  O : TFileSearchOptions;
+begin
+  D:=DirList;
+  if (D='') then
+    D:=GetEnvironmentVariable('PATH');
+{$ifdef unix}
+  O:=[];
+{$else unix}
+  O:=[sfoImplicitCurrentDir,sfoStripQuotes];
+{$endif unix}
+  Result := FileSearch(Name, D, O);
+end;
+
+{$endif}
+
+Function FileSearch (Const Name, DirList : RawByteString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : RawByteString;
+Var
+  I : longint;
+  Temp : RawByteString;
+
+begin
+  Result:=Name;
+  temp:=SetDirSeparators(DirList);
+  // Start with checking the file in the current directory
+  If (sfoImplicitCurrentDir in Options) and (Result <> '') and FileExists(Result) Then
+    exit;
+  while True do begin
+    If Temp = '' then
+      Break; // No more directories to search - fail
+    I:=pos(PathSeparator,Temp);
+    If I<>0 then
+      begin
+        Result:=Copy (Temp,1,i-1);
+        system.Delete(Temp,1,I);
+      end
+    else
+      begin
+        Result:=Temp;
+        Temp:='';
+      end;
+    If Result<>'' then
+      begin
+      If (sfoStripQuotes in Options) and (Result[1]='"') and (Result[Length(Result)]='"') then
+        Result:=Copy(Result,2,Length(Result)-2);
+      if (Result<>'') then
+        Result:=IncludeTrailingPathDelimiter(Result)+name;
+      end;
+    If (Result <> '') and FileExists(Result) Then
+      exit;
+  end;
+  result:='';
+end;
+Function FileSearch (Const Name, DirList : RawByteString; ImplicitCurrentDir : Boolean) : RawByteString;
+
+begin
+  if ImplicitCurrentDir then
+    Result:=FileSearch(Name,DirList,[sfoImplicitCurrentDir])
+  else  
+    Result:=FileSearch(Name,DirList,[]);
+end;
+Function ExeSearch (Const Name : RawByteString; Const DirList : RawByteString ='' ) : RawByteString;
+
+Var
+  D : RawByteString;
+  O : TFileSearchOptions;
+begin
+  D:=DirList;
+  if (D='') then
+    D:=GetEnvironmentVariable('PATH');
+{$ifdef unix}
+  O:=[];
+{$else unix}
+  O:=[sfoImplicitCurrentDir,sfoStripQuotes];
+{$endif unix}
+  Result := FileSearch(Name, D, O);
+end;
+
+{$IFNDEF FPC_UNICODE_RTL}
+function FileAge(const FileName: RawByteString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
+
+Var
+  Info : TSearchRec;
+  A : Integer;
+   
+begin
+  for A:=1 to Length(FileName) do
+    If (FileName[A] in ['?','*']) then
+      Exit(False);
+  A:=0;
+  if Not FollowLink then
+    A:=A or faSymLink;
+  Result:=FindFirst(FileName,A,Info)=0;
+  If Result then 
+    FileDateTime:=FileDatetoDateTime (Info.Time);
+  FindClose(Info);
+end;
+{$ENDIF}

+ 130 - 42
rtl/objpas/sysutils/filutilh.inc

@@ -14,36 +14,99 @@
  **********************************************************************}
 
 Type
-  TSearchRec = Record
-    Time : Longint;
-    Size : Int64;
-    Attr : Longint;
-    Name : TFileName;
-    ExcludeAttr : Longint;
-{$ifdef unix}
-    FindHandle : Pointer;
-    Mode : TMode;
-    PathOnly : AnsiString {$ifndef VER2_2} deprecated{$endif};
-{$else unix}
-    FindHandle : THandle;
-{$endif unix}
+
+{$IFDEF FPC_UNICODE_RTL}
+
+  // Some operating systems need extra find data.
 {$if defined(Win32) or defined(WinCE) or defined(Win64)}
-    FindData : TWin32FindData;
+    TUnicodeSearchFindData = TWin32FindDataW;
+{$ENDIF}
+{$ifdef netware_clib}
+    TUnicodeSearchFindData = TNetwareFindData;
+{$endif}
+{$ifdef netware_libc}
+    TUnicodeSearchFindData = TNetwareLibcFindData;
+{$endif}
+{$ifdef MacOS}
+    TUnicodeSearchFindData = TMacOSFindData;
 {$endif}
+{$ifdef nativent}
+    TUnicodeSearchFindData = TNativeNTFindData;
+{$endif}
+
+
+{$ENDIF FPC_UNICODE_RTL}
+
+// USEFINDDATA is only defined here.
+
+{$if defined(Win32) or defined(Win64)}
+    {$DEFINE USEFINDDATA}
+    TRawByteSearchFindData = TWin32FindDataA;
+{$ENDIF}
+{$if defined(Wince)}
+    {$DEFINE USEFINDDATA}
+    TRawByteSearchFindData = TWin32FindDataW;
+{$ENDIF}
 {$ifdef netware_clib}
-    FindData : TNetwareFindData;
+    TRawByteSearchFindData = TNetwareFindData;
+    {$DEFINE USEFINDDATA}
 {$endif}
 {$ifdef netware_libc}
-    FindData : TNetwareLibcFindData;
+    TRawByteSearchFindData = TNetwareLibcFindData;
+    {$DEFINE USEFINDDATA}
 {$endif}
 {$ifdef MacOS}
-    FindData : TMacOSFindData;
+    TRawByteSearchFindData = TMacOSFindData;
+    {$DEFINE USEFINDDATA}
 {$endif}
 {$ifdef nativent}
-    FindData : TNativeNTFindData;
+    TRawByteSearchFindData = TNativeNTFindData;
+    {$DEFINE USEFINDDATA}
 {$endif}
+
+{$IFDEF FPC_UNICODE_RTL}
+  // The actual unicode search record
+  TUnicodeSearchRec = Record
+    Time : Longint;
+    Size : Int64;
+    Attr : Longint;
+    Name : UnicodeString;
+    ExcludeAttr : Longint;
+{$ifdef unix}
+    FindHandle : Pointer;
+    Mode : TMode;
+{$else unix}
+    FindHandle : THandle;
+{$endif unix}
+{$IFDEF USEFINDDATA}
+    FindData : TUnicodeSearchFindData;
+{$ENDIF}    
+  end;
+{$ENDIF}
+
+  TRawbyteSearchRec = Record
+    Time : Longint;
+    Size : Int64;
+    Attr : Longint;
+    Name : RawByteString;
+    ExcludeAttr : Longint;
+{$ifdef unix}
+    FindHandle : Pointer;
+    Mode : TMode;
+{$else unix}
+    FindHandle : THandle;
+{$endif unix}
+{$IFDEF USEFINDDATA}
+    FindData : TRawByteSearchFindData;
+{$ENDIF}    
   end;
 
+{$IFDEF FPC_UNICODE_RTL}
+  TSearchRec = TUnicodeSearchRec;
+{$ELSE}
+  TSearchRec = TRawbyteSearchRec;
+{$ENDIF}
+
 Const
   { File attributes }
   faReadOnly  = $00000001;
@@ -78,37 +141,62 @@ Type
   TFileSearchOption = (sfoImplicitCurrentDir,sfoStripQuotes);
   TFileSearchOptions = set of TFileSearchOption;
 
-Function FileOpen (Const FileName : string; Mode : Integer) : THandle;
-Function FileCreate (Const FileName : String) : THandle;
-Function FileCreate (Const FileName : String; Rights : Integer) : THandle;
-Function FileCreate (Const FileName : String; ShareMode : Integer; Rights : Integer) : THandle;
+{$IFDEF FPC_UNICODE_RTL}
+
+Function FileOpen (Const FileName : unicodestring; Mode : Integer) : THandle;
+Function FileCreate (Const FileName : UnicodeString) : THandle;
+Function FileCreate (Const FileName : UnicodeString; Rights : Integer) : THandle;
+Function FileCreate (Const FileName : UnicodeString; ShareMode : Integer; Rights : Integer) : THandle;
+{$IFNDEF FPUNONE}
+Function FileAge (Const FileName : UnicodeString): Longint;
+{$ENDIF}
+Function FileExists (Const FileName : UnicodeString) : Boolean;
+Function DirectoryExists (Const Directory : UnicodeString) : Boolean;
+Function FileSetDate (Const FileName : UnicodeString;Age : Longint) : Longint;
+Function FileGetAttr (Const FileName : UnicodeString) : Longint;
+Function FileSetAttr (Const Filename : UnicodeString; Attr: longint) : Longint;
+Function DeleteFile (Const FileName : UnicodeString) : Boolean;
+Function RenameFile (Const OldName, NewName : UnicodeString) : Boolean;
+Function FindFirst (Const Path : UnicodeString; Attr : Longint; out Rslt : TUnicodeSearchRec) : Longint;
+Function FindNext (Var Rslt : TUnicodeSearchRec) : Longint;
+Procedure FindClose (Var F : TUnicodeSearchrec);
+Function FileSearch (Const Name, DirList : UnicodeString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : UnicodeString;
+Function FileSearch (Const Name, DirList : UnicodeString; ImplicitCurrentDir : Boolean) : UnicodeString;
+Function ExeSearch  (Const Name : UnicodeString; Const DirList : UnicodeString = '') : UnicodeString;
+Function FileIsReadOnly(const FileName : UnicodeString): Boolean;
+function FileAge(const FileName: UnicodeString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
+{$ENDIF UNICODERTL}
+
+Function FileOpen (Const FileName : RawByteString; Mode : Integer) : THandle;
+Function FileCreate (Const FileName : RawByteString) : THandle;
+Function FileCreate (Const FileName : RawByteString; Rights : Integer) : THandle;
+Function FileCreate (Const FileName : RawByteString; ShareMode : Integer; Rights : Integer) : THandle;
+Function FileExists (Const FileName : RawByteString) : Boolean;
+Function DirectoryExists (Const Directory : RawByteString) : Boolean;
+Function FileSetDate (Const FileName : RawByteString;Age : Longint) : Longint;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
+Function DeleteFile (Const FileName : RawByteString) : Boolean;
+Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
+Function FindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TRawByteSearchRec) : Longint;
+Function FileSearch (Const Name, DirList : RawByteString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : RawByteString;
+Function FileSearch (Const Name, DirList : RawByteString; ImplicitCurrentDir : Boolean) : RawByteString;
+Function ExeSearch  (Const Name : RawByteString; Const DirList : RawByteString = '') : RawByteString;
+Function FileIsReadOnly(const FileName: RawByteString): Boolean;
+function FileAge(const FileName: RawByteString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
+{$ifndef FPUNONE}
+Function FileAge (Const FileName : RawByteString): Longint;
+{$endif}
+
 Function FileRead (Handle : THandle; out Buffer; Count : longint) : Longint;
 Function FileWrite (Handle : THandle; const Buffer; Count : Longint) : Longint;
 Function FileSeek (Handle : THandle; FOffset, Origin: Longint) : Longint;
 Function FileSeek (Handle : THandle; FOffset: Int64; Origin: Longint) : Int64;
 Procedure FileClose (Handle : THandle);
 Function FileTruncate (Handle : THandle;Size: Int64) : boolean;
-{$ifndef FPUNONE}
-Function FileAge (Const FileName : String): Longint;
-{$endif}
-Function FileExists (Const FileName : String) : Boolean;
-Function DirectoryExists (Const Directory : String) : Boolean;
-Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
-Function FindNext (Var Rslt : TSearchRec) : Longint;
-Procedure FindClose (Var F : TSearchrec);
+Function FindNext (Var Rslt : TRawByteSearchRec) : Longint;
+Procedure FindClose (Var F : TRawByteSearchrec);
 Function FileGetDate (Handle : THandle) : Longint;
 Function FileSetDate (Handle : THandle;Age : Longint) : Longint;
-Function FileSetDate (Const FileName : String;Age : Longint) : Longint;
-Function FileGetAttr (Const FileName : String) : Longint;
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
-Function DeleteFile (Const FileName : String) : Boolean;
-Function RenameFile (Const OldName, NewName : String) : Boolean;
-
-Function FileSearch (Const Name, DirList : String; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : String;
-Function FileSearch (Const Name, DirList : String; ImplicitCurrentDir : Boolean) : String;
-Function ExeSearch  (Const Name : String; Const DirList : String = '') : String;
-Function FileIsReadOnly(const FileName: String): Boolean;
-
 Function GetFileHandle(var f : File):THandle;
 Function GetFileHandle(var f : Text):THandle;
-function FileAge(const FileName: string; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;

+ 13 - 2
rtl/objpas/sysutils/fina.inc

@@ -127,13 +127,24 @@ begin
 {$endif}
 end;
 
-type
-  PathStr=string;
+{$MACRO ON}
 
 {$DEFINE FPC_FEXPAND_SYSUTILS}
 
+{$IFDEF FPC_UNICODE_RTL}
+{$DEFINE PathStr:=UnicodeString}
 {$I fexpand.inc}
 
+{$DEFINE PathStr:=RawByteString}
+{$I fexpand.inc}
+{$ELSE}
+
+{$DEFINE PathStr:=AnsiString}
+{$I fexpand.inc}
+
+{$ENDIF}
+{$UNDEFINE PathStr}
+
 
 function ExpandFileName (Const FileName : string): String;
 

+ 3 - 81
rtl/objpas/sysutils/sysutils.inc

@@ -15,72 +15,12 @@
   { Read filename handling functions implementation }
   {$i fina.inc}
 
+  { Read file utility functions implementation }
+  {$i filutil.inc}
+
   { variant error codes }
   {$i varerror.inc}
 
-    Function FileSearch (Const Name, DirList : String; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : String;
-    Var
-      I : longint;
-      Temp : String;
-
-    begin
-      Result:=Name;
-      temp:=SetDirSeparators(DirList);
-      // Start with checking the file in the current directory
-      If (sfoImplicitCurrentDir in Options) and (Result <> '') and FileExists(Result) Then
-        exit;
-      while True do begin
-        If Temp = '' then
-          Break; // No more directories to search - fail
-        I:=pos(PathSeparator,Temp);
-        If I<>0 then
-          begin
-            Result:=Copy (Temp,1,i-1);
-            system.Delete(Temp,1,I);
-          end
-        else
-          begin
-            Result:=Temp;
-            Temp:='';
-          end;
-        If Result<>'' then
-          begin
-          If (sfoStripQuotes in Options) and (Result[1]='"') and (Result[Length(Result)]='"') then
-            Result:=Copy(Result,2,Length(Result)-2);
-          if (Result<>'') then
-            Result:=IncludeTrailingPathDelimiter(Result)+name;
-          end;
-        If (Result <> '') and FileExists(Result) Then
-          exit;
-      end;
-      result:='';
-    end;
-
-    Function FileSearch (Const Name, DirList : String; ImplicitCurrentDir : Boolean) : String;
-
-    begin
-      if ImplicitCurrentDir then
-        Result:=FileSearch(Name,DirList,[sfoImplicitCurrentDir])
-      else  
-        Result:=FileSearch(Name,DirList,[]);
-    end;
-    
-    Function ExeSearch (Const Name : String; Const DirList : String ='' ) : String;
-    
-    Var
-      D : String;
-      O : TFileSearchOptions;
-    begin
-      D:=DirList;
-      if (D='') then
-        D:=GetEnvironmentVariable('PATH');
-    {$ifdef unix}
-      O:=[];
-    {$else unix}
-      O:=[sfoImplicitCurrentDir,sfoStripQuotes];
-    {$endif unix}
-      Result := FileSearch(Name, D, O);
-    end;
 
   {$ifndef OS_FILEISREADONLY}
   Function FileIsReadOnly(const FileName: String): Boolean;
@@ -177,24 +117,6 @@ end;
         temp.free;
       end;
 
-   function FileAge(const FileName: string; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
-   
-   Var
-     Info : TSearchRec;
-     A : Integer;
-      
-   begin
-     for A:=1 to Length(FileName) do
-       If (FileName[A] in ['?','*']) then
-         Exit(False);
-     A:=0;
-     if Not FollowLink then
-       A:=A or faSymLink;
-     Result:=FindFirst(FileName,A,Info)=0;
-     If Result then 
-       FileDateTime:=FileDatetoDateTime (Info.Time);
-     FindClose(Info);
-   end;
 
   { Interfaces support }
   {$i sysuintf.inc}

+ 18 - 2
rtl/unix/printer.pp

@@ -115,7 +115,11 @@ end;
 
 Procedure OpenLstPipe ( Var F : Text);
 begin
+{$IFDEF FPC_UNICODE_RTL}
+  POpen (f,textrec(f).name,'W');
+{$ELSE}
   POpen (f,StrPas(textrec(f).name),'W');
+{$ENDIF}
 end;
 
 
@@ -131,7 +135,11 @@ begin
   exit;
  textrec(f).userdata[15]:=0; { set Zero length flag }
  repeat
-   i:=fpOpen(StrPas(textrec(f).name),(Open_WrOnly or Open_Creat), 438);
+{$IFDEF FPC_UNICODE_RTL}
+   i:=fpOpen(textrec(f).name,(Open_WrOnly or Open_Creat), 438);
+{$ELSE}
+  i:=fpOpen(StrPas(textrec(f).name),(Open_WrOnly or Open_Creat), 438);
+{$ENDIF}
  until (i<>-1) or (fpgeterrno<>ESysEINTR);
  if i<0 then
   textrec(f).mode:=fmclosed
@@ -154,12 +162,20 @@ begin
 { In case length is zero, don't print : lpr would give an error }
   if (textrec(f).userdata[15]=0) and (textrec(f).userdata[16]=P_TOF) then
    begin
-     fpUnlink(StrPas(textrec(f).name));
+{$IFDEF FPC_UNICODE_RTL}
+     fpUnlink(textrec(f).name);
+{$ELSE}
+    fpUnlink(StrPas(textrec(f).name));
+{$ENDIF}
      exit
    end;
 { Non empty : needs printing ? }
   if (textrec(f).userdata[16]=P_TOF) then
+{$IFDEF FPC_UNICODE_RTL}
+   PrintAndDelete (textrec(f).name);
+{$ELSE}
    PrintAndDelete (strpas(textrec(f).name));
+{$ENDIF}
   textrec(f).mode:=fmclosed
 end;
 

+ 106 - 11
rtl/unix/sysdir.inc

@@ -18,7 +18,6 @@
                            Directory Handling
 *****************************************************************************}
 
-Procedure MkDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_MKDIR'];
 const
   { read/write search permission for everyone }
   MODE_MKDIR = S_IWUSR OR S_IRUSR OR
@@ -26,36 +25,91 @@ const
                S_IWOTH OR S_IROTH OR
                S_IXUSR OR S_IXGRP OR S_IXOTH;
 
+{$IFDEF FPC_UNICODE_RTL}
+Procedure Do_MkDir(s: rawbytestring);[IOCheck];
+
+Begin
+  If (S='') or (InOutRes <> 0) then
+    exit;
+  If Fpmkdir(pchar(s), MODE_MKDIR)<0 Then
+   Errno2Inoutres
+  Else
+   InOutRes:=0;
+End;
+
+Procedure Do_MkDir(s: unicodestring);[IOCheck];
+
+Var
+  R : RawByteString;
+
+begin
+  R:=ToSingleByteFileSystemEncodedFileName(S);
+  Do_MkDir(R);  
+end;
+
+{$ELSE}
+
+Procedure do_MkDir(p: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_MKDIR'];
+Begin
+  If (P=nil) or (p[0]=#0) or (InOutRes <> 0) then
+    exit;
+  If Fpmkdir(p, MODE_MKDIR)<0 Then
+   Errno2Inoutres
+  Else
+   InOutRes:=0;
+End;
+{$ENDIF}
+
 // len is not passed to the *nix functions because the unix API doesn't 
 // use length safeguards for these functions. (probably because there
 // already is a length limit due to PATH_MAX)
 
-Begin
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
+{$IFDEF FPC_UNICODE_RTL}
+Procedure Do_RmDir(s: rawbytestring);[IOCheck];
+
+begin
+  If (S='') or (InOutRes <> 0) then
     exit;
-  If Fpmkdir(s, MODE_MKDIR)<0 Then
+  if (s='.') then
+    InOutRes := 16;
+  If Fprmdir(pchar(S))<0 Then
    Errno2Inoutres
   Else
    InOutRes:=0;
 End;
 
-Procedure RmDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_RMDIR'];
+Procedure Do_RmDir(s: unicodestring);[IOCheck];
+
+Var
+  R : RawByteString;
+
+begin
+  R:=ToSingleByteFileSystemEncodedFileName(S);
+  Do_RMDir(R);  
+end;
+
+{$ELSE}
+Procedure do_RMDir(p: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_RMDIR'];
+
 Begin
-  if (len=1) and (s^ = '.') then
+  if (len=1) and (p^ = '.') then
     InOutRes := 16;
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
+  If not assigned(p) or (len=0) or (InOutRes <> 0) then
     exit;
-  If Fprmdir(s)<0 Then
+  If Fprmdir(p)<0 Then
    Errno2Inoutres
   Else
    InOutRes:=0;
 End;
+{$ENDIF}
+
+{$IFDEF FPC_UNICODE_RTL}
+Procedure do_ChDir(s: rawbytestring);[IOCheck];
 
-Procedure ChDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
 Begin
-  If not assigned(s) or (len=0) or (InOutRes <> 0) then
+  If (s='') or (InOutRes <> 0) then
    exit;
-  If Fpchdir(s)<0 Then
+  If Fpchdir(pchar(s))<0 Then
    Errno2Inoutres
   Else
    InOutRes:=0;
@@ -64,13 +118,43 @@ Begin
    InOutRes:=3;
 End;
 
+Procedure Do_ChDir(s: unicodestring);[IOCheck];
+
+Var
+  R : RawByteString;
+
+begin
+  R:=ToSingleByteFileSystemEncodedFileName(S);
+  Do_ChDir(R);  
+end;
+
+{$ELSE}
+
+Procedure do_ChDir(s: pchar;len:sizeuint);[IOCheck, public, alias : 'FPC_SYS_CHDIR'];
+Begin
+  If not assigned(s) or (len=0) or (InOutRes <> 0) then
+    exit;
+  If Fpchdir(s)<0 Then
+    Errno2Inoutres
+   Else
+    InOutRes:=0;
+end;
+
+{$ENDIF}
+
 // !! for now we use getcwd, unless we are fpc_use_libc.
 // !! the old code  is _still needed_ since the syscall sometimes doesn't work
 // !! on special filesystems like NFS etc.
 // !! In the libc versions, the alt code is already integrated in the libc code.
 // !! Also significantly boosted buffersize. This will make failure of the 
 // !! dos legacy api's better visibile due to cut-off path, instead of "empty"
+
+
+{$IFDEF FPC_UNICODE_RTL}
+procedure do_getdir(drivenr : byte;var dir : rawbytestring);
+{$ELSE}
 procedure getdir(drivenr : byte;var dir : shortstring);
+{$ENDIF}
 var
   buf          : array[0..2047] of char;
   cwdinfo      : stat;
@@ -144,3 +228,14 @@ begin
  {$endif}
 end;
 
+{$IFDEF FPC_UNICODE_RTL}
+procedure do_getdir(drivenr : byte;var dir : unicodestring);
+
+Var
+  S : rawbytestring;
+
+begin
+  do_getdir(drivenr,S);
+  dir:=S;
+end;
+{$ENDIF}

+ 89 - 11
rtl/unix/sysfile.inc

@@ -22,14 +22,44 @@ Begin
   until (res<>-1) or (geterrno<>ESysEINTR);
 End;
 
-Procedure Do_Erase(p:pchar);
+{$IFDEF FPC_UNICODE_RTL}
+Procedure Do_Erase(S : UnicodeString);
+
+var
+  fileinfo : stat;
+  R : RawByteString;
+
+Begin
+  R:=ToSingleByteFileSystemEncodedFileName(S);
+  { verify if the filename is actually a directory }
+  { if so return error and do nothing, as defined  }
+  { by POSIX                                       }
+  if Fpstat(PChar(R),fileinfo)<0 then
+   begin
+     Errno2Inoutres;
+     exit;
+   end;
+  if FpS_ISDIR(fileinfo.st_mode) then
+   begin
+     InOutRes := 2;
+     exit;
+   end;
+  if Fpunlink(pchar(R))<0 then
+   Errno2Inoutres
+  Else
+   InOutRes:=0;
+End;
+{$ELSE}
+Procedure Do_Erase(p : pchar);
+
 var
- fileinfo : stat;
+  fileinfo : stat;
+
 Begin
   { verify if the filename is actually a directory }
   { if so return error and do nothing, as defined  }
   { by POSIX                                       }
-  if Fpstat(p,fileinfo)<0 then
+  if Fpstat(P,fileinfo)<0 then
    begin
      Errno2Inoutres;
      exit;
@@ -44,6 +74,7 @@ Begin
   Else
    InOutRes:=0;
 End;
+{$ENDIF}
 
 { truncate at a given position }
 procedure do_truncate (handle:thandle;fpos:longint);
@@ -56,17 +87,41 @@ begin
    InOutRes:=0;
 end;
 
+{$IFDEF FPC_UNICODE_RTL}
+Procedure Do_Rename(Src : UnicodeString; Dest : RawByteString);
 
+Var
+ S : RawbyteString;
 
-Procedure Do_Rename(p1,p2:pchar);
 Begin
-  If Fprename(p1,p2)<0 Then
-   Errno2Inoutres
+  S:=ToSingleByteFileSystemEncodedFileName(Src);
+  If Fprename(Pchar(S),Pchar(Dest))<0 Then
+    Errno2Inoutres
   Else
-   InOutRes:=0;
+    InOutRes:=0;
 End;
 
 
+Procedure Do_Rename(Src,Dest : UnicodeString);
+
+Var
+ S : RawbyteString;
+
+Begin
+  S:=ToSingleByteFileSystemEncodedFileName(Dest);
+  Do_Rename(Src,S);
+end;
+{$ELSE}
+Procedure Do_Rename(p1,p2:pchar);
+
+Begin
+  If Fprename(P1,P2)<0 Then
+    Errno2Inoutres
+  Else
+    InOutRes:=0;
+End;
+{$ENDIF}
+
 Function Do_Write(Handle:thandle;Addr:Pointer;Len:Longint):longint;
 
 var j : cint;
@@ -145,7 +200,12 @@ Begin
    InOutRes:=0;
 End;
 
-Procedure Do_Open(var f;p:pchar;flags:longint);
+{$IFNDEF FPC_UNICODE_RTL}
+Procedure Do_Open(var f; p:pchar; flags:longint);
+{$ELSE}
+Procedure Do_Open(var f; const s : RawByteString;flags:longint);
+{$ENDIF}
+
 {
   FileRec and textrec have both Handle and mode as the first items so
   they could use the same routine for opening/creating.
@@ -160,7 +220,14 @@ const
               S_IWOTH OR S_IROTH;
 var
   oflags : cint;
+{$IFDEF FPC_UNICODE_RTL}
+  p : pchar;
+{$ENDIF}
 Begin
+{$IFDEF FPC_UNICODE_RTL}
+  p:=pchar(S);
+{$ENDIF}
+  {}
 { close first if opened }
   if ((flags and $10000)=0) then
    begin
@@ -197,7 +264,7 @@ Begin
    if (flags and $100)=$100 then
     oflags:=oflags or (O_APPEND);
 { empty name is special }
-  if p[0]=#0 then
+  if (P=Nil) or (P[0]=#0) then
    begin
      case FileRec(f).mode of
        fminput :
@@ -215,14 +282,14 @@ Begin
    end;
 { real open call }
   repeat
-    FileRec(f).Handle:=Fpopen(p,oflags,MODE_OPEN);
+    FileRec(f).Handle:=Fpopen(P,oflags,MODE_OPEN);
   until (FileRec(f).Handle<>-1) or (geterrno<>ESysEINTR);
   if (FileRec(f).Handle<0) and
     (getErrNo=ESysEROFS) and ((OFlags and O_RDWR)<>0) then
    begin
      Oflags:=Oflags and not(O_RDWR);
      repeat
-       FileRec(f).Handle:=Fpopen(p,oflags,MODE_OPEN);
+       FileRec(f).Handle:=Fpopen(P,oflags,MODE_OPEN);
      until (FileRec(f).Handle<>-1) or (geterrno<>ESysEINTR);
    end;
   If Filerec(f).Handle<0 Then
@@ -231,4 +298,15 @@ Begin
    InOutRes:=0;
 End;
 
+{$IFDEF FPC_UNICODE_RTL}
+
+Procedure Do_Open(var f; const s : UnicodeString;flags:longint);
+
+Var
+  R : RawByteString;
 
+begin
+  R:=ToSingleByteFileSystemEncodedFileName(S);
+  Do_open(F,R,Flags);
+end;
+{$ENDIF}

+ 170 - 76
rtl/unix/sysutils.pp

@@ -265,6 +265,12 @@ procedure UnhookSignal(RtlSigNum: Integer; OnlyIfHooked: Boolean = True);
 {$DEFINE FPC_FEXPAND_TILDE} { Tilde is expanded to home }
 {$DEFINE FPC_FEXPAND_GETENVPCHAR} { GetEnv result is a PChar }
 
+{$DEFINE SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
+
+{$IFNDEF FPC_UNICODE_RTL}
+{$DEFINE SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
+{$ENDIF}
+
 { Include platform independent implementation part }
 {$i sysutils.inc}
 
@@ -432,8 +438,7 @@ begin
 {$endif not beos}
 end;
 
-
-Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
+Function FileOpen (Const FileName : rawbytestring; Mode : Integer) : Longint;
 
 Var
   LinuxFlags : longint;
@@ -452,8 +457,7 @@ begin
   FileOpen:=DoFileLocking(FileOpen, Mode);
 end;
 
-
-Function FileCreate (Const FileName : String) : Longint;
+Function FileCreate (Const FileName : RawByteString) : Longint;
 
 begin
   repeat
@@ -461,8 +465,7 @@ begin
   until (FileCreate<>-1) or (fpgeterrno<>ESysEINTR);
 end;
 
-
-Function FileCreate (Const FileName : String;Rights : Longint) : Longint;
+Function FileCreate (Const FileName : RawByteString;Rights : Longint) : Longint;
 
 begin
   repeat
@@ -470,8 +473,7 @@ begin
   until (FileCreate<>-1) or (fpgeterrno<>ESysEINTR);
 end;
 
-Function FileCreate (Const FileName : String; ShareMode : Longint; Rights:LongInt ) : Longint;
-
+Function FileCreate (Const FileName : RawByteString; ShareMode : Longint; Rights:LongInt ) : Longint;
 begin
   Result:=FileCreate( FileName, Rights );
   Result:=DoFileLocking(Result,ShareMode);
@@ -534,8 +536,7 @@ begin
     end;
 end;
 
-
-Function FileAge (Const FileName : String): Longint;
+Function FileAge (Const FileName : RawByteString): Longint;
 
 Var Info : Stat;
 
@@ -546,17 +547,14 @@ begin
     Result:=info.st_mtime;
 end;
 
-
-Function FileExists (Const FileName : String) : Boolean;
-
+Function FileExists (Const FileName : RawByteString) : Boolean;
 begin
   // Don't use stat. It fails on files >2 GB.
   // Access obeys the same access rules, so the result should be the same.
   FileExists:=fpAccess(pointer(filename),F_OK)=0;
 end;
 
-
-Function DirectoryExists (Const Directory : String) : Boolean;
+Function DirectoryExists (Const Directory : RawByteString) : Boolean;
 
 Var Info : Stat;
 
@@ -564,12 +562,12 @@ begin
   DirectoryExists:=(fpstat(pointer(Directory),Info)>=0) and fpS_ISDIR(Info.st_mode);
 end;
 
-
-Function LinuxToWinAttr (const FN : Ansistring; Const Info : Stat) : Longint;
+Function LinuxToWinAttr (const FN : RawByteString; Const Info : Stat) : Longint;
 
 Var
   LinkInfo : Stat;
-  nm : AnsiString;
+  nm : RawByteString;
+
 begin
   Result:=faArchive;
   If fpS_ISDIR(Info.st_mode) then
@@ -679,78 +677,121 @@ Type
   TUnixFindData = Record
     NamePos    : LongInt;     {to track which search this is}
     DirPtr     : Pointer;     {directory pointer for reading directory}
-    SearchSpec : String;
+    SearchSpec : RawbyteString;
     SearchType : Byte;        {0=normal, 1=open will close, 2=only 1 file}
     SearchAttr : Byte;        {attribute we are searching for}
   End;
   PUnixFindData = ^TUnixFindData;
 
-Procedure FindClose(Var f: TSearchRec);
-var
-  UnixFindData : PUnixFindData;
-Begin
-  UnixFindData:=PUnixFindData(f.FindHandle);
-  If (UnixFindData=Nil) then
+Procedure Do_FindClose(D : PUnixFindData);
+
+begin
+  If (D=Nil) then
     Exit;
-  if UnixFindData^.SearchType=0 then
+  if D^.SearchType=0 then
     begin
-      if UnixFindData^.dirptr<>nil then
-        fpclosedir(pdir(UnixFindData^.dirptr)^);
+      if D^.dirptr<>nil then
+        fpclosedir(pdir(D^.dirptr)^);
     end;
-  Dispose(UnixFindData);
+  Dispose(D);
+  
+end;
+
+Procedure FindClose(Var f: TRawByteSearchRec);
+Begin
+  Do_findClose(PUnixFindData(f.FindHandle));
   f.FindHandle:=nil;
 End;
 
+{$IFDEF FPC_UNICODE_RTL}
+Procedure FindClose(Var f: TUnicodeSearchRec);
+Begin
+  Do_findClose(PUnixFindData(f.FindHandle));
+  f.FindHandle:=nil;
+End;
+{$ENDIF}
 
-Function FindGetFileInfo(const s:string;var f:TSearchRec):boolean;
-var
-  st           : baseunix.stat;
-  WinAttr      : longint;
+Function Do_FindGetFileInfo(const s:RawByteString; D:PUnixFindData; 
+                            out st : baseunix.stat; out WinAttr : longint):boolean;
 
 begin
-  FindGetFileInfo:=false;
-  If Assigned(F.FindHandle) and ((((PUnixFindData(f.FindHandle)^.searchattr)) and faSymlink) > 0) then
-    FindGetFileInfo:=(fplstat(pointer(s),st)=0)
+  If Assigned(D) and ( (D^.searchattr and faSymlink) > 0) then
+    Do_FindGetFileInfo:=(fplstat(pointer(s),st)=0)
   else
-    FindGetFileInfo:=(fpstat(pointer(s),st)=0);
-  If not FindGetFileInfo then
+    Do_FindGetFileInfo:=(fpstat(pointer(s),st)=0);
+  If not Do_FindGetFileInfo then
     exit;
   WinAttr:=LinuxToWinAttr(s,st);
-  If ((WinAttr and Not(PUnixFindData(f.FindHandle)^.searchattr))=0) Then
-   Begin
-     f.Name:=ExtractFileName(s);
-     f.Attr:=WinAttr;
-     f.Size:=st.st_Size;
-     f.Mode:=st.st_mode;
-     f.Time:=st.st_mtime;
-     FindGetFileInfo:=true;
-   End
-  else
-    FindGetFileInfo:=false;
 end;
 
+Type
+  PRawByteSearchRec = ^TRawByteSearchRec;
+
+Function FindGetFileInfoR(const s: RawByteString; P : Pointer):boolean;
 
-Function FindNext (Var Rslt : TSearchRec) : Longint;
-{
-  re-opens dir if not already in array and calls FindGetFileInfo
-}
 Var
-  DirName  : String;
+  st : baseunix.stat;
+  A : longint;
+  F : PRawbyteSearchRec;
+
+begin
+  F:=PRawbyteSearchRec(P);
+  Result:=Do_FindGetFileInfo(S,PUnixFindData(f^.FindHandle),st,A);
+  If Result Then
+    Begin
+    f^.Name:=ExtractFileName(s);
+    f^.Attr:=A;
+    f^.Size:=st.st_Size;
+    f^.Mode:=st.st_mode;
+    f^.Time:=st.st_mtime;
+    End;
+end;
+
+{$IFDEF FPC_UNICODE_RTL}
+
+Type
+  PUnicodeSearchRec = ^TUnicodeSearchRec;
+
+Function FindGetFileInfoU(const s: RawByteString ; P : Pointer):boolean;
+
+Var
+  st : baseunix.stat;
+  A : longint;
+  F : PUnicodeSearchRec;
+
+begin
+  F:=PUnicodeSearchRec(P);
+  Result:=Do_FindGetFileInfo(S,PUnixFindData(f^.FindHandle),st,A);
+  If Result Then
+    Begin
+    f^.Name:=ExtractFileName(s);
+    f^.Attr:=A;
+    f^.Size:=st.st_Size;
+    f^.Mode:=st.st_mode;
+    f^.Time:=st.st_mtime;
+    End;
+end;
+{$ENDIF}
+
+// Returns the FOUND filename. Empty if no result is found.
+// Uses CB to return file info
+
+Type
+  TGetFileInfoCB = Function (const s: RawByteString ; P : Pointer):boolean;
+
+Function Do_FindNext (UnixFindData : PUnixFindData; CB : TGetFileInfoCB; Data : Pointer) : Longint;
+
+Var
+  DirName  : RawByteString;
   FName,
-  SName    : string;
+  SName    : RawBytestring;
   Found,
   Finished : boolean;
   p        : pdirent;
-  UnixFindData : PUnixFindData;
+
 Begin
   Result:=-1;
-  UnixFindData:=PUnixFindData(Rslt.FindHandle);
-  { SearchSpec='' means that there were no wild cards, so only one file to
-    find.
-  }
-  If (UnixFindData=Nil) then 
-    exit;
-  if UnixFindData^.SearchSpec='' then
+  If (UnixFindData=Nil) or (UnixFindData^.SearchSpec='') then 
     exit;
   if (UnixFindData^.SearchType=0) and
      (UnixFindData^.Dirptr=nil) then
@@ -777,7 +818,7 @@ Begin
       Begin
         If FNMatch(SName,FName) Then
          Begin
-           Found:=FindGetFileInfo(Copy(UnixFindData^.SearchSpec,1,UnixFindData^.NamePos)+FName,Rslt);
+           Found:=CB(Copy(UnixFindData^.SearchSpec,1,UnixFindData^.NamePos)+FName,Data);
            if Found then
              begin
                Result:=0;
@@ -788,8 +829,23 @@ Begin
    End;
 End;
 
+Function FindNext (Var Rslt : TRawByteSearchRec) : Longint;
+
+
+begin
+  FindNext:=Do_findNext(PUnixFindData(Rslt.FindHandle),@FindGetFileInfoR,@Rslt);
+end;
+
+{$IFDEF FPC_UNICODE_RTL}
+Function FindNext (Var Rslt : TUnicodeSearchRec) : Longint;
+
+begin
+  FindNext:=Do_findNext(PUnixFindData(Rslt.FindHandle),@FindGetFileInfoU,@Rslt);
+end;
+{$ENDIF}
+
+Function FindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TRawByteSearchRec) : Longint;
 
-Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
 {
   opens dir and calls FindNext if needed.
 }
@@ -809,7 +865,7 @@ Begin
   {Wildcards?}
   if (Pos('?',Path)=0)  and (Pos('*',Path)=0) then
     begin
-    if FindGetFileInfo(Path,Rslt) then
+    if FindGetFileInfoR(Path,@Rslt) then
       Result:=0;
     end
   else
@@ -825,6 +881,48 @@ Begin
     FindClose(Rslt); 
 End;
 
+{$IFDEF FPC_UNICODE_RTL}
+Function FindFirst (Const Path : UnicodeString; Attr : Longint; out Rslt : TUnicodeSearchRec) : Longint;
+
+{
+  opens dir and calls FindNext if needed.
+}
+var
+  UnixFindData : PUnixFindData;
+  P : RawByteString;
+
+Begin
+  Result:=-1;
+  fillchar(Rslt,sizeof(Rslt),0);
+  if Path='' then
+    exit;
+  P:=ToSingleByteFileSystemEncodedFileName(Path);
+  { Allocate UnixFindData (we always need it, for the search attributes) }
+  New(UnixFindData);
+  FillChar(UnixFindData^,sizeof(UnixFindData^),0);
+  Rslt.FindHandle:=UnixFindData;
+   {We always also search for readonly and archive, regardless of Attr:}
+  UnixFindData^.SearchAttr := Attr or faarchive or fareadonly;
+  {Wildcards?}
+  if (Pos('?',P)=0)  and (Pos('*',P)=0) then
+    begin
+    if FindGetFileInfoR(P,@Rslt) then
+      Result:=0;
+    end
+  else
+    begin
+    {Create Info}
+    UnixFindData^.SearchSpec := P;
+    UnixFindData^.NamePos := Length(UnixFindData^.SearchSpec);
+    while (UnixFindData^.NamePos>0) and (UnixFindData^.SearchSpec[UnixFindData^.NamePos]<>'/') do
+      dec(UnixFindData^.NamePos);
+    Result:=FindNext(Rslt);
+    end;
+  If (Result<>0) then
+    FindClose(Rslt); 
+End;
+{$ENDIF}
+
 
 Function FileGetDate (Handle : Longint) : Longint;
 
@@ -845,8 +943,7 @@ begin
   FileSetDate:=-1;
 end;
 
-
-Function FileGetAttr (Const FileName : String) : Longint;
+Function FileGetAttr (Const FileName : RawByteString) : Longint;
 
 Var Info : Stat;
   res : Integer;
@@ -860,34 +957,31 @@ begin
     Result:=LinuxToWinAttr(Pchar(FileName),Info);
 end;
 
-
-Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
-
+Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
 begin
   Result:=-1;
 end;
 
 
-Function DeleteFile (Const FileName : String) : Boolean;
+Function DeleteFile (Const FileName : RawByteString) : Boolean;
 
 begin
   Result:=fpUnLink (pointer(FileName))>=0;
 end;
 
-
-Function RenameFile (Const OldName, NewName : String) : Boolean;
+Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
 
 begin
   RenameFile:=BaseUnix.FpRename(pointer(OldNAme),pointer(NewName))>=0;
 end;
 
-Function FileIsReadOnly(const FileName: String): Boolean;
+Function FileIsReadOnly(const FileName: RawByteString): Boolean;
 
 begin
   Result := fpAccess(PChar(pointer(FileName)),W_OK)<>0;
 end;
 
-Function FileSetDate (Const FileName : String;Age : Longint) : Longint;
+Function FileSetDate (Const FileName : RawByteString;Age : Longint) : Longint;
 
 var
   t: TUTimBuf;

+ 1 - 1
utils/fpcm/revision.inc

@@ -1 +1 @@
-'2013-04-26 rev 24324'
+'2013-05-26 rev 24621'