OSDN Git Service

2010-10-05 Ed Schonberg <schonberg@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / prj-pp.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                               P R J . P P                                --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 2001-2010, Free Software Foundation, Inc.         --
10 --                                                                          --
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.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
20 --                                                                          --
21 -- GNAT was originally developed  by the GNAT team at  New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
23 --                                                                          --
24 ------------------------------------------------------------------------------
25
26 with Ada.Characters.Handling; use Ada.Characters.Handling;
27
28 with Output;   use Output;
29 with Snames;
30
31 package body Prj.PP is
32
33    use Prj.Tree;
34
35    Not_Tested : array (Project_Node_Kind) of Boolean := (others => True);
36
37    procedure Indicate_Tested (Kind : Project_Node_Kind);
38    --  Set the corresponding component of array Not_Tested to False.
39    --  Only called by pragmas Debug.
40
41    ---------------------
42    -- Indicate_Tested --
43    ---------------------
44
45    procedure Indicate_Tested (Kind : Project_Node_Kind) is
46    begin
47       Not_Tested (Kind) := False;
48    end Indicate_Tested;
49
50    ------------------
51    -- Pretty_Print --
52    ------------------
53
54    procedure Pretty_Print
55      (Project                            : Prj.Tree.Project_Node_Id;
56       In_Tree                            : Prj.Tree.Project_Node_Tree_Ref;
57       Increment                          : Positive       := 3;
58       Eliminate_Empty_Case_Constructions : Boolean        := False;
59       Minimize_Empty_Lines               : Boolean        := False;
60       W_Char                             : Write_Char_Ap  := null;
61       W_Eol                              : Write_Eol_Ap   := null;
62       W_Str                              : Write_Str_Ap   := null;
63       Backward_Compatibility             : Boolean;
64       Id                                 : Prj.Project_Id := Prj.No_Project;
65       Max_Line_Length                    : Max_Length_Of_Line :=
66                                              Max_Length_Of_Line'Last)
67    is
68       procedure Print (Node : Project_Node_Id; Indent : Natural);
69       --  A recursive procedure that traverses a project file tree and outputs
70       --  its source. Current_Prj is the project that we are printing. This
71       --  is used when printing attributes, since in nested packages they
72       --  need to use a fully qualified name.
73
74       procedure Output_Attribute_Name (Name : Name_Id; Indent : Natural);
75       --  Outputs an attribute name, taking into account the value of
76       --  Backward_Compatibility.
77
78       procedure Output_Name
79         (Name       : Name_Id;
80          Indent     : Natural;
81          Capitalize : Boolean := True);
82       --  Outputs a name
83
84       procedure Start_Line (Indent : Natural);
85       --  Outputs the indentation at the beginning of the line
86
87       procedure Output_String (S : Name_Id; Indent : Natural);
88       procedure Output_String (S : Path_Name_Type; Indent : Natural);
89       --  Outputs a string using the default output procedures
90
91       procedure Write_Empty_Line (Always : Boolean := False);
92       --  Outputs an empty line, only if the previous line was not empty
93       --  already and either Always is True or Minimize_Empty_Lines is
94       --  False.
95
96       procedure Write_Line (S : String);
97       --  Outputs S followed by a new line
98
99       procedure Write_String
100         (S         : String;
101          Indent    : Natural;
102          Truncated : Boolean := False);
103       --  Outputs S using Write_Str, starting a new line if line would
104       --  become too long, when Truncated = False.
105       --  When Truncated = True, only the part of the string that can fit on
106       --  the line is output.
107
108       procedure Write_End_Of_Line_Comment (Node : Project_Node_Id);
109
110       Write_Char : Write_Char_Ap := Output.Write_Char'Access;
111       Write_Eol  : Write_Eol_Ap := Output.Write_Eol'Access;
112       Write_Str  : Write_Str_Ap := Output.Write_Str'Access;
113       --  These three access to procedure values are used for the output
114
115       Last_Line_Is_Empty : Boolean := False;
116       --  Used to avoid two consecutive empty lines
117
118       Column : Natural := 0;
119       --  Column number of the last character in the line. Used to avoid
120       --  outputting lines longer than Max_Line_Length.
121
122       First_With_In_List : Boolean := True;
123       --  Indicate that the next with clause is first in a list such as
124       --    with "A", "B";
125       --  First_With_In_List will be True for "A", but not for "B".
126
127       ---------------------------
128       -- Output_Attribute_Name --
129       ---------------------------
130
131       procedure Output_Attribute_Name (Name : Name_Id; Indent : Natural) is
132       begin
133          if Backward_Compatibility then
134             case Name is
135                when Snames.Name_Spec =>
136                   Output_Name (Snames.Name_Specification, Indent);
137
138                when Snames.Name_Spec_Suffix =>
139                   Output_Name (Snames.Name_Specification_Suffix, Indent);
140
141                when Snames.Name_Body =>
142                   Output_Name (Snames.Name_Implementation, Indent);
143
144                when Snames.Name_Body_Suffix =>
145                   Output_Name (Snames.Name_Implementation_Suffix, Indent);
146
147                when others =>
148                   Output_Name (Name, Indent);
149             end case;
150
151          else
152             Output_Name (Name, Indent);
153          end if;
154       end Output_Attribute_Name;
155
156       -----------------
157       -- Output_Name --
158       -----------------
159
160       procedure Output_Name
161         (Name       : Name_Id;
162          Indent     : Natural;
163          Capitalize : Boolean := True)
164       is
165          Capital : Boolean := Capitalize;
166
167       begin
168          if Column = 0 and then Indent /= 0 then
169             Start_Line (Indent + Increment);
170          end if;
171
172          Get_Name_String (Name);
173
174          --  If line would become too long, create new line
175
176          if Column + Name_Len > Max_Line_Length then
177             Write_Eol.all;
178             Column := 0;
179
180             if Indent /= 0 then
181                Start_Line (Indent + Increment);
182             end if;
183          end if;
184
185          for J in 1 .. Name_Len loop
186             if Capital then
187                Write_Char (To_Upper (Name_Buffer (J)));
188             else
189                Write_Char (Name_Buffer (J));
190             end if;
191
192             if Capitalize then
193                Capital :=
194                  Name_Buffer (J) = '_'
195                  or else Is_Digit (Name_Buffer (J));
196             end if;
197          end loop;
198
199          Column := Column + Name_Len;
200       end Output_Name;
201
202       -------------------
203       -- Output_String --
204       -------------------
205
206       procedure Output_String (S : Name_Id; Indent : Natural) is
207       begin
208          if Column = 0 and then Indent /= 0 then
209             Start_Line (Indent + Increment);
210          end if;
211
212          Get_Name_String (S);
213
214          --  If line could become too long, create new line. Note that the
215          --  number of characters on the line could be twice the number of
216          --  character in the string (if every character is a '"') plus two
217          --  (the initial and final '"').
218
219          if Column + Name_Len + Name_Len + 2 > Max_Line_Length then
220             Write_Eol.all;
221             Column := 0;
222
223             if Indent /= 0 then
224                Start_Line (Indent + Increment);
225             end if;
226          end if;
227
228          Write_Char ('"');
229          Column := Column + 1;
230          Get_Name_String (S);
231
232          for J in 1 .. Name_Len loop
233             if Name_Buffer (J) = '"' then
234                Write_Char ('"');
235                Write_Char ('"');
236                Column := Column + 2;
237             else
238                Write_Char (Name_Buffer (J));
239                Column := Column + 1;
240             end if;
241
242             --  If the string does not fit on one line, cut it in parts and
243             --  concatenate.
244
245             if J < Name_Len and then Column >= Max_Line_Length then
246                Write_Str (""" &");
247                Write_Eol.all;
248                Column := 0;
249                Start_Line (Indent + Increment);
250                Write_Char ('"');
251                Column := Column + 1;
252             end if;
253          end loop;
254
255          Write_Char ('"');
256          Column := Column + 1;
257       end Output_String;
258
259       procedure Output_String (S : Path_Name_Type; Indent : Natural) is
260       begin
261          Output_String (Name_Id (S), Indent);
262       end Output_String;
263
264       ----------------
265       -- Start_Line --
266       ----------------
267
268       procedure Start_Line (Indent : Natural) is
269       begin
270          if not Minimize_Empty_Lines then
271             Write_Str ((1 .. Indent => ' '));
272             Column := Column + Indent;
273          end if;
274       end Start_Line;
275
276       ----------------------
277       -- Write_Empty_Line --
278       ----------------------
279
280       procedure Write_Empty_Line (Always : Boolean := False) is
281       begin
282          if (Always or else not Minimize_Empty_Lines)
283            and then not Last_Line_Is_Empty then
284             Write_Eol.all;
285             Column := 0;
286             Last_Line_Is_Empty := True;
287          end if;
288       end Write_Empty_Line;
289
290       -------------------------------
291       -- Write_End_Of_Line_Comment --
292       -------------------------------
293
294       procedure Write_End_Of_Line_Comment (Node : Project_Node_Id) is
295          Value : constant Name_Id := End_Of_Line_Comment (Node, In_Tree);
296
297       begin
298          if Value /= No_Name then
299             Write_String (" --", 0);
300             Write_String (Get_Name_String (Value), 0, Truncated => True);
301          end if;
302
303          Write_Line ("");
304       end Write_End_Of_Line_Comment;
305
306       ----------------
307       -- Write_Line --
308       ----------------
309
310       procedure Write_Line (S : String) is
311       begin
312          Write_String (S, 0);
313          Last_Line_Is_Empty := False;
314          Write_Eol.all;
315          Column := 0;
316       end Write_Line;
317
318       ------------------
319       -- Write_String --
320       ------------------
321
322       procedure Write_String
323         (S         : String;
324          Indent    : Natural;
325          Truncated : Boolean := False) is
326          Length : Natural := S'Length;
327       begin
328          if Column = 0 and then Indent /= 0 then
329             Start_Line (Indent + Increment);
330          end if;
331
332          --  If the string would not fit on the line,
333          --  start a new line.
334
335          if Column + Length > Max_Line_Length then
336             if Truncated then
337                Length := Max_Line_Length - Column;
338
339             else
340                Write_Eol.all;
341                Column := 0;
342
343                if Indent /= 0 then
344                   Start_Line (Indent + Increment);
345                end if;
346             end if;
347          end if;
348
349          Write_Str (S (S'First .. S'First + Length - 1));
350          Column := Column + Length;
351       end Write_String;
352
353       -----------
354       -- Print --
355       -----------
356
357       procedure Print (Node : Project_Node_Id; Indent : Natural) is
358       begin
359          if Present (Node) then
360
361             case Kind_Of (Node, In_Tree) is
362
363                when N_Project  =>
364                   pragma Debug (Indicate_Tested (N_Project));
365                   if Present (First_With_Clause_Of (Node, In_Tree)) then
366
367                      --  with clause(s)
368
369                      First_With_In_List := True;
370                      Print (First_With_Clause_Of (Node, In_Tree), Indent);
371                      Write_Empty_Line (Always => True);
372                   end if;
373
374                   Print (First_Comment_Before (Node, In_Tree), Indent);
375                   Start_Line (Indent);
376                   Write_String ("project ", Indent);
377
378                   if Id /= Prj.No_Project then
379                      Output_Name (Id.Display_Name, Indent);
380                   else
381                      Output_Name (Name_Of (Node, In_Tree), Indent);
382                   end if;
383
384                   --  Check if this project extends another project
385
386                   if Extended_Project_Path_Of (Node, In_Tree) /= No_Path then
387                      Write_String (" extends ", Indent);
388
389                      if Is_Extending_All (Node, In_Tree) then
390                         Write_String ("all ", Indent);
391                      end if;
392
393                      Output_String
394                        (Extended_Project_Path_Of (Node, In_Tree),
395                         Indent);
396                   end if;
397
398                   Write_String (" is", Indent);
399                   Write_End_Of_Line_Comment (Node);
400                   Print
401                     (First_Comment_After (Node, In_Tree), Indent + Increment);
402                   Write_Empty_Line (Always => True);
403
404                   --  Output all of the declarations in the project
405
406                   Print (Project_Declaration_Of (Node, In_Tree), Indent);
407                   Print
408                     (First_Comment_Before_End (Node, In_Tree),
409                      Indent + Increment);
410                   Start_Line (Indent);
411                   Write_String ("end ", Indent);
412
413                   if Id /= Prj.No_Project then
414                      Output_Name (Id.Display_Name, Indent);
415                   else
416                      Output_Name (Name_Of (Node, In_Tree), Indent);
417                   end if;
418
419                   Write_Line (";");
420                   Print (First_Comment_After_End (Node, In_Tree), Indent);
421
422                when N_With_Clause =>
423                   pragma Debug (Indicate_Tested (N_With_Clause));
424
425                   --  The with clause will sometimes contain an invalid name
426                   --  when we are importing a virtual project from an
427                   --  extending all project. Do not output anything in this
428                   --  case
429
430                   if Name_Of (Node, In_Tree) /= No_Name
431                     and then String_Value_Of (Node, In_Tree) /= No_Name
432                   then
433                      if First_With_In_List then
434                         Print (First_Comment_Before (Node, In_Tree), Indent);
435                         Start_Line (Indent);
436
437                         if Non_Limited_Project_Node_Of (Node, In_Tree) =
438                              Empty_Node
439                         then
440                            Write_String ("limited ", Indent);
441                         end if;
442
443                         Write_String ("with ", Indent);
444                      end if;
445
446                      Output_String (String_Value_Of (Node, In_Tree), Indent);
447
448                      if Is_Not_Last_In_List (Node, In_Tree) then
449                         Write_String (", ", Indent);
450                         First_With_In_List := False;
451
452                      else
453                         Write_String (";", Indent);
454                         Write_End_Of_Line_Comment (Node);
455                         Print (First_Comment_After (Node, In_Tree), Indent);
456                         First_With_In_List := True;
457                      end if;
458                   end if;
459
460                   Print (Next_With_Clause_Of (Node, In_Tree), Indent);
461
462                when N_Project_Declaration =>
463                   pragma Debug (Indicate_Tested (N_Project_Declaration));
464
465                   if
466                     Present (First_Declarative_Item_Of (Node, In_Tree))
467                   then
468                      Print
469                        (First_Declarative_Item_Of (Node, In_Tree),
470                         Indent + Increment);
471                      Write_Empty_Line (Always => True);
472                   end if;
473
474                when N_Declarative_Item =>
475                   pragma Debug (Indicate_Tested (N_Declarative_Item));
476                   Print (Current_Item_Node (Node, In_Tree), Indent);
477                   Print (Next_Declarative_Item (Node, In_Tree), Indent);
478
479                when N_Package_Declaration =>
480                   pragma Debug (Indicate_Tested (N_Package_Declaration));
481                   Write_Empty_Line (Always => True);
482                   Print (First_Comment_Before (Node, In_Tree), Indent);
483                   Start_Line (Indent);
484                   Write_String ("package ", Indent);
485                   Output_Name (Name_Of (Node, In_Tree), Indent);
486
487                   if Project_Of_Renamed_Package_Of (Node, In_Tree) /=
488                        Empty_Node
489                   then
490                      Write_String (" renames ", Indent);
491                      Output_Name
492                        (Name_Of
493                           (Project_Of_Renamed_Package_Of (Node, In_Tree),
494                            In_Tree),
495                         Indent);
496                      Write_String (".", Indent);
497                      Output_Name (Name_Of (Node, In_Tree), Indent);
498                      Write_String (";", Indent);
499                      Write_End_Of_Line_Comment (Node);
500                      Print (First_Comment_After_End (Node, In_Tree), Indent);
501
502                   else
503                      Write_String (" is", Indent);
504                      Write_End_Of_Line_Comment (Node);
505                      Print (First_Comment_After (Node, In_Tree),
506                             Indent + Increment);
507
508                      if First_Declarative_Item_Of (Node, In_Tree) /=
509                           Empty_Node
510                      then
511                         Print
512                           (First_Declarative_Item_Of (Node, In_Tree),
513                            Indent + Increment);
514                      end if;
515
516                      Print (First_Comment_Before_End (Node, In_Tree),
517                             Indent + Increment);
518                      Start_Line (Indent);
519                      Write_String ("end ", Indent);
520                      Output_Name (Name_Of (Node, In_Tree), Indent);
521                      Write_Line (";");
522                      Print (First_Comment_After_End (Node, In_Tree), Indent);
523                      Write_Empty_Line;
524                   end if;
525
526                when N_String_Type_Declaration =>
527                   pragma Debug (Indicate_Tested (N_String_Type_Declaration));
528                   Print (First_Comment_Before (Node, In_Tree), Indent);
529                   Start_Line (Indent);
530                   Write_String ("type ", Indent);
531                   Output_Name (Name_Of (Node, In_Tree), Indent);
532                   Write_Line (" is");
533                   Start_Line (Indent + Increment);
534                   Write_String ("(", Indent);
535
536                   declare
537                      String_Node : Project_Node_Id :=
538                        First_Literal_String (Node, In_Tree);
539
540                   begin
541                      while Present (String_Node) loop
542                         Output_String
543                           (String_Value_Of (String_Node, In_Tree),
544                            Indent);
545                         String_Node :=
546                           Next_Literal_String (String_Node, In_Tree);
547
548                         if Present (String_Node) then
549                            Write_String (", ", Indent);
550                         end if;
551                      end loop;
552                   end;
553
554                   Write_String (");", Indent);
555                   Write_End_Of_Line_Comment (Node);
556                   Print (First_Comment_After (Node, In_Tree), Indent);
557
558                when N_Literal_String =>
559                   pragma Debug (Indicate_Tested (N_Literal_String));
560                   Output_String (String_Value_Of (Node, In_Tree), Indent);
561
562                   if Source_Index_Of (Node, In_Tree) /= 0 then
563                      Write_String (" at", Indent);
564                      Write_String
565                        (Source_Index_Of (Node, In_Tree)'Img,
566                         Indent);
567                   end if;
568
569                when N_Attribute_Declaration =>
570                   pragma Debug (Indicate_Tested (N_Attribute_Declaration));
571                   Print (First_Comment_Before (Node, In_Tree), Indent);
572                   Start_Line (Indent);
573                   Write_String ("for ", Indent);
574                   Output_Attribute_Name (Name_Of (Node, In_Tree), Indent);
575
576                   if Associative_Array_Index_Of (Node, In_Tree) /= No_Name then
577                      Write_String (" (", Indent);
578                      Output_String
579                        (Associative_Array_Index_Of (Node, In_Tree),
580                         Indent);
581
582                      if Source_Index_Of (Node, In_Tree) /= 0 then
583                         Write_String (" at", Indent);
584                         Write_String
585                           (Source_Index_Of (Node, In_Tree)'Img,
586                            Indent);
587                      end if;
588
589                      Write_String (")", Indent);
590                   end if;
591
592                   Write_String (" use ", Indent);
593
594                   if Present (Expression_Of (Node, In_Tree)) then
595                      Print (Expression_Of (Node, In_Tree), Indent);
596
597                   else
598                      --  Full associative array declaration
599
600                      if
601                        Present (Associative_Project_Of (Node, In_Tree))
602                      then
603                         Output_Name
604                           (Name_Of
605                              (Associative_Project_Of (Node, In_Tree),
606                               In_Tree),
607                            Indent);
608
609                         if
610                           Present (Associative_Package_Of (Node, In_Tree))
611                         then
612                            Write_String (".", Indent);
613                            Output_Name
614                              (Name_Of
615                                 (Associative_Package_Of (Node, In_Tree),
616                                  In_Tree),
617                               Indent);
618                         end if;
619
620                      elsif
621                        Present (Associative_Package_Of (Node, In_Tree))
622                      then
623                         Output_Name
624                           (Name_Of
625                              (Associative_Package_Of (Node, In_Tree),
626                               In_Tree),
627                            Indent);
628                      end if;
629
630                      Write_String ("'", Indent);
631                      Output_Attribute_Name (Name_Of (Node, In_Tree), Indent);
632                   end if;
633
634                   Write_String (";", Indent);
635                   Write_End_Of_Line_Comment (Node);
636                   Print (First_Comment_After (Node, In_Tree), Indent);
637
638                when N_Typed_Variable_Declaration =>
639                   pragma Debug
640                     (Indicate_Tested (N_Typed_Variable_Declaration));
641                   Print (First_Comment_Before (Node, In_Tree), Indent);
642                   Start_Line (Indent);
643                   Output_Name (Name_Of (Node, In_Tree), Indent);
644                   Write_String (" : ", Indent);
645                   Output_Name
646                     (Name_Of (String_Type_Of (Node, In_Tree), In_Tree),
647                      Indent);
648                   Write_String (" := ", Indent);
649                   Print (Expression_Of (Node, In_Tree), Indent);
650                   Write_String (";", Indent);
651                   Write_End_Of_Line_Comment (Node);
652                   Print (First_Comment_After (Node, In_Tree), Indent);
653
654                when N_Variable_Declaration =>
655                   pragma Debug (Indicate_Tested (N_Variable_Declaration));
656                   Print (First_Comment_Before (Node, In_Tree), Indent);
657                   Start_Line (Indent);
658                   Output_Name (Name_Of (Node, In_Tree), Indent);
659                   Write_String (" := ", Indent);
660                   Print (Expression_Of (Node, In_Tree), Indent);
661                   Write_String (";", Indent);
662                   Write_End_Of_Line_Comment (Node);
663                   Print (First_Comment_After (Node, In_Tree), Indent);
664
665                when N_Expression =>
666                   pragma Debug (Indicate_Tested (N_Expression));
667                   declare
668                      Term : Project_Node_Id := First_Term (Node, In_Tree);
669
670                   begin
671                      while Present (Term) loop
672                         Print (Term, Indent);
673                         Term := Next_Term (Term, In_Tree);
674
675                         if Present (Term) then
676                            Write_String (" & ", Indent);
677                         end if;
678                      end loop;
679                   end;
680
681                when N_Term =>
682                   pragma Debug (Indicate_Tested (N_Term));
683                   Print (Current_Term (Node, In_Tree), Indent);
684
685                when N_Literal_String_List =>
686                   pragma Debug (Indicate_Tested (N_Literal_String_List));
687                   Write_String ("(", Indent);
688
689                   declare
690                      Expression : Project_Node_Id :=
691                        First_Expression_In_List (Node, In_Tree);
692
693                   begin
694                      while Present (Expression) loop
695                         Print (Expression, Indent);
696                         Expression :=
697                           Next_Expression_In_List (Expression, In_Tree);
698
699                         if Present (Expression) then
700                            Write_String (", ", Indent);
701                         end if;
702                      end loop;
703                   end;
704
705                   Write_String (")", Indent);
706
707                when N_Variable_Reference =>
708                   pragma Debug (Indicate_Tested (N_Variable_Reference));
709                   if Present (Project_Node_Of (Node, In_Tree)) then
710                      Output_Name
711                        (Name_Of (Project_Node_Of (Node, In_Tree), In_Tree),
712                         Indent);
713                      Write_String (".", Indent);
714                   end if;
715
716                   if Present (Package_Node_Of (Node, In_Tree)) then
717                      Output_Name
718                        (Name_Of (Package_Node_Of (Node, In_Tree), In_Tree),
719                         Indent);
720                      Write_String (".", Indent);
721                   end if;
722
723                   Output_Name (Name_Of (Node, In_Tree), Indent);
724
725                when N_External_Value =>
726                   pragma Debug (Indicate_Tested (N_External_Value));
727                   Write_String ("external (", Indent);
728                   Print (External_Reference_Of (Node, In_Tree), Indent);
729
730                   if Present (External_Default_Of (Node, In_Tree)) then
731                      Write_String (", ", Indent);
732                      Print (External_Default_Of (Node, In_Tree), Indent);
733                   end if;
734
735                   Write_String (")", Indent);
736
737                when N_Attribute_Reference =>
738                   pragma Debug (Indicate_Tested (N_Attribute_Reference));
739
740                   if Present (Project_Node_Of (Node, In_Tree))
741                     and then Project_Node_Of (Node, In_Tree) /= Project
742                   then
743                      Output_Name
744                        (Name_Of (Project_Node_Of (Node, In_Tree), In_Tree),
745                         Indent);
746
747                      if Present (Package_Node_Of (Node, In_Tree)) then
748                         Write_String (".", Indent);
749                         Output_Name
750                           (Name_Of (Package_Node_Of (Node, In_Tree), In_Tree),
751                            Indent);
752                      end if;
753
754                   elsif Present (Package_Node_Of (Node, In_Tree)) then
755                      Output_Name
756                        (Name_Of (Package_Node_Of (Node, In_Tree), In_Tree),
757                         Indent);
758
759                   else
760                      Write_String ("project", Indent);
761                   end if;
762
763                   Write_String ("'", Indent);
764                   Output_Attribute_Name (Name_Of (Node, In_Tree), Indent);
765
766                   declare
767                      Index : constant Name_Id :=
768                                Associative_Array_Index_Of (Node, In_Tree);
769
770                   begin
771                      if Index /= No_Name then
772                         Write_String (" (", Indent);
773                         Output_String (Index, Indent);
774                         Write_String (")", Indent);
775                      end if;
776                   end;
777
778                when N_Case_Construction =>
779                   pragma Debug (Indicate_Tested (N_Case_Construction));
780
781                   declare
782                      Case_Item    : Project_Node_Id;
783                      Is_Non_Empty : Boolean := False;
784
785                   begin
786                      Case_Item := First_Case_Item_Of (Node, In_Tree);
787                      while Present (Case_Item) loop
788                         if Present
789                             (First_Declarative_Item_Of (Case_Item, In_Tree))
790                            or else not Eliminate_Empty_Case_Constructions
791                         then
792                            Is_Non_Empty := True;
793                            exit;
794                         end if;
795
796                         Case_Item := Next_Case_Item (Case_Item, In_Tree);
797                      end loop;
798
799                      if Is_Non_Empty then
800                         Write_Empty_Line;
801                         Print (First_Comment_Before (Node, In_Tree), Indent);
802                         Start_Line (Indent);
803                         Write_String ("case ", Indent);
804                         Print
805                           (Case_Variable_Reference_Of (Node, In_Tree),
806                            Indent);
807                         Write_String (" is", Indent);
808                         Write_End_Of_Line_Comment (Node);
809                         Print
810                           (First_Comment_After (Node, In_Tree),
811                            Indent + Increment);
812
813                         declare
814                            Case_Item : Project_Node_Id :=
815                                          First_Case_Item_Of (Node, In_Tree);
816                         begin
817                            while Present (Case_Item) loop
818                               pragma Assert
819                                 (Kind_Of (Case_Item, In_Tree) = N_Case_Item);
820                               Print (Case_Item, Indent + Increment);
821                               Case_Item :=
822                                 Next_Case_Item (Case_Item, In_Tree);
823                            end loop;
824                         end;
825
826                         Print (First_Comment_Before_End (Node, In_Tree),
827                                Indent + Increment);
828                         Start_Line (Indent);
829                         Write_Line ("end case;");
830                         Print
831                           (First_Comment_After_End (Node, In_Tree), Indent);
832                      end if;
833                   end;
834
835                when N_Case_Item =>
836                   pragma Debug (Indicate_Tested (N_Case_Item));
837
838                   if Present (First_Declarative_Item_Of (Node, In_Tree))
839                     or else not Eliminate_Empty_Case_Constructions
840                   then
841                      Write_Empty_Line;
842                      Print (First_Comment_Before (Node, In_Tree), Indent);
843                      Start_Line (Indent);
844                      Write_String ("when ", Indent);
845
846                      if No (First_Choice_Of (Node, In_Tree)) then
847                         Write_String ("others", Indent);
848
849                      else
850                         declare
851                            Label : Project_Node_Id :=
852                                      First_Choice_Of (Node, In_Tree);
853                         begin
854                            while Present (Label) loop
855                               Print (Label, Indent);
856                               Label := Next_Literal_String (Label, In_Tree);
857
858                               if Present (Label) then
859                                  Write_String (" | ", Indent);
860                               end if;
861                            end loop;
862                         end;
863                      end if;
864
865                      Write_String (" =>", Indent);
866                      Write_End_Of_Line_Comment (Node);
867                      Print
868                        (First_Comment_After (Node, In_Tree),
869                         Indent + Increment);
870
871                      declare
872                         First : constant Project_Node_Id :=
873                                   First_Declarative_Item_Of (Node, In_Tree);
874                      begin
875                         if No (First) then
876                            Write_Empty_Line;
877                         else
878                            Print (First, Indent + Increment);
879                         end if;
880                      end;
881                   end if;
882
883                when N_Comment_Zones =>
884
885                --  Nothing to do, because it will not be processed directly
886
887                   null;
888
889                when N_Comment =>
890                   pragma Debug (Indicate_Tested (N_Comment));
891
892                   if Follows_Empty_Line (Node, In_Tree) then
893                      Write_Empty_Line;
894                   end if;
895
896                   Start_Line (Indent);
897                   Write_String ("--", Indent);
898                   Write_String
899                     (Get_Name_String (String_Value_Of (Node, In_Tree)),
900                      Indent,
901                      Truncated => True);
902                   Write_Line ("");
903
904                   if Is_Followed_By_Empty_Line (Node, In_Tree) then
905                      Write_Empty_Line;
906                   end if;
907
908                   Print (Next_Comment (Node, In_Tree), Indent);
909             end case;
910          end if;
911       end Print;
912
913    --  Start of processing for Pretty_Print
914
915    begin
916       if W_Char = null then
917          Write_Char := Output.Write_Char'Access;
918       else
919          Write_Char := W_Char;
920       end if;
921
922       if W_Eol = null then
923          Write_Eol := Output.Write_Eol'Access;
924       else
925          Write_Eol := W_Eol;
926       end if;
927
928       if W_Str = null then
929          Write_Str := Output.Write_Str'Access;
930       else
931          Write_Str := W_Str;
932       end if;
933
934       Print (Project, 0);
935
936       if W_Char = null or else W_Str = null then
937          Output.Write_Eol;
938       end if;
939    end Pretty_Print;
940
941    -----------------------
942    -- Output_Statistics --
943    -----------------------
944
945    procedure Output_Statistics is
946    begin
947       Output.Write_Line ("Project_Node_Kinds not tested:");
948
949       for Kind in Project_Node_Kind loop
950          if Kind /= N_Comment_Zones and then Not_Tested (Kind) then
951             Output.Write_Str ("   ");
952             Output.Write_Line (Project_Node_Kind'Image (Kind));
953          end if;
954       end loop;
955
956       Output.Write_Eol;
957    end Output_Statistics;
958
959 end Prj.PP;