111
|
1 ------------------------------------------------------------------------------
|
|
2 -- --
|
|
3 -- GNAT COMPILER COMPONENTS --
|
|
4 -- --
|
|
5 -- S W I T C H - M --
|
|
6 -- --
|
|
7 -- B o d y --
|
|
8 -- --
|
131
|
9 -- Copyright (C) 2001-2018, Free Software Foundation, Inc. --
|
111
|
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 Debug; use Debug;
|
|
27 with Osint; use Osint;
|
|
28 with Opt; use Opt;
|
|
29 with Table;
|
|
30
|
|
31 with System.Multiprocessors; use System.Multiprocessors;
|
|
32
|
|
33 package body Switch.M is
|
|
34
|
|
35 package Normalized_Switches is new Table.Table
|
|
36 (Table_Component_Type => String_Access,
|
|
37 Table_Index_Type => Integer,
|
|
38 Table_Low_Bound => 1,
|
|
39 Table_Initial => 20,
|
|
40 Table_Increment => 100,
|
|
41 Table_Name => "Switch.M.Normalized_Switches");
|
|
42 -- This table is used to keep the normalized switches, so that they may be
|
|
43 -- reused for subsequent invocations of Normalize_Compiler_Switches with
|
|
44 -- similar switches.
|
|
45
|
|
46 Initial_Number_Of_Switches : constant := 10;
|
|
47
|
|
48 Global_Switches : Argument_List_Access := null;
|
|
49 -- Used by function Normalize_Compiler_Switches
|
|
50
|
|
51 Subdirs_Option : constant String := "--subdirs=";
|
|
52
|
|
53 ---------------------------------
|
|
54 -- Normalize_Compiler_Switches --
|
|
55 ---------------------------------
|
|
56
|
|
57 procedure Normalize_Compiler_Switches
|
|
58 (Switch_Chars : String;
|
|
59 Switches : in out Argument_List_Access;
|
|
60 Last : out Natural)
|
|
61 is
|
|
62 Switch_Starts_With_Gnat : Boolean;
|
|
63
|
|
64 Ptr : Integer := Switch_Chars'First;
|
|
65 Max : constant Integer := Switch_Chars'Last;
|
|
66 C : Character := ' ';
|
|
67
|
|
68 Storing : String := Switch_Chars;
|
|
69 First_Stored : Positive := Ptr + 1;
|
|
70 Last_Stored : Positive := First_Stored;
|
|
71
|
|
72 procedure Add_Switch_Component (S : String);
|
|
73 -- Add a new String_Access component in Switches. If a string equal
|
|
74 -- to S is already stored in the table Normalized_Switches, use it.
|
|
75 -- Otherwise add a new component to the table.
|
|
76
|
|
77 --------------------------
|
|
78 -- Add_Switch_Component --
|
|
79 --------------------------
|
|
80
|
|
81 procedure Add_Switch_Component (S : String) is
|
|
82 begin
|
|
83 -- If Switches is null, allocate a new array
|
|
84
|
|
85 if Switches = null then
|
|
86 Switches := new Argument_List (1 .. Initial_Number_Of_Switches);
|
|
87
|
|
88 -- Otherwise, if Switches is full, extend it
|
|
89
|
|
90 elsif Last = Switches'Last then
|
|
91 declare
|
|
92 New_Switches : constant Argument_List_Access :=
|
|
93 new Argument_List
|
|
94 (1 .. Switches'Length + Switches'Length);
|
|
95 begin
|
|
96 New_Switches (1 .. Switches'Length) := Switches.all;
|
|
97 Last := Switches'Length;
|
|
98 Switches := New_Switches;
|
|
99 end;
|
|
100 end if;
|
|
101
|
|
102 -- If this is the first switch, Last designates the first component
|
|
103
|
|
104 if Last = 0 then
|
|
105 Last := Switches'First;
|
|
106 else
|
|
107 Last := Last + 1;
|
|
108 end if;
|
|
109
|
|
110 -- Look into the table Normalized_Switches for a similar string.
|
|
111 -- If one is found, put it at the added component, and return.
|
|
112
|
|
113 for Index in 1 .. Normalized_Switches.Last loop
|
|
114 if S = Normalized_Switches.Table (Index).all then
|
|
115 Switches (Last) := Normalized_Switches.Table (Index);
|
|
116 return;
|
|
117 end if;
|
|
118 end loop;
|
|
119
|
|
120 -- No string equal to S was found in the table Normalized_Switches.
|
|
121 -- Add a new component in the table.
|
|
122
|
|
123 Switches (Last) := new String'(S);
|
|
124 Normalized_Switches.Append (Switches (Last));
|
|
125 end Add_Switch_Component;
|
|
126
|
|
127 -- Start of processing for Normalize_Compiler_Switches
|
|
128
|
|
129 begin
|
|
130 Last := 0;
|
|
131
|
|
132 if Ptr = Max or else Switch_Chars (Ptr) /= '-' then
|
|
133 return;
|
|
134 end if;
|
|
135
|
|
136 Ptr := Ptr + 1;
|
|
137
|
|
138 Switch_Starts_With_Gnat :=
|
|
139 Ptr + 3 <= Max and then Switch_Chars (Ptr .. Ptr + 3) = "gnat";
|
|
140
|
|
141 if Switch_Starts_With_Gnat then
|
|
142 Ptr := Ptr + 4;
|
|
143 First_Stored := Ptr;
|
|
144 end if;
|
|
145
|
|
146 while Ptr <= Max loop
|
|
147 C := Switch_Chars (Ptr);
|
|
148
|
|
149 -- Processing for a switch
|
|
150
|
|
151 case Switch_Starts_With_Gnat is
|
|
152 when False =>
|
|
153
|
|
154 -- All switches that don't start with -gnat stay as is,
|
|
155 -- except -pg, -Wall, -k8, -w
|
|
156
|
|
157 if Switch_Chars = "-pg" or else Switch_Chars = "-p" then
|
|
158
|
|
159 -- The gcc driver converts -pg to -p, so that is what
|
|
160 -- is stored in the ALI file.
|
|
161
|
|
162 Add_Switch_Component ("-p");
|
|
163
|
|
164 elsif Switch_Chars = "-Wall" then
|
|
165
|
|
166 -- The gcc driver adds -gnatwa when -Wall is used
|
|
167
|
|
168 Add_Switch_Component ("-gnatwa");
|
|
169 Add_Switch_Component ("-Wall");
|
|
170
|
|
171 elsif Switch_Chars = "-k8" then
|
|
172
|
|
173 -- The gcc driver transforms -k8 into -gnatk8
|
|
174
|
|
175 Add_Switch_Component ("-gnatk8");
|
|
176
|
|
177 elsif Switch_Chars = "-w" then
|
|
178
|
|
179 -- The gcc driver adds -gnatws when -w is used
|
|
180
|
|
181 Add_Switch_Component ("-gnatws");
|
|
182 Add_Switch_Component ("-w");
|
|
183
|
|
184 elsif Switch_Chars'Length > 6
|
|
185 and then
|
|
186 Switch_Chars (Switch_Chars'First .. Switch_Chars'First + 5)
|
|
187 = "--RTS="
|
|
188 then
|
|
189 Add_Switch_Component (Switch_Chars);
|
|
190
|
|
191 -- When --RTS=mtp is used, the gcc driver adds -mrtp
|
|
192
|
|
193 if Switch_Chars = "--RTS=mtp" then
|
|
194 Add_Switch_Component ("-mrtp");
|
|
195 end if;
|
|
196
|
|
197 -- Special case for -fstack-check (alias for
|
|
198 -- -fstack-check=specific)
|
|
199
|
|
200 elsif Switch_Chars = "-fstack-check" then
|
|
201 Add_Switch_Component ("-fstack-check=specific");
|
|
202
|
|
203 -- Take only into account switches that are transmitted to
|
|
204 -- gnat1 by the gcc driver and stored by gnat1 in the ALI file.
|
|
205
|
|
206 else
|
|
207 case C is
|
|
208 when 'O' | 'W' | 'w' | 'f' | 'd' | 'g' | 'm' =>
|
|
209 Add_Switch_Component (Switch_Chars);
|
|
210
|
|
211 when others =>
|
|
212 null;
|
|
213 end case;
|
|
214 end if;
|
|
215
|
|
216 return;
|
|
217
|
|
218 when True =>
|
|
219 case C is
|
|
220
|
|
221 -- One-letter switches
|
|
222
|
|
223 when 'a' | 'A' | 'b' | 'B' | 'c' | 'C' | 'E' | 'f' | 'F'
|
|
224 | 'g' | 'h' | 'H' | 'I' | 'L' | 'N' | 'p' | 'P' | 'q'
|
|
225 | 'Q' | 'r' | 's' | 'S' | 't' | 'u' | 'U' | 'v' | 'x'
|
|
226 | 'X' | 'Z'
|
|
227 =>
|
|
228 Storing (First_Stored) := C;
|
|
229 Add_Switch_Component
|
|
230 (Storing (Storing'First .. First_Stored));
|
|
231 Ptr := Ptr + 1;
|
|
232
|
|
233 -- One-letter switches followed by a positive number
|
|
234
|
|
235 when 'D' | 'G' | 'j' | 'k' | 'm' | 'T' =>
|
|
236 Storing (First_Stored) := C;
|
|
237 Last_Stored := First_Stored;
|
|
238
|
|
239 if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
|
|
240 Ptr := Ptr + 1;
|
|
241 end if;
|
|
242
|
|
243 loop
|
|
244 Ptr := Ptr + 1;
|
|
245 exit when Ptr > Max
|
|
246 or else Switch_Chars (Ptr) not in '0' .. '9';
|
|
247 Last_Stored := Last_Stored + 1;
|
|
248 Storing (Last_Stored) := Switch_Chars (Ptr);
|
|
249 end loop;
|
|
250
|
|
251 Add_Switch_Component
|
|
252 (Storing (Storing'First .. Last_Stored));
|
|
253
|
|
254 when 'd' =>
|
|
255 Storing (First_Stored) := 'd';
|
|
256
|
|
257 while Ptr < Max loop
|
|
258 Ptr := Ptr + 1;
|
|
259 C := Switch_Chars (Ptr);
|
|
260 exit when C = ASCII.NUL or else C = '/'
|
|
261 or else C = '-';
|
|
262
|
|
263 if C in '1' .. '9' or else
|
|
264 C in 'a' .. 'z' or else
|
|
265 C in 'A' .. 'Z'
|
|
266 then
|
|
267 Storing (First_Stored + 1) := C;
|
|
268 Add_Switch_Component
|
|
269 (Storing (Storing'First .. First_Stored + 1));
|
|
270
|
|
271 else
|
|
272 Last := 0;
|
|
273 return;
|
|
274 end if;
|
|
275 end loop;
|
|
276
|
|
277 return;
|
|
278
|
|
279 when 'e' =>
|
|
280
|
|
281 -- Some of the gnate... switches are not stored
|
|
282
|
|
283 Storing (First_Stored) := 'e';
|
|
284 Ptr := Ptr + 1;
|
|
285
|
|
286 if Ptr > Max then
|
|
287 Last := 0;
|
|
288 return;
|
|
289
|
|
290 else
|
|
291 case Switch_Chars (Ptr) is
|
|
292 when 'A' =>
|
|
293 Ptr := Ptr + 1;
|
|
294 Add_Switch_Component ("-gnateA");
|
|
295
|
|
296 when 'D' =>
|
|
297 Storing (First_Stored + 1 ..
|
|
298 First_Stored + Max - Ptr + 1) :=
|
|
299 Switch_Chars (Ptr .. Max);
|
|
300 Add_Switch_Component
|
|
301 (Storing (Storing'First ..
|
|
302 First_Stored + Max - Ptr + 1));
|
|
303 Ptr := Max + 1;
|
|
304
|
|
305 when 'E' | 'F' | 'G' | 'S' | 'u' | 'V' | 'Y' =>
|
|
306 Add_Switch_Component
|
|
307 ("-gnate" & Switch_Chars (Ptr));
|
|
308 Ptr := Ptr + 1;
|
|
309
|
|
310 when 'i' | 'I' =>
|
|
311 declare
|
|
312 First : constant Positive := Ptr;
|
|
313
|
|
314 begin
|
|
315 Ptr := Ptr + 1;
|
|
316
|
|
317 if Ptr <= Max and then
|
|
318 Switch_Chars (Ptr) = '='
|
|
319 then
|
|
320 Ptr := Ptr + 1;
|
|
321 end if;
|
|
322
|
|
323 while Ptr <= Max and then
|
|
324 Switch_Chars (Ptr) in '0' .. '9'
|
|
325 loop
|
|
326 Ptr := Ptr + 1;
|
|
327 end loop;
|
|
328
|
|
329 Storing (First_Stored + 1 ..
|
|
330 First_Stored + Ptr - First) :=
|
|
331 Switch_Chars (First .. Ptr - 1);
|
|
332 Add_Switch_Component
|
|
333 (Storing (Storing'First ..
|
|
334 First_Stored + Ptr - First));
|
|
335 end;
|
|
336
|
|
337 when 'l' =>
|
|
338 Ptr := Ptr + 1;
|
|
339 Add_Switch_Component ("-gnatel");
|
|
340
|
|
341 when 'L' =>
|
|
342 Ptr := Ptr + 1;
|
|
343 Add_Switch_Component ("-gnateL");
|
|
344
|
|
345 when 'p' =>
|
|
346 Ptr := Ptr + 1;
|
|
347
|
|
348 if Ptr = Max then
|
|
349 Last := 0;
|
|
350 return;
|
|
351 end if;
|
|
352
|
|
353 if Switch_Chars (Ptr) = '=' then
|
|
354 Ptr := Ptr + 1;
|
|
355 end if;
|
|
356
|
|
357 -- To normalize, always put a '=' after
|
|
358 -- -gnatep. Because that could lengthen the
|
|
359 -- switch string, declare a local variable.
|
|
360
|
|
361 declare
|
|
362 To_Store : String (1 .. Max - Ptr + 9);
|
|
363 begin
|
|
364 To_Store (1 .. 8) := "-gnatep=";
|
|
365 To_Store (9 .. Max - Ptr + 9) :=
|
|
366 Switch_Chars (Ptr .. Max);
|
|
367 Add_Switch_Component (To_Store);
|
|
368 end;
|
|
369
|
|
370 return;
|
|
371
|
|
372 when others =>
|
|
373 Last := 0;
|
|
374 return;
|
|
375 end case;
|
|
376 end if;
|
|
377
|
|
378 when 'i' =>
|
|
379 Storing (First_Stored) := 'i';
|
|
380
|
|
381 Ptr := Ptr + 1;
|
|
382
|
|
383 if Ptr > Max then
|
|
384 Last := 0;
|
|
385 return;
|
|
386 end if;
|
|
387
|
|
388 C := Switch_Chars (Ptr);
|
|
389
|
|
390 if C in '1' .. '5'
|
|
391 or else C = '8'
|
|
392 or else C = 'p'
|
|
393 or else C = 'f'
|
|
394 or else C = 'n'
|
|
395 or else C = 'w'
|
|
396 then
|
|
397 Storing (First_Stored + 1) := C;
|
|
398 Add_Switch_Component
|
|
399 (Storing (Storing'First .. First_Stored + 1));
|
|
400 Ptr := Ptr + 1;
|
|
401
|
|
402 else
|
|
403 Last := 0;
|
|
404 return;
|
|
405 end if;
|
|
406
|
|
407 -- -gnatl may be -gnatl=<file name>
|
|
408
|
|
409 when 'l' =>
|
|
410 Ptr := Ptr + 1;
|
|
411
|
|
412 if Ptr > Max or else Switch_Chars (Ptr) /= '=' then
|
|
413 Add_Switch_Component ("-gnatl");
|
|
414
|
|
415 else
|
|
416 Add_Switch_Component
|
|
417 ("-gnatl" & Switch_Chars (Ptr .. Max));
|
|
418 return;
|
|
419 end if;
|
|
420
|
|
421 -- -gnatn may be -gnatn, -gnatn1, or -gnatn2
|
|
422
|
|
423 when 'n' =>
|
|
424 Last_Stored := First_Stored;
|
|
425 Storing (Last_Stored) := 'n';
|
|
426 Ptr := Ptr + 1;
|
|
427
|
|
428 if Ptr <= Max
|
|
429 and then Switch_Chars (Ptr) in '1' .. '2'
|
|
430 then
|
|
431 Last_Stored := Last_Stored + 1;
|
|
432 Storing (Last_Stored) := Switch_Chars (Ptr);
|
|
433 Ptr := Ptr + 1;
|
|
434 end if;
|
|
435
|
|
436 Add_Switch_Component
|
|
437 (Storing (Storing'First .. Last_Stored));
|
|
438
|
|
439 -- -gnato may be -gnatox or -gnatoxx, with x=0/1/2/3
|
|
440
|
|
441 when 'o' =>
|
|
442 Last_Stored := First_Stored;
|
|
443 Storing (Last_Stored) := 'o';
|
|
444 Ptr := Ptr + 1;
|
|
445
|
|
446 if Ptr <= Max
|
|
447 and then Switch_Chars (Ptr) in '0' .. '3'
|
|
448 then
|
|
449 Last_Stored := Last_Stored + 1;
|
|
450 Storing (Last_Stored) := Switch_Chars (Ptr);
|
|
451 Ptr := Ptr + 1;
|
|
452
|
|
453 if Ptr <= Max
|
|
454 and then Switch_Chars (Ptr) in '0' .. '3'
|
|
455 then
|
|
456 Last_Stored := Last_Stored + 1;
|
|
457 Storing (Last_Stored) := Switch_Chars (Ptr);
|
|
458 Ptr := Ptr + 1;
|
|
459 end if;
|
|
460 end if;
|
|
461
|
|
462 Add_Switch_Component
|
|
463 (Storing (Storing'First .. Last_Stored));
|
|
464
|
|
465 -- -gnatR may be followed by '0', '1', '2' or '3',
|
|
466 -- then by 's'
|
|
467
|
|
468 when 'R' =>
|
|
469 Last_Stored := First_Stored;
|
|
470 Storing (Last_Stored) := 'R';
|
|
471 Ptr := Ptr + 1;
|
|
472
|
|
473 if Ptr <= Max
|
|
474 and then Switch_Chars (Ptr) in '0' .. '9'
|
|
475 then
|
|
476 C := Switch_Chars (Ptr);
|
|
477
|
|
478 if C in '4' .. '9' then
|
|
479 Last := 0;
|
|
480 return;
|
|
481
|
|
482 else
|
|
483 Last_Stored := Last_Stored + 1;
|
|
484 Storing (Last_Stored) := C;
|
|
485 Ptr := Ptr + 1;
|
|
486
|
|
487 if Ptr <= Max
|
|
488 and then Switch_Chars (Ptr) = 's'
|
|
489 then
|
|
490 Last_Stored := Last_Stored + 1;
|
|
491 Storing (Last_Stored) := 's';
|
|
492 Ptr := Ptr + 1;
|
|
493 end if;
|
|
494 end if;
|
|
495 end if;
|
|
496
|
|
497 Add_Switch_Component
|
|
498 (Storing (Storing'First .. Last_Stored));
|
|
499
|
|
500 -- -gnatWx, x = 'h'. 'u', 's', 'e', '8' or 'b'
|
|
501
|
|
502 when 'W' =>
|
|
503 Storing (First_Stored) := 'W';
|
|
504 Ptr := Ptr + 1;
|
|
505
|
|
506 if Ptr <= Max then
|
|
507 case Switch_Chars (Ptr) is
|
|
508 when 'h' | 'u' | 's' | 'e' | '8' | 'b' =>
|
|
509 Storing (First_Stored + 1) := Switch_Chars (Ptr);
|
|
510 Add_Switch_Component
|
|
511 (Storing (Storing'First .. First_Stored + 1));
|
|
512 Ptr := Ptr + 1;
|
|
513
|
|
514 when others =>
|
|
515 Last := 0;
|
|
516 return;
|
|
517 end case;
|
|
518 end if;
|
|
519
|
|
520 -- Multiple switches
|
|
521
|
|
522 when 'V' | 'w' | 'y' =>
|
|
523 Storing (First_Stored) := C;
|
|
524 Ptr := Ptr + 1;
|
|
525
|
|
526 if Ptr > Max then
|
|
527 if C = 'y' then
|
|
528 Add_Switch_Component
|
|
529 (Storing (Storing'First .. First_Stored));
|
|
530
|
|
531 else
|
|
532 Last := 0;
|
|
533 return;
|
|
534 end if;
|
|
535 end if;
|
|
536
|
|
537 -- Loop through remaining switch characters in string
|
|
538
|
|
539 while Ptr <= Max loop
|
|
540 C := Switch_Chars (Ptr);
|
|
541 Ptr := Ptr + 1;
|
|
542
|
|
543 -- -gnatyMxxx
|
|
544
|
|
545 if C = 'M' and then Storing (First_Stored) = 'y' then
|
|
546 Last_Stored := First_Stored + 1;
|
|
547 Storing (Last_Stored) := 'M';
|
|
548 while Ptr <= Max loop
|
|
549 C := Switch_Chars (Ptr);
|
|
550 exit when C not in '0' .. '9';
|
|
551 Last_Stored := Last_Stored + 1;
|
|
552 Storing (Last_Stored) := C;
|
|
553 Ptr := Ptr + 1;
|
|
554 end loop;
|
|
555
|
|
556 -- If there is no digit after -gnatyM,
|
|
557 -- the switch is invalid.
|
|
558
|
|
559 if Last_Stored = First_Stored + 1 then
|
|
560 Last := 0;
|
|
561 return;
|
|
562
|
|
563 else
|
|
564 Add_Switch_Component
|
|
565 (Storing (Storing'First .. Last_Stored));
|
|
566 end if;
|
|
567
|
|
568 -- --gnatx.x
|
|
569
|
|
570 elsif C = '.' and then Ptr <= Max then
|
|
571 Storing (First_Stored + 1) := '.';
|
|
572 Storing (First_Stored + 2) := Switch_Chars (Ptr);
|
|
573 Ptr := Ptr + 1;
|
|
574 Add_Switch_Component
|
|
575 (Storing (Storing'First .. First_Stored + 2));
|
|
576
|
|
577 -- All other switches are -gnatxx
|
|
578
|
|
579 else
|
|
580 Storing (First_Stored + 1) := C;
|
|
581 Add_Switch_Component
|
|
582 (Storing (Storing'First .. First_Stored + 1));
|
|
583 end if;
|
|
584 end loop;
|
|
585
|
|
586 -- -gnat95 -gnat05
|
|
587
|
|
588 when '0' | '9' =>
|
|
589 Last_Stored := First_Stored;
|
|
590 Storing (Last_Stored) := C;
|
|
591 Ptr := Ptr + 1;
|
|
592
|
|
593 if Ptr /= Max or else Switch_Chars (Ptr) /= '5' then
|
|
594
|
|
595 -- Invalid switch
|
|
596
|
|
597 Last := 0;
|
|
598 return;
|
|
599
|
|
600 else
|
|
601 Last_Stored := Last_Stored + 1;
|
|
602 Storing (Last_Stored) := '5';
|
|
603 Add_Switch_Component
|
|
604 (Storing (Storing'First .. Last_Stored));
|
|
605 Ptr := Ptr + 1;
|
|
606 end if;
|
|
607
|
|
608 -- -gnat12
|
|
609
|
|
610 when '1' =>
|
|
611 Last_Stored := First_Stored;
|
|
612 Storing (Last_Stored) := C;
|
|
613 Ptr := Ptr + 1;
|
|
614
|
|
615 if Ptr /= Max or else Switch_Chars (Ptr) /= '2' then
|
|
616
|
|
617 -- Invalid switch
|
|
618
|
|
619 Last := 0;
|
|
620 return;
|
|
621
|
|
622 else
|
|
623 Last_Stored := Last_Stored + 1;
|
|
624 Storing (Last_Stored) := '2';
|
|
625 Add_Switch_Component
|
|
626 (Storing (Storing'First .. Last_Stored));
|
|
627 Ptr := Ptr + 1;
|
|
628 end if;
|
|
629
|
|
630 -- -gnat2005 -gnat2012
|
|
631
|
|
632 when '2' =>
|
|
633 if Ptr + 3 /= Max then
|
|
634 Last := 0;
|
|
635 return;
|
|
636
|
|
637 elsif Switch_Chars (Ptr + 1 .. Ptr + 3) = "005" then
|
|
638 Last_Stored := First_Stored + 3;
|
|
639 Storing (First_Stored .. Last_Stored) := "2005";
|
|
640 Add_Switch_Component
|
|
641 (Storing (Storing'First .. Last_Stored));
|
|
642 Ptr := Max + 1;
|
|
643
|
|
644 elsif Switch_Chars (Ptr + 1 .. Ptr + 3) = "012" then
|
|
645 Last_Stored := First_Stored + 3;
|
|
646 Storing (First_Stored .. Last_Stored) := "2012";
|
|
647 Add_Switch_Component
|
|
648 (Storing (Storing'First .. Last_Stored));
|
|
649 Ptr := Max + 1;
|
|
650
|
|
651 else
|
|
652
|
|
653 -- Invalid switch
|
|
654
|
|
655 Last := 0;
|
|
656 return;
|
|
657
|
|
658 end if;
|
|
659
|
|
660 -- -gnat83
|
|
661
|
|
662 when '8' =>
|
|
663 Last_Stored := First_Stored;
|
|
664 Storing (Last_Stored) := '8';
|
|
665 Ptr := Ptr + 1;
|
|
666
|
|
667 if Ptr /= Max or else Switch_Chars (Ptr) /= '3' then
|
|
668
|
|
669 -- Invalid switch
|
|
670
|
|
671 Last := 0;
|
|
672 return;
|
|
673
|
|
674 else
|
|
675 Last_Stored := Last_Stored + 1;
|
|
676 Storing (Last_Stored) := '3';
|
|
677 Add_Switch_Component
|
|
678 (Storing (Storing'First .. Last_Stored));
|
|
679 Ptr := Ptr + 1;
|
|
680 end if;
|
|
681
|
|
682 -- Not a valid switch
|
|
683
|
|
684 when others =>
|
|
685 Last := 0;
|
|
686 return;
|
|
687 end case;
|
|
688 end case;
|
|
689 end loop;
|
|
690 end Normalize_Compiler_Switches;
|
|
691
|
|
692 function Normalize_Compiler_Switches
|
|
693 (Switch_Chars : String) return Argument_List
|
|
694 is
|
|
695 Last : Natural;
|
|
696
|
|
697 begin
|
|
698 Normalize_Compiler_Switches (Switch_Chars, Global_Switches, Last);
|
|
699
|
|
700 if Last = 0 then
|
|
701 return (1 .. 0 => null);
|
|
702 else
|
|
703 return Global_Switches (Global_Switches'First .. Last);
|
|
704 end if;
|
|
705 end Normalize_Compiler_Switches;
|
|
706
|
|
707 ------------------------
|
|
708 -- Scan_Make_Switches --
|
|
709 ------------------------
|
|
710
|
|
711 procedure Scan_Make_Switches
|
|
712 (Switch_Chars : String;
|
|
713 Success : out Boolean)
|
|
714 is
|
|
715 Ptr : Integer := Switch_Chars'First;
|
|
716 Max : constant Integer := Switch_Chars'Last;
|
|
717 C : Character := ' ';
|
|
718
|
|
719 begin
|
|
720 -- Assume a good switch
|
|
721
|
|
722 Success := True;
|
|
723
|
|
724 -- Skip past the initial character (must be the switch character)
|
|
725
|
|
726 if Ptr = Max then
|
|
727 Bad_Switch (Switch_Chars);
|
|
728
|
|
729 else
|
|
730 Ptr := Ptr + 1;
|
|
731 end if;
|
|
732
|
|
733 -- A little check, "gnat" at the start of a switch is for the compiler
|
|
734
|
|
735 if Switch_Chars'Length >= Ptr + 3
|
|
736 and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
|
|
737 then
|
|
738 Success := False;
|
|
739 return;
|
|
740 end if;
|
|
741
|
|
742 C := Switch_Chars (Ptr);
|
|
743
|
|
744 -- Multiple character switches
|
|
745
|
|
746 -- To preserve building gnat_util, it is not possible to use the
|
|
747 -- constant Strings declare in Make_Util, as Make_Util is not in
|
|
748 -- gnat_util.
|
|
749
|
|
750 if Switch_Chars'Length > 2 then
|
|
751 if Switch_Chars = "--create-missing-dirs" then
|
|
752 Setup_Projects := True;
|
|
753
|
|
754 elsif Switch_Chars'Length > Subdirs_Option'Length
|
|
755 and then
|
|
756 Switch_Chars
|
|
757 (Switch_Chars'First ..
|
|
758 Switch_Chars'First + Subdirs_Option'Length - 1) =
|
|
759 Subdirs_Option
|
|
760 then
|
|
761 Subdirs :=
|
|
762 new String'(Switch_Chars
|
|
763 (Switch_Chars'First + Subdirs_Option'Length ..
|
|
764 Switch_Chars'Last));
|
|
765
|
|
766 elsif Switch_Chars = "--unchecked-shared-lib-imports" then
|
|
767 Opt.Unchecked_Shared_Lib_Imports := True;
|
|
768
|
|
769 elsif Switch_Chars = "--single-compile-per-obj-dir" then
|
|
770 Opt.One_Compilation_Per_Obj_Dir := True;
|
|
771
|
|
772 elsif Switch_Chars = "--no-exit-message" then
|
|
773 Opt.No_Exit_Message := True;
|
|
774
|
|
775 elsif Switch_Chars = "--keep-temp-files" then
|
|
776 Opt.Keep_Temporary_Files := True;
|
|
777
|
|
778 elsif Switch_Chars (Ptr) = '-' then
|
|
779 Bad_Switch (Switch_Chars);
|
|
780
|
|
781 elsif Switch_Chars'Length > 3
|
|
782 and then Switch_Chars (Ptr .. Ptr + 1) = "aP"
|
|
783 then
|
|
784 null;
|
|
785 -- This is only used by gprbuild
|
|
786
|
|
787 elsif C = 'v' and then Switch_Chars'Length = 3 then
|
|
788 Ptr := Ptr + 1;
|
|
789 Verbose_Mode := True;
|
|
790
|
|
791 case Switch_Chars (Ptr) is
|
|
792 when 'l' => Verbosity_Level := Opt.Low;
|
|
793 when 'm' => Verbosity_Level := Opt.Medium;
|
|
794 when 'h' => Verbosity_Level := Opt.High;
|
|
795 when others => Success := False;
|
|
796 end case;
|
|
797
|
|
798 elsif C = 'd' then
|
|
799
|
|
800 -- Note: for the debug switch, the remaining characters in this
|
|
801 -- switch field must all be debug flags, since all valid switch
|
|
802 -- characters are also valid debug characters. This switch is not
|
|
803 -- documented on purpose because it is only used by the
|
|
804 -- implementors.
|
|
805
|
|
806 -- Loop to scan out debug flags
|
|
807
|
|
808 while Ptr < Max loop
|
|
809 Ptr := Ptr + 1;
|
|
810 C := Switch_Chars (Ptr);
|
|
811
|
|
812 if C in 'a' .. 'z' or else C in 'A' .. 'Z' then
|
|
813 Set_Debug_Flag (C);
|
|
814 else
|
|
815 Bad_Switch (Switch_Chars);
|
|
816 end if;
|
|
817 end loop;
|
|
818
|
|
819 elsif C = 'e' then
|
|
820 Ptr := Ptr + 1;
|
|
821
|
|
822 case Switch_Chars (Ptr) is
|
|
823
|
|
824 -- Processing for eI switch
|
|
825
|
|
826 when 'I' =>
|
|
827 Ptr := Ptr + 1;
|
|
828 Scan_Pos (Switch_Chars, Max, Ptr, Main_Index, C);
|
|
829
|
|
830 if Ptr <= Max then
|
|
831 Bad_Switch (Switch_Chars);
|
|
832 end if;
|
|
833
|
|
834 -- Processing for eL switch
|
|
835
|
|
836 when 'L' =>
|
|
837 if Ptr /= Max then
|
|
838 Bad_Switch (Switch_Chars);
|
|
839
|
|
840 else
|
|
841 Follow_Links_For_Files := True;
|
|
842 Follow_Links_For_Dirs := True;
|
|
843 end if;
|
|
844
|
|
845 -- Processing for eS switch
|
|
846
|
|
847 when 'S' =>
|
|
848 if Ptr /= Max then
|
|
849 Bad_Switch (Switch_Chars);
|
|
850
|
|
851 else
|
|
852 Commands_To_Stdout := True;
|
|
853 end if;
|
|
854
|
|
855 when others =>
|
|
856 Bad_Switch (Switch_Chars);
|
|
857 end case;
|
|
858
|
|
859 elsif C = 'j' then
|
|
860 Ptr := Ptr + 1;
|
|
861
|
|
862 declare
|
|
863 Max_Proc : Nat;
|
|
864
|
|
865 begin
|
|
866 Scan_Nat (Switch_Chars, Max, Ptr, Max_Proc, C);
|
|
867
|
|
868 if Ptr <= Max then
|
|
869 Bad_Switch (Switch_Chars);
|
|
870
|
|
871 else
|
|
872 if Max_Proc = 0 then
|
|
873 Max_Proc := Nat (Number_Of_CPUs);
|
|
874
|
|
875 if Max_Proc = 0 then
|
|
876 Max_Proc := 1;
|
|
877 end if;
|
|
878 end if;
|
|
879
|
|
880 Maximum_Processes := Positive (Max_Proc);
|
|
881 end if;
|
|
882 end;
|
|
883
|
|
884 elsif C = 'w' and then Switch_Chars'Length = 3 then
|
|
885 Ptr := Ptr + 1;
|
|
886
|
|
887 if Switch_Chars = "-we" then
|
|
888 Warning_Mode := Treat_As_Error;
|
|
889
|
|
890 elsif Switch_Chars = "-wn" then
|
|
891 Warning_Mode := Normal;
|
|
892
|
|
893 elsif Switch_Chars = "-ws" then
|
|
894 Warning_Mode := Suppress;
|
|
895
|
|
896 else
|
|
897 Success := False;
|
|
898 end if;
|
|
899
|
|
900 else
|
|
901 Success := False;
|
|
902 end if;
|
|
903
|
|
904 -- Single-character switches
|
|
905
|
|
906 else
|
|
907 Check_Switch : begin
|
|
908 case C is
|
|
909 when 'a' =>
|
|
910 Check_Readonly_Files := True;
|
|
911
|
|
912 -- Processing for b switch
|
|
913
|
|
914 when 'b' =>
|
|
915 Bind_Only := True;
|
|
916 Make_Steps := True;
|
|
917
|
|
918 -- Processing for B switch
|
|
919
|
|
920 when 'B' =>
|
|
921 Build_Bind_And_Link_Full_Project := True;
|
|
922
|
|
923 -- Processing for c switch
|
|
924
|
|
925 when 'c' =>
|
|
926 Compile_Only := True;
|
|
927 Make_Steps := True;
|
|
928
|
|
929 -- Processing for C switch
|
|
930
|
|
931 when 'C' =>
|
|
932 Opt.Create_Mapping_File := True;
|
|
933
|
|
934 -- Processing for D switch
|
|
935
|
|
936 when 'D' =>
|
|
937 if Object_Directory_Present then
|
|
938 Osint.Fail ("duplicate -D switch");
|
|
939
|
|
940 else
|
|
941 Object_Directory_Present := True;
|
|
942 end if;
|
|
943
|
|
944 -- Processing for f switch
|
|
945
|
|
946 when 'f' =>
|
|
947 Force_Compilations := True;
|
|
948
|
|
949 -- Processing for F switch
|
|
950
|
|
951 when 'F' =>
|
|
952 Full_Path_Name_For_Brief_Errors := True;
|
|
953
|
|
954 -- Processing for h switch
|
|
955
|
|
956 when 'h' =>
|
|
957 Usage_Requested := True;
|
|
958
|
|
959 -- Processing for i switch
|
|
960
|
|
961 when 'i' =>
|
|
962 In_Place_Mode := True;
|
|
963
|
|
964 -- Processing for j switch
|
|
965
|
|
966 when 'j' =>
|
|
967 -- -j not followed by a number is an error
|
|
968
|
|
969 Bad_Switch (Switch_Chars);
|
|
970
|
|
971 -- Processing for k switch
|
|
972
|
|
973 when 'k' =>
|
|
974 Keep_Going := True;
|
|
975
|
|
976 -- Processing for l switch
|
|
977
|
|
978 when 'l' =>
|
|
979 Link_Only := True;
|
|
980 Make_Steps := True;
|
|
981
|
|
982 -- Processing for M switch
|
|
983
|
|
984 when 'M' =>
|
|
985 List_Dependencies := True;
|
|
986
|
|
987 -- Processing for n switch
|
|
988
|
|
989 when 'n' =>
|
|
990 Do_Not_Execute := True;
|
|
991
|
|
992 -- Processing for o switch
|
|
993
|
|
994 when 'o' =>
|
|
995 if Output_File_Name_Present then
|
|
996 Osint.Fail ("duplicate -o switch");
|
|
997 else
|
|
998 Output_File_Name_Present := True;
|
|
999 end if;
|
|
1000
|
|
1001 -- Processing for p switch
|
|
1002
|
|
1003 when 'p' =>
|
|
1004 Setup_Projects := True;
|
|
1005
|
|
1006 -- Processing for q switch
|
|
1007
|
|
1008 when 'q' =>
|
|
1009 Quiet_Output := True;
|
|
1010
|
|
1011 -- Processing for R switch
|
|
1012
|
|
1013 when 'R' =>
|
|
1014 Run_Path_Option := False;
|
|
1015
|
|
1016 -- Processing for s switch
|
|
1017
|
|
1018 when 's' =>
|
|
1019 Ptr := Ptr + 1;
|
|
1020 Check_Switches := True;
|
|
1021
|
|
1022 -- Processing for v switch
|
|
1023
|
|
1024 when 'v' =>
|
|
1025 Verbose_Mode := True;
|
|
1026 Verbosity_Level := Opt.High;
|
|
1027
|
|
1028 -- Processing for x switch
|
|
1029
|
|
1030 when 'x' =>
|
|
1031 External_Unit_Compilation_Allowed := True;
|
|
1032 Use_Include_Path_File := True;
|
|
1033
|
|
1034 -- Processing for z switch
|
|
1035
|
|
1036 when 'z' =>
|
|
1037 No_Main_Subprogram := True;
|
|
1038
|
|
1039 -- Any other small letter is an illegal switch
|
|
1040
|
|
1041 when others =>
|
|
1042 if C in 'a' .. 'z' then
|
|
1043 Bad_Switch (Switch_Chars);
|
|
1044
|
|
1045 else
|
|
1046 Success := False;
|
|
1047 end if;
|
|
1048 end case;
|
|
1049 end Check_Switch;
|
|
1050 end if;
|
|
1051 end Scan_Make_Switches;
|
|
1052
|
|
1053 end Switch.M;
|