Commit 0ee30464 by Pascal Obry Committed by Arnaud Charlet

i-cstrea.ads: (fopen): Add encoding parameter.

2007-04-06  Pascal Obry  <obry@adacore.com>

	* i-cstrea.ads: (fopen): Add encoding parameter.
	(freopen): Idem.
	Change reference from a-sysdep.c to sysdep.c in comment.
	Update copyright notice.
	This set of patch add support for the encoding form parameter.

	* mingw32.h (S2WSU): New macro to convert from a string to a
	wide-string using the UTF-8 encoding. The S2WS macro supports now only
	standard 8bits encoding.
	(WS2SU): As above but converting from wide-sring to string.
	This is needed as it is necessary to have access to both versions in the
	runtime for the form parameter encoding support.
	This set of patch add support for the encoding form parameter.
	(S2WS): Improve implementation to handle cases where the filename is not
	UTF-8 encoded. In this case we default to using the current code page
	for the conversion.

	* s-crtl-vms64.ads, s-crtl.ads (Filename_Encoding): New enumeration
	type (UTF8, ASCII_8bits). This enumeration has a rep clause to match
	the constants defined in adaint.h.
	(fopen): Add encoding parameter.
	(freopen): Idem.

	* s-ficobl.ads (AFCB): Add Encoding field to record the filename
	encoding. This is needed for the Reset routine (freopen low level-call).

	* s-fileio.adb (Open): Decode encoding form parameter and set the
	corresponding encoding value into AFCB structure.
	(Reset): Pass the encoding value to freopen.
	(Close): Move the call to Lock_Task to the beginning of the procedure.

