OSDN Git Service

2008-04-08 Ed Schonberg <schonberg@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / a-tideau.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT RUN-TIME COMPONENTS                         --
4 --                                                                          --
5 --              A D A . T E X T _ I O . D E C I M A L _ A U X               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2008, Free Software Foundation, Inc.         --
10 --                                                                          --
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 2,  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.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
19 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, USA.                                              --
21 --                                                                          --
22 -- As a special exception,  if other files  instantiate  generics from this --
23 -- unit, or you link  this unit with other files  to produce an executable, --
24 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
25 -- covered  by the  GNU  General  Public  License.  This exception does not --
26 -- however invalidate  any other reasons why  the executable file  might be --
27 -- covered by the  GNU Public License.                                      --
28 --                                                                          --
29 -- GNAT was originally developed  by the GNAT team at  New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
31 --                                                                          --
32 ------------------------------------------------------------------------------
33
34 with Ada.Text_IO.Generic_Aux; use Ada.Text_IO.Generic_Aux;
35 with Ada.Text_IO.Float_Aux;   use Ada.Text_IO.Float_Aux;
36
37 with System.Img_Dec; use System.Img_Dec;
38 with System.Img_LLD; use System.Img_LLD;
39 with System.Val_Dec; use System.Val_Dec;
40 with System.Val_LLD; use System.Val_LLD;
41
42 package body Ada.Text_IO.Decimal_Aux is
43
44    -------------
45    -- Get_Dec --
46    -------------
47
48    function Get_Dec
49      (File  : File_Type;
50       Width : Field;
51       Scale : Integer) return Integer
52    is
53       Buf  : String (1 .. Field'Last);
54       Ptr  : aliased Integer;
55       Stop : Integer := 0;
56       Item : Integer;
57
58    begin
59       if Width /= 0 then
60          Load_Width (File, Width, Buf, Stop);
61          String_Skip (Buf, Ptr);
62       else
63          Load_Real (File, Buf, Stop);
64          Ptr := 1;
65       end if;
66
67       Item := Scan_Decimal (Buf, Ptr'Access, Stop, Scale);
68       Check_End_Of_Field (Buf, Stop, Ptr, Width);
69       return Item;
70    end Get_Dec;
71
72    -------------
73    -- Get_LLD --
74    -------------
75
76    function Get_LLD
77      (File  : File_Type;
78       Width : Field;
79       Scale : Integer) return Long_Long_Integer
80    is
81       Buf  : String (1 .. Field'Last);
82       Ptr  : aliased Integer;
83       Stop : Integer := 0;
84       Item : Long_Long_Integer;
85
86    begin
87       if Width /= 0 then
88          Load_Width (File, Width, Buf, Stop);
89          String_Skip (Buf, Ptr);
90       else
91          Load_Real (File, Buf, Stop);
92          Ptr := 1;
93       end if;
94
95       Item := Scan_Long_Long_Decimal (Buf, Ptr'Access, Stop, Scale);
96       Check_End_Of_Field (Buf, Stop, Ptr, Width);
97       return Item;
98    end Get_LLD;
99
100    --------------
101    -- Gets_Dec --
102    --------------
103
104    function Gets_Dec
105      (From  : String;
106       Last  : not null access Positive;
107       Scale : Integer) return Integer
108    is
109       Pos  : aliased Integer;
110       Item : Integer;
111
112    begin
113       String_Skip (From, Pos);
114       Item := Scan_Decimal (From, Pos'Access, From'Last, Scale);
115       Last.all := Pos - 1;
116       return Item;
117
118    exception
119       when Constraint_Error =>
120          Last.all := Pos - 1;
121          raise Data_Error;
122    end Gets_Dec;
123
124    --------------
125    -- Gets_LLD --
126    --------------
127
128    function Gets_LLD
129      (From  : String;
130       Last  : not null access Positive;
131       Scale : Integer) return Long_Long_Integer
132    is
133       Pos  : aliased Integer;
134       Item : Long_Long_Integer;
135
136    begin
137       String_Skip (From, Pos);
138       Item := Scan_Long_Long_Decimal (From, Pos'Access, From'Last, Scale);
139       Last.all := Pos - 1;
140       return Item;
141
142    exception
143       when Constraint_Error =>
144          Last.all := Pos - 1;
145          raise Data_Error;
146    end Gets_LLD;
147
148    -------------
149    -- Put_Dec --
150    -------------
151
152    procedure Put_Dec
153      (File  : File_Type;
154       Item  : Integer;
155       Fore  : Field;
156       Aft   : Field;
157       Exp   : Field;
158       Scale : Integer)
159    is
160       Buf : String (1 .. Field'Last);
161       Ptr : Natural := 0;
162
163    begin
164       Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
165       Put_Item (File, Buf (1 .. Ptr));
166    end Put_Dec;
167
168    -------------
169    -- Put_LLD --
170    -------------
171
172    procedure Put_LLD
173      (File  : File_Type;
174       Item  : Long_Long_Integer;
175       Fore  : Field;
176       Aft   : Field;
177       Exp   : Field;
178       Scale : Integer)
179    is
180       Buf : String (1 .. Field'Last);
181       Ptr : Natural := 0;
182
183    begin
184       Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
185       Put_Item (File, Buf (1 .. Ptr));
186    end Put_LLD;
187
188    --------------
189    -- Puts_Dec --
190    --------------
191
192    procedure Puts_Dec
193      (To    : out String;
194       Item  : Integer;
195       Aft   : Field;
196       Exp   : Field;
197       Scale : Integer)
198    is
199       Buf  : String (1 .. Field'Last);
200       Fore : Integer;
201       Ptr  : Natural := 0;
202
203    begin
204       --  Compute Fore, allowing for Aft digits and the decimal dot
205
206       Fore := To'Length - Field'Max (1, Aft) - 1;
207
208       --  Allow for Exp and two more for E+ or E- if exponent present
209
210       if Exp /= 0 then
211          Fore := Fore - 2 - Exp;
212       end if;
213
214       --  Make sure we have enough room
215
216       if Fore < 1 then
217          raise Layout_Error;
218       end if;
219
220       --  Do the conversion and check length of result
221
222       Set_Image_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
223
224       if Ptr > To'Length then
225          raise Layout_Error;
226       else
227          To := Buf (1 .. Ptr);
228       end if;
229    end Puts_Dec;
230
231    --------------
232    -- Puts_Dec --
233    --------------
234
235    procedure Puts_LLD
236      (To    : out String;
237       Item  : Long_Long_Integer;
238       Aft   : Field;
239       Exp   : Field;
240       Scale : Integer)
241    is
242       Buf  : String (1 .. Field'Last);
243       Fore : Integer;
244       Ptr  : Natural := 0;
245
246    begin
247       if Exp = 0 then
248          Fore := To'Length - 1 - Aft;
249       else
250          Fore := To'Length - 2 - Aft - Exp;
251       end if;
252
253       if Fore < 1 then
254          raise Layout_Error;
255       end if;
256
257       Set_Image_Long_Long_Decimal (Item, Buf, Ptr, Scale, Fore, Aft, Exp);
258
259       if Ptr > To'Length then
260          raise Layout_Error;
261       else
262          To := Buf (1 .. Ptr);
263       end if;
264    end Puts_LLD;
265
266 end Ada.Text_IO.Decimal_Aux;