OSDN Git Service

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