From-SVN: r123578
parent 5bdd76e8
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- S p e c --
-- -- -- --
-- Copyright (C) 1995-2005, Free Software Foundation, Inc. -- -- Copyright (C) 1995-2006, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -105,10 +105,14 @@ package Interfaces.C_Streams is ...@@ -105,10 +105,14 @@ package Interfaces.C_Streams is
function fileno (stream : FILEs) return int; function fileno (stream : FILEs) return int;
function fopen (filename : chars; Mode : chars) return FILEs function fopen
(filename : chars;
mode : chars;
encoding : System.CRTL.Filename_Encoding := System.CRTL.UTF8)
return FILEs
renames System.CRTL.fopen; renames System.CRTL.fopen;
-- Note: to maintain target independence, use text_translation_required, -- Note: to maintain target independence, use text_translation_required,
-- a boolean variable defined in a-sysdep.c to deal with the target -- a boolean variable defined in sysdep.c to deal with the target
-- dependent text translation requirement. If this variable is set, -- dependent text translation requirement. If this variable is set,
-- then b/t should be appended to the standard mode argument to set -- then b/t should be appended to the standard mode argument to set
-- the text translation mode off or on as required. -- the text translation mode off or on as required.
...@@ -140,14 +144,16 @@ package Interfaces.C_Streams is ...@@ -140,14 +144,16 @@ package Interfaces.C_Streams is
function freopen function freopen
(filename : chars; (filename : chars;
mode : chars; mode : chars;
stream : FILEs) stream : FILEs;
return FILEs renames System.CRTL.freopen; encoding : System.CRTL.Filename_Encoding := System.CRTL.UTF8)
return FILEs
renames System.CRTL.freopen;
function fseek function fseek
(stream : FILEs; (stream : FILEs;
offset : long; offset : long;
origin : int) origin : int) return int
return int renames System.CRTL.fseek; renames System.CRTL.fseek;
function ftell (stream : FILEs) return long function ftell (stream : FILEs) return long
renames System.CRTL.ftell; renames System.CRTL.ftell;
...@@ -156,8 +162,7 @@ package Interfaces.C_Streams is ...@@ -156,8 +162,7 @@ package Interfaces.C_Streams is
(buffer : voids; (buffer : voids;
size : size_t; size : size_t;
count : size_t; count : size_t;
stream : FILEs) stream : FILEs) return size_t;
return size_t;
function isatty (handle : int) return int renames System.CRTL.isatty; function isatty (handle : int) return int renames System.CRTL.isatty;
...@@ -170,8 +175,7 @@ package Interfaces.C_Streams is ...@@ -170,8 +175,7 @@ package Interfaces.C_Streams is
(stream : FILEs; (stream : FILEs;
buffer : chars; buffer : chars;
mode : int; mode : int;
size : size_t) size : size_t) return int;
return int;
procedure tmpnam (string : chars) renames System.CRTL.tmpnam; procedure tmpnam (string : chars) renames System.CRTL.tmpnam;
-- The parameter must be a pointer to a string buffer of at least L_tmpnam -- The parameter must be a pointer to a string buffer of at least L_tmpnam
......
...@@ -71,13 +71,19 @@ ...@@ -71,13 +71,19 @@
the proper translations using the UTF-8 encoding. */ the proper translations using the UTF-8 encoding. */
#ifdef GNAT_UNICODE_SUPPORT #ifdef GNAT_UNICODE_SUPPORT
#define S2WSU(wstr,str,len) \
MultiByteToWideChar (CP_UTF8,0,str,-1,wstr,len)
#define WS2SU(str,wstr,len) \
WideCharToMultiByte (CP_UTF8,0,wstr,-1,str,len,NULL,NULL)
#define S2WS(wstr,str,len) \ #define S2WS(wstr,str,len) \
MultiByteToWideChar (CP_UTF8,0,str,-1,wstr,len); MultiByteToWideChar (CP_ACP,0,str,-1,wstr,len)
#define WS2S(str,wstr,len) \ #define WS2S(str,wstr,len) \
WideCharToMultiByte (CP_UTF8,0,wstr,-1,str,len,NULL,NULL); WideCharToMultiByte (CP_ACP,0,wstr,-1,str,len,NULL,NULL)
#else #else
#define S2WS(wstr,str,len) strncpy(wstr,str,len); #define S2WSU(wstr,str,len) strncpy(wstr,str,len)
#define WS2S(str,wstr,len) strncpy(str,wstr,len); #define WS2SU(str,wstr,len) strncpy(str,wstr,len)
#define S2WS(wstr,str,len) strncpy(wstr,str,len)
#define WS2S(str,wstr,len) strncpy(str,wstr,len)
#endif #endif
#include <stdlib.h> #include <stdlib.h>
......
...@@ -57,6 +57,11 @@ package System.CRTL is ...@@ -57,6 +57,11 @@ package System.CRTL is
type size_t is mod 2 ** Standard'Address_Size; type size_t is mod 2 ** Standard'Address_Size;
type Filename_Encoding is (UTF8, ASCII_8bits);
for Filename_Encoding use (UTF8 => 0, ASCII_8bits => 1);
pragma Convention (C, Filename_Encoding);
-- Describes the filename's encoding
function atoi (A : System.Address) return Integer; function atoi (A : System.Address) return Integer;
pragma Import (C, atoi, "decc$atoi"); pragma Import (C, atoi, "decc$atoi");
...@@ -84,8 +89,11 @@ package System.CRTL is ...@@ -84,8 +89,11 @@ package System.CRTL is
function fgets (strng : chars; n : int; stream : FILEs) return chars; function fgets (strng : chars; n : int; stream : FILEs) return chars;
pragma Import (C, fgets, "decc$_fgets64"); pragma Import (C, fgets, "decc$_fgets64");
function fopen (filename : chars; Mode : chars) return FILEs; function fopen
pragma Import (C, fopen, "decc$fopen"); (filename : chars;
mode : chars;
encoding : Filename_Encoding := UTF8) return FILEs;
pragma Import (C, fopen, "__gnat_fopen");
function fputc (C : int; stream : FILEs) return int; function fputc (C : int; stream : FILEs) return int;
pragma Import (C, fputc, "decc$fputc"); pragma Import (C, fputc, "decc$fputc");
...@@ -99,9 +107,10 @@ package System.CRTL is ...@@ -99,9 +107,10 @@ package System.CRTL is
function freopen function freopen
(filename : chars; (filename : chars;
mode : chars; mode : chars;
stream : FILEs) stream : FILEs;
encoding : Filename_Encoding := UTF8)
return FILEs; return FILEs;
pragma Import (C, freopen, "decc$freopen"); pragma Import (C, freopen, "__gnat_freopen");
function fseek function fseek
(stream : FILEs; (stream : FILEs;
...@@ -175,4 +184,5 @@ package System.CRTL is ...@@ -175,4 +184,5 @@ package System.CRTL is
function write (fd : int; buffer : chars; nbytes : int) return int; function write (fd : int; buffer : chars; nbytes : int) return int;
pragma Import (C, write, "decc$write"); pragma Import (C, write, "decc$write");
end System.CRTL; end System.CRTL;
...@@ -57,6 +57,11 @@ package System.CRTL is ...@@ -57,6 +57,11 @@ package System.CRTL is
type size_t is mod 2 ** Standard'Address_Size; type size_t is mod 2 ** Standard'Address_Size;
type Filename_Encoding is (UTF8, ASCII_8bits);
for Filename_Encoding use (UTF8 => 0, ASCII_8bits => 1);
pragma Convention (C, Filename_Encoding);
-- Describes the filename's encoding
function atoi (A : System.Address) return Integer; function atoi (A : System.Address) return Integer;
pragma Import (C, atoi, "atoi"); pragma Import (C, atoi, "atoi");
...@@ -84,7 +89,10 @@ package System.CRTL is ...@@ -84,7 +89,10 @@ package System.CRTL is
function fgets (strng : chars; n : int; stream : FILEs) return chars; function fgets (strng : chars; n : int; stream : FILEs) return chars;
pragma Import (C, fgets, "fgets"); pragma Import (C, fgets, "fgets");
function fopen (filename : chars; Mode : chars) return FILEs; function fopen
(filename : chars;
mode : chars;
encoding : Filename_Encoding := UTF8) return FILEs;
pragma Import (C, fopen, "__gnat_fopen"); pragma Import (C, fopen, "__gnat_fopen");
function fputc (C : int; stream : FILEs) return int; function fputc (C : int; stream : FILEs) return int;
...@@ -99,8 +107,8 @@ package System.CRTL is ...@@ -99,8 +107,8 @@ package System.CRTL is
function freopen function freopen
(filename : chars; (filename : chars;
mode : chars; mode : chars;
stream : FILEs) stream : FILEs;
return FILEs; encoding : Filename_Encoding := UTF8) return FILEs;
pragma Import (C, freopen, "__gnat_freopen"); pragma Import (C, freopen, "__gnat_freopen");
function fseek function fseek
...@@ -175,4 +183,5 @@ package System.CRTL is ...@@ -175,4 +183,5 @@ package System.CRTL is
function write (fd : int; buffer : chars; nbytes : int) return int; function write (fd : int; buffer : chars; nbytes : int) return int;
pragma Import (C, write, "write"); pragma Import (C, write, "write");
end System.CRTL; end System.CRTL;
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- S p e c --
-- -- -- --
-- Copyright (C) 1992-2004 Free Software Foundation, Inc. -- -- Copyright (C) 1992-2006, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
with Ada.Streams; with Ada.Streams;
with Interfaces.C_Streams; with Interfaces.C_Streams;
with System.CRTL;
package System.File_Control_Block is package System.File_Control_Block is
...@@ -90,6 +91,9 @@ package System.File_Control_Block is ...@@ -90,6 +91,9 @@ package System.File_Control_Block is
-- files, and also for standard files (stdin, stdout, stderr). The -- files, and also for standard files (stdin, stdout, stderr). The
-- name is always null-terminated if it is non-null. -- name is always null-terminated if it is non-null.
Encoding : System.CRTL.Filename_Encoding;
-- Encoding used to specified the filename
Form : Pstring; Form : Pstring;
-- A pointer to the form string. This is the string used in the -- A pointer to the form string. This is the string used in the
-- fopen call, and must be supplied by the caller (there are no -- fopen call, and must be supplied by the caller (there are no
...@@ -143,13 +147,13 @@ package System.File_Control_Block is ...@@ -143,13 +147,13 @@ package System.File_Control_Block is
-- that the argument Control_Block is not used other than as the argument -- that the argument Control_Block is not used other than as the argument
-- that controls which version of AFCB_Allocate is called. -- that controls which version of AFCB_Allocate is called.
procedure AFCB_Close (File : access AFCB) is abstract; procedure AFCB_Close (File : not null access AFCB) is abstract;
-- Performs any specialized close actions on a file before the file is -- Performs any specialized close actions on a file before the file is
-- actually closed at the system level. This is called by Close, and -- actually closed at the system level. This is called by Close, and
-- the reason we need the primitive operation is for the automatic -- the reason we need the primitive operation is for the automatic
-- close operations done as part of finalization. -- close operations done as part of finalization.
procedure AFCB_Free (File : access AFCB) is abstract; procedure AFCB_Free (File : not null access AFCB) is abstract;
-- Frees the AFCB referenced by the given parameter. It is not necessary -- Frees the AFCB referenced by the given parameter. It is not necessary
-- to free the strings referenced by the Form and Name fields, but if the -- to free the strings referenced by the Form and Name fields, but if the
-- extension has any other heap objects, they must be freed as well. This -- extension has any other heap objects, they must be freed as well. This
......
...@@ -199,13 +199,13 @@ package body System.File_IO is ...@@ -199,13 +199,13 @@ package body System.File_IO is
Dup_Strm : Boolean := False; Dup_Strm : Boolean := False;
begin begin
Check_File_Open (File);
AFCB_Close (File);
-- Take a task lock, to protect the global data value Open_Files -- Take a task lock, to protect the global data value Open_Files
SSL.Lock_Task.all; SSL.Lock_Task.all;
Check_File_Open (File);
AFCB_Close (File);
-- Sever the association between the given file and its associated -- Sever the association between the given file and its associated
-- external file. The given file is left closed. Do not perform system -- external file. The given file is left closed. Do not perform system
-- closes on the standard input, output and error files and also do -- closes on the standard input, output and error files and also do
...@@ -435,7 +435,7 @@ package body System.File_IO is ...@@ -435,7 +435,7 @@ package body System.File_IO is
Amethod : Character; Amethod : Character;
Fopstr : out Fopen_String) Fopstr : out Fopen_String)
is is
Fptr : Positive; Fptr : Positive;
begin begin
case Mode is case Mode is
...@@ -733,6 +733,9 @@ package body System.File_IO is ...@@ -733,6 +733,9 @@ package body System.File_IO is
Full_Name_Len : Integer; Full_Name_Len : Integer;
-- Length of name actually stored in Fullname -- Length of name actually stored in Fullname
Encoding : System.CRTL.Filename_Encoding;
-- Filename encoding specified into the form parameter
begin begin
if File_Ptr /= null then if File_Ptr /= null then
raise Status_Error; raise Status_Error;
...@@ -773,6 +776,28 @@ package body System.File_IO is ...@@ -773,6 +776,28 @@ package body System.File_IO is
end if; end if;
end; end;
-- Acquire setting of shared parameter
declare
V1, V2 : Natural;
begin
Form_Parameter (Formstr, "encoding", V1, V2);
if V1 = 0 then
Encoding := System.CRTL.UTF8;
elsif Formstr (V1 .. V2) = "utf8" then
Encoding := System.CRTL.UTF8;
elsif Formstr (V1 .. V2) = "8bits" then
Encoding := System.CRTL.ASCII_8bits;
else
raise Use_Error;
end if;
end;
-- If we were given a stream (call from xxx.C_Streams.Open), then set -- If we were given a stream (call from xxx.C_Streams.Open), then set
-- the full name to the given one, and skip to end of processing. -- the full name to the given one, and skip to end of processing.
...@@ -928,7 +953,7 @@ package body System.File_IO is ...@@ -928,7 +953,7 @@ package body System.File_IO is
-- current working directory may have changed and -- current working directory may have changed and
-- we do not want to delete a different file! -- we do not want to delete a different file!
Stream := fopen (Namestr'Address, Fopstr'Address); Stream := fopen (Namestr'Address, Fopstr'Address, Encoding);
if Stream = NULL_Stream then if Stream = NULL_Stream then
if file_exists (Namestr'Address) = 0 then if file_exists (Namestr'Address) = 0 then
...@@ -946,18 +971,17 @@ package body System.File_IO is ...@@ -946,18 +971,17 @@ package body System.File_IO is
File_Ptr := AFCB_Allocate (Dummy_FCB); File_Ptr := AFCB_Allocate (Dummy_FCB);
File_Ptr.Is_Regular_File := (is_regular_file File_Ptr.Is_Regular_File := (is_regular_file (fileno (Stream)) /= 0);
(fileno (Stream)) /= 0);
File_Ptr.Is_System_File := False; File_Ptr.Is_System_File := False;
File_Ptr.Is_Text_File := Text; File_Ptr.Is_Text_File := Text;
File_Ptr.Shared_Status := Shared; File_Ptr.Shared_Status := Shared;
File_Ptr.Access_Method := Amethod; File_Ptr.Access_Method := Amethod;
File_Ptr.Stream := Stream; File_Ptr.Stream := Stream;
File_Ptr.Form := new String'(Formstr); File_Ptr.Form := new String'(Formstr);
File_Ptr.Name := new String'(Fullname File_Ptr.Name := new String'(Fullname (1 .. Full_Name_Len));
(1 .. Full_Name_Len));
File_Ptr.Mode := Mode; File_Ptr.Mode := Mode;
File_Ptr.Is_Temporary_File := Tempfile; File_Ptr.Is_Temporary_File := Tempfile;
File_Ptr.Encoding := Encoding;
Chain_File (File_Ptr); Chain_File (File_Ptr);
Append_Set (File_Ptr); Append_Set (File_Ptr);
...@@ -1050,8 +1074,8 @@ package body System.File_IO is ...@@ -1050,8 +1074,8 @@ package body System.File_IO is
Fopen_Mode Fopen_Mode
(Mode, File.Is_Text_File, False, File.Access_Method, Fopstr); (Mode, File.Is_Text_File, False, File.Access_Method, Fopstr);
File.Stream := File.Stream := freopen
freopen (File.Name.all'Address, Fopstr'Address, File.Stream); (File.Name.all'Address, Fopstr'Address, File.Stream, File.Encoding);
if File.Stream = NULL_Stream then if File.Stream = NULL_Stream then
Close (File); Close (File);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment