1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2013, 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 package body Output
is
34 Current_FD
: File_Descriptor
:= Standout
;
35 -- File descriptor for current output
37 Special_Output_Proc
: Output_Proc
:= null;
38 -- Record argument to last call to Set_Special_Output. If this is
39 -- non-null, then we are in special output mode.
41 Indentation_Amount
: constant Positive := 3;
42 -- Number of spaces to output for each indentation level
44 Indentation_Limit
: constant Positive := 40;
45 -- Indentation beyond this number of spaces wraps around
47 pragma Assert
(Indentation_Limit
< Buffer_Max
/ 2);
48 -- Make sure this is substantially shorter than the line length
50 Cur_Indentation
: Natural := 0;
51 -- Number of spaces to indent each line
53 -----------------------
54 -- Local_Subprograms --
55 -----------------------
57 procedure Flush_Buffer
;
58 -- Flush buffer if non-empty and reset column counter
60 ---------------------------
61 -- Cancel_Special_Output --
62 ---------------------------
64 procedure Cancel_Special_Output
is
66 Special_Output_Proc
:= null;
67 end Cancel_Special_Output
;
73 function Column
return Pos
is
75 return Pos
(Next_Col
);
78 ----------------------
79 -- Delete_Last_Char --
80 ----------------------
82 procedure Delete_Last_Char
is
85 Next_Col
:= Next_Col
- 1;
93 procedure Flush_Buffer
is
94 Write_Error
: exception;
95 -- Raised if Write fails
101 procedure Write_Buffer
(Buf
: String);
102 -- Write out Buf, either using Special_Output_Proc, or the normal way
103 -- using Write. Raise Write_Error if Write fails (presumably due to disk
104 -- full). Write_Error is not used in the case of Special_Output_Proc.
106 procedure Write_Buffer
(Buf
: String) is
108 -- If Special_Output_Proc has been set, then use it
110 if Special_Output_Proc
/= null then
111 Special_Output_Proc
.all (Buf
);
113 -- If output is not set, then output to either standard output
114 -- or standard error.
116 elsif Write
(Current_FD
, Buf
'Address, Buf
'Length) /= Buf
'Length then
122 Len
: constant Natural := Next_Col
- 1;
124 -- Start of processing for Flush_Buffer
129 -- If there's no indentation, or if the line is too long with
130 -- indentation, or if it's a blank line, just write the buffer.
132 if Cur_Indentation
= 0
133 or else Cur_Indentation
+ Len
> Buffer_Max
134 or else Buffer
(1 .. Len
) = (1 => ASCII
.LF
)
136 Write_Buffer
(Buffer
(1 .. Len
));
138 -- Otherwise, construct a new buffer with preceding spaces, and
143 Indented_Buffer
: constant String :=
144 (1 .. Cur_Indentation
=> ' ') &
147 Write_Buffer
(Indented_Buffer
);
154 -- If there are errors with standard error just quit. Otherwise
155 -- set the output to standard error before reporting a failure
158 if Current_FD
/= Standerr
then
159 Current_FD
:= Standerr
;
161 Write_Line
("fatal error: disk full");
167 -- Buffer is now empty
177 procedure Ignore_Output
(S
: String) is
188 -- The "mod" in the following assignment is to cause a wrap around in
189 -- the case where there is too much indentation.
192 (Cur_Indentation
+ Indentation_Amount
) mod Indentation_Limit
;
199 function Last_Char
return Character is
201 if Next_Col
/= 1 then
202 return Buffer
(Next_Col
- 1);
214 -- The "mod" here undoes the wrap around from Indent above
217 (Cur_Indentation
- Indentation_Amount
) mod Indentation_Limit
;
220 ---------------------------
221 -- Restore_Output_Buffer --
222 ---------------------------
224 procedure Restore_Output_Buffer
(S
: Saved_Output_Buffer
) is
226 Next_Col
:= S
.Next_Col
;
227 Cur_Indentation
:= S
.Cur_Indentation
;
228 Buffer
(1 .. Next_Col
- 1) := S
.Buffer
(1 .. Next_Col
- 1);
229 end Restore_Output_Buffer
;
231 ------------------------
232 -- Save_Output_Buffer --
233 ------------------------
235 function Save_Output_Buffer
return Saved_Output_Buffer
is
236 S
: Saved_Output_Buffer
;
238 S
.Buffer
(1 .. Next_Col
- 1) := Buffer
(1 .. Next_Col
- 1);
239 S
.Next_Col
:= Next_Col
;
240 S
.Cur_Indentation
:= Cur_Indentation
;
242 Cur_Indentation
:= 0;
244 end Save_Output_Buffer
;
246 ------------------------
247 -- Set_Special_Output --
248 ------------------------
250 procedure Set_Special_Output
(P
: Output_Proc
) is
252 Special_Output_Proc
:= P
;
253 end Set_Special_Output
;
259 procedure Set_Output
(FD
: File_Descriptor
) is
261 if Special_Output_Proc
= null then
268 ------------------------
269 -- Set_Standard_Error --
270 ------------------------
272 procedure Set_Standard_Error
is
274 Set_Output
(Standerr
);
275 end Set_Standard_Error
;
277 -------------------------
278 -- Set_Standard_Output --
279 -------------------------
281 procedure Set_Standard_Output
is
283 Set_Output
(Standout
);
284 end Set_Standard_Output
;
290 procedure w
(C
: Character) is
298 procedure w
(S
: String) is
304 procedure w
(V
: Int
) is
310 procedure w
(B
: Boolean) is
319 procedure w
(L
: String; C
: Character) is
326 procedure w
(L
: String; S
: String) is
333 procedure w
(L
: String; V
: Int
) is
340 procedure w
(L
: String; B
: Boolean) is
351 procedure Write_Char
(C
: Character) is
353 if Next_Col
= Buffer
'Length then
360 Buffer
(Next_Col
) := C
;
361 Next_Col
:= Next_Col
+ 1;
369 procedure Write_Eol
is
371 -- Remove any trailing spaces
373 while Next_Col
> 1 and then Buffer
(Next_Col
- 1) = ' ' loop
374 Next_Col
:= Next_Col
- 1;
377 Buffer
(Next_Col
) := ASCII
.LF
;
378 Next_Col
:= Next_Col
+ 1;
382 ---------------------------
383 -- Write_Eol_Keep_Blanks --
384 ---------------------------
386 procedure Write_Eol_Keep_Blanks
is
388 Buffer
(Next_Col
) := ASCII
.LF
;
389 Next_Col
:= Next_Col
+ 1;
391 end Write_Eol_Keep_Blanks
;
393 ----------------------
394 -- Write_Erase_Char --
395 ----------------------
397 procedure Write_Erase_Char
(C
: Character) is
399 if Next_Col
/= 1 and then Buffer
(Next_Col
- 1) = C
then
400 Next_Col
:= Next_Col
- 1;
402 end Write_Erase_Char
;
408 procedure Write_Int
(Val
: Int
) is
416 Write_Int
(Val
/ 10);
419 Write_Char
(Character'Val ((Val
mod 10) + Character'Pos ('0')));
427 procedure Write_Line
(S
: String) is
437 procedure Write_Spaces
(N
: Nat
) is
448 procedure Write_Str
(S
: String) is
450 for J
in S
'Range loop