summaryrefslogtreecommitdiff
path: root/src/grt/grt-astdio.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/grt/grt-astdio.adb')
-rw-r--r--src/grt/grt-astdio.adb231
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;