annotate gcc/ada/libgnat/g-forstr.adb @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- G N A T . F O R M A T T E D _ S T R I N G --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
9 -- Copyright (C) 2014-2018, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
29 -- --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 with Ada.Characters.Handling;
kono
parents:
diff changeset
33 with Ada.Float_Text_IO;
kono
parents:
diff changeset
34 with Ada.Integer_Text_IO;
kono
parents:
diff changeset
35 with Ada.Long_Float_Text_IO;
kono
parents:
diff changeset
36 with Ada.Long_Integer_Text_IO;
kono
parents:
diff changeset
37 with Ada.Strings.Fixed;
kono
parents:
diff changeset
38 with Ada.Unchecked_Deallocation;
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 with System.Address_Image;
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 package body GNAT.Formatted_String is
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 type F_Kind is (Decimal_Int, -- %d %i
kono
parents:
diff changeset
45 Unsigned_Decimal_Int, -- %u
kono
parents:
diff changeset
46 Unsigned_Octal, -- %o
kono
parents:
diff changeset
47 Unsigned_Hexadecimal_Int, -- %x
kono
parents:
diff changeset
48 Unsigned_Hexadecimal_Int_Up, -- %X
kono
parents:
diff changeset
49 Decimal_Float, -- %f %F
kono
parents:
diff changeset
50 Decimal_Scientific_Float, -- %e
kono
parents:
diff changeset
51 Decimal_Scientific_Float_Up, -- %E
kono
parents:
diff changeset
52 Shortest_Decimal_Float, -- %g
kono
parents:
diff changeset
53 Shortest_Decimal_Float_Up, -- %G
kono
parents:
diff changeset
54 Char, -- %c
kono
parents:
diff changeset
55 Str, -- %s
kono
parents:
diff changeset
56 Pointer -- %p
kono
parents:
diff changeset
57 );
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 type Sign_Kind is (Neg, Zero, Pos);
kono
parents:
diff changeset
60
kono
parents:
diff changeset
61 subtype Is_Number is F_Kind range Decimal_Int .. Decimal_Float;
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 type F_Sign is (If_Neg, Forced, Space) with Default_Value => If_Neg;
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65 type F_Base is (None, C_Style, Ada_Style) with Default_Value => None;
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 Unset : constant Integer := -1;
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 type F_Data is record
kono
parents:
diff changeset
70 Kind : F_Kind;
kono
parents:
diff changeset
71 Width : Natural := 0;
kono
parents:
diff changeset
72 Precision : Integer := Unset;
kono
parents:
diff changeset
73 Left_Justify : Boolean := False;
kono
parents:
diff changeset
74 Sign : F_Sign;
kono
parents:
diff changeset
75 Base : F_Base;
kono
parents:
diff changeset
76 Zero_Pad : Boolean := False;
kono
parents:
diff changeset
77 Value_Needed : Natural range 0 .. 2 := 0;
kono
parents:
diff changeset
78 end record;
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 procedure Next_Format
kono
parents:
diff changeset
81 (Format : Formatted_String;
kono
parents:
diff changeset
82 F_Spec : out F_Data;
kono
parents:
diff changeset
83 Start : out Positive);
kono
parents:
diff changeset
84 -- Parse the next format specifier, a format specifier has the following
kono
parents:
diff changeset
85 -- syntax: %[flags][width][.precision][length]specifier
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 function Get_Formatted
kono
parents:
diff changeset
88 (F_Spec : F_Data;
kono
parents:
diff changeset
89 Value : String;
kono
parents:
diff changeset
90 Len : Positive) return String;
kono
parents:
diff changeset
91 -- Returns Value formatted given the information in F_Spec
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 procedure Raise_Wrong_Format (Format : Formatted_String) with No_Return;
kono
parents:
diff changeset
94 -- Raise the Format_Error exception which information about the context
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 generic
kono
parents:
diff changeset
97 type Flt is private;
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 with procedure Put
kono
parents:
diff changeset
100 (To : out String;
kono
parents:
diff changeset
101 Item : Flt;
kono
parents:
diff changeset
102 Aft : Text_IO.Field;
kono
parents:
diff changeset
103 Exp : Text_IO.Field);
kono
parents:
diff changeset
104 function P_Flt_Format
kono
parents:
diff changeset
105 (Format : Formatted_String;
kono
parents:
diff changeset
106 Var : Flt) return Formatted_String;
kono
parents:
diff changeset
107 -- Generic routine which handles all floating point numbers
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 generic
kono
parents:
diff changeset
110 type Int is private;
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 with function To_Integer (Item : Int) return Integer;
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 with function Sign (Item : Int) return Sign_Kind;
kono
parents:
diff changeset
115
kono
parents:
diff changeset
116 with procedure Put
kono
parents:
diff changeset
117 (To : out String;
kono
parents:
diff changeset
118 Item : Int;
kono
parents:
diff changeset
119 Base : Text_IO.Number_Base);
kono
parents:
diff changeset
120 function P_Int_Format
kono
parents:
diff changeset
121 (Format : Formatted_String;
kono
parents:
diff changeset
122 Var : Int) return Formatted_String;
kono
parents:
diff changeset
123 -- Generic routine which handles all the integer numbers
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 ---------
kono
parents:
diff changeset
126 -- "+" --
kono
parents:
diff changeset
127 ---------
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 function "+" (Format : String) return Formatted_String is
kono
parents:
diff changeset
130 begin
kono
parents:
diff changeset
131 return Formatted_String'
kono
parents:
diff changeset
132 (Finalization.Controlled with
kono
parents:
diff changeset
133 D => new Data'(Format'Length, 1, 1,
kono
parents:
diff changeset
134 Null_Unbounded_String, 0, 0, (0, 0), Format));
kono
parents:
diff changeset
135 end "+";
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 ---------
kono
parents:
diff changeset
138 -- "-" --
kono
parents:
diff changeset
139 ---------
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 function "-" (Format : Formatted_String) return String is
kono
parents:
diff changeset
142 F : String renames Format.D.Format;
kono
parents:
diff changeset
143 J : Natural renames Format.D.Index;
kono
parents:
diff changeset
144 R : Unbounded_String := Format.D.Result;
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 begin
kono
parents:
diff changeset
147 -- Make sure we get the remaining character up to the next unhandled
kono
parents:
diff changeset
148 -- format specifier.
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 while (J <= F'Length and then F (J) /= '%')
kono
parents:
diff changeset
151 or else (J < F'Length - 1 and then F (J + 1) = '%')
kono
parents:
diff changeset
152 loop
kono
parents:
diff changeset
153 Append (R, F (J));
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155 -- If we have two consecutive %, skip the second one
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 if F (J) = '%' and then J < F'Length - 1 and then F (J + 1) = '%' then
kono
parents:
diff changeset
158 J := J + 1;
kono
parents:
diff changeset
159 end if;
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 J := J + 1;
kono
parents:
diff changeset
162 end loop;
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 return To_String (R);
kono
parents:
diff changeset
165 end "-";
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 ---------
kono
parents:
diff changeset
168 -- "&" --
kono
parents:
diff changeset
169 ---------
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 function "&"
kono
parents:
diff changeset
172 (Format : Formatted_String;
kono
parents:
diff changeset
173 Var : Character) return Formatted_String
kono
parents:
diff changeset
174 is
kono
parents:
diff changeset
175 F : F_Data;
kono
parents:
diff changeset
176 Start : Positive;
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 begin
kono
parents:
diff changeset
179 Next_Format (Format, F, Start);
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 if F.Value_Needed > 0 then
kono
parents:
diff changeset
182 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
183 end if;
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 case F.Kind is
kono
parents:
diff changeset
186 when Char =>
kono
parents:
diff changeset
187 Append (Format.D.Result, Get_Formatted (F, String'(1 => Var), 1));
kono
parents:
diff changeset
188 when others =>
kono
parents:
diff changeset
189 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
190 end case;
kono
parents:
diff changeset
191
kono
parents:
diff changeset
192 return Format;
kono
parents:
diff changeset
193 end "&";
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 function "&"
kono
parents:
diff changeset
196 (Format : Formatted_String;
kono
parents:
diff changeset
197 Var : String) return Formatted_String
kono
parents:
diff changeset
198 is
kono
parents:
diff changeset
199 F : F_Data;
kono
parents:
diff changeset
200 Start : Positive;
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 begin
kono
parents:
diff changeset
203 Next_Format (Format, F, Start);
kono
parents:
diff changeset
204
kono
parents:
diff changeset
205 if F.Value_Needed > 0 then
kono
parents:
diff changeset
206 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
207 end if;
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 case F.Kind is
kono
parents:
diff changeset
210 when Str =>
kono
parents:
diff changeset
211 declare
kono
parents:
diff changeset
212 S : constant String := Get_Formatted (F, Var, Var'Length);
kono
parents:
diff changeset
213 begin
kono
parents:
diff changeset
214 if F.Precision = Unset then
kono
parents:
diff changeset
215 Append (Format.D.Result, S);
kono
parents:
diff changeset
216 else
kono
parents:
diff changeset
217 Append
kono
parents:
diff changeset
218 (Format.D.Result,
kono
parents:
diff changeset
219 S (S'First .. S'First + F.Precision - 1));
kono
parents:
diff changeset
220 end if;
kono
parents:
diff changeset
221 end;
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 when others =>
kono
parents:
diff changeset
224 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
225 end case;
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 return Format;
kono
parents:
diff changeset
228 end "&";
kono
parents:
diff changeset
229
kono
parents:
diff changeset
230 function "&"
kono
parents:
diff changeset
231 (Format : Formatted_String;
kono
parents:
diff changeset
232 Var : Boolean) return Formatted_String is
kono
parents:
diff changeset
233 begin
kono
parents:
diff changeset
234 return Format & Boolean'Image (Var);
kono
parents:
diff changeset
235 end "&";
kono
parents:
diff changeset
236
kono
parents:
diff changeset
237 function "&"
kono
parents:
diff changeset
238 (Format : Formatted_String;
kono
parents:
diff changeset
239 Var : Float) return Formatted_String
kono
parents:
diff changeset
240 is
kono
parents:
diff changeset
241 function Float_Format is new Flt_Format (Float, Float_Text_IO.Put);
kono
parents:
diff changeset
242 begin
kono
parents:
diff changeset
243 return Float_Format (Format, Var);
kono
parents:
diff changeset
244 end "&";
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 function "&"
kono
parents:
diff changeset
247 (Format : Formatted_String;
kono
parents:
diff changeset
248 Var : Long_Float) return Formatted_String
kono
parents:
diff changeset
249 is
kono
parents:
diff changeset
250 function Float_Format is
kono
parents:
diff changeset
251 new Flt_Format (Long_Float, Long_Float_Text_IO.Put);
kono
parents:
diff changeset
252 begin
kono
parents:
diff changeset
253 return Float_Format (Format, Var);
kono
parents:
diff changeset
254 end "&";
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 function "&"
kono
parents:
diff changeset
257 (Format : Formatted_String;
kono
parents:
diff changeset
258 Var : Duration) return Formatted_String
kono
parents:
diff changeset
259 is
kono
parents:
diff changeset
260 package Duration_Text_IO is new Text_IO.Fixed_IO (Duration);
kono
parents:
diff changeset
261 function Duration_Format is
kono
parents:
diff changeset
262 new P_Flt_Format (Duration, Duration_Text_IO.Put);
kono
parents:
diff changeset
263 begin
kono
parents:
diff changeset
264 return Duration_Format (Format, Var);
kono
parents:
diff changeset
265 end "&";
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 function "&"
kono
parents:
diff changeset
268 (Format : Formatted_String;
kono
parents:
diff changeset
269 Var : Integer) return Formatted_String
kono
parents:
diff changeset
270 is
kono
parents:
diff changeset
271 function Integer_Format is
kono
parents:
diff changeset
272 new Int_Format (Integer, Integer_Text_IO.Put);
kono
parents:
diff changeset
273 begin
kono
parents:
diff changeset
274 return Integer_Format (Format, Var);
kono
parents:
diff changeset
275 end "&";
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 function "&"
kono
parents:
diff changeset
278 (Format : Formatted_String;
kono
parents:
diff changeset
279 Var : Long_Integer) return Formatted_String
kono
parents:
diff changeset
280 is
kono
parents:
diff changeset
281 function Integer_Format is
kono
parents:
diff changeset
282 new Int_Format (Long_Integer, Long_Integer_Text_IO.Put);
kono
parents:
diff changeset
283 begin
kono
parents:
diff changeset
284 return Integer_Format (Format, Var);
kono
parents:
diff changeset
285 end "&";
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287 function "&"
kono
parents:
diff changeset
288 (Format : Formatted_String;
kono
parents:
diff changeset
289 Var : System.Address) return Formatted_String
kono
parents:
diff changeset
290 is
kono
parents:
diff changeset
291 A_Img : constant String := System.Address_Image (Var);
kono
parents:
diff changeset
292 F : F_Data;
kono
parents:
diff changeset
293 Start : Positive;
kono
parents:
diff changeset
294
kono
parents:
diff changeset
295 begin
kono
parents:
diff changeset
296 Next_Format (Format, F, Start);
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 if F.Value_Needed > 0 then
kono
parents:
diff changeset
299 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
300 end if;
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 case F.Kind is
kono
parents:
diff changeset
303 when Pointer =>
kono
parents:
diff changeset
304 Append (Format.D.Result, Get_Formatted (F, A_Img, A_Img'Length));
kono
parents:
diff changeset
305 when others =>
kono
parents:
diff changeset
306 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
307 end case;
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 return Format;
kono
parents:
diff changeset
310 end "&";
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 ------------
kono
parents:
diff changeset
313 -- Adjust --
kono
parents:
diff changeset
314 ------------
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 overriding procedure Adjust (F : in out Formatted_String) is
kono
parents:
diff changeset
317 begin
kono
parents:
diff changeset
318 F.D.Ref_Count := F.D.Ref_Count + 1;
kono
parents:
diff changeset
319 end Adjust;
kono
parents:
diff changeset
320
kono
parents:
diff changeset
321 --------------------
kono
parents:
diff changeset
322 -- Decimal_Format --
kono
parents:
diff changeset
323 --------------------
kono
parents:
diff changeset
324
kono
parents:
diff changeset
325 function Decimal_Format
kono
parents:
diff changeset
326 (Format : Formatted_String;
kono
parents:
diff changeset
327 Var : Flt) return Formatted_String
kono
parents:
diff changeset
328 is
kono
parents:
diff changeset
329 function Flt_Format is new P_Flt_Format (Flt, Put);
kono
parents:
diff changeset
330 begin
kono
parents:
diff changeset
331 return Flt_Format (Format, Var);
kono
parents:
diff changeset
332 end Decimal_Format;
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 -----------------
kono
parents:
diff changeset
335 -- Enum_Format --
kono
parents:
diff changeset
336 -----------------
kono
parents:
diff changeset
337
kono
parents:
diff changeset
338 function Enum_Format
kono
parents:
diff changeset
339 (Format : Formatted_String;
kono
parents:
diff changeset
340 Var : Enum) return Formatted_String is
kono
parents:
diff changeset
341 begin
kono
parents:
diff changeset
342 return Format & Enum'Image (Var);
kono
parents:
diff changeset
343 end Enum_Format;
kono
parents:
diff changeset
344
kono
parents:
diff changeset
345 --------------
kono
parents:
diff changeset
346 -- Finalize --
kono
parents:
diff changeset
347 --------------
kono
parents:
diff changeset
348
kono
parents:
diff changeset
349 overriding procedure Finalize (F : in out Formatted_String) is
kono
parents:
diff changeset
350 procedure Unchecked_Free is
kono
parents:
diff changeset
351 new Unchecked_Deallocation (Data, Data_Access);
kono
parents:
diff changeset
352
kono
parents:
diff changeset
353 D : Data_Access := F.D;
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355 begin
kono
parents:
diff changeset
356 F.D := null;
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 D.Ref_Count := D.Ref_Count - 1;
kono
parents:
diff changeset
359
kono
parents:
diff changeset
360 if D.Ref_Count = 0 then
kono
parents:
diff changeset
361 Unchecked_Free (D);
kono
parents:
diff changeset
362 end if;
kono
parents:
diff changeset
363 end Finalize;
kono
parents:
diff changeset
364
kono
parents:
diff changeset
365 ------------------
kono
parents:
diff changeset
366 -- Fixed_Format --
kono
parents:
diff changeset
367 ------------------
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 function Fixed_Format
kono
parents:
diff changeset
370 (Format : Formatted_String;
kono
parents:
diff changeset
371 Var : Flt) return Formatted_String
kono
parents:
diff changeset
372 is
kono
parents:
diff changeset
373 function Flt_Format is new P_Flt_Format (Flt, Put);
kono
parents:
diff changeset
374 begin
kono
parents:
diff changeset
375 return Flt_Format (Format, Var);
kono
parents:
diff changeset
376 end Fixed_Format;
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 ----------------
kono
parents:
diff changeset
379 -- Flt_Format --
kono
parents:
diff changeset
380 ----------------
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 function Flt_Format
kono
parents:
diff changeset
383 (Format : Formatted_String;
kono
parents:
diff changeset
384 Var : Flt) return Formatted_String
kono
parents:
diff changeset
385 is
kono
parents:
diff changeset
386 function Flt_Format is new P_Flt_Format (Flt, Put);
kono
parents:
diff changeset
387 begin
kono
parents:
diff changeset
388 return Flt_Format (Format, Var);
kono
parents:
diff changeset
389 end Flt_Format;
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 -------------------
kono
parents:
diff changeset
392 -- Get_Formatted --
kono
parents:
diff changeset
393 -------------------
kono
parents:
diff changeset
394
kono
parents:
diff changeset
395 function Get_Formatted
kono
parents:
diff changeset
396 (F_Spec : F_Data;
kono
parents:
diff changeset
397 Value : String;
kono
parents:
diff changeset
398 Len : Positive) return String
kono
parents:
diff changeset
399 is
kono
parents:
diff changeset
400 use Ada.Strings.Fixed;
kono
parents:
diff changeset
401
kono
parents:
diff changeset
402 Res : Unbounded_String;
kono
parents:
diff changeset
403 S : Positive := Value'First;
kono
parents:
diff changeset
404
kono
parents:
diff changeset
405 begin
kono
parents:
diff changeset
406 -- Handle the flags
kono
parents:
diff changeset
407
kono
parents:
diff changeset
408 if F_Spec.Kind in Is_Number then
kono
parents:
diff changeset
409 if F_Spec.Sign = Forced and then Value (Value'First) /= '-' then
kono
parents:
diff changeset
410 Append (Res, "+");
kono
parents:
diff changeset
411 elsif F_Spec.Sign = Space and then Value (Value'First) /= '-' then
kono
parents:
diff changeset
412 Append (Res, " ");
kono
parents:
diff changeset
413 end if;
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 if Value (Value'First) = '-' then
kono
parents:
diff changeset
416 Append (Res, "-");
kono
parents:
diff changeset
417 S := S + 1;
kono
parents:
diff changeset
418 end if;
kono
parents:
diff changeset
419 end if;
kono
parents:
diff changeset
420
kono
parents:
diff changeset
421 -- Zero padding if required and possible
kono
parents:
diff changeset
422
kono
parents:
diff changeset
423 if F_Spec.Left_Justify = False
kono
parents:
diff changeset
424 and then F_Spec.Zero_Pad
kono
parents:
diff changeset
425 and then F_Spec.Width > Len + Value'First - S
kono
parents:
diff changeset
426 then
kono
parents:
diff changeset
427 Append (Res, String'((F_Spec.Width - Len + Value'First - S) * '0'));
kono
parents:
diff changeset
428 end if;
kono
parents:
diff changeset
429
kono
parents:
diff changeset
430 -- Add the value now
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 Append (Res, Value (S .. Value'Last));
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 declare
kono
parents:
diff changeset
435 R : String (1 .. Natural'Max (Natural'Max (F_Spec.Width, Len),
kono
parents:
diff changeset
436 Length (Res))) := (others => ' ');
kono
parents:
diff changeset
437 begin
kono
parents:
diff changeset
438 if F_Spec.Left_Justify then
kono
parents:
diff changeset
439 R (1 .. Length (Res)) := To_String (Res);
kono
parents:
diff changeset
440 else
kono
parents:
diff changeset
441 R (R'Last - Length (Res) + 1 .. R'Last) := To_String (Res);
kono
parents:
diff changeset
442 end if;
kono
parents:
diff changeset
443
kono
parents:
diff changeset
444 return R;
kono
parents:
diff changeset
445 end;
kono
parents:
diff changeset
446 end Get_Formatted;
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 ----------------
kono
parents:
diff changeset
449 -- Int_Format --
kono
parents:
diff changeset
450 ----------------
kono
parents:
diff changeset
451
kono
parents:
diff changeset
452 function Int_Format
kono
parents:
diff changeset
453 (Format : Formatted_String;
kono
parents:
diff changeset
454 Var : Int) return Formatted_String
kono
parents:
diff changeset
455 is
kono
parents:
diff changeset
456 function Sign (Var : Int) return Sign_Kind is
kono
parents:
diff changeset
457 (if Var < 0 then Neg elsif Var = 0 then Zero else Pos);
kono
parents:
diff changeset
458
kono
parents:
diff changeset
459 function To_Integer (Var : Int) return Integer is
kono
parents:
diff changeset
460 (Integer (Var));
kono
parents:
diff changeset
461
kono
parents:
diff changeset
462 function Int_Format is new P_Int_Format (Int, To_Integer, Sign, Put);
kono
parents:
diff changeset
463
kono
parents:
diff changeset
464 begin
kono
parents:
diff changeset
465 return Int_Format (Format, Var);
kono
parents:
diff changeset
466 end Int_Format;
kono
parents:
diff changeset
467
kono
parents:
diff changeset
468 ----------------
kono
parents:
diff changeset
469 -- Mod_Format --
kono
parents:
diff changeset
470 ----------------
kono
parents:
diff changeset
471
kono
parents:
diff changeset
472 function Mod_Format
kono
parents:
diff changeset
473 (Format : Formatted_String;
kono
parents:
diff changeset
474 Var : Int) return Formatted_String
kono
parents:
diff changeset
475 is
kono
parents:
diff changeset
476 function Sign (Var : Int) return Sign_Kind is
kono
parents:
diff changeset
477 (if Var < 0 then Neg elsif Var = 0 then Zero else Pos);
kono
parents:
diff changeset
478
kono
parents:
diff changeset
479 function To_Integer (Var : Int) return Integer is
kono
parents:
diff changeset
480 (Integer (Var));
kono
parents:
diff changeset
481
kono
parents:
diff changeset
482 function Int_Format is new P_Int_Format (Int, To_Integer, Sign, Put);
kono
parents:
diff changeset
483
kono
parents:
diff changeset
484 begin
kono
parents:
diff changeset
485 return Int_Format (Format, Var);
kono
parents:
diff changeset
486 end Mod_Format;
kono
parents:
diff changeset
487
kono
parents:
diff changeset
488 -----------------
kono
parents:
diff changeset
489 -- Next_Format --
kono
parents:
diff changeset
490 -----------------
kono
parents:
diff changeset
491
kono
parents:
diff changeset
492 procedure Next_Format
kono
parents:
diff changeset
493 (Format : Formatted_String;
kono
parents:
diff changeset
494 F_Spec : out F_Data;
kono
parents:
diff changeset
495 Start : out Positive)
kono
parents:
diff changeset
496 is
kono
parents:
diff changeset
497 F : String renames Format.D.Format;
kono
parents:
diff changeset
498 J : Natural renames Format.D.Index;
kono
parents:
diff changeset
499 S : Natural;
kono
parents:
diff changeset
500 Width_From_Var : Boolean := False;
kono
parents:
diff changeset
501
kono
parents:
diff changeset
502 begin
kono
parents:
diff changeset
503 Format.D.Current := Format.D.Current + 1;
kono
parents:
diff changeset
504 F_Spec.Value_Needed := 0;
kono
parents:
diff changeset
505
kono
parents:
diff changeset
506 -- Got to next %
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 while (J <= F'Last and then F (J) /= '%')
kono
parents:
diff changeset
509 or else (J < F'Last - 1 and then F (J + 1) = '%')
kono
parents:
diff changeset
510 loop
kono
parents:
diff changeset
511 Append (Format.D.Result, F (J));
kono
parents:
diff changeset
512
kono
parents:
diff changeset
513 -- If we have two consecutive %, skip the second one
kono
parents:
diff changeset
514
kono
parents:
diff changeset
515 if F (J) = '%' and then J < F'Last - 1 and then F (J + 1) = '%' then
kono
parents:
diff changeset
516 J := J + 1;
kono
parents:
diff changeset
517 end if;
kono
parents:
diff changeset
518
kono
parents:
diff changeset
519 J := J + 1;
kono
parents:
diff changeset
520 end loop;
kono
parents:
diff changeset
521
kono
parents:
diff changeset
522 if F (J) /= '%' or else J = F'Last then
kono
parents:
diff changeset
523 raise Format_Error with "no format specifier found for parameter"
kono
parents:
diff changeset
524 & Positive'Image (Format.D.Current);
kono
parents:
diff changeset
525 end if;
kono
parents:
diff changeset
526
kono
parents:
diff changeset
527 Start := J;
kono
parents:
diff changeset
528
kono
parents:
diff changeset
529 J := J + 1;
kono
parents:
diff changeset
530
kono
parents:
diff changeset
531 -- Check for any flags
kono
parents:
diff changeset
532
kono
parents:
diff changeset
533 Flags_Check : while J < F'Last loop
kono
parents:
diff changeset
534 if F (J) = '-' then
kono
parents:
diff changeset
535 F_Spec.Left_Justify := True;
kono
parents:
diff changeset
536 elsif F (J) = '+' then
kono
parents:
diff changeset
537 F_Spec.Sign := Forced;
kono
parents:
diff changeset
538 elsif F (J) = ' ' then
kono
parents:
diff changeset
539 F_Spec.Sign := Space;
kono
parents:
diff changeset
540 elsif F (J) = '#' then
kono
parents:
diff changeset
541 F_Spec.Base := C_Style;
kono
parents:
diff changeset
542 elsif F (J) = '~' then
kono
parents:
diff changeset
543 F_Spec.Base := Ada_Style;
kono
parents:
diff changeset
544 elsif F (J) = '0' then
kono
parents:
diff changeset
545 F_Spec.Zero_Pad := True;
kono
parents:
diff changeset
546 else
kono
parents:
diff changeset
547 exit Flags_Check;
kono
parents:
diff changeset
548 end if;
kono
parents:
diff changeset
549
kono
parents:
diff changeset
550 J := J + 1;
kono
parents:
diff changeset
551 end loop Flags_Check;
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553 -- Check width if any
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 if F (J) in '0' .. '9' then
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 -- We have a width parameter
kono
parents:
diff changeset
558
kono
parents:
diff changeset
559 S := J;
kono
parents:
diff changeset
560
kono
parents:
diff changeset
561 while J < F'Last and then F (J + 1) in '0' .. '9' loop
kono
parents:
diff changeset
562 J := J + 1;
kono
parents:
diff changeset
563 end loop;
kono
parents:
diff changeset
564
kono
parents:
diff changeset
565 F_Spec.Width := Natural'Value (F (S .. J));
kono
parents:
diff changeset
566
kono
parents:
diff changeset
567 J := J + 1;
kono
parents:
diff changeset
568
kono
parents:
diff changeset
569 elsif F (J) = '*' then
kono
parents:
diff changeset
570
kono
parents:
diff changeset
571 -- The width will be taken from the integer parameter
kono
parents:
diff changeset
572
kono
parents:
diff changeset
573 F_Spec.Value_Needed := 1;
kono
parents:
diff changeset
574 Width_From_Var := True;
kono
parents:
diff changeset
575
kono
parents:
diff changeset
576 J := J + 1;
kono
parents:
diff changeset
577 end if;
kono
parents:
diff changeset
578
kono
parents:
diff changeset
579 if F (J) = '.' then
kono
parents:
diff changeset
580
kono
parents:
diff changeset
581 -- We have a precision parameter
kono
parents:
diff changeset
582
kono
parents:
diff changeset
583 J := J + 1;
kono
parents:
diff changeset
584
kono
parents:
diff changeset
585 if F (J) in '0' .. '9' then
kono
parents:
diff changeset
586 S := J;
kono
parents:
diff changeset
587
kono
parents:
diff changeset
588 while J < F'Length and then F (J + 1) in '0' .. '9' loop
kono
parents:
diff changeset
589 J := J + 1;
kono
parents:
diff changeset
590 end loop;
kono
parents:
diff changeset
591
kono
parents:
diff changeset
592 if F (J) = '.' then
kono
parents:
diff changeset
593
kono
parents:
diff changeset
594 -- No precision, 0 is assumed
kono
parents:
diff changeset
595
kono
parents:
diff changeset
596 F_Spec.Precision := 0;
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598 else
kono
parents:
diff changeset
599 F_Spec.Precision := Natural'Value (F (S .. J));
kono
parents:
diff changeset
600 end if;
kono
parents:
diff changeset
601
kono
parents:
diff changeset
602 J := J + 1;
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 elsif F (J) = '*' then
kono
parents:
diff changeset
605
kono
parents:
diff changeset
606 -- The prevision will be taken from the integer parameter
kono
parents:
diff changeset
607
kono
parents:
diff changeset
608 F_Spec.Value_Needed := F_Spec.Value_Needed + 1;
kono
parents:
diff changeset
609 J := J + 1;
kono
parents:
diff changeset
610 end if;
kono
parents:
diff changeset
611 end if;
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 -- Skip the length specifier, this is not needed for this implementation
kono
parents:
diff changeset
614 -- but yet for compatibility reason it is handled.
kono
parents:
diff changeset
615
kono
parents:
diff changeset
616 Length_Check :
kono
parents:
diff changeset
617 while J <= F'Last
kono
parents:
diff changeset
618 and then F (J) in 'h' | 'l' | 'j' | 'z' | 't' | 'L'
kono
parents:
diff changeset
619 loop
kono
parents:
diff changeset
620 J := J + 1;
kono
parents:
diff changeset
621 end loop Length_Check;
kono
parents:
diff changeset
622
kono
parents:
diff changeset
623 if J > F'Last then
kono
parents:
diff changeset
624 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
625 end if;
kono
parents:
diff changeset
626
kono
parents:
diff changeset
627 -- Read next character which should be the expected type
kono
parents:
diff changeset
628
kono
parents:
diff changeset
629 case F (J) is
kono
parents:
diff changeset
630 when 'c' => F_Spec.Kind := Char;
kono
parents:
diff changeset
631 when 's' => F_Spec.Kind := Str;
kono
parents:
diff changeset
632 when 'd' | 'i' => F_Spec.Kind := Decimal_Int;
kono
parents:
diff changeset
633 when 'u' => F_Spec.Kind := Unsigned_Decimal_Int;
kono
parents:
diff changeset
634 when 'f' | 'F' => F_Spec.Kind := Decimal_Float;
kono
parents:
diff changeset
635 when 'e' => F_Spec.Kind := Decimal_Scientific_Float;
kono
parents:
diff changeset
636 when 'E' => F_Spec.Kind := Decimal_Scientific_Float_Up;
kono
parents:
diff changeset
637 when 'g' => F_Spec.Kind := Shortest_Decimal_Float;
kono
parents:
diff changeset
638 when 'G' => F_Spec.Kind := Shortest_Decimal_Float_Up;
kono
parents:
diff changeset
639 when 'o' => F_Spec.Kind := Unsigned_Octal;
kono
parents:
diff changeset
640 when 'x' => F_Spec.Kind := Unsigned_Hexadecimal_Int;
kono
parents:
diff changeset
641 when 'X' => F_Spec.Kind := Unsigned_Hexadecimal_Int_Up;
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 when others =>
kono
parents:
diff changeset
644 raise Format_Error with "unknown format specified for parameter"
kono
parents:
diff changeset
645 & Positive'Image (Format.D.Current);
kono
parents:
diff changeset
646 end case;
kono
parents:
diff changeset
647
kono
parents:
diff changeset
648 J := J + 1;
kono
parents:
diff changeset
649
kono
parents:
diff changeset
650 if F_Spec.Value_Needed > 0
kono
parents:
diff changeset
651 and then F_Spec.Value_Needed = Format.D.Stored_Value
kono
parents:
diff changeset
652 then
kono
parents:
diff changeset
653 if F_Spec.Value_Needed = 1 then
kono
parents:
diff changeset
654 if Width_From_Var then
kono
parents:
diff changeset
655 F_Spec.Width := Format.D.Stack (1);
kono
parents:
diff changeset
656 else
kono
parents:
diff changeset
657 F_Spec.Precision := Format.D.Stack (1);
kono
parents:
diff changeset
658 end if;
kono
parents:
diff changeset
659
kono
parents:
diff changeset
660 else
kono
parents:
diff changeset
661 F_Spec.Width := Format.D.Stack (1);
kono
parents:
diff changeset
662 F_Spec.Precision := Format.D.Stack (2);
kono
parents:
diff changeset
663 end if;
kono
parents:
diff changeset
664 end if;
kono
parents:
diff changeset
665 end Next_Format;
kono
parents:
diff changeset
666
kono
parents:
diff changeset
667 ------------------
kono
parents:
diff changeset
668 -- P_Flt_Format --
kono
parents:
diff changeset
669 ------------------
kono
parents:
diff changeset
670
kono
parents:
diff changeset
671 function P_Flt_Format
kono
parents:
diff changeset
672 (Format : Formatted_String;
kono
parents:
diff changeset
673 Var : Flt) return Formatted_String
kono
parents:
diff changeset
674 is
kono
parents:
diff changeset
675 F : F_Data;
kono
parents:
diff changeset
676 Buffer : String (1 .. 50);
kono
parents:
diff changeset
677 S, E : Positive := 1;
kono
parents:
diff changeset
678 Start : Positive;
kono
parents:
diff changeset
679 Aft : Text_IO.Field;
kono
parents:
diff changeset
680
kono
parents:
diff changeset
681 begin
kono
parents:
diff changeset
682 Next_Format (Format, F, Start);
kono
parents:
diff changeset
683
kono
parents:
diff changeset
684 if F.Value_Needed > 0 then
kono
parents:
diff changeset
685 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
686 end if;
kono
parents:
diff changeset
687
kono
parents:
diff changeset
688 if F.Precision = Unset then
kono
parents:
diff changeset
689 Aft := 6;
kono
parents:
diff changeset
690 else
kono
parents:
diff changeset
691 Aft := F.Precision;
kono
parents:
diff changeset
692 end if;
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 case F.Kind is
kono
parents:
diff changeset
695 when Decimal_Float =>
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 Put (Buffer, Var, Aft, Exp => 0);
kono
parents:
diff changeset
698 S := Strings.Fixed.Index_Non_Blank (Buffer);
kono
parents:
diff changeset
699 E := Buffer'Last;
kono
parents:
diff changeset
700
kono
parents:
diff changeset
701 when Decimal_Scientific_Float
kono
parents:
diff changeset
702 | Decimal_Scientific_Float_Up
kono
parents:
diff changeset
703 =>
kono
parents:
diff changeset
704 Put (Buffer, Var, Aft, Exp => 3);
kono
parents:
diff changeset
705 S := Strings.Fixed.Index_Non_Blank (Buffer);
kono
parents:
diff changeset
706 E := Buffer'Last;
kono
parents:
diff changeset
707
kono
parents:
diff changeset
708 if F.Kind = Decimal_Scientific_Float then
kono
parents:
diff changeset
709 Buffer (S .. E) :=
kono
parents:
diff changeset
710 Characters.Handling.To_Lower (Buffer (S .. E));
kono
parents:
diff changeset
711 end if;
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 when Shortest_Decimal_Float
kono
parents:
diff changeset
714 | Shortest_Decimal_Float_Up
kono
parents:
diff changeset
715 =>
kono
parents:
diff changeset
716 -- Without exponent
kono
parents:
diff changeset
717
kono
parents:
diff changeset
718 Put (Buffer, Var, Aft, Exp => 0);
kono
parents:
diff changeset
719 S := Strings.Fixed.Index_Non_Blank (Buffer);
kono
parents:
diff changeset
720 E := Buffer'Last;
kono
parents:
diff changeset
721
kono
parents:
diff changeset
722 -- Check with exponent
kono
parents:
diff changeset
723
kono
parents:
diff changeset
724 declare
kono
parents:
diff changeset
725 Buffer2 : String (1 .. 50);
kono
parents:
diff changeset
726 S2, E2 : Positive;
kono
parents:
diff changeset
727
kono
parents:
diff changeset
728 begin
kono
parents:
diff changeset
729 Put (Buffer2, Var, Aft, Exp => 3);
kono
parents:
diff changeset
730 S2 := Strings.Fixed.Index_Non_Blank (Buffer2);
kono
parents:
diff changeset
731 E2 := Buffer2'Last;
kono
parents:
diff changeset
732
kono
parents:
diff changeset
733 -- If with exponent it is shorter, use it
kono
parents:
diff changeset
734
kono
parents:
diff changeset
735 if (E2 - S2) < (E - S) then
kono
parents:
diff changeset
736 Buffer := Buffer2;
kono
parents:
diff changeset
737 S := S2;
kono
parents:
diff changeset
738 E := E2;
kono
parents:
diff changeset
739 end if;
kono
parents:
diff changeset
740 end;
kono
parents:
diff changeset
741
kono
parents:
diff changeset
742 if F.Kind = Shortest_Decimal_Float then
kono
parents:
diff changeset
743 Buffer (S .. E) :=
kono
parents:
diff changeset
744 Characters.Handling.To_Lower (Buffer (S .. E));
kono
parents:
diff changeset
745 end if;
kono
parents:
diff changeset
746
kono
parents:
diff changeset
747 when others =>
kono
parents:
diff changeset
748 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
749 end case;
kono
parents:
diff changeset
750
kono
parents:
diff changeset
751 Append (Format.D.Result,
kono
parents:
diff changeset
752 Get_Formatted (F, Buffer (S .. E), Buffer (S .. E)'Length));
kono
parents:
diff changeset
753
kono
parents:
diff changeset
754 return Format;
kono
parents:
diff changeset
755 end P_Flt_Format;
kono
parents:
diff changeset
756
kono
parents:
diff changeset
757 ------------------
kono
parents:
diff changeset
758 -- P_Int_Format --
kono
parents:
diff changeset
759 ------------------
kono
parents:
diff changeset
760
kono
parents:
diff changeset
761 function P_Int_Format
kono
parents:
diff changeset
762 (Format : Formatted_String;
kono
parents:
diff changeset
763 Var : Int) return Formatted_String
kono
parents:
diff changeset
764 is
kono
parents:
diff changeset
765 function Handle_Precision return Boolean;
kono
parents:
diff changeset
766 -- Return True if nothing else to do
kono
parents:
diff changeset
767
kono
parents:
diff changeset
768 F : F_Data;
kono
parents:
diff changeset
769 Buffer : String (1 .. 50);
kono
parents:
diff changeset
770 S, E : Positive := 1;
kono
parents:
diff changeset
771 Len : Natural := 0;
kono
parents:
diff changeset
772 Start : Positive;
kono
parents:
diff changeset
773
kono
parents:
diff changeset
774 ----------------------
kono
parents:
diff changeset
775 -- Handle_Precision --
kono
parents:
diff changeset
776 ----------------------
kono
parents:
diff changeset
777
kono
parents:
diff changeset
778 function Handle_Precision return Boolean is
kono
parents:
diff changeset
779 begin
kono
parents:
diff changeset
780 if F.Precision = 0 and then Sign (Var) = Zero then
kono
parents:
diff changeset
781 return True;
kono
parents:
diff changeset
782
kono
parents:
diff changeset
783 elsif F.Precision = Natural'Last then
kono
parents:
diff changeset
784 null;
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 elsif F.Precision > E - S + 1 then
kono
parents:
diff changeset
787 Len := F.Precision - (E - S + 1);
kono
parents:
diff changeset
788 Buffer (S - Len .. S - 1) := (others => '0');
kono
parents:
diff changeset
789 S := S - Len;
kono
parents:
diff changeset
790 end if;
kono
parents:
diff changeset
791
kono
parents:
diff changeset
792 return False;
kono
parents:
diff changeset
793 end Handle_Precision;
kono
parents:
diff changeset
794
kono
parents:
diff changeset
795 -- Start of processing for P_Int_Format
kono
parents:
diff changeset
796
kono
parents:
diff changeset
797 begin
kono
parents:
diff changeset
798 Next_Format (Format, F, Start);
kono
parents:
diff changeset
799
kono
parents:
diff changeset
800 if Format.D.Stored_Value < F.Value_Needed then
kono
parents:
diff changeset
801 Format.D.Stored_Value := Format.D.Stored_Value + 1;
kono
parents:
diff changeset
802 Format.D.Stack (Format.D.Stored_Value) := To_Integer (Var);
kono
parents:
diff changeset
803 Format.D.Index := Start;
kono
parents:
diff changeset
804 return Format;
kono
parents:
diff changeset
805 end if;
kono
parents:
diff changeset
806
kono
parents:
diff changeset
807 case F.Kind is
kono
parents:
diff changeset
808 when Unsigned_Octal =>
kono
parents:
diff changeset
809 if Sign (Var) = Neg then
kono
parents:
diff changeset
810 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
811 end if;
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 Put (Buffer, Var, Base => 8);
kono
parents:
diff changeset
814 S := Strings.Fixed.Index (Buffer, "8#") + 2;
kono
parents:
diff changeset
815 E := Strings.Fixed.Index (Buffer (S .. Buffer'Last), "#") - 1;
kono
parents:
diff changeset
816
kono
parents:
diff changeset
817 if Handle_Precision then
kono
parents:
diff changeset
818 return Format;
kono
parents:
diff changeset
819 end if;
kono
parents:
diff changeset
820
kono
parents:
diff changeset
821 case F.Base is
kono
parents:
diff changeset
822 when None => null;
kono
parents:
diff changeset
823 when C_Style => Len := 1;
kono
parents:
diff changeset
824 when Ada_Style => Len := 3;
kono
parents:
diff changeset
825 end case;
kono
parents:
diff changeset
826
kono
parents:
diff changeset
827 when Unsigned_Hexadecimal_Int =>
kono
parents:
diff changeset
828 if Sign (Var) = Neg then
kono
parents:
diff changeset
829 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
830 end if;
kono
parents:
diff changeset
831
kono
parents:
diff changeset
832 Put (Buffer, Var, Base => 16);
kono
parents:
diff changeset
833 S := Strings.Fixed.Index (Buffer, "16#") + 3;
kono
parents:
diff changeset
834 E := Strings.Fixed.Index (Buffer (S .. Buffer'Last), "#") - 1;
kono
parents:
diff changeset
835 Buffer (S .. E) := Characters.Handling.To_Lower (Buffer (S .. E));
kono
parents:
diff changeset
836
kono
parents:
diff changeset
837 if Handle_Precision then
kono
parents:
diff changeset
838 return Format;
kono
parents:
diff changeset
839 end if;
kono
parents:
diff changeset
840
kono
parents:
diff changeset
841 case F.Base is
kono
parents:
diff changeset
842 when None => null;
kono
parents:
diff changeset
843 when C_Style => Len := 2;
kono
parents:
diff changeset
844 when Ada_Style => Len := 4;
kono
parents:
diff changeset
845 end case;
kono
parents:
diff changeset
846
kono
parents:
diff changeset
847 when Unsigned_Hexadecimal_Int_Up =>
kono
parents:
diff changeset
848 if Sign (Var) = Neg then
kono
parents:
diff changeset
849 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
850 end if;
kono
parents:
diff changeset
851
kono
parents:
diff changeset
852 Put (Buffer, Var, Base => 16);
kono
parents:
diff changeset
853 S := Strings.Fixed.Index (Buffer, "16#") + 3;
kono
parents:
diff changeset
854 E := Strings.Fixed.Index (Buffer (S .. Buffer'Last), "#") - 1;
kono
parents:
diff changeset
855
kono
parents:
diff changeset
856 if Handle_Precision then
kono
parents:
diff changeset
857 return Format;
kono
parents:
diff changeset
858 end if;
kono
parents:
diff changeset
859
kono
parents:
diff changeset
860 case F.Base is
kono
parents:
diff changeset
861 when None => null;
kono
parents:
diff changeset
862 when C_Style => Len := 2;
kono
parents:
diff changeset
863 when Ada_Style => Len := 4;
kono
parents:
diff changeset
864 end case;
kono
parents:
diff changeset
865
kono
parents:
diff changeset
866 when Unsigned_Decimal_Int =>
kono
parents:
diff changeset
867 if Sign (Var) = Neg then
kono
parents:
diff changeset
868 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
869 end if;
kono
parents:
diff changeset
870
kono
parents:
diff changeset
871 Put (Buffer, Var, Base => 10);
kono
parents:
diff changeset
872 S := Strings.Fixed.Index_Non_Blank (Buffer);
kono
parents:
diff changeset
873 E := Buffer'Last;
kono
parents:
diff changeset
874
kono
parents:
diff changeset
875 if Handle_Precision then
kono
parents:
diff changeset
876 return Format;
kono
parents:
diff changeset
877 end if;
kono
parents:
diff changeset
878
kono
parents:
diff changeset
879 when Decimal_Int =>
kono
parents:
diff changeset
880 Put (Buffer, Var, Base => 10);
kono
parents:
diff changeset
881 S := Strings.Fixed.Index_Non_Blank (Buffer);
kono
parents:
diff changeset
882 E := Buffer'Last;
kono
parents:
diff changeset
883
kono
parents:
diff changeset
884 if Handle_Precision then
kono
parents:
diff changeset
885 return Format;
kono
parents:
diff changeset
886 end if;
kono
parents:
diff changeset
887
kono
parents:
diff changeset
888 when Char =>
kono
parents:
diff changeset
889 S := Buffer'First;
kono
parents:
diff changeset
890 E := Buffer'First;
kono
parents:
diff changeset
891 Buffer (S) := Character'Val (To_Integer (Var));
kono
parents:
diff changeset
892
kono
parents:
diff changeset
893 if Handle_Precision then
kono
parents:
diff changeset
894 return Format;
kono
parents:
diff changeset
895 end if;
kono
parents:
diff changeset
896
kono
parents:
diff changeset
897 when others =>
kono
parents:
diff changeset
898 Raise_Wrong_Format (Format);
kono
parents:
diff changeset
899 end case;
kono
parents:
diff changeset
900
kono
parents:
diff changeset
901 -- Then add base if needed
kono
parents:
diff changeset
902
kono
parents:
diff changeset
903 declare
kono
parents:
diff changeset
904 N : String := Get_Formatted (F, Buffer (S .. E), E - S + 1 + Len);
kono
parents:
diff changeset
905 P : constant Positive :=
kono
parents:
diff changeset
906 (if F.Left_Justify
kono
parents:
diff changeset
907 then N'First
kono
parents:
diff changeset
908 else Natural'Max (Strings.Fixed.Index_Non_Blank (N) - 1,
kono
parents:
diff changeset
909 N'First));
kono
parents:
diff changeset
910 begin
kono
parents:
diff changeset
911 case F.Base is
kono
parents:
diff changeset
912 when None =>
kono
parents:
diff changeset
913 null;
kono
parents:
diff changeset
914
kono
parents:
diff changeset
915 when C_Style =>
kono
parents:
diff changeset
916 case F.Kind is
kono
parents:
diff changeset
917 when Unsigned_Octal =>
kono
parents:
diff changeset
918 N (P) := 'O';
kono
parents:
diff changeset
919
kono
parents:
diff changeset
920 when Unsigned_Hexadecimal_Int =>
kono
parents:
diff changeset
921 if F.Left_Justify then
kono
parents:
diff changeset
922 N (P .. P + 1) := "Ox";
kono
parents:
diff changeset
923 else
kono
parents:
diff changeset
924 N (P - 1 .. P) := "0x";
kono
parents:
diff changeset
925 end if;
kono
parents:
diff changeset
926
kono
parents:
diff changeset
927 when Unsigned_Hexadecimal_Int_Up =>
kono
parents:
diff changeset
928 if F.Left_Justify then
kono
parents:
diff changeset
929 N (P .. P + 1) := "OX";
kono
parents:
diff changeset
930 else
kono
parents:
diff changeset
931 N (P - 1 .. P) := "0X";
kono
parents:
diff changeset
932 end if;
kono
parents:
diff changeset
933
kono
parents:
diff changeset
934 when others =>
kono
parents:
diff changeset
935 null;
kono
parents:
diff changeset
936 end case;
kono
parents:
diff changeset
937
kono
parents:
diff changeset
938 when Ada_Style =>
kono
parents:
diff changeset
939 case F.Kind is
kono
parents:
diff changeset
940 when Unsigned_Octal =>
kono
parents:
diff changeset
941 if F.Left_Justify then
kono
parents:
diff changeset
942 N (N'First + 2 .. N'Last) := N (N'First .. N'Last - 2);
kono
parents:
diff changeset
943 else
kono
parents:
diff changeset
944 N (P .. N'Last - 1) := N (P + 1 .. N'Last);
kono
parents:
diff changeset
945 end if;
kono
parents:
diff changeset
946
kono
parents:
diff changeset
947 N (N'First .. N'First + 1) := "8#";
kono
parents:
diff changeset
948 N (N'Last) := '#';
kono
parents:
diff changeset
949
kono
parents:
diff changeset
950 when Unsigned_Hexadecimal_Int
kono
parents:
diff changeset
951 | Unsigned_Hexadecimal_Int_Up
kono
parents:
diff changeset
952 =>
kono
parents:
diff changeset
953 if F.Left_Justify then
kono
parents:
diff changeset
954 N (N'First + 3 .. N'Last) := N (N'First .. N'Last - 3);
kono
parents:
diff changeset
955 else
kono
parents:
diff changeset
956 N (P .. N'Last - 1) := N (P + 1 .. N'Last);
kono
parents:
diff changeset
957 end if;
kono
parents:
diff changeset
958
kono
parents:
diff changeset
959 N (N'First .. N'First + 2) := "16#";
kono
parents:
diff changeset
960 N (N'Last) := '#';
kono
parents:
diff changeset
961
kono
parents:
diff changeset
962 when others =>
kono
parents:
diff changeset
963 null;
kono
parents:
diff changeset
964 end case;
kono
parents:
diff changeset
965 end case;
kono
parents:
diff changeset
966
kono
parents:
diff changeset
967 Append (Format.D.Result, N);
kono
parents:
diff changeset
968 end;
kono
parents:
diff changeset
969
kono
parents:
diff changeset
970 return Format;
kono
parents:
diff changeset
971 end P_Int_Format;
kono
parents:
diff changeset
972
kono
parents:
diff changeset
973 ------------------------
kono
parents:
diff changeset
974 -- Raise_Wrong_Format --
kono
parents:
diff changeset
975 ------------------------
kono
parents:
diff changeset
976
kono
parents:
diff changeset
977 procedure Raise_Wrong_Format (Format : Formatted_String) is
kono
parents:
diff changeset
978 begin
kono
parents:
diff changeset
979 raise Format_Error with
kono
parents:
diff changeset
980 "wrong format specified for parameter"
kono
parents:
diff changeset
981 & Positive'Image (Format.D.Current);
kono
parents:
diff changeset
982 end Raise_Wrong_Format;
kono
parents:
diff changeset
983
kono
parents:
diff changeset
984 end GNAT.Formatted_String;