1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
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. --
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. --
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/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
32 with System.OS_Lib; use System.OS_Lib;
34 package body Output is
36 Current_FD : File_Descriptor := Standout;
37 -- File descriptor for current output
39 Special_Output_Proc : Output_Proc := null;
40 -- Record argument to last call to Set_Special_Output. If this is
41 -- non-null, then we are in special output mode.
43 Indentation_Amount : constant Positive := 3;
44 -- Number of spaces to output for each indentation level
46 Indentation_Limit : constant Positive := 40;
47 -- Indentation beyond this number of spaces wraps around
49 pragma Assert (Indentation_Limit < Buffer_Max / 2);
50 -- Make sure this is substantially shorter than the line length
52 Cur_Indentation : Natural := 0;
53 -- Number of spaces to indent each line
55 -----------------------
56 -- Local_Subprograms --
57 -----------------------
59 procedure Flush_Buffer;
60 -- Flush buffer if non-empty and reset column counter
62 ---------------------------
63 -- Cancel_Special_Output --
64 ---------------------------
66 procedure Cancel_Special_Output is
68 Special_Output_Proc := null;
69 end Cancel_Special_Output;
75 function Column return Pos is
77 return Pos (Next_Col);
84 procedure Flush_Buffer is
85 Write_Error : exception;
86 -- Raised if Write fails
92 procedure Write_Buffer (Buf : String);
93 -- Write out Buf, either using Special_Output_Proc, or the normal way
94 -- using Write. Raise Write_Error if Write fails (presumably due to disk
95 -- full). Write_Error is not used in the case of Special_Output_Proc.
97 procedure Write_Buffer (Buf : String) is
99 -- If Special_Output_Proc has been set, then use it
101 if Special_Output_Proc /= null then
102 Special_Output_Proc.all (Buf);
104 -- If output is not set, then output to either standard output
105 -- or standard error.
107 elsif Write (Current_FD, Buf'Address, Buf'Length) /= Buf'Length then
113 Len : constant Natural := Next_Col - 1;
118 -- If there's no indentation, or if the line is too long with
119 -- indentation, just write the buffer.
121 if Cur_Indentation = 0
122 or else Cur_Indentation + Len > Buffer_Max
124 Write_Buffer (Buffer (1 .. Len));
126 -- Otherwise, construct a new buffer with preceding spaces, and
131 Indented_Buffer : constant String
132 := (1 .. Cur_Indentation => ' ') & Buffer (1 .. Len);
134 Write_Buffer (Indented_Buffer);
140 -- If there are errors with standard error, just quit.
141 -- Otherwise, set the output to standard error before reporting
142 -- a failure and quitting.
144 if Current_FD /= Standerr then
145 Current_FD := Standerr;
147 Write_Line ("fatal error: disk full");
153 -- Buffer is now empty
166 (Cur_Indentation + Indentation_Amount) mod Indentation_Limit;
167 -- The "mod" is to wrap around in case there's too much indentation
177 (Cur_Indentation - Indentation_Amount) mod Indentation_Limit;
180 ---------------------------
181 -- Restore_Output_Buffer --
182 ---------------------------
184 procedure Restore_Output_Buffer (S : Saved_Output_Buffer) is
186 Next_Col := S.Next_Col;
187 Cur_Indentation := S.Cur_Indentation;
188 Buffer (1 .. Next_Col - 1) := S.Buffer (1 .. Next_Col - 1);
189 end Restore_Output_Buffer;
191 ------------------------
192 -- Save_Output_Buffer --
193 ------------------------
195 function Save_Output_Buffer return Saved_Output_Buffer is
196 S : Saved_Output_Buffer;
198 S.Buffer (1 .. Next_Col - 1) := Buffer (1 .. Next_Col - 1);
199 S.Next_Col := Next_Col;
200 S.Cur_Indentation := Cur_Indentation;
202 Cur_Indentation := 0;
204 end Save_Output_Buffer;
206 ------------------------
207 -- Set_Special_Output --
208 ------------------------
210 procedure Set_Special_Output (P : Output_Proc) is
212 Special_Output_Proc := P;
213 end Set_Special_Output;
215 ------------------------
216 -- Set_Standard_Error --
217 ------------------------
219 procedure Set_Standard_Error is
221 if Special_Output_Proc = null then
225 Current_FD := Standerr;
226 end Set_Standard_Error;
228 -------------------------
229 -- Set_Standard_Output --
230 -------------------------
232 procedure Set_Standard_Output is
234 if Special_Output_Proc = null then
238 Current_FD := Standout;
239 end Set_Standard_Output;
245 procedure w (C : Character) is
253 procedure w (S : String) is
259 procedure w (V : Int) is
265 procedure w (B : Boolean) is
274 procedure w (L : String; C : Character) is
281 procedure w (L : String; S : String) is
288 procedure w (L : String; V : Int) is
295 procedure w (L : String; B : Boolean) is
306 procedure Write_Char (C : Character) is
308 if Next_Col = Buffer'Length then
315 Buffer (Next_Col) := C;
316 Next_Col := Next_Col + 1;
324 procedure Write_Eol is
326 -- Remove any trailing space
328 while Next_Col > 1 and then Buffer (Next_Col - 1) = ' ' loop
329 Next_Col := Next_Col - 1;
332 Buffer (Next_Col) := ASCII.LF;
333 Next_Col := Next_Col + 1;
337 ---------------------------
338 -- Write_Eol_Keep_Blanks --
339 ---------------------------
341 procedure Write_Eol_Keep_Blanks is
343 Buffer (Next_Col) := ASCII.LF;
344 Next_Col := Next_Col + 1;
346 end Write_Eol_Keep_Blanks;
348 ----------------------
349 -- Write_Erase_Char --
350 ----------------------
352 procedure Write_Erase_Char (C : Character) is
354 if Next_Col /= 1 and then Buffer (Next_Col - 1) = C then
355 Next_Col := Next_Col - 1;
357 end Write_Erase_Char;
363 procedure Write_Int (Val : Int) is
371 Write_Int (Val / 10);
374 Write_Char (Character'Val ((Val mod 10) + Character'Pos ('0')));
382 procedure Write_Line (S : String) is
392 procedure Write_Spaces (N : Nat) is
403 procedure Write_Str (S : String) is
405 for J in S'Range loop