111
|
1 ------------------------------------------------------------------------------
|
|
2 -- --
|
|
3 -- GNAT COMPILER COMPONENTS --
|
|
4 -- --
|
|
5 -- G N A T . F O R M A T T E D _ S T R I N G --
|
|
6 -- --
|
|
7 -- S p e c --
|
|
8 -- --
|
|
9 -- Copyright (C) 2014-2017, 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 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. --
|
|
17 -- --
|
|
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. --
|
|
21 -- --
|
|
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/>. --
|
|
26 -- --
|
|
27 -- GNAT was originally developed by the GNAT team at New York University. --
|
|
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
|
|
29 -- --
|
|
30 ------------------------------------------------------------------------------
|
|
31
|
|
32 -- This package add support for formatted string as supported by C printf()
|
|
33
|
|
34 -- A simple usage is:
|
|
35 --
|
|
36 -- Put_Line (-(+"%s" & "a string"));
|
|
37 --
|
|
38 -- or with a constant for the format:
|
|
39 --
|
|
40 -- declare
|
|
41 -- Format : constant Formatted_String := +"%s";
|
|
42 -- begin
|
|
43 -- Put_Line (-(Format & "a string"));
|
|
44 -- end;
|
|
45 --
|
|
46 -- Finally a more complex example:
|
|
47 --
|
|
48 -- declare
|
|
49 -- F : Formatted_String := +"['%c' ; %10d]";
|
|
50 -- C : Character := 'v';
|
|
51 -- I : Integer := 98;
|
|
52 -- begin
|
|
53 -- F := F & C & I;
|
|
54 -- Put_Line (-F);
|
|
55 -- end;
|
|
56
|
|
57 -- Which will display:
|
|
58
|
|
59 -- ['v' ; 98]
|
|
60
|
|
61 -- Each format specifier is: %[flags][width][.precision][length]specifier
|
|
62
|
|
63 -- Specifiers:
|
|
64 -- d or i Signed decimal integer
|
|
65 -- u Unsigned decimal integer
|
|
66 -- o Unsigned octal
|
|
67 -- x Unsigned hexadecimal integer
|
|
68 -- X Unsigned hexadecimal integer (uppercase)
|
|
69 -- f Decimal floating point, lowercase
|
|
70 -- F Decimal floating point, uppercase
|
|
71 -- e Scientific notation (mantissa/exponent), lowercase
|
|
72 -- E Scientific notation (mantissa/exponent), uppercase
|
|
73 -- g Use the shortest representation: %e or %f
|
|
74 -- G Use the shortest representation: %E or %F
|
|
75 -- c Character
|
|
76 -- s String of characters
|
|
77 -- p Pointer address
|
|
78 -- % A % followed by another % character will write a single %
|
|
79
|
|
80 -- Flags:
|
|
81
|
|
82 -- - Left-justify within the given field width;
|
|
83 -- Right justification is the default.
|
|
84
|
|
85 -- + Forces to preceed the result with a plus or minus sign (+ or -)
|
|
86 -- even for positive numbers. By default, only negative numbers
|
|
87 -- are preceded with a - sign.
|
|
88
|
|
89 -- (space) If no sign is going to be written, a blank space is inserted
|
|
90 -- before the value.
|
|
91
|
|
92 -- # Used with o, x or X specifiers the value is preceeded with
|
|
93 -- 0, 0x or 0X respectively for values different than zero.
|
|
94 -- Used with a, A, e, E, f, F, g or G it forces the written
|
|
95 -- output to contain a decimal point even if no more digits
|
|
96 -- follow. By default, if no digits follow, no decimal point is
|
|
97 -- written.
|
|
98
|
|
99 -- ~ As above, but using Ada style based <base>#<number>#
|
|
100
|
|
101 -- 0 Left-pads the number with zeroes (0) instead of spaces when
|
|
102 -- padding is specified.
|
|
103
|
|
104 -- Width:
|
|
105 -- number Minimum number of characters to be printed. If the value to
|
|
106 -- be printed is shorter than this number, the result is padded
|
|
107 -- with blank spaces. The value is not truncated even if the
|
|
108 -- result is larger.
|
|
109
|
|
110 -- * The width is not specified in the format string, but as an
|
|
111 -- additional integer value argument preceding the argument that
|
|
112 -- has to be formatted.
|
|
113 -- Precision:
|
|
114 -- number For integer specifiers (d, i, o, u, x, X): precision specifies
|
|
115 -- the minimum number of digits to be written. If the value to be
|
|
116 -- written is shorter than this number, the result is padded with
|
|
117 -- leading zeros. The value is not truncated even if the result
|
|
118 -- is longer. A precision of 0 means that no character is written
|
|
119 -- for the value 0.
|
|
120
|
|
121 -- For e, E, f and F specifiers: this is the number of digits to
|
|
122 -- be printed after the decimal point (by default, this is 6).
|
|
123 -- For g and G specifiers: This is the maximum number of
|
|
124 -- significant digits to be printed.
|
|
125
|
|
126 -- For s: this is the maximum number of characters to be printed.
|
|
127 -- By default all characters are printed until the ending null
|
|
128 -- character is encountered.
|
|
129
|
|
130 -- If the period is specified without an explicit value for
|
|
131 -- precision, 0 is assumed.
|
|
132
|
|
133 -- .* The precision is not specified in the format string, but as an
|
|
134 -- additional integer value argument preceding the argument that
|
|
135 -- has to be formatted.
|
|
136
|
|
137 with Ada.Text_IO;
|
|
138 with System;
|
|
139
|
|
140 private with Ada.Finalization;
|
|
141 private with Ada.Strings.Unbounded;
|
|
142
|
|
143 package GNAT.Formatted_String is
|
|
144 use Ada;
|
|
145
|
|
146 type Formatted_String (<>) is private;
|
|
147 -- A format string as defined for printf routine. This string is the
|
|
148 -- actual format for all the parameters added with the "&" routines below.
|
|
149 -- Note that a Formatted_String object can't be reused as it serves as
|
|
150 -- recipient for the final result. That is, each use of "&" will build
|
|
151 -- incrementally the final result string which can be retrieved with
|
|
152 -- the "-" routine below.
|
|
153
|
|
154 Format_Error : exception;
|
|
155 -- Raised for every mismatch between the parameter and the expected format
|
|
156 -- and for malformed format.
|
|
157
|
|
158 function "+" (Format : String) return Formatted_String;
|
|
159 -- Create the format string
|
|
160
|
|
161 function "-" (Format : Formatted_String) return String;
|
|
162 -- Get the result of the formatted string corresponding to the current
|
|
163 -- rendering (up to the last parameter formated).
|
|
164
|
|
165 function "&"
|
|
166 (Format : Formatted_String;
|
|
167 Var : Character) return Formatted_String;
|
|
168 -- A character, expect a %c
|
|
169
|
|
170 function "&"
|
|
171 (Format : Formatted_String;
|
|
172 Var : String) return Formatted_String;
|
|
173 -- A string, expect a %s
|
|
174
|
|
175 function "&"
|
|
176 (Format : Formatted_String;
|
|
177 Var : Boolean) return Formatted_String;
|
|
178 -- A boolean image, expect a %s
|
|
179
|
|
180 function "&"
|
|
181 (Format : Formatted_String;
|
|
182 Var : Integer) return Formatted_String;
|
|
183 -- An integer, expect a %d, %o, %x, %X
|
|
184
|
|
185 function "&"
|
|
186 (Format : Formatted_String;
|
|
187 Var : Long_Integer) return Formatted_String;
|
|
188 -- As above
|
|
189
|
|
190 function "&"
|
|
191 (Format : Formatted_String;
|
|
192 Var : System.Address) return Formatted_String;
|
|
193 -- An address, expect a %p
|
|
194
|
|
195 function "&"
|
|
196 (Format : Formatted_String;
|
|
197 Var : Float) return Formatted_String;
|
|
198 -- A float, expect %f, %e, %F, %E, %g, %G
|
|
199
|
|
200 function "&"
|
|
201 (Format : Formatted_String;
|
|
202 Var : Long_Float) return Formatted_String;
|
|
203 -- As above
|
|
204
|
|
205 function "&"
|
|
206 (Format : Formatted_String;
|
|
207 Var : Duration) return Formatted_String;
|
|
208 -- As above
|
|
209
|
|
210 -- Some generics
|
|
211
|
|
212 generic
|
|
213 type Int is range <>;
|
|
214
|
|
215 with procedure Put
|
|
216 (To : out String;
|
|
217 Item : Int;
|
|
218 Base : Text_IO.Number_Base);
|
|
219 function Int_Format
|
|
220 (Format : Formatted_String;
|
|
221 Var : Int) return Formatted_String;
|
|
222 -- As for Integer above
|
|
223
|
|
224 generic
|
|
225 type Int is mod <>;
|
|
226
|
|
227 with procedure Put
|
|
228 (To : out String;
|
|
229 Item : Int;
|
|
230 Base : Text_IO.Number_Base);
|
|
231 function Mod_Format
|
|
232 (Format : Formatted_String;
|
|
233 Var : Int) return Formatted_String;
|
|
234 -- As for Integer above
|
|
235
|
|
236 generic
|
|
237 type Flt is digits <>;
|
|
238
|
|
239 with procedure Put
|
|
240 (To : out String;
|
|
241 Item : Flt;
|
|
242 Aft : Text_IO.Field;
|
|
243 Exp : Text_IO.Field);
|
|
244 function Flt_Format
|
|
245 (Format : Formatted_String;
|
|
246 Var : Flt) return Formatted_String;
|
|
247 -- As for Float above
|
|
248
|
|
249 generic
|
|
250 type Flt is delta <>;
|
|
251
|
|
252 with procedure Put
|
|
253 (To : out String;
|
|
254 Item : Flt;
|
|
255 Aft : Text_IO.Field;
|
|
256 Exp : Text_IO.Field);
|
|
257 function Fixed_Format
|
|
258 (Format : Formatted_String;
|
|
259 Var : Flt) return Formatted_String;
|
|
260 -- As for Float above
|
|
261
|
|
262 generic
|
|
263 type Flt is delta <> digits <>;
|
|
264
|
|
265 with procedure Put
|
|
266 (To : out String;
|
|
267 Item : Flt;
|
|
268 Aft : Text_IO.Field;
|
|
269 Exp : Text_IO.Field);
|
|
270 function Decimal_Format
|
|
271 (Format : Formatted_String;
|
|
272 Var : Flt) return Formatted_String;
|
|
273 -- As for Float above
|
|
274
|
|
275 generic
|
|
276 type Enum is (<>);
|
|
277 function Enum_Format
|
|
278 (Format : Formatted_String;
|
|
279 Var : Enum) return Formatted_String;
|
|
280 -- As for String above, output the string representation of the enumeration
|
|
281
|
|
282 private
|
|
283 use Ada.Strings.Unbounded;
|
|
284
|
|
285 type I_Vars is array (Positive range 1 .. 2) of Integer;
|
|
286 -- Used to keep 2 numbers for the possible * for the width and precision
|
|
287
|
|
288 type Data (Size : Natural) is record
|
|
289 Ref_Count : Natural := 1;
|
|
290 Index : Positive := 1; -- format index for next value
|
|
291 Result : Unbounded_String; -- current value
|
|
292 Current : Natural; -- the current format number
|
|
293 Stored_Value : Natural := 0; -- number of stored values in Stack
|
|
294 Stack : I_Vars;
|
|
295 Format : String (1 .. Size); -- the format string
|
|
296 end record;
|
|
297
|
|
298 type Data_Access is access Data;
|
|
299
|
|
300 -- The formatted string record is controlled and do not need an initialize
|
|
301 -- as it requires an explit initial value. This is given with "+" and
|
|
302 -- properly initialize the record at this point.
|
|
303
|
|
304 type Formatted_String is new Finalization.Controlled with record
|
|
305 D : Data_Access;
|
|
306 end record;
|
|
307
|
|
308 overriding procedure Adjust (F : in out Formatted_String);
|
|
309 overriding procedure Finalize (F : in out Formatted_String);
|
|
310
|
|
311 end GNAT.Formatted_String;
|