blob: b746ba02f2360724eae815d16ae65f0a4c48aa27 [file] [log] [blame]
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- G N A T N A M E --
-- --
-- B o d y --
-- --
-- Copyright (C) 2001-2006, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 2, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNAT; see file COPYING. If not, write --
-- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
-- Boston, MA 02110-1301, USA. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
with Gnatvsn; use Gnatvsn;
with Hostparm;
with Opt;
with Osint; use Osint;
with Output; use Output;
with Prj.Makr;
with Table;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
with GNAT.Command_Line; use GNAT.Command_Line;
with GNAT.OS_Lib; use GNAT.OS_Lib;
procedure Gnatname is
Usage_Output : Boolean := False;
-- Set to True when usage is output, to avoid multiple output
Usage_Needed : Boolean := False;
-- Set to True by -h switch
Version_Output : Boolean := False;
-- Set to True when version is output, to avoid multiple output
Very_Verbose : Boolean := False;
-- Set to True with -v -v
Create_Project : Boolean := False;
-- Set to True with a -P switch
File_Path : String_Access := new String'("gnat.adc");
-- Path name of the file specified by -c or -P switch
File_Set : Boolean := False;
-- Set to True by -c or -P switch.
-- Used to detect multiple -c/-P switches.
package Excluded_Patterns is new Table.Table
(Table_Component_Type => String_Access,
Table_Index_Type => Natural,
Table_Low_Bound => 0,
Table_Initial => 10,
Table_Increment => 10,
Table_Name => "Gnatname.Excluded_Patterns");
-- Table to accumulate the negative patterns
package Foreign_Patterns is new Table.Table
(Table_Component_Type => String_Access,
Table_Index_Type => Natural,
Table_Low_Bound => 0,
Table_Initial => 10,
Table_Increment => 10,
Table_Name => "Gnatname.Foreign_Patterns");
-- Table to accumulate the foreign patterns
package Patterns is new Table.Table
(Table_Component_Type => String_Access,
Table_Index_Type => Natural,
Table_Low_Bound => 0,
Table_Initial => 10,
Table_Increment => 10,
Table_Name => "Gnatname.Patterns");
-- Table to accumulate the name patterns
package Source_Directories is new Table.Table
(Table_Component_Type => String_Access,
Table_Index_Type => Natural,
Table_Low_Bound => 0,
Table_Initial => 10,
Table_Increment => 10,
Table_Name => "Gnatname.Source_Directories");
-- Table to accumulate the source directories specified directly with -d
-- or indirectly with -D.
package Preprocessor_Switches is new Table.Table
(Table_Component_Type => String_Access,
Table_Index_Type => Natural,
Table_Low_Bound => 0,
Table_Initial => 2,
Table_Increment => 50,
Table_Name => "Gnatname.Preprocessor_Switches");
-- Table to store the preprocessor switches to be used in the call
-- to the compiler.
procedure Output_Version;
-- Print name and version
procedure Usage;
-- Print usage
procedure Scan_Args;
-- Scan the command line arguments
procedure Add_Source_Directory (S : String);
-- Add S in the Source_Directories table
procedure Get_Directories (From_File : String);
-- Read a source directory text file
--------------------------
-- Add_Source_Directory --
--------------------------
procedure Add_Source_Directory (S : String) is
begin
Source_Directories.Increment_Last;
Source_Directories.Table (Source_Directories.Last) := new String'(S);
end Add_Source_Directory;
---------------------
-- Get_Directories --
---------------------
procedure Get_Directories (From_File : String) is
File : Ada.Text_IO.File_Type;
Line : String (1 .. 2_000);
Last : Natural;
begin
Open (File, In_File, From_File);
while not End_Of_File (File) loop
Get_Line (File, Line, Last);
if Last /= 0 then
Add_Source_Directory (Line (1 .. Last));
end if;
end loop;
Close (File);
exception
when Name_Error =>
Fail ("cannot open source directory """ & From_File & '"');
end Get_Directories;
--------------------
-- Output_Version --
--------------------
procedure Output_Version is
begin
if not Version_Output then
Version_Output := True;
Output.Write_Eol;
Output.Write_Str ("GNATNAME ");
Output.Write_Line (Gnatvsn.Gnat_Version_String);
Output.Write_Line
("Copyright 2001-" &
Current_Year &
", Free Software Foundation, Inc.");
end if;
end Output_Version;
---------------
-- Scan_Args --
---------------
procedure Scan_Args is
begin
Initialize_Option_Scan;
-- Scan options first
loop
case Getopt ("c: d: gnatep=! gnatep! gnateD! D: h P: v x: f:") is
when ASCII.NUL =>
exit;
when 'c' =>
if File_Set then
Fail ("only one -P or -c switch may be specified");
end if;
File_Set := True;
File_Path := new String'(Parameter);
Create_Project := False;
when 'd' =>
Add_Source_Directory (Parameter);
when 'D' =>
Get_Directories (Parameter);
when 'f' =>
Foreign_Patterns.Increment_Last;
Foreign_Patterns.Table (Foreign_Patterns.Last) :=
new String'(Parameter);
when 'g' =>
Preprocessor_Switches.Increment_Last;
Preprocessor_Switches.Table (Preprocessor_Switches.Last) :=
new String'('-' & Full_Switch & Parameter);
when 'h' =>
Usage_Needed := True;
when 'P' =>
if File_Set then
Fail ("only one -c or -P switch may be specified");
end if;
File_Set := True;
File_Path := new String'(Parameter);
Create_Project := True;
when 'v' =>
if Opt.Verbose_Mode then
Very_Verbose := True;
else
Opt.Verbose_Mode := True;
end if;
when 'x' =>
Excluded_Patterns.Increment_Last;
Excluded_Patterns.Table (Excluded_Patterns.Last) :=
new String'(Parameter);
when others =>
null;
end case;
end loop;
-- Now, get the name patterns, if any
loop
declare
S : String := Get_Argument (Do_Expansion => False);
begin
exit when S = "";
Canonical_Case_File_Name (S);
Patterns.Increment_Last;
Patterns.Table (Patterns.Last) := new String'(S);
end;
end loop;
exception
when Invalid_Switch =>
Fail ("invalid switch " & Full_Switch);
end Scan_Args;
-----------
-- Usage --
-----------
procedure Usage is
begin
if not Usage_Output then
Usage_Needed := False;
Usage_Output := True;
Write_Str ("Usage: ");
Osint.Write_Program_Name;
Write_Line (" [switches] naming-pattern [naming-patterns]");
Write_Eol;
Write_Line ("switches:");
Write_Line (" -cfile create configuration pragmas file");
Write_Line (" -ddir use dir as one of the source " &
"directories");
Write_Line (" -Dfile get source directories from file");
Write_Line (" -fpat foreign pattern");
Write_Line (" -gnateDsym=v preprocess with symbol definition");
Write_Line (" -gnatep=data preprocess files with data file");
Write_Line (" -h output this help message");
Write_Line (" -Pproj update or create project file proj");
Write_Line (" -v verbose output");
Write_Line (" -v -v very verbose output");
Write_Line (" -xpat exclude pattern pat");
end if;
end Usage;
-- Start of processing for Gnatname
begin
-- Add the directory where gnatname is invoked in front of the
-- path, if gnatname is invoked with directory information.
-- Only do this if the platform is not VMS, where the notion of path
-- does not really exist.
if not Hostparm.OpenVMS then
declare
Command : constant String := Command_Name;
begin
for Index in reverse Command'Range loop
if Command (Index) = Directory_Separator then
declare
Absolute_Dir : constant String :=
Normalize_Pathname
(Command (Command'First .. Index));
PATH : constant String :=
Absolute_Dir &
Path_Separator &
Getenv ("PATH").all;
begin
Setenv ("PATH", PATH);
end;
exit;
end if;
end loop;
end;
end if;
-- Initialize tables
Excluded_Patterns.Set_Last (0);
Foreign_Patterns.Set_Last (0);
Patterns.Set_Last (0);
Source_Directories.Set_Last (0);
Preprocessor_Switches.Set_Last (0);
-- Get the arguments
Scan_Args;
if Opt.Verbose_Mode then
Output_Version;
end if;
if Usage_Needed then
Usage;
end if;
-- If no pattern was specified, print the usage and return
if Patterns.Last = 0 and Foreign_Patterns.Last = 0 then
Usage;
return;
end if;
-- If no source directory was specified, use the current directory as the
-- unique directory. Note that if a file was specified with directory
-- information, the current directory is the directory of the specified
-- file.
if Source_Directories.Last = 0 then
Source_Directories.Increment_Last;
Source_Directories.Table (Source_Directories.Last) := new String'(".");
end if;
declare
Directories : Argument_List (1 .. Integer (Source_Directories.Last));
Name_Patterns : Argument_List (1 .. Integer (Patterns.Last));
Excl_Patterns : Argument_List (1 .. Integer (Excluded_Patterns.Last));
Frgn_Patterns : Argument_List (1 .. Integer (Foreign_Patterns.Last));
Prep_Switches : Argument_List
(1 .. Integer (Preprocessor_Switches.Last));
begin
-- Build the Directories and Name_Patterns arguments
for Index in Directories'Range loop
Directories (Index) := Source_Directories.Table (Index);
end loop;
for Index in Name_Patterns'Range loop
Name_Patterns (Index) := Patterns.Table (Index);
end loop;
for Index in Excl_Patterns'Range loop
Excl_Patterns (Index) := Excluded_Patterns.Table (Index);
end loop;
for Index in Frgn_Patterns'Range loop
Frgn_Patterns (Index) := Foreign_Patterns.Table (Index);
end loop;
for Index in Prep_Switches'Range loop
Prep_Switches (Index) := Preprocessor_Switches.Table (Index);
end loop;
-- Call Prj.Makr.Make where the real work is done
Prj.Makr.Make
(File_Path => File_Path.all,
Project_File => Create_Project,
Directories => Directories,
Name_Patterns => Name_Patterns,
Excluded_Patterns => Excl_Patterns,
Foreign_Patterns => Frgn_Patterns,
Preproc_Switches => Prep_Switches,
Very_Verbose => Very_Verbose);
end;
if Opt.Verbose_Mode then
Write_Eol;
end if;
end Gnatname;