@@ -383,7 +383,7 @@ package body METRICS.Actions is
383383 function Fine_Kind_String_For_Header (M : Metrix) return String;
384384 -- Name of the node kind for printing in both XML and text
385385
386- procedure Write_XML_Schema (Xsd_File_Name : String );
386+ procedure Write_Xsd (Xsd_Virtual_File : GNATCOLL.VFS.Virtual_File );
387387 -- Write the XSD file
388388
389389 function XML (X : String) return String;
@@ -1985,16 +1985,26 @@ package body METRICS.Actions is
19851985 Free (M);
19861986 end Destroy ;
19871987
1988- -- --------------------
1989- -- Write_XML_Schema --
1990- -- --------------------
1988+ -- -------------
1989+ -- Write_Xsd --
1990+ -- -------------
1991+
1992+ procedure Write_Xsd (Xsd_Virtual_File : GNATCOLL.VFS.Virtual_File) is
1993+ use GNATCOLL.VFS;
1994+
1995+ Xsd_File : Ada.Text_IO.File_Type;
19911996
1992- procedure Write_XML_Schema (Xsd_File_Name : String) is
1993- XSD_Out_File : Text_IO.File_Type;
19941997 begin
1998+ Xsd_Virtual_File.Normalize_Path;
1999+
19952000 if not Output_To_Standard_Output then
1996- Text_IO.Create (XSD_Out_File, Name => Xsd_File_Name);
1997- Text_IO.Set_Output (XSD_Out_File);
2001+ if Xsd_Virtual_File.Get_Parent /= No_File then
2002+ Make_Dir (Xsd_Virtual_File.Get_Parent);
2003+ end if ;
2004+
2005+ Ada.Text_IO.Create
2006+ (Xsd_File, Name => Xsd_Virtual_File.Display_Full_Name);
2007+ Ada.Text_IO.Set_Output (Xsd_File);
19982008 end if ;
19992009
20002010 pragma Style_Checks (" M200" ); -- Allow long lines
@@ -2065,10 +2075,10 @@ package body METRICS.Actions is
20652075 pragma Style_Checks (" M79" );
20662076
20672077 if not Output_To_Standard_Output then
2068- Text_IO.Set_Output (Text_IO.Standard_Output);
2069- Text_IO.Close (XSD_Out_File );
2078+ Ada. Text_IO.Set_Output (Ada. Text_IO.Standard_Output);
2079+ Ada. Text_IO.Close (Xsd_File );
20702080 end if ;
2071- end Write_XML_Schema ;
2081+ end Write_Xsd ;
20722082
20732083 -- --------
20742084 -- Init --
@@ -2576,7 +2586,13 @@ package body METRICS.Actions is
25762586 Outdent;
25772587 end XML_Print_Coupling ;
25782588
2589+ -- ---------
2590+ -- Final --
2591+ -- ---------
2592+
25792593 procedure Final (Tool : in out Metrics_Tool; Cmd : Command_Line) is
2594+ use type GNATCOLL.VFS.Virtual_File;
2595+
25802596 Metrics_To_Compute : Metrics_Set renames Tool.Metrics_To_Compute;
25812597 Without_Coupling : constant Metrics_Set :=
25822598 Metrics_To_Compute and not Coupling_Only;
@@ -2593,66 +2609,110 @@ package body METRICS.Actions is
25932609 -- switch was given. By default, this information is sent to standard
25942610 -- output.
25952611
2596- function Get_Object_Dir return String;
2597- -- Name of the Object_Dir specified in the project file, if any
2612+ function Get_Object_Directory return GNATCOLL.VFS.Virtual_File;
2613+ -- Object_Dir specified in the project file.
2614+ -- Returns GNATCOLL.VFS.No_File is not specified.
2615+
2616+ function Get_Xml_Virtual_File
2617+ (Object_Directory : GNATCOLL.VFS.Virtual_File)
2618+ return GNATCOLL.VFS.Virtual_File;
2619+ -- If the user supplies a full or relative file path, it is used
2620+ -- directly.
2621+ -- If the user provides only a filename (e.g., "data.xml"), it is
2622+ -- resolved relative to the object directory (if one is configured).
2623+ -- If no user-provided path or filename is given, the default
2624+ -- "metrix.xml" is used, also resolved relative to the object directory
2625+ -- (if configured).
2626+
2627+ function Get_Xsd_Virtual_File
2628+ (Xml_Virtual_File : GNATCOLL.VFS.Virtual_File)
2629+ return GNATCOLL.VFS.Virtual_File;
2630+ -- Return the GNATCOLL.VFS.Virtual_File of the XSD (schema) file name,
2631+ -- which is based on the XML file name. In particular if the XML file
2632+ -- name ends in ".xml", that is replaced by ".xsd"; otherwise,
2633+ -- ".xsd" is appended. So "foo.xml" --> "foo.xsd", but
2634+ -- "foo.bar" --> "foo.bar.xsd".
2635+ --
2636+ -- Note that this name is written to the XML file, in addition
2637+ -- to being used to open the XSD file.
25982638
2599- function Get_Object_Dir return String is
2639+ -- ------------------------
2640+ -- Get_Object_Directory --
2641+ -- ------------------------
2642+
2643+ function Get_Object_Directory return GNATCOLL.VFS.Virtual_File is
26002644 use GNATCOLL.Projects, GNATCOLL.VFS;
2645+
26012646 begin
26022647 if Status (Tool.Project_Tree.all ) = Empty then
2603- return " " ;
2648+ return No_File;
2649+
26042650 else
2605- declare
2606- Prj : constant Project_Type := Tool.Project_Tree.Root_Project;
2607- Name : constant Filesystem_String :=
2608- Full_Name (Object_Dir (Prj));
2609- begin
2610- return String (Name);
2611- end ;
2651+ return Object_Dir (Tool.Project_Tree.Root_Project);
26122652 end if ;
2613- end Get_Object_Dir ;
2614-
2615- Object_Dir : constant String := Get_Object_Dir;
2653+ end Get_Object_Directory ;
26162654
2617- Xml_F_Name : constant String :=
2618- (if Arg (Cmd, Xml_File_Name) = null
2619- then " metrix.xml"
2620- else Arg (Cmd, Xml_File_Name).all );
2621- -- ASIS-based gnatmetric ignores Output_Dir for the xml.
2655+ -- ------------------------
2656+ -- Get_Xml_Virtual_File --
2657+ -- ------------------------
26222658
2623- Has_Dir : constant Boolean :=
2624- Directories.Simple_Name (Xml_F_Name) /= Xml_F_Name;
2625- -- True if Xml_F_Name contains directory information
2659+ function Get_Xml_Virtual_File
2660+ (Object_Directory : GNATCOLL.VFS.Virtual_File)
2661+ return GNATCOLL.VFS.Virtual_File
2662+ is
2663+ use GNATCOLL.VFS;
26262664
2627- Xml_FD_Name : constant String :=
2628- (if Object_Dir = " " or else Has_Dir
2629- then Xml_F_Name
2630- else Directories.Compose (Object_Dir, Xml_F_Name));
2665+ Xml_Virtual_File_Aux : constant Virtual_File :=
2666+ (if Arg (Cmd, Xml_File_Name) = null
2667+ then Create_From_UTF8 (" metrix.xml" )
2668+ else
2669+ Create_From_UTF8
2670+ (Arg (Cmd, Xml_File_Name).all , Normalize => True));
2671+ begin
2672+ return
2673+ (if Xml_Virtual_File_Aux.Is_Absolute_Path
2674+ then Xml_Virtual_File_Aux
2675+ elsif Object_Directory /= No_File
2676+ then Object_Directory / Xml_Virtual_File_Aux
2677+ else Get_Current_Dir / Xml_Virtual_File_Aux);
2678+ end Get_Xml_Virtual_File ;
2679+
2680+ -- ------------------------
2681+ -- Get_Xsd_Virtual_File --
2682+ -- ------------------------
2683+
2684+ function Get_Xsd_Virtual_File
2685+ (Xml_Virtual_File : GNATCOLL.VFS.Virtual_File)
2686+ return GNATCOLL.VFS.Virtual_File
2687+ is
2688+ use GNATCOLL.VFS;
26312689
2632- XML_File : Text_IO.File_Type;
2633- -- All XML output for all source files goes to this file.
2690+ Normalized_Xml_Path : constant String :=
2691+ Xml_Virtual_File.Display_Full_Name;
26342692
2635- function Xsd_File_Name return String;
2636- -- Return the name of the XSD (schema) file name, which is based
2637- -- on the XML file name. In particular if the XML file name
2638- -- ends in ".xml", that is replaced by ".xsd"; otherwise,
2639- -- ".xsd" is appended. So "foo.xml" --> "foo.xsd", but
2640- -- "foo.bar" --> "foo.bar.xsd".
2641- --
2642- -- Note that this name is written to the XML file, in addition
2643- -- to being used to open the XSD file.
2693+ Xml : constant String := " .xml" ;
2694+ Xsd : constant String := " .xsd" ;
26442695
2645- function Xsd_File_Name return String is
2646- Norm : constant String := Normalize_Pathname (Xml_FD_Name);
2647- Xml : constant String := " .xml" ;
2648- Xsd : constant String := " .xsd" ;
26492696 begin
2650- if Has_Suffix (Norm, Suffix => Xml) then
2651- return Replace_String (Norm, Xml, Xsd);
2697+ if Xml_Virtual_File.Has_Suffix (+Xml) then
2698+ return
2699+ Create_From_UTF8
2700+ (Replace_String (Normalized_Xml_Path, Xml, Xsd));
26522701 else
2653- return Norm & Xsd;
2702+ return Create_From_UTF8 (Normalized_Xml_Path & Xsd) ;
26542703 end if ;
2655- end Xsd_File_Name ;
2704+ end Get_Xsd_Virtual_File ;
2705+
2706+ Object_Directory : constant GNATCOLL.VFS.Virtual_File :=
2707+ Get_Object_Directory;
2708+
2709+ Xml_Virtual_File : constant GNATCOLL.VFS.Virtual_File :=
2710+ Get_Xml_Virtual_File (Object_Directory);
2711+ XML_File : Text_IO.File_Type;
2712+ -- All XML output for all source files goes to this file.
2713+
2714+ Xsd_Virtual_File : constant GNATCOLL.VFS.Virtual_File :=
2715+ Get_Xsd_Virtual_File (Xml_Virtual_File);
26562716
26572717 procedure Print_Computed_Metric
26582718 (T : Formatted_Output.Template;
@@ -2702,14 +2762,18 @@ package body METRICS.Actions is
27022762 Pop (Metrix_Stack);
27032763 Clear (Metrix_Stack);
27042764
2705- if Object_Dir /= " " and then not Directories.Exists (Object_Dir) then
2765+ if Object_Directory /= GNATCOLL.VFS.No_File then
27062766 begin
2707- Directories.Create_Path (Object_Dir);
2767+ GNATCOLL.VFS.Make_Dir (Object_Directory);
2768+
27082769 exception
2709- when Directories.Name_Error | Directories.Use_Error =>
2710- Cmd_Error (" cannot create directory " & Object_Dir);
2770+ when GNATCOLL.VFS.VFS_Directory_Error =>
2771+ Cmd_Error
2772+ (" cannot create directory "
2773+ & Object_Directory.Display_Full_Name (Normalize => True));
27112774 end ;
27122775 end if ;
2776+ Xml_Virtual_File.Normalize_Path;
27132777
27142778 Dump (Tool, Global_M.all , " Initial:" );
27152779 Compute_Indirect_Dependencies (Global_M.all );
@@ -2721,14 +2785,19 @@ package body METRICS.Actions is
27212785 -- Generate schema (XSD file), if requested
27222786
27232787 if Arg (Cmd, Generate_XML_Schema) then
2724- Write_XML_Schema (Xsd_File_Name );
2788+ Write_Xsd (Xsd_Virtual_File );
27252789 end if ;
27262790
27272791 -- Put initial lines of XML
27282792
27292793 if not Output_To_Standard_Output then
2730- Text_IO.Create (XML_File, Name => Xml_FD_Name);
2731- Text_IO.Set_Output (XML_File);
2794+ if Xml_Virtual_File.Get_Parent /= GNATCOLL.VFS.No_File then
2795+ GNATCOLL.VFS.Make_Dir (Xml_Virtual_File.Get_Parent);
2796+ end if ;
2797+
2798+ Ada.Text_IO.Create
2799+ (XML_File, Name => Xml_Virtual_File.Display_Full_Name);
2800+ Ada.Text_IO.Set_Output (XML_File);
27322801 end if ;
27332802 Put (" <?xml version=\1?>\n" , Q (" 1.0" ));
27342803
@@ -2737,7 +2806,7 @@ package body METRICS.Actions is
27372806 (" <global xmlns:xsi="
27382807 & " "" http://www.w3.org/2001/XMLSchema-instance"" "
27392808 & " xsi:noNamespaceSchemaLocation="" \1"" >\n" ,
2740- Xsd_File_Name );
2809+ Xsd_Virtual_File.Display_Full_Name );
27412810 else
27422811 Put (" <global>\n" );
27432812 end if ;
@@ -2752,7 +2821,11 @@ package body METRICS.Actions is
27522821 for File_M of Global_M.Submetrix loop
27532822 pragma Assert (Debug_Flag_V or else Indentation_Level = 0 );
27542823 Print_File_Metrics
2755- (Cmd, XML_File, File_M.all , Without_Coupling, Object_Dir);
2824+ (Cmd,
2825+ XML_File,
2826+ File_M.all ,
2827+ Without_Coupling,
2828+ Object_Directory.Display_Full_Name);
27562829 pragma Assert (Debug_Flag_V or else Indentation_Level = 0 );
27572830 -- Destroy (File_M);
27582831 end loop ;
0 commit comments