1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- A D A . W I D E _ W I D E _ T E X T _ I O . F I X E D _ I O --
9 -- Copyright (C) 1992-2023, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
33 with Ada
.Wide_Wide_Text_IO
.Fixed_Aux
;
34 with Ada
.Wide_Wide_Text_IO
.Float_Aux
;
35 with System
.Img_Fixed_32
; use System
.Img_Fixed_32
;
36 with System
.Img_Fixed_64
; use System
.Img_Fixed_64
;
37 with System
.Img_LFlt
; use System
.Img_LFlt
;
38 with System
.Val_Fixed_32
; use System
.Val_Fixed_32
;
39 with System
.Val_Fixed_64
; use System
.Val_Fixed_64
;
40 with System
.Val_LFlt
; use System
.Val_LFlt
;
41 with System
.WCh_Con
; use System
.WCh_Con
;
42 with System
.WCh_WtS
; use System
.WCh_WtS
;
44 package body Ada
.Wide_Wide_Text_IO
.Fixed_IO
is
46 -- Note: we still use the floating-point I/O routines for types whose small
47 -- is not the ratio of two sufficiently small integers. This will result in
48 -- inaccuracies for fixed point types that require more precision than is
49 -- available in Long_Float.
51 subtype Int32
is Interfaces
.Integer_32
; use type Int32
;
52 subtype Int64
is Interfaces
.Integer_64
; use type Int64
;
55 Ada
.Wide_Wide_Text_IO
.Fixed_Aux
(Int32
, Scan_Fixed32
, Set_Image_Fixed32
);
58 Ada
.Wide_Wide_Text_IO
.Fixed_Aux
(Int64
, Scan_Fixed64
, Set_Image_Fixed64
);
60 package Aux_Long_Float
is new
61 Ada
.Wide_Wide_Text_IO
.Float_Aux
62 (Long_Float, Scan_Long_Float
, Set_Image_Long_Float
);
64 -- Throughout this generic body, we distinguish between the case where type
65 -- Int32 is OK and where type Int64 is OK. These boolean constants are used
66 -- to test for this, such that only code for the relevant case is included
67 -- in the instance; that's why the computation of their value must be fully
68 -- static (although it is not a static expressions in the RM sense).
70 OK_Get_32
: constant Boolean :=
71 Num
'Base'Object_Size <= 32
73 ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
75 (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
77 (Num'Small_Numerator <= 2**27
78 and then Num'Small_Denominator <= 2**27));
79 -- These conditions are derived from the prerequisites of System.Value_F
81 OK_Put_32 : constant Boolean :=
82 Num'Base'Object_Size
<= 32
84 ((Num
'Small_Numerator = 1 and then Num
'Small_Denominator <= 2**31)
86 (Num
'Small_Denominator = 1 and then Num
'Small_Numerator <= 2**31)
88 (Num
'Small_Numerator < Num
'Small_Denominator
89 and then Num
'Small_Denominator <= 2**27)
91 (Num
'Small_Denominator < Num
'Small_Numerator
92 and then Num
'Small_Numerator <= 2**25));
93 -- These conditions are derived from the prerequisites of System.Image_F
95 OK_Get_64
: constant Boolean :=
96 Num
'Base'Object_Size <= 64
98 ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
100 (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
102 (Num'Small_Numerator <= 2**59
103 and then Num'Small_Denominator <= 2**59));
104 -- These conditions are derived from the prerequisites of System.Value_F
106 OK_Put_64 : constant Boolean :=
107 Num'Base'Object_Size
<= 64
109 ((Num
'Small_Numerator = 1 and then Num
'Small_Denominator <= 2**63)
111 (Num
'Small_Denominator = 1 and then Num
'Small_Numerator <= 2**63)
113 (Num
'Small_Numerator < Num
'Small_Denominator
114 and then Num
'Small_Denominator <= 2**59)
116 (Num
'Small_Denominator < Num
'Small_Numerator
117 and then Num
'Small_Numerator <= 2**53));
118 -- These conditions are derived from the prerequisites of System.Image_F
120 E
: constant Natural := 63 - 32 * Boolean'Pos (OK_Put_32
);
121 -- T'Size - 1 for the selected Int{32,64}
123 F0
: constant Natural := 0;
124 F1
: constant Natural :=
125 F0
+ 18 * Boolean'Pos (2.0**E
* Num
'Small * 10.0**(-F0
) >= 1.0E+18);
126 F2
: constant Natural :=
127 F1
+ 9 * Boolean'Pos (2.0**E
* Num
'Small * 10.0**(-F1
) >= 1.0E+9);
128 F3
: constant Natural :=
129 F2
+ 5 * Boolean'Pos (2.0**E
* Num
'Small * 10.0**(-F2
) >= 1.0E+5);
130 F4
: constant Natural :=
131 F3
+ 3 * Boolean'Pos (2.0**E
* Num
'Small * 10.0**(-F3
) >= 1.0E+3);
132 F5
: constant Natural :=
133 F4
+ 2 * Boolean'Pos (2.0**E
* Num
'Small * 10.0**(-F4
) >= 1.0E+2);
134 F6
: constant Natural :=
135 F5
+ 1 * Boolean'Pos (2.0**E
* Num
'Small * 10.0**(-F5
) >= 1.0E+1);
136 -- Binary search for the number of digits - 1 before the decimal point of
137 -- the product 2.0**E * Num'Small.
139 For0
: constant Natural := 2 + F6
;
140 -- Fore value for the fixed point type whose mantissa is Int{32,64} and
141 -- whose small is Num'Small.
152 pragma Unsuppress
(Range_Check
);
156 Item
:= Num
'Fixed_Value
157 (Aux32
.Get
(File
, Width
,
158 -Num
'Small_Numerator,
159 -Num
'Small_Denominator));
161 Item
:= Num
'Fixed_Value
162 (Aux64
.Get
(File
, Width
,
163 -Num
'Small_Numerator,
164 -Num
'Small_Denominator));
166 Aux_Long_Float
.Get
(File
, Long_Float (Item
), Width
);
170 when Constraint_Error
=> raise Data_Error
;
178 Get
(Current_In
, Item
, Width
);
182 (From
: Wide_Wide_String
;
186 pragma Unsuppress
(Range_Check
);
188 S
: constant String := Wide_Wide_String_To_String
(From
, WCEM_Upper
);
189 -- String on which we do the actual conversion. Note that the method
190 -- used for wide character encoding is irrelevant, since if there is
191 -- a character outside the Standard.Character range then the call to
192 -- Aux.Gets will raise Data_Error in any case.
196 Item
:= Num
'Fixed_Value
197 (Aux32
.Gets
(S
, Last
,
198 -Num
'Small_Numerator,
199 -Num
'Small_Denominator));
201 Item
:= Num
'Fixed_Value
202 (Aux64
.Gets
(S
, Last
,
203 -Num
'Small_Numerator,
204 -Num
'Small_Denominator));
206 Aux_Long_Float
.Gets
(S
, Long_Float (Item
), Last
);
210 when Constraint_Error
=> raise Data_Error
;
220 Fore
: Field
:= Default_Fore
;
221 Aft
: Field
:= Default_Aft
;
222 Exp
: Field
:= Default_Exp
)
226 Aux32
.Put
(File
, Int32
'Integer_Value (Item
), Fore
, Aft
, Exp
,
227 -Num
'Small_Numerator, -Num
'Small_Denominator,
230 Aux64
.Put
(File
, Int64
'Integer_Value (Item
), Fore
, Aft
, Exp
,
231 -Num
'Small_Numerator, -Num
'Small_Denominator,
234 Aux_Long_Float
.Put
(File
, Long_Float (Item
), Fore
, Aft
, Exp
);
240 Fore
: Field
:= Default_Fore
;
241 Aft
: Field
:= Default_Aft
;
242 Exp
: Field
:= Default_Exp
)
245 Put
(Current_Out
, Item
, Fore
, Aft
, Exp
);
249 (To
: out Wide_Wide_String
;
251 Aft
: Field
:= Default_Aft
;
252 Exp
: Field
:= Default_Exp
)
254 S
: String (To
'First .. To
'Last);
258 Aux32
.Puts
(S
, Int32
'Integer_Value (Item
), Aft
, Exp
,
259 -Num
'Small_Numerator, -Num
'Small_Denominator,
262 Aux64
.Puts
(S
, Int64
'Integer_Value (Item
), Aft
, Exp
,
263 -Num
'Small_Numerator, -Num
'Small_Denominator,
266 Aux_Long_Float
.Puts
(S
, Long_Float (Item
), Aft
, Exp
);
269 for J
in S
'Range loop
270 To
(J
) := Wide_Wide_Character
'Val (Character'Pos (S
(J
)));
274 end Ada
.Wide_Wide_Text_IO
.Fixed_IO
;