1
------------------------------------------------------------------------------
3
-- GNATPP COMPONENTS --
5
-- G N A T P P . P P _ O U T P U T --
9
-- Copyright (C) 2001-2004, ACT Europe --
11
-- GNATPP 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 2, or (at your option) any later ver- --
14
-- sion. GNATPP is distributed in the hope that it will be useful, but --
15
-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABI- --
16
-- LITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
17
-- License for more details. You should have received a copy of the GNU --
18
-- General Public License distributed with GNAT; see file COPYING. If not, --
19
-- write to the Free Software Foundation, 59 Temple Place - Suite 330, --
22
-- GNATPP is maintained by ACT Europe (http://www.act-europe.fr). --
24
------------------------------------------------------------------------------
26
with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;
27
with Ada.Characters.Handling; use Ada.Characters.Handling;
29
with GNATPP.Source_Line_Buffer; use GNATPP.Source_Line_Buffer;
30
with GNATPP.Output; use GNATPP.Output;
31
with GNATPP.State; use GNATPP.State;
32
with GNATPP.Paragraphs; use GNATPP.Paragraphs;
34
package body GNATPP.PP_Output is
36
Last_Char_Was_Space : Boolean := False;
38
-------------------------
39
-- Available_In_Output --
40
-------------------------
42
function Available_In_Output return Integer is
43
Result : Integer := Max_Line_Length - Output_Pos + 1;
45
if Postponed_Space then
50
end Available_In_Output;
56
function Get_Output_Pos return Integer is
57
Result : Integer := Output_Pos;
60
if Postponed_Space then
71
procedure PP_Close_Line is
74
if The_Very_First_Line then
75
The_Very_First_Line := False;
80
Current_Out_Line := Current_Out_Line + 1;
81
Is_New_Output_Line := True;
83
Output_Line := Output_Line + 1;
84
Last_Char_Was_Space := False;
87
----------------------
88
-- PP_Continue_Line --
89
----------------------
91
procedure PP_Continue_Line (Adjust_New_Line_Depth : Integer := 0) is
93
Saved_Last_KW := Last_KW;
94
Saved_Last_Dlm := Last_Dlm;
96
if Is_New_Output_Line then
98
PP_New_Continuation_Line (Adjust_New_Line_Depth);
99
Last_Char_Was_Space := True;
101
elsif not Last_Char_Was_Space and then
102
Output_Pos < Max_Line_Length
104
PP_Word_No_Move (" ");
105
Last_Char_Was_Space := True;
106
Postponed_Space := False;
109
Last_KW := Saved_Last_KW;
110
Last_Dlm := Saved_Last_Dlm;
111
end PP_Continue_Line;
113
--------------------------------
114
-- PP_Continue_Line_Postponed --
115
--------------------------------
117
procedure PP_Continue_Line_Postponed
118
(Adjust_New_Line_Depth : Integer := 0)
121
Saved_Last_KW := Last_KW;
122
Saved_Last_Dlm := Last_Dlm;
124
if Is_New_Output_Line then
126
(Adjust_Depth => Adjust_New_Line_Depth + 1,
128
Last_Char_Was_Space := True;
130
elsif not Last_Char_Was_Space and then
131
Output_Pos < Max_Line_Length
133
Postponed_Space := True;
136
Last_KW := Saved_Last_KW;
137
Last_Dlm := Saved_Last_Dlm;
138
end PP_Continue_Line_Postponed;
144
procedure PP_Delimiter (DL : Delimiter_Kinds) is
148
when Not_A_Dlm => null;
149
when Ampersand_Dlm => PP_Word ("&");
150
when Tick_Dlm => PP_Word ("'");
151
when Left_Parenthesis_Dlm => PP_Word ("(");
152
when Right_Parenthesis_Dlm => PP_Word (")");
153
when Asterisk_Dlm => PP_Word ("*");
154
when Plus_Dlm => PP_Word ("+");
155
when Comma_Dlm => PP_Word (",");
156
when Minus_Dlm => PP_Word ("-");
157
when Dot_Dlm => PP_Word (".");
158
when Divide_Dlm => PP_Word ("/");
159
when Colon_Dlm => PP_Word (":");
160
when Semicolon_Dlm => PP_Word (";");
161
when Less_Than_Dlm => PP_Word ("<");
162
when Equals_Dlm => PP_Word ("=");
163
when Greater_Than_Dlm => PP_Word (">");
164
when Vertical_Line_Dlm => PP_Word ("|");
165
when Exclamation_Mark_Dlm => PP_Word ("!");
166
when Arrow_Dlm => PP_Word ("=>");
167
when Double_Dot_Dlm => PP_Word ("..");
168
when Double_Star_Dlm => PP_Word ("**");
169
when Assignment_Dlm => PP_Word (":=");
170
when Inequality_Dlm => PP_Word ("/=");
171
when Greater_Or_Equal_Dlm => PP_Word (">=");
172
when Less_Or_Equal_Dlm => PP_Word ("<=");
173
when Left_Label_Bracket_Dlm => PP_Word ("<<");
174
when Right_Label_Bracket_Dlm => PP_Word (">>");
175
when Box_Dlm => PP_Word ("<>");
181
if DL /= Not_A_Dlm then
182
Last_Char_Was_Space := False;
191
procedure PP_Keyword (KW : Keyword_Kinds) is
192
function Adjust_KW_Case (Str : Program_Text) return Program_Text;
193
-- Converts the keyword casing according to the gnatpp settings
195
function Adjust_KW_Case (Str : Program_Text) return Program_Text is
196
Result : Program_Text := Str;
199
if GNATPP.Options.PP_Keyword_Casing = Upper_Case then
200
Result := To_Wide_String (To_Upper (To_String (Result)));
211
when Not_A_KW => null;
212
when KW_Abort => PP_Word (Adjust_KW_Case (Abort_String));
213
when KW_Abs => PP_Word (Adjust_KW_Case (Abs_String));
214
when KW_Abstract => PP_Word (Adjust_KW_Case (Abstract_String));
215
when KW_Accept => PP_Word (Adjust_KW_Case (Accept_String));
216
when KW_Access => PP_Word (Adjust_KW_Case (Access_String));
217
when KW_Aliased => PP_Word (Adjust_KW_Case (Aliased_String));
218
when KW_All => PP_Word (Adjust_KW_Case (All_String));
219
when KW_And => PP_Word (Adjust_KW_Case (And_String));
220
when KW_Array => PP_Word (Adjust_KW_Case (Array_String));
221
when KW_At => PP_Word (Adjust_KW_Case (At_String));
224
PP_Word (Adjust_KW_Case (Begin_String));
227
when KW_Body => PP_Word (Adjust_KW_Case (Body_String));
228
when KW_Case => PP_Word (Adjust_KW_Case (Case_String));
229
when KW_Constant => PP_Word (Adjust_KW_Case (Constant_String));
230
when KW_Declare => PP_Word (Adjust_KW_Case (Declare_String));
231
when KW_Delay => PP_Word (Adjust_KW_Case (Delay_String));
232
when KW_Delta => PP_Word (Adjust_KW_Case (Delta_String));
233
when KW_Digits => PP_Word (Adjust_KW_Case (Digits_String));
234
when KW_Do => PP_Word (Adjust_KW_Case (Do_String));
235
when KW_Else => PP_Word (Adjust_KW_Case (Else_String));
238
PP_Word (Adjust_KW_Case (Elsif_String));
239
Last_If_Path_Start := Current_Out_Line;
241
when KW_End => PP_Word (Adjust_KW_Case (End_String));
242
when KW_Entry => PP_Word (Adjust_KW_Case (Entry_String));
243
when KW_Exception => PP_Word (Adjust_KW_Case (Exception_String));
244
when KW_Exit => PP_Word (Adjust_KW_Case (Exit_String));
247
PP_Word (Adjust_KW_Case (For_String));
248
Last_Loop_Start := Current_Out_Line;
250
when KW_Function => PP_Word (Adjust_KW_Case (Function_String));
251
when KW_Generic => PP_Word (Adjust_KW_Case (Generic_String));
252
when KW_Goto => PP_Word (Adjust_KW_Case (Goto_String));
255
PP_Word (Adjust_KW_Case (If_String));
256
Last_If_Path_Start := Current_Out_Line;
258
when KW_In => PP_Word (Adjust_KW_Case (In_String));
259
when KW_Is => PP_Word (Adjust_KW_Case (KW_Is_String));
260
when KW_Limited => PP_Word (Adjust_KW_Case (Limited_String));
261
when KW_Loop => PP_Word (Adjust_KW_Case (Loop_String));
262
when KW_Mod => PP_Word (Adjust_KW_Case (Mod_String));
263
when KW_New => PP_Word (Adjust_KW_Case (New_String));
264
when KW_Not => PP_Word (Adjust_KW_Case (Not_String));
265
when KW_Null => PP_Word (Adjust_KW_Case (Null_String));
266
when KW_Of => PP_Word (Adjust_KW_Case (Of_String));
267
when KW_Or => PP_Word (Adjust_KW_Case (Or_String));
268
when KW_Others => PP_Word (Adjust_KW_Case (Others_String));
269
when KW_Out => PP_Word (Adjust_KW_Case (Out_String));
270
when KW_Package => PP_Word (Adjust_KW_Case (Package_String));
271
when KW_Pragma => PP_Word (Adjust_KW_Case (Pragma_String));
274
PP_Word (Adjust_KW_Case (Private_String));
277
when KW_Procedure => PP_Word (Adjust_KW_Case (Procedure_String));
278
when KW_Protected => PP_Word (Adjust_KW_Case (Protected_String));
279
when KW_Raise => PP_Word (Adjust_KW_Case (Raise_String));
280
when KW_Range => PP_Word (Adjust_KW_Case (Range_String));
281
when KW_Record => PP_Word (Adjust_KW_Case (Record_String));
282
when KW_Rem => PP_Word (Adjust_KW_Case (Rem_String));
283
when KW_Renames => PP_Word (Adjust_KW_Case (Renames_String));
284
when KW_Requeue => PP_Word (Adjust_KW_Case (Requeue_String));
285
when KW_Return => PP_Word (Adjust_KW_Case (Return_String));
286
when KW_Reverse => PP_Word (Adjust_KW_Case (Reverse_String));
287
when KW_Select => PP_Word (Adjust_KW_Case (Select_String));
288
when KW_Separate => PP_Word (Adjust_KW_Case (Separate_String));
289
when KW_Subtype => PP_Word (Adjust_KW_Case (Subtype_String));
290
when KW_Tagged => PP_Word (Adjust_KW_Case (Tagged_String));
291
when KW_Task => PP_Word (Adjust_KW_Case (Task_String));
292
when KW_Terminate => PP_Word (Adjust_KW_Case (Terminate_String));
293
when KW_Then => PP_Word (Adjust_KW_Case (Then_String));
296
PP_Word (Adjust_KW_Case (Type_String));
297
Last_Type_Start := Current_Out_Line;
299
when KW_Until => PP_Word (Adjust_KW_Case (Until_String));
300
when KW_Use => PP_Word (Adjust_KW_Case (Use_String));
301
when KW_When => PP_Word (Adjust_KW_Case (When_String));
304
PP_Word (Adjust_KW_Case (While_String));
305
Last_Loop_Start := Current_Out_Line;
307
when KW_With => PP_Word (Adjust_KW_Case (With_String));
308
when KW_Xor => PP_Word (Adjust_KW_Case (Xor_String));
312
Last_Dlm := Not_A_Dlm;
314
if KW /= Not_A_KW then
315
Last_Char_Was_Space := False;
320
------------------------------
321
-- PP_New_Continuation_Line --
322
------------------------------
324
procedure PP_New_Continuation_Line (Adjust_New_Line_Depth : Integer := 0) is
326
if not Is_New_Output_Line or else
329
PP_New_Line (Adjust_Depth => Adjust_New_Line_Depth);
330
PP_Pad (PP_Cont_Line_Indentation + 1);
331
Last_Char_Was_Space := True;
332
Postponed_Space := False;
334
end PP_New_Continuation_Line;
340
procedure PP_New_Line
341
(Adjust_Depth : Integer := 0;
342
Backspace : Natural := 0)
344
Actual_Indent : Natural;
347
if The_Very_First_Line then
348
The_Very_First_Line := False;
352
if not Is_New_Output_Line then
354
Last_Char_Was_Space := False;
357
Output_Pos := Integer (Col);
359
if Output_Pos = 1 then
361
(Logical_Depth + Adjust_Depth) * PP_Indentation - Backspace;
363
for J in 1 .. Actual_Indent loop
367
if Actual_Indent > 0 then
368
Last_Char_Was_Space := True;
373
Postponed_Space := False;
376
-------------------------
377
-- PP_New_Line_And_Pad --
378
-------------------------
380
procedure PP_New_Line_And_Pad (Up_To : Natural := 0) is
383
Last_Char_Was_Space := False;
385
if The_Very_First_Line then
386
The_Very_First_Line := False;
390
if not Is_New_Output_Line then
394
if Output_Pos = 1 then
398
end PP_New_Line_And_Pad;
400
-------------------------------
401
-- PP_New_Line_For_Index_Def --
402
-------------------------------
404
procedure PP_New_Line_For_Index_Def is
405
Up_To : constant Natural := (Logical_Depth + 1) * PP_Indentation + 6 + 1;
407
PP_New_Line_And_Pad (Up_To);
408
end PP_New_Line_For_Index_Def;
414
procedure PP_Operator (Op : Flat_Element_Kinds) is
417
Last_Dlm := Not_A_Dlm;
420
when A_Concatenate_Operator =>
422
Last_Dlm := Ampersand_Dlm;
424
when A_Multiply_Operator =>
426
Last_Dlm := Asterisk_Dlm;
428
when A_Unary_Plus_Operator |
431
Last_Dlm := Plus_Dlm;
433
when A_Unary_Minus_Operator |
436
Last_Dlm := Minus_Dlm;
438
when A_Divide_Operator =>
440
Last_Dlm := Divide_Dlm;
442
when A_Less_Than_Operator =>
444
Last_Dlm := Less_Than_Dlm;
446
when An_Equal_Operator =>
448
Last_Dlm := Equals_Dlm;
450
when A_Greater_Than_Operator =>
452
Last_Dlm := Greater_Than_Dlm;
454
when An_Exponentiate_Operator =>
456
Last_Dlm := Double_Star_Dlm;
458
when A_Not_Equal_Operator =>
460
Last_Dlm := Inequality_Dlm;
462
when A_Greater_Than_Or_Equal_Operator =>
464
Last_Dlm := Greater_Or_Equal_Dlm;
466
when A_Less_Than_Or_Equal_Operator =>
468
Last_Dlm := Less_Or_Equal_Dlm;
470
when An_And_Operator =>
473
when An_Or_Operator =>
476
when An_Xor_Operator =>
479
when A_Mod_Operator =>
482
when A_Rem_Operator =>
485
when An_Abs_Operator =>
488
when A_Not_Operator =>
495
if Op = A_Unary_Minus_Operator or else
496
Op = A_Unary_Plus_Operator
498
Unary_Adding_Op_Just_Printed := True;
500
Unary_Adding_Op_Just_Printed := False;
503
Last_Char_Was_Space := False;
511
procedure PP_Pad (N : Natural) is
518
Postponed_Space := False;
520
for J in 1 .. N - 1 loop
524
Output_Pos := Output_Pos + N - 1;
527
Last_Char_Was_Space := True;
536
procedure PP_Pad_Up_To (N : Natural) is
539
if N >= Output_Pos then
540
PP_Pad (N - Output_Pos + 1);
541
Last_Char_Was_Space := True;
546
------------------------
547
-- PP_Postponed_Space --
548
------------------------
550
procedure PP_Postponed_Space is
553
if Postponed_Space and then
554
not Last_Char_Was_Space
557
Postponed_Space := False;
560
end PP_Postponed_Space;
566
procedure PP_Space is
569
if Output_Pos < Max_Line_Length then
571
Output_Pos := Output_Pos + 1;
572
Last_Char_Was_Space := True;
577
------------------------
578
-- PP_Space_If_Needed --
579
------------------------
581
procedure PP_Space_If_Needed is
584
if not Last_Char_Was_Space then
588
end PP_Space_If_Needed;
594
procedure PP_Word (S : Program_Text) is
598
Line_Pos := Line_Pos + S'Length;
600
if Line_Pos > Line_Len then
605
Last_Dlm := Not_A_Dlm;
609
---------------------
610
-- PP_Word_No_Move --
611
---------------------
613
procedure PP_Word_No_Move (S : Program_Text) is
616
if S'Length > Available_In_Output then
617
Error ("the line is too long");
619
if not Is_New_Output_Line then
626
Output_Pos := Output_Pos + S'Length;
627
Is_New_Output_Line := False;
630
Last_Dlm := Not_A_Dlm;
632
Last_Char_Was_Space := False;
635
------------------------
636
-- Space_Just_Printed --
637
------------------------
639
function Space_Just_Printed return Boolean is
641
return Last_Char_Was_Space;
642
end Space_Just_Printed;
644
end GNATPP.PP_Output;