* options.c (gfc_handle_module_path_options): Fix buffer overrun.
[official-gcc.git] / gcc / ada / gnatname.adb
blobfb35abb388a225cca97863d5e4bff3a32530c4e8
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- G N A T N A M E --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2001-2004 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 2, 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 COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
27 with Gnatvsn;
28 with Opt;
29 with Osint; use Osint;
30 with Output; use Output;
31 with Prj.Makr;
32 with Table;
34 with Ada.Text_IO; use Ada.Text_IO;
35 with GNAT.Command_Line; use GNAT.Command_Line;
36 with GNAT.OS_Lib; use GNAT.OS_Lib;
38 procedure Gnatname is
40 Usage_Output : Boolean := False;
41 -- Set to True when usage is output, to avoid multiple output
43 Usage_Needed : Boolean := False;
44 -- Set to True by -h switch
46 Version_Output : Boolean := False;
47 -- Set to True when version is output, to avoid multiple output
49 Very_Verbose : Boolean := False;
50 -- Set to True with -v -v
52 Create_Project : Boolean := False;
53 -- Set to True with a -P switch
55 File_Path : String_Access := new String'("gnat.adc");
56 -- Path name of the file specified by -c or -P switch
58 File_Set : Boolean := False;
59 -- Set to True by -c or -P switch.
60 -- Used to detect multiple -c/-P switches.
62 package Excluded_Patterns is new Table.Table
63 (Table_Component_Type => String_Access,
64 Table_Index_Type => Natural,
65 Table_Low_Bound => 0,
66 Table_Initial => 10,
67 Table_Increment => 10,
68 Table_Name => "Gnatname.Excluded_Patterns");
69 -- Table to accumulate the negative patterns
71 package Foreign_Patterns is new Table.Table
72 (Table_Component_Type => String_Access,
73 Table_Index_Type => Natural,
74 Table_Low_Bound => 0,
75 Table_Initial => 10,
76 Table_Increment => 10,
77 Table_Name => "Gnatname.Foreign_Patterns");
78 -- Table to accumulate the foreign patterns
80 package Patterns is new Table.Table
81 (Table_Component_Type => String_Access,
82 Table_Index_Type => Natural,
83 Table_Low_Bound => 0,
84 Table_Initial => 10,
85 Table_Increment => 10,
86 Table_Name => "Gnatname.Patterns");
87 -- Table to accumulate the name patterns
89 package Source_Directories is new Table.Table
90 (Table_Component_Type => String_Access,
91 Table_Index_Type => Natural,
92 Table_Low_Bound => 0,
93 Table_Initial => 10,
94 Table_Increment => 10,
95 Table_Name => "Gnatname.Source_Directories");
96 -- Table to accumulate the source directories specified directly with -d
97 -- or indirectly with -D.
99 package Preprocessor_Switches is new Table.Table
100 (Table_Component_Type => String_Access,
101 Table_Index_Type => Natural,
102 Table_Low_Bound => 0,
103 Table_Initial => 2,
104 Table_Increment => 50,
105 Table_Name => "Gnatname.Preprocessor_Switches");
106 -- Table to store the preprocessor switches to be used in the call
107 -- to the compiler.
109 procedure Output_Version;
110 -- Print name and version
112 procedure Usage;
113 -- Print usage
115 procedure Scan_Args;
116 -- Scan the command line arguments
118 procedure Add_Source_Directory (S : String);
119 -- Add S in the Source_Directories table
121 procedure Get_Directories (From_File : String);
122 -- Read a source directory text file
124 --------------------------
125 -- Add_Source_Directory --
126 --------------------------
128 procedure Add_Source_Directory (S : String) is
129 begin
130 Source_Directories.Increment_Last;
131 Source_Directories.Table (Source_Directories.Last) := new String'(S);
132 end Add_Source_Directory;
134 ---------------------
135 -- Get_Directories --
136 ---------------------
138 procedure Get_Directories (From_File : String) is
139 File : Ada.Text_IO.File_Type;
140 Line : String (1 .. 2_000);
141 Last : Natural;
143 begin
144 Open (File, In_File, From_File);
146 while not End_Of_File (File) loop
147 Get_Line (File, Line, Last);
149 if Last /= 0 then
150 Add_Source_Directory (Line (1 .. Last));
151 end if;
152 end loop;
154 Close (File);
156 exception
157 when Name_Error =>
158 Fail ("cannot open source directory """ & From_File & '"');
159 end Get_Directories;
161 --------------------
162 -- Output_Version --
163 --------------------
165 procedure Output_Version is
166 begin
167 if not Version_Output then
168 Version_Output := True;
169 Output.Write_Eol;
170 Output.Write_Str ("GNATNAME ");
171 Output.Write_Str (Gnatvsn.Gnat_Version_String);
172 Output.Write_Line
173 (" Copyright 2001-2004 Free Software Foundation, Inc.");
174 end if;
175 end Output_Version;
177 ---------------
178 -- Scan_Args --
179 ---------------
181 procedure Scan_Args is
182 begin
183 Initialize_Option_Scan;
185 -- Scan options first
187 loop
188 case Getopt ("c: d: gnatep=! gnatep! gnateD! D: h P: v x: f:") is
189 when ASCII.NUL =>
190 exit;
192 when 'c' =>
193 if File_Set then
194 Fail ("only one -P or -c switch may be specified");
195 end if;
197 File_Set := True;
198 File_Path := new String'(Parameter);
199 Create_Project := False;
201 when 'd' =>
202 Add_Source_Directory (Parameter);
204 when 'D' =>
205 Get_Directories (Parameter);
207 when 'f' =>
208 Foreign_Patterns.Increment_Last;
209 Foreign_Patterns.Table (Foreign_Patterns.Last) :=
210 new String'(Parameter);
212 when 'g' =>
213 Preprocessor_Switches.Increment_Last;
214 Preprocessor_Switches.Table (Preprocessor_Switches.Last) :=
215 new String'('-' & Full_Switch & Parameter);
217 when 'h' =>
218 Usage_Needed := True;
220 when 'P' =>
221 if File_Set then
222 Fail ("only one -c or -P switch may be specified");
223 end if;
225 File_Set := True;
226 File_Path := new String'(Parameter);
227 Create_Project := True;
229 when 'v' =>
230 if Opt.Verbose_Mode then
231 Very_Verbose := True;
233 else
234 Opt.Verbose_Mode := True;
235 end if;
237 when 'x' =>
238 Excluded_Patterns.Increment_Last;
239 Excluded_Patterns.Table (Excluded_Patterns.Last) :=
240 new String'(Parameter);
242 when others =>
243 null;
244 end case;
245 end loop;
247 -- Now, get the name patterns, if any
249 loop
250 declare
251 S : String := Get_Argument (Do_Expansion => False);
253 begin
254 exit when S = "";
255 Canonical_Case_File_Name (S);
256 Patterns.Increment_Last;
257 Patterns.Table (Patterns.Last) := new String'(S);
258 end;
259 end loop;
261 exception
262 when Invalid_Switch =>
263 Fail ("invalid switch " & Full_Switch);
264 end Scan_Args;
266 -----------
267 -- Usage --
268 -----------
270 procedure Usage is
271 begin
272 if not Usage_Output then
273 Usage_Needed := False;
274 Usage_Output := True;
275 Write_Str ("Usage: ");
276 Osint.Write_Program_Name;
277 Write_Line (" [switches] naming-pattern [naming-patterns]");
278 Write_Eol;
279 Write_Line ("switches:");
281 Write_Line (" -cfile create configuration pragmas file");
282 Write_Line (" -ddir use dir as one of the source " &
283 "directories");
284 Write_Line (" -Dfile get source directories from file");
285 Write_Line (" -fpat foreign pattern");
286 Write_Line (" -gnateDsym=v preprocess with symbol definition");
287 Write_Line (" -gnatep=data preprocess files with data file");
288 Write_Line (" -h output this help message");
289 Write_Line (" -Pproj update or create project file proj");
290 Write_Line (" -v verbose output");
291 Write_Line (" -v -v very verbose output");
292 Write_Line (" -xpat exclude pattern pat");
293 end if;
294 end Usage;
296 -- Start of processing for Gnatname
298 begin
299 -- Initialize tables
301 Excluded_Patterns.Set_Last (0);
302 Foreign_Patterns.Set_Last (0);
303 Patterns.Set_Last (0);
304 Source_Directories.Set_Last (0);
305 Preprocessor_Switches.Set_Last (0);
307 -- Get the arguments
309 Scan_Args;
311 if Opt.Verbose_Mode then
312 Output_Version;
313 end if;
315 if Usage_Needed then
316 Usage;
317 end if;
319 -- If no pattern was specified, print the usage and return
321 if Patterns.Last = 0 and Foreign_Patterns.Last = 0 then
322 Usage;
323 return;
324 end if;
326 -- If no source directory was specified, use the current directory as the
327 -- unique directory. Note that if a file was specified with directory
328 -- information, the current directory is the directory of the specified
329 -- file.
331 if Source_Directories.Last = 0 then
332 Source_Directories.Increment_Last;
333 Source_Directories.Table (Source_Directories.Last) := new String'(".");
334 end if;
336 declare
337 Directories : Argument_List (1 .. Integer (Source_Directories.Last));
338 Name_Patterns : Argument_List (1 .. Integer (Patterns.Last));
339 Excl_Patterns : Argument_List (1 .. Integer (Excluded_Patterns.Last));
340 Frgn_Patterns : Argument_List (1 .. Integer (Foreign_Patterns.Last));
341 Prep_Switches : Argument_List
342 (1 .. Integer (Preprocessor_Switches.Last));
344 begin
345 -- Build the Directories and Name_Patterns arguments
347 for Index in Directories'Range loop
348 Directories (Index) := Source_Directories.Table (Index);
349 end loop;
351 for Index in Name_Patterns'Range loop
352 Name_Patterns (Index) := Patterns.Table (Index);
353 end loop;
355 for Index in Excl_Patterns'Range loop
356 Excl_Patterns (Index) := Excluded_Patterns.Table (Index);
357 end loop;
359 for Index in Frgn_Patterns'Range loop
360 Frgn_Patterns (Index) := Foreign_Patterns.Table (Index);
361 end loop;
363 for Index in Prep_Switches'Range loop
364 Prep_Switches (Index) := Preprocessor_Switches.Table (Index);
365 end loop;
367 -- Call Prj.Makr.Make where the real work is done
369 Prj.Makr.Make
370 (File_Path => File_Path.all,
371 Project_File => Create_Project,
372 Directories => Directories,
373 Name_Patterns => Name_Patterns,
374 Excluded_Patterns => Excl_Patterns,
375 Foreign_Patterns => Frgn_Patterns,
376 Preproc_Switches => Prep_Switches,
377 Very_Verbose => Very_Verbose);
378 end;
380 if Opt.Verbose_Mode then
381 Write_Eol;
382 end if;
383 end Gnatname;