-- GHDL Run Time (GRT) stdio subprograms for GRT types. -- Copyright (C) 2002 - 2014 Tristan Gingold -- -- GHDL is free software; you can redistribute it and/or modify it under -- the terms of the GNU General Public License as published by the Free -- Software Foundation; either version 2, or (at your option) any later -- version. -- -- GHDL is distributed in the hope that it will be useful, but WITHOUT ANY -- WARRANTY; without even the implied warranty of MERCHANTABILITY or -- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- for more details. -- -- You should have received a copy of the GNU General Public License -- along with GCC; see the file COPYING. If not, write to the Free -- Software Foundation, 59 Temple Place - Suite 330, Boston, MA -- 02111-1307, USA. -- -- As a special exception, if other files instantiate generics from this -- unit, or you link this unit with other files to produce an executable, -- this unit does not by itself cause the resulting executable to be -- covered by the GNU General Public License. This exception does not -- however invalidate any other reasons why the executable file might be -- covered by the GNU Public License. with Grt.C; use Grt.C; package body Grt.Astdio is procedure Put (Stream : FILEs; Str : String) is S : size_t; pragma Unreferenced (S); begin S := fwrite (Str'Address, Str'Length, 1, Stream); end Put; procedure Put (Stream : FILEs; C : Character) is R : int; pragma Unreferenced (R); begin R := fputc (Character'Pos (C), Stream); end Put; procedure Put (Stream : FILEs; Str : Ghdl_C_String) is Len : Natural; S : size_t; pragma Unreferenced (S); begin Len := strlen (Str); S := fwrite (Str (1)'Address, size_t (Len), 1, Stream); end Put; procedure New_Line (Stream : FILEs) is begin Put (Stream, Nl); end New_Line; procedure Put (Str : String) is S : size_t; pragma Unreferenced (S); begin S := fwrite (Str'Address, Str'Length, 1, stdout); end Put; procedure Put (C : Character) is R : int; pragma Unreferenced (R); begin R := fputc (Character'Pos (C), stdout); end Put; procedure Put (Str : Ghdl_C_String) is Len : Natural; S : size_t; pragma Unreferenced (S); begin Len := strlen (Str); S := fwrite (Str (1)'Address, size_t (Len), 1, stdout); end Put; procedure New_Line is begin Put (Nl); end New_Line; procedure Put_Line (Str : String) is begin Put (Str); New_Line; end Put_Line; procedure Put_Str_Len (Stream : FILEs; Str : Ghdl_Str_Len_Type) is S : String (1 .. 3); begin if Str.Str = null then S (1) := '''; S (2) := Character'Val (Str.Len); S (3) := '''; Put (Stream, S); else Put (Stream, Str.Str (1 .. Str.Len)); end if; end Put_Str_Len; generic type Ntype is range <>; Max_Len : Natural; procedure Put_Ntype (Stream : FILEs; N : Ntype); procedure Put_Ntype (Stream : FILEs; N : Ntype) is Str : String (1 .. Max_Len); P : Natural := Str'Last; V : Ntype; begin -- V is negativ. if N > 0 then V := -N; else V := N; end if; loop Str (P) := Character'Val (48 - (V rem 10)); -- V is <= 0. V := V / 10; exit when V = 0; P := P - 1; end loop; if N < 0 then P := P - 1; Str (P) := '-'; end if; Put (Stream, Str (P .. Max_Len)); end Put_Ntype; generic type Utype is mod <>; Max_Len : Natural; procedure Put_Utype (Stream : FILEs; N : Utype); procedure Put_Utype (Stream : FILEs; N : Utype) is Str : String (1 .. Max_Len); P : Natural := Str'Last; V : Utype := N; begin loop Str (P) := Character'Val (48 + (V rem 10)); V := V / 10; exit when V = 0; P := P - 1; end loop; Put (Stream, Str (P .. Max_Len)); end Put_Utype; procedure Put_I32_1 is new Put_Ntype (Ntype => Ghdl_I32, Max_Len => 11); procedure Put_I32 (Stream : FILEs; I32 : Ghdl_I32) renames Put_I32_1; procedure Put_U32_1 is new Put_Utype (Utype => Ghdl_U32, Max_Len => 11); procedure Put_U32 (Stream : FILEs; U32 : Ghdl_U32) renames Put_U32_1; procedure Put_I64_1 is new Put_Ntype (Ntype => Ghdl_I64, Max_Len => 20); procedure Put_I64 (Stream : FILEs; I64 : Ghdl_I64) renames Put_I64_1; procedure Put_U64_1 is new Put_Utype (Utype => Ghdl_U64, Max_Len => 20); procedure Put_U64 (Stream : FILEs; U64 : Ghdl_U64) renames Put_U64_1; procedure Put_F64 (Stream : FILEs; F64 : Ghdl_F64) is procedure Fprintf_G (Stream : FILEs; Arg : Ghdl_F64); pragma Import (C, Fprintf_G, "__ghdl_fprintf_g"); begin Fprintf_G (Stream, F64); end Put_F64; Hex_Map : constant array (0 .. 15) of Character := "0123456789ABCDEF"; procedure Put (Stream : FILEs; Addr : System.Address) is Res : String (1 .. System.Word_Size / 4); Val : Integer_Address := To_Integer (Addr); begin for I in reverse Res'Range loop Res (I) := Hex_Map (Natural (Val and 15)); Val := Val / 16; end loop; Put (Stream, Res); end Put; procedure Put_Dir (Stream : FILEs; Dir : Ghdl_Dir_Type) is begin case Dir is when Dir_To => Put (Stream, " to "); when Dir_Downto => Put (Stream, " downto "); end case; end Put_Dir; procedure Put_Time (Stream : FILEs; Time : Std_Time) is begin if Time = Std_Time'First then Put (Stream, "-Inf"); else -- Do not bother with sec, min, and hr. if (Time mod 1_000_000_000_000) = 0 then Put_I64 (Stream, Ghdl_I64 (Time / 1_000_000_000_000)); Put (Stream, "ms"); elsif (Time mod 1_000_000_000) = 0 then Put_I64 (Stream, Ghdl_I64 (Time / 1_000_000_000)); Put (Stream, "us"); elsif (Time mod 1_000_000) = 0 then Put_I64 (Stream, Ghdl_I64 (Time / 1_000_000)); Put (Stream, "ns"); elsif (Time mod 1_000) = 0 then Put_I64 (Stream, Ghdl_I64 (Time / 1_000)); Put (Stream, "ps"); else Put_I64 (Stream, Ghdl_I64 (Time)); Put (Stream, "fs"); end if; end if; end Put_Time; end Grt.Astdio;