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-2018, 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 137with Ada.Text_IO; 138with System; 139 140private with Ada.Finalization; 141private with Ada.Strings.Unbounded; 142 143package 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 282private 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 311end GNAT.Formatted_String; 312