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