------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- G N A T . F O R M A T T E D _ S T R I N G -- -- -- -- S p e c -- -- -- -- Copyright (C) 2014-2019, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- As a special exception under Section 7 of GPL version 3, you are granted -- -- additional permissions described in the GCC Runtime Library Exception, -- -- version 3.1, as published by the Free Software Foundation. -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ -- This package add support for formatted string as supported by C printf() -- A simple usage is: -- -- Put_Line (-(+"%s" & "a string")); -- -- or with a constant for the format: -- -- declare -- Format : constant Formatted_String := +"%s"; -- begin -- Put_Line (-(Format & "a string")); -- end; -- -- Finally a more complex example: -- -- declare -- F : Formatted_String := +"['%c' ; %10d]"; -- C : Character := 'v'; -- I : Integer := 98; -- begin -- F := F & C & I; -- Put_Line (-F); -- end; -- Which will display: -- ['v' ; 98] -- Each format specifier is: %[flags][width][.precision][length]specifier -- Specifiers: -- d or i Signed decimal integer -- u Unsigned decimal integer -- o Unsigned octal -- x Unsigned hexadecimal integer -- X Unsigned hexadecimal integer (uppercase) -- f Decimal floating point, lowercase -- F Decimal floating point, uppercase -- e Scientific notation (mantissa/exponent), lowercase -- E Scientific notation (mantissa/exponent), uppercase -- g Use the shortest representation: %e or %f -- G Use the shortest representation: %E or %F -- c Character -- s String of characters -- p Pointer address -- % A % followed by another % character will write a single % -- Flags: -- - Left-justify within the given field width; -- Right justification is the default. -- + Forces to preceed the result with a plus or minus sign (+ or -) -- even for positive numbers. By default, only negative numbers -- are preceded with a - sign. -- (space) If no sign is going to be written, a blank space is inserted -- before the value. -- # Used with o, x or X specifiers the value is preceeded with -- 0, 0x or 0X respectively for values different than zero. -- Used with a, A, e, E, f, F, g or G it forces the written -- output to contain a decimal point even if no more digits -- follow. By default, if no digits follow, no decimal point is -- written. -- ~ As above, but using Ada style based ## -- 0 Left-pads the number with zeroes (0) instead of spaces when -- padding is specified. -- Width: -- number Minimum number of characters to be printed. If the value to -- be printed is shorter than this number, the result is padded -- with blank spaces. The value is not truncated even if the -- result is larger. -- * The width is not specified in the format string, but as an -- additional integer value argument preceding the argument that -- has to be formatted. -- Precision: -- number For integer specifiers (d, i, o, u, x, X): precision specifies -- the minimum number of digits to be written. If the value to be -- written is shorter than this number, the result is padded with -- leading zeros. The value is not truncated even if the result -- is longer. A precision of 0 means that no character is written -- for the value 0. -- For e, E, f and F specifiers: this is the number of digits to -- be printed after the decimal point (by default, this is 6). -- For g and G specifiers: This is the maximum number of -- significant digits to be printed. -- For s: this is the maximum number of characters to be printed. -- By default all characters are printed until the ending null -- character is encountered. -- If the period is specified without an explicit value for -- precision, 0 is assumed. -- .* The precision is not specified in the format string, but as an -- additional integer value argument preceding the argument that -- has to be formatted. with Ada.Text_IO; with System; private with Ada.Finalization; private with Ada.Strings.Unbounded; package GNAT.Formatted_String is use Ada; type Formatted_String (<>) is private; -- A format string as defined for printf routine. This string is the -- actual format for all the parameters added with the "&" routines below. -- Note that a Formatted_String object can't be reused as it serves as -- recipient for the final result. That is, each use of "&" will build -- incrementally the final result string which can be retrieved with -- the "-" routine below. Format_Error : exception; -- Raised for every mismatch between the parameter and the expected format -- and for malformed format. function "+" (Format : String) return Formatted_String; -- Create the format string function "-" (Format : Formatted_String) return String; -- Get the result of the formatted string corresponding to the current -- rendering (up to the last parameter formated). function "&" (Format : Formatted_String; Var : Character) return Formatted_String; -- A character, expect a %c function "&" (Format : Formatted_String; Var : String) return Formatted_String; -- A string, expect a %s function "&" (Format : Formatted_String; Var : Boolean) return Formatted_String; -- A boolean image, expect a %s function "&" (Format : Formatted_String; Var : Integer) return Formatted_String; -- An integer, expect a %d, %o, %x, %X function "&" (Format : Formatted_String; Var : Long_Integer) return Formatted_String; -- As above function "&" (Format : Formatted_String; Var : System.Address) return Formatted_String; -- An address, expect a %p function "&" (Format : Formatted_String; Var : Float) return Formatted_String; -- A float, expect %f, %e, %F, %E, %g, %G function "&" (Format : Formatted_String; Var : Long_Float) return Formatted_String; -- As above function "&" (Format : Formatted_String; Var : Duration) return Formatted_String; -- As above -- Some generics generic type Int is range <>; with procedure Put (To : out String; Item : Int; Base : Text_IO.Number_Base); function Int_Format (Format : Formatted_String; Var : Int) return Formatted_String; -- As for Integer above generic type Int is mod <>; with procedure Put (To : out String; Item : Int; Base : Text_IO.Number_Base); function Mod_Format (Format : Formatted_String; Var : Int) return Formatted_String; -- As for Integer above generic type Flt is digits <>; with procedure Put (To : out String; Item : Flt; Aft : Text_IO.Field; Exp : Text_IO.Field); function Flt_Format (Format : Formatted_String; Var : Flt) return Formatted_String; -- As for Float above generic type Flt is delta <>; with procedure Put (To : out String; Item : Flt; Aft : Text_IO.Field; Exp : Text_IO.Field); function Fixed_Format (Format : Formatted_String; Var : Flt) return Formatted_String; -- As for Float above generic type Flt is delta <> digits <>; with procedure Put (To : out String; Item : Flt; Aft : Text_IO.Field; Exp : Text_IO.Field); function Decimal_Format (Format : Formatted_String; Var : Flt) return Formatted_String; -- As for Float above generic type Enum is (<>); function Enum_Format (Format : Formatted_String; Var : Enum) return Formatted_String; -- As for String above, output the string representation of the enumeration private use Ada.Strings.Unbounded; type I_Vars is array (Positive range 1 .. 2) of Integer; -- Used to keep 2 numbers for the possible * for the width and precision type Data (Size : Natural) is record Ref_Count : Natural := 1; Index : Positive := 1; -- format index for next value Result : Unbounded_String; -- current value Current : Natural; -- the current format number Stored_Value : Natural := 0; -- number of stored values in Stack Stack : I_Vars; Format : String (1 .. Size); -- the format string end record; type Data_Access is access Data; -- The formatted string record is controlled and do not need an initialize -- as it requires an explit initial value. This is given with "+" and -- properly initialize the record at this point. type Formatted_String is new Finalization.Controlled with record D : Data_Access; end record; overriding procedure Adjust (F : in out Formatted_String); overriding procedure Finalize (F : in out Formatted_String); end GNAT.Formatted_String;