diff options
Diffstat (limited to 'src/grt/grt-astdio.adb')
-rw-r--r-- | src/grt/grt-astdio.adb | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/src/grt/grt-astdio.adb b/src/grt/grt-astdio.adb new file mode 100644 index 0000000..456d024 --- /dev/null +++ b/src/grt/grt-astdio.adb @@ -0,0 +1,231 @@ +-- 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; |