]>
Commit | Line | Data |
---|---|---|
43ff4547 GB |
1 | ------------------------------------------------------------------------------ |
2 | -- -- | |
3 | -- GNAT COMPILER COMPONENTS -- | |
4 | -- -- | |
5 | -- S W I T C H - M -- | |
6 | -- -- | |
7 | -- B o d y -- | |
8 | -- -- | |
1d005acc | 9 | -- Copyright (C) 2001-2019, Free Software Foundation, Inc. -- |
43ff4547 GB |
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- -- | |
b5c84c3c | 13 | -- ware Foundation; either version 3, or (at your option) any later ver- -- |
43ff4547 GB |
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 -- | |
b5c84c3c RD |
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. -- | |
43ff4547 GB |
20 | -- -- |
21 | -- GNAT was originally developed by the GNAT team at New York University. -- | |
1f02b6af | 22 | -- Extensive contributions were provided by Ada Core Technologies Inc. -- |
43ff4547 GB |
23 | -- -- |
24 | ------------------------------------------------------------------------------ | |
25 | ||
26 | with Debug; use Debug; | |
27 | with Osint; use Osint; | |
28 | with Opt; use Opt; | |
29 | with Table; | |
30 | ||
3c971dcc AC |
31 | with System.Multiprocessors; use System.Multiprocessors; |
32 | ||
43ff4547 GB |
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, | |
fbf5a39b | 41 | Table_Name => "Switch.M.Normalized_Switches"); |
43ff4547 GB |
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 | ||
315f0c42 AC |
51 | Subdirs_Option : constant String := "--subdirs="; |
52 | ||
43ff4547 GB |
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 | ||
43ff4547 GB |
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. | |
bb481772 | 75 | -- Otherwise add a new component to the table. |
43ff4547 GB |
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 | ||
1be9633f | 88 | -- Otherwise, if Switches is full, extend it |
43ff4547 GB |
89 | |
90 | elsif Last = Switches'Last then | |
91 | declare | |
6b6fcd3e AC |
92 | New_Switches : constant Argument_List_Access := |
93 | new Argument_List | |
94 | (1 .. Switches'Length + Switches'Length); | |
43ff4547 GB |
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 | |
6b6fcd3e | 103 | |
43ff4547 GB |
104 | if Last = 0 then |
105 | Last := Switches'First; | |
43ff4547 GB |
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); | |
1d6f10a1 | 124 | Normalized_Switches.Append (Switches (Last)); |
43ff4547 GB |
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 | |
43ff4547 GB |
147 | C := Switch_Chars (Ptr); |
148 | ||
149 | -- Processing for a switch | |
150 | ||
151 | case Switch_Starts_With_Gnat is | |
43ff4547 | 152 | when False => |
43ff4547 | 153 | |
fbf5a39b | 154 | -- All switches that don't start with -gnat stay as is, |
68c3f02a | 155 | -- except -pg, -Wall, -k8, -w |
fbf5a39b | 156 | |
68c3f02a | 157 | if Switch_Chars = "-pg" or else Switch_Chars = "-p" then |
fbf5a39b AC |
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 | ||
68c3f02a | 164 | elsif Switch_Chars = "-Wall" then |
c7f0bdd2 | 165 | |
68c3f02a VC |
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 | |
fbf5a39b | 189 | Add_Switch_Component (Switch_Chars); |
68c3f02a VC |
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 | ||
1824c168 AC |
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 | ||
68c3f02a VC |
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; | |
fbf5a39b AC |
214 | end if; |
215 | ||
43ff4547 GB |
216 | return; |
217 | ||
218 | when True => | |
43ff4547 GB |
219 | case C is |
220 | ||
221 | -- One-letter switches | |
222 | ||
d8f43ee6 HK |
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 | => | |
43ff4547 GB |
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 | ||
9a0ddeee | 235 | when 'D' | 'G' | 'j' | 'k' | 'm' | 'T' => |
43ff4547 GB |
236 | Storing (First_Stored) := C; |
237 | Last_Stored := First_Stored; | |
238 | ||
9a0ddeee AC |
239 | if Ptr <= Max and then Switch_Chars (Ptr) = '=' then |
240 | Ptr := Ptr + 1; | |
241 | end if; | |
242 | ||
43ff4547 GB |
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' => | |
fbf5a39b | 280 | |
9a0ddeee | 281 | -- Some of the gnate... switches are not stored |
fbf5a39b AC |
282 | |
283 | Storing (First_Stored) := 'e'; | |
284 | Ptr := Ptr + 1; | |
285 | ||
9a0ddeee | 286 | if Ptr > Max then |
fbf5a39b AC |
287 | Last := 0; |
288 | return; | |
fbf5a39b | 289 | |
9a0ddeee AC |
290 | else |
291 | case Switch_Chars (Ptr) is | |
8880426d AC |
292 | when 'A' => |
293 | Ptr := Ptr + 1; | |
294 | Add_Switch_Component ("-gnateA"); | |
295 | ||
9a0ddeee AC |
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 | ||
8880426d AC |
305 | when 'E' | 'F' | 'G' | 'S' | 'u' | 'V' | 'Y' => |
306 | Add_Switch_Component | |
307 | ("-gnate" & Switch_Chars (Ptr)); | |
9a0ddeee | 308 | Ptr := Ptr + 1; |
fbf5a39b | 309 | |
8880426d | 310 | when 'i' | 'I' => |
9a0ddeee | 311 | declare |
8880426d | 312 | First : constant Positive := Ptr; |
fe2194df | 313 | |
9a0ddeee | 314 | begin |
8880426d AC |
315 | Ptr := Ptr + 1; |
316 | ||
9a0ddeee AC |
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 | ||
fe2194df RD |
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 | ||
9a0ddeee AC |
345 | when 'p' => |
346 | Ptr := Ptr + 1; | |
fbf5a39b | 347 | |
9a0ddeee AC |
348 | if Ptr = Max then |
349 | Last := 0; | |
350 | return; | |
351 | end if; | |
fbf5a39b | 352 | |
9a0ddeee AC |
353 | if Switch_Chars (Ptr) = '=' then |
354 | Ptr := Ptr + 1; | |
355 | end if; | |
fbf5a39b | 356 | |
9a0ddeee AC |
357 | -- To normalize, always put a '=' after |
358 | -- -gnatep. Because that could lengthen the | |
359 | -- switch string, declare a local variable. | |
fbf5a39b | 360 | |
9a0ddeee AC |
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; | |
fbf5a39b | 369 | |
9a0ddeee | 370 | return; |
a037f912 | 371 | |
9a0ddeee AC |
372 | when others => |
373 | Last := 0; | |
374 | return; | |
375 | end case; | |
fbf5a39b | 376 | end if; |
43ff4547 | 377 | |
43ff4547 GB |
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 | ||
9a0ddeee AC |
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 | ||
c4250ab1 | 421 | -- -gnatn may be -gnatn, -gnatn1, or -gnatn2 |
79ee6ab3 AC |
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 | ||
2a7b8e18 AC |
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 | ||
b5f581cd EB |
465 | -- -gnatR may be followed by '0', '1', '2', '3' or '4', |
466 | -- then by 'e', 'j', 'm' or 's'. | |
43ff4547 GB |
467 | |
468 | when 'R' => | |
469 | Last_Stored := First_Stored; | |
470 | Storing (Last_Stored) := 'R'; | |
471 | Ptr := Ptr + 1; | |
472 | ||
b5f581cd | 473 | while Ptr <= Max loop |
43ff4547 GB |
474 | C := Switch_Chars (Ptr); |
475 | ||
b5f581cd | 476 | case C is |
43ff4547 | 477 | |
b5f581cd | 478 | when '0' .. '4' | 'e' | 'j' | 'm' | 's' => |
43ff4547 GB |
479 | Last_Stored := Last_Stored + 1; |
480 | Storing (Last_Stored) := C; | |
481 | Ptr := Ptr + 1; | |
482 | ||
b5f581cd EB |
483 | when others => |
484 | Last := 0; | |
485 | return; | |
486 | end case; | |
487 | end loop; | |
43ff4547 GB |
488 | |
489 | Add_Switch_Component | |
490 | (Storing (Storing'First .. Last_Stored)); | |
491 | ||
9a0ddeee AC |
492 | -- -gnatWx, x = 'h'. 'u', 's', 'e', '8' or 'b' |
493 | ||
494 | when 'W' => | |
495 | Storing (First_Stored) := 'W'; | |
496 | Ptr := Ptr + 1; | |
497 | ||
498 | if Ptr <= Max then | |
499 | case Switch_Chars (Ptr) is | |
500 | when 'h' | 'u' | 's' | 'e' | '8' | 'b' => | |
501 | Storing (First_Stored + 1) := Switch_Chars (Ptr); | |
502 | Add_Switch_Component | |
503 | (Storing (Storing'First .. First_Stored + 1)); | |
504 | Ptr := Ptr + 1; | |
505 | ||
506 | when others => | |
507 | Last := 0; | |
508 | return; | |
509 | end case; | |
510 | end if; | |
511 | ||
43ff4547 GB |
512 | -- Multiple switches |
513 | ||
514 | when 'V' | 'w' | 'y' => | |
515 | Storing (First_Stored) := C; | |
516 | Ptr := Ptr + 1; | |
517 | ||
518 | if Ptr > Max then | |
519 | if C = 'y' then | |
520 | Add_Switch_Component | |
521 | (Storing (Storing'First .. First_Stored)); | |
522 | ||
523 | else | |
524 | Last := 0; | |
525 | return; | |
526 | end if; | |
527 | end if; | |
528 | ||
1be9633f AC |
529 | -- Loop through remaining switch characters in string |
530 | ||
43ff4547 GB |
531 | while Ptr <= Max loop |
532 | C := Switch_Chars (Ptr); | |
533 | Ptr := Ptr + 1; | |
534 | ||
958a816e | 535 | -- -gnatyMxxx |
43ff4547 | 536 | |
68c3f02a | 537 | if C = 'M' and then Storing (First_Stored) = 'y' then |
958a816e VC |
538 | Last_Stored := First_Stored + 1; |
539 | Storing (Last_Stored) := 'M'; | |
958a816e VC |
540 | while Ptr <= Max loop |
541 | C := Switch_Chars (Ptr); | |
542 | exit when C not in '0' .. '9'; | |
543 | Last_Stored := Last_Stored + 1; | |
544 | Storing (Last_Stored) := C; | |
545 | Ptr := Ptr + 1; | |
546 | end loop; | |
43ff4547 | 547 | |
958a816e VC |
548 | -- If there is no digit after -gnatyM, |
549 | -- the switch is invalid. | |
43ff4547 | 550 | |
958a816e VC |
551 | if Last_Stored = First_Stored + 1 then |
552 | Last := 0; | |
553 | return; | |
43ff4547 GB |
554 | |
555 | else | |
43ff4547 | 556 | Add_Switch_Component |
958a816e | 557 | (Storing (Storing'First .. Last_Stored)); |
43ff4547 | 558 | end if; |
958a816e | 559 | |
1be9633f AC |
560 | -- --gnatx.x |
561 | ||
562 | elsif C = '.' and then Ptr <= Max then | |
563 | Storing (First_Stored + 1) := '.'; | |
564 | Storing (First_Stored + 2) := Switch_Chars (Ptr); | |
565 | Ptr := Ptr + 1; | |
566 | Add_Switch_Component | |
567 | (Storing (Storing'First .. First_Stored + 2)); | |
568 | ||
569 | -- All other switches are -gnatxx | |
958a816e VC |
570 | |
571 | else | |
572 | Storing (First_Stored + 1) := C; | |
573 | Add_Switch_Component | |
574 | (Storing (Storing'First .. First_Stored + 1)); | |
43ff4547 GB |
575 | end if; |
576 | end loop; | |
577 | ||
8095d0fa VC |
578 | -- -gnat95 -gnat05 |
579 | ||
580 | when '0' | '9' => | |
581 | Last_Stored := First_Stored; | |
582 | Storing (Last_Stored) := C; | |
583 | Ptr := Ptr + 1; | |
584 | ||
585 | if Ptr /= Max or else Switch_Chars (Ptr) /= '5' then | |
586 | ||
587 | -- Invalid switch | |
588 | ||
589 | Last := 0; | |
590 | return; | |
591 | ||
592 | else | |
593 | Last_Stored := Last_Stored + 1; | |
594 | Storing (Last_Stored) := '5'; | |
595 | Add_Switch_Component | |
596 | (Storing (Storing'First .. Last_Stored)); | |
597 | Ptr := Ptr + 1; | |
598 | end if; | |
599 | ||
87729e5a AC |
600 | -- -gnat12 |
601 | ||
602 | when '1' => | |
603 | Last_Stored := First_Stored; | |
604 | Storing (Last_Stored) := C; | |
605 | Ptr := Ptr + 1; | |
606 | ||
607 | if Ptr /= Max or else Switch_Chars (Ptr) /= '2' then | |
608 | ||
609 | -- Invalid switch | |
610 | ||
611 | Last := 0; | |
612 | return; | |
613 | ||
614 | else | |
615 | Last_Stored := Last_Stored + 1; | |
616 | Storing (Last_Stored) := '2'; | |
617 | Add_Switch_Component | |
618 | (Storing (Storing'First .. Last_Stored)); | |
619 | Ptr := Ptr + 1; | |
620 | end if; | |
621 | ||
622 | -- -gnat2005 -gnat2012 | |
623 | ||
624 | when '2' => | |
625 | if Ptr + 3 /= Max then | |
626 | Last := 0; | |
627 | return; | |
628 | ||
629 | elsif Switch_Chars (Ptr + 1 .. Ptr + 3) = "005" then | |
630 | Last_Stored := First_Stored + 3; | |
631 | Storing (First_Stored .. Last_Stored) := "2005"; | |
632 | Add_Switch_Component | |
633 | (Storing (Storing'First .. Last_Stored)); | |
634 | Ptr := Max + 1; | |
635 | ||
636 | elsif Switch_Chars (Ptr + 1 .. Ptr + 3) = "012" then | |
637 | Last_Stored := First_Stored + 3; | |
638 | Storing (First_Stored .. Last_Stored) := "2012"; | |
639 | Add_Switch_Component | |
640 | (Storing (Storing'First .. Last_Stored)); | |
641 | Ptr := Max + 1; | |
642 | ||
643 | else | |
644 | ||
645 | -- Invalid switch | |
646 | ||
647 | Last := 0; | |
648 | return; | |
649 | ||
650 | end if; | |
651 | ||
8095d0fa VC |
652 | -- -gnat83 |
653 | ||
654 | when '8' => | |
655 | Last_Stored := First_Stored; | |
656 | Storing (Last_Stored) := '8'; | |
657 | Ptr := Ptr + 1; | |
658 | ||
659 | if Ptr /= Max or else Switch_Chars (Ptr) /= '3' then | |
660 | ||
661 | -- Invalid switch | |
662 | ||
663 | Last := 0; | |
664 | return; | |
665 | ||
666 | else | |
667 | Last_Stored := Last_Stored + 1; | |
668 | Storing (Last_Stored) := '3'; | |
669 | Add_Switch_Component | |
670 | (Storing (Storing'First .. Last_Stored)); | |
671 | Ptr := Ptr + 1; | |
672 | end if; | |
673 | ||
43ff4547 GB |
674 | -- Not a valid switch |
675 | ||
676 | when others => | |
677 | Last := 0; | |
678 | return; | |
43ff4547 | 679 | end case; |
43ff4547 GB |
680 | end case; |
681 | end loop; | |
682 | end Normalize_Compiler_Switches; | |
683 | ||
684 | function Normalize_Compiler_Switches | |
1be9633f | 685 | (Switch_Chars : String) return Argument_List |
43ff4547 GB |
686 | is |
687 | Last : Natural; | |
688 | ||
689 | begin | |
690 | Normalize_Compiler_Switches (Switch_Chars, Global_Switches, Last); | |
691 | ||
692 | if Last = 0 then | |
693 | return (1 .. 0 => null); | |
43ff4547 GB |
694 | else |
695 | return Global_Switches (Global_Switches'First .. Last); | |
696 | end if; | |
43ff4547 GB |
697 | end Normalize_Compiler_Switches; |
698 | ||
699 | ------------------------ | |
700 | -- Scan_Make_Switches -- | |
701 | ------------------------ | |
702 | ||
958a816e | 703 | procedure Scan_Make_Switches |
315f0c42 | 704 | (Switch_Chars : String; |
52545f22 | 705 | Success : out Boolean) |
958a816e | 706 | is |
fbf5a39b AC |
707 | Ptr : Integer := Switch_Chars'First; |
708 | Max : constant Integer := Switch_Chars'Last; | |
709 | C : Character := ' '; | |
43ff4547 GB |
710 | |
711 | begin | |
958a816e VC |
712 | -- Assume a good switch |
713 | ||
714 | Success := True; | |
715 | ||
43ff4547 GB |
716 | -- Skip past the initial character (must be the switch character) |
717 | ||
718 | if Ptr = Max then | |
61dddae4 | 719 | Bad_Switch (Switch_Chars); |
43ff4547 GB |
720 | |
721 | else | |
722 | Ptr := Ptr + 1; | |
723 | end if; | |
724 | ||
958a816e | 725 | -- A little check, "gnat" at the start of a switch is for the compiler |
43ff4547 GB |
726 | |
727 | if Switch_Chars'Length >= Ptr + 3 | |
728 | and then Switch_Chars (Ptr .. Ptr + 3) = "gnat" | |
729 | then | |
958a816e VC |
730 | Success := False; |
731 | return; | |
43ff4547 GB |
732 | end if; |
733 | ||
958a816e | 734 | C := Switch_Chars (Ptr); |
91b1417d | 735 | |
958a816e | 736 | -- Multiple character switches |
43ff4547 | 737 | |
315f0c42 AC |
738 | -- To preserve building gnat_util, it is not possible to use the |
739 | -- constant Strings declare in Make_Util, as Make_Util is not in | |
740 | -- gnat_util. | |
741 | ||
958a816e VC |
742 | if Switch_Chars'Length > 2 then |
743 | if Switch_Chars = "--create-missing-dirs" then | |
744 | Setup_Projects := True; | |
43ff4547 | 745 | |
68c3f02a VC |
746 | elsif Switch_Chars'Length > Subdirs_Option'Length |
747 | and then | |
748 | Switch_Chars | |
749 | (Switch_Chars'First .. | |
750 | Switch_Chars'First + Subdirs_Option'Length - 1) = | |
751 | Subdirs_Option | |
752 | then | |
753 | Subdirs := | |
315f0c42 AC |
754 | new String'(Switch_Chars |
755 | (Switch_Chars'First + Subdirs_Option'Length .. | |
756 | Switch_Chars'Last)); | |
68c3f02a | 757 | |
315f0c42 | 758 | elsif Switch_Chars = "--unchecked-shared-lib-imports" then |
eeb41f01 VC |
759 | Opt.Unchecked_Shared_Lib_Imports := True; |
760 | ||
315f0c42 | 761 | elsif Switch_Chars = "--single-compile-per-obj-dir" then |
02954c25 AC |
762 | Opt.One_Compilation_Per_Obj_Dir := True; |
763 | ||
315f0c42 | 764 | elsif Switch_Chars = "--no-exit-message" then |
3849c246 VC |
765 | Opt.No_Exit_Message := True; |
766 | ||
315f0c42 | 767 | elsif Switch_Chars = "--keep-temp-files" then |
b330e3c8 AC |
768 | Opt.Keep_Temporary_Files := True; |
769 | ||
68c3f02a VC |
770 | elsif Switch_Chars (Ptr) = '-' then |
771 | Bad_Switch (Switch_Chars); | |
772 | ||
773 | elsif Switch_Chars'Length > 3 | |
774 | and then Switch_Chars (Ptr .. Ptr + 1) = "aP" | |
c7f0bdd2 | 775 | then |
315f0c42 AC |
776 | null; |
777 | -- This is only used by gprbuild | |
c7f0bdd2 | 778 | |
958a816e | 779 | elsif C = 'v' and then Switch_Chars'Length = 3 then |
43ff4547 | 780 | Ptr := Ptr + 1; |
958a816e | 781 | Verbose_Mode := True; |
fbf5a39b | 782 | |
958a816e | 783 | case Switch_Chars (Ptr) is |
315f0c42 AC |
784 | when 'l' => Verbosity_Level := Opt.Low; |
785 | when 'm' => Verbosity_Level := Opt.Medium; | |
786 | when 'h' => Verbosity_Level := Opt.High; | |
787 | when others => Success := False; | |
958a816e | 788 | end case; |
43ff4547 | 789 | |
958a816e | 790 | elsif C = 'd' then |
43ff4547 GB |
791 | |
792 | -- Note: for the debug switch, the remaining characters in this | |
793 | -- switch field must all be debug flags, since all valid switch | |
794 | -- characters are also valid debug characters. This switch is not | |
795 | -- documented on purpose because it is only used by the | |
796 | -- implementors. | |
797 | ||
798 | -- Loop to scan out debug flags | |
799 | ||
800 | while Ptr < Max loop | |
801 | Ptr := Ptr + 1; | |
802 | C := Switch_Chars (Ptr); | |
43ff4547 | 803 | |
61dddae4 | 804 | if C in 'a' .. 'z' or else C in 'A' .. 'Z' then |
43ff4547 GB |
805 | Set_Debug_Flag (C); |
806 | else | |
61dddae4 | 807 | Bad_Switch (Switch_Chars); |
43ff4547 GB |
808 | end if; |
809 | end loop; | |
810 | ||
958a816e | 811 | elsif C = 'e' then |
7324bf49 AC |
812 | Ptr := Ptr + 1; |
813 | ||
7324bf49 AC |
814 | case Switch_Chars (Ptr) is |
815 | ||
64c69860 | 816 | -- Processing for eI switch |
aa720a54 | 817 | |
315f0c42 AC |
818 | when 'I' => |
819 | Ptr := Ptr + 1; | |
820 | Scan_Pos (Switch_Chars, Max, Ptr, Main_Index, C); | |
aa720a54 | 821 | |
315f0c42 AC |
822 | if Ptr <= Max then |
823 | Bad_Switch (Switch_Chars); | |
824 | end if; | |
958a816e | 825 | |
64c69860 | 826 | -- Processing for eL switch |
7324bf49 | 827 | |
315f0c42 AC |
828 | when 'L' => |
829 | if Ptr /= Max then | |
830 | Bad_Switch (Switch_Chars); | |
958a816e | 831 | |
315f0c42 AC |
832 | else |
833 | Follow_Links_For_Files := True; | |
834 | Follow_Links_For_Dirs := True; | |
835 | end if; | |
958a816e VC |
836 | |
837 | -- Processing for eS switch | |
838 | ||
315f0c42 AC |
839 | when 'S' => |
840 | if Ptr /= Max then | |
841 | Bad_Switch (Switch_Chars); | |
958a816e | 842 | |
315f0c42 AC |
843 | else |
844 | Commands_To_Stdout := True; | |
845 | end if; | |
7324bf49 | 846 | |
315f0c42 AC |
847 | when others => |
848 | Bad_Switch (Switch_Chars); | |
7324bf49 AC |
849 | end case; |
850 | ||
958a816e | 851 | elsif C = 'j' then |
43ff4547 | 852 | Ptr := Ptr + 1; |
43ff4547 | 853 | |
958a816e | 854 | declare |
3c971dcc | 855 | Max_Proc : Nat; |
f16e8df9 | 856 | |
958a816e | 857 | begin |
3c971dcc | 858 | Scan_Nat (Switch_Chars, Max, Ptr, Max_Proc, C); |
fbf5a39b | 859 | |
958a816e VC |
860 | if Ptr <= Max then |
861 | Bad_Switch (Switch_Chars); | |
fbf5a39b | 862 | |
958a816e | 863 | else |
3c971dcc AC |
864 | if Max_Proc = 0 then |
865 | Max_Proc := Nat (Number_Of_CPUs); | |
866 | ||
867 | if Max_Proc = 0 then | |
868 | Max_Proc := 1; | |
869 | end if; | |
870 | end if; | |
871 | ||
958a816e VC |
872 | Maximum_Processes := Positive (Max_Proc); |
873 | end if; | |
874 | end; | |
43ff4547 | 875 | |
958a816e | 876 | elsif C = 'w' and then Switch_Chars'Length = 3 then |
43ff4547 | 877 | Ptr := Ptr + 1; |
43ff4547 | 878 | |
958a816e VC |
879 | if Switch_Chars = "-we" then |
880 | Warning_Mode := Treat_As_Error; | |
43ff4547 | 881 | |
958a816e VC |
882 | elsif Switch_Chars = "-wn" then |
883 | Warning_Mode := Normal; | |
43ff4547 | 884 | |
958a816e VC |
885 | elsif Switch_Chars = "-ws" then |
886 | Warning_Mode := Suppress; | |
43ff4547 | 887 | |
958a816e VC |
888 | else |
889 | Success := False; | |
61dddae4 RD |
890 | end if; |
891 | ||
958a816e VC |
892 | else |
893 | Success := False; | |
894 | end if; | |
43ff4547 | 895 | |
958a816e | 896 | -- Single-character switches |
43ff4547 | 897 | |
958a816e VC |
898 | else |
899 | Check_Switch : begin | |
958a816e | 900 | case C is |
958a816e VC |
901 | when 'a' => |
902 | Check_Readonly_Files := True; | |
43ff4547 | 903 | |
958a816e | 904 | -- Processing for b switch |
43ff4547 | 905 | |
958a816e VC |
906 | when 'b' => |
907 | Bind_Only := True; | |
908 | Make_Steps := True; | |
43ff4547 | 909 | |
958a816e | 910 | -- Processing for B switch |
43ff4547 | 911 | |
958a816e VC |
912 | when 'B' => |
913 | Build_Bind_And_Link_Full_Project := True; | |
43ff4547 | 914 | |
958a816e | 915 | -- Processing for c switch |
43ff4547 | 916 | |
958a816e VC |
917 | when 'c' => |
918 | Compile_Only := True; | |
919 | Make_Steps := True; | |
43ff4547 | 920 | |
958a816e | 921 | -- Processing for C switch |
43ff4547 | 922 | |
958a816e | 923 | when 'C' => |
a0a786e3 | 924 | Opt.Create_Mapping_File := True; |
43ff4547 | 925 | |
958a816e | 926 | -- Processing for D switch |
43ff4547 | 927 | |
958a816e VC |
928 | when 'D' => |
929 | if Object_Directory_Present then | |
930 | Osint.Fail ("duplicate -D switch"); | |
fbf5a39b | 931 | |
958a816e VC |
932 | else |
933 | Object_Directory_Present := True; | |
934 | end if; | |
fbf5a39b | 935 | |
958a816e | 936 | -- Processing for f switch |
43ff4547 | 937 | |
958a816e VC |
938 | when 'f' => |
939 | Force_Compilations := True; | |
43ff4547 | 940 | |
958a816e | 941 | -- Processing for F switch |
64c69860 | 942 | |
958a816e VC |
943 | when 'F' => |
944 | Full_Path_Name_For_Brief_Errors := True; | |
64c69860 | 945 | |
958a816e | 946 | -- Processing for h switch |
43ff4547 | 947 | |
958a816e VC |
948 | when 'h' => |
949 | Usage_Requested := True; | |
a7ab2998 | 950 | |
958a816e | 951 | -- Processing for i switch |
a7ab2998 | 952 | |
958a816e VC |
953 | when 'i' => |
954 | In_Place_Mode := True; | |
a7ab2998 | 955 | |
958a816e | 956 | -- Processing for j switch |
a7ab2998 | 957 | |
958a816e VC |
958 | when 'j' => |
959 | -- -j not followed by a number is an error | |
a7ab2998 | 960 | |
958a816e | 961 | Bad_Switch (Switch_Chars); |
43ff4547 | 962 | |
958a816e | 963 | -- Processing for k switch |
5950a3ac | 964 | |
958a816e VC |
965 | when 'k' => |
966 | Keep_Going := True; | |
5950a3ac | 967 | |
958a816e | 968 | -- Processing for l switch |
43ff4547 | 969 | |
958a816e VC |
970 | when 'l' => |
971 | Link_Only := True; | |
972 | Make_Steps := True; | |
43ff4547 | 973 | |
958a816e | 974 | -- Processing for M switch |
43ff4547 | 975 | |
958a816e VC |
976 | when 'M' => |
977 | List_Dependencies := True; | |
43ff4547 | 978 | |
958a816e | 979 | -- Processing for n switch |
fbf5a39b | 980 | |
958a816e VC |
981 | when 'n' => |
982 | Do_Not_Execute := True; | |
983 | ||
984 | -- Processing for o switch | |
985 | ||
986 | when 'o' => | |
987 | if Output_File_Name_Present then | |
988 | Osint.Fail ("duplicate -o switch"); | |
989 | else | |
990 | Output_File_Name_Present := True; | |
991 | end if; | |
992 | ||
993 | -- Processing for p switch | |
994 | ||
995 | when 'p' => | |
996 | Setup_Projects := True; | |
997 | ||
998 | -- Processing for q switch | |
999 | ||
1000 | when 'q' => | |
1001 | Quiet_Output := True; | |
1002 | ||
1003 | -- Processing for R switch | |
1004 | ||
1005 | when 'R' => | |
1006 | Run_Path_Option := False; | |
fbf5a39b | 1007 | |
958a816e | 1008 | -- Processing for s switch |
43ff4547 | 1009 | |
958a816e VC |
1010 | when 's' => |
1011 | Ptr := Ptr + 1; | |
1012 | Check_Switches := True; | |
1013 | ||
1014 | -- Processing for v switch | |
1015 | ||
1016 | when 'v' => | |
1017 | Verbose_Mode := True; | |
1018 | Verbosity_Level := Opt.High; | |
1019 | ||
1020 | -- Processing for x switch | |
1021 | ||
1022 | when 'x' => | |
1023 | External_Unit_Compilation_Allowed := True; | |
b29def53 | 1024 | Use_Include_Path_File := True; |
958a816e VC |
1025 | |
1026 | -- Processing for z switch | |
1027 | ||
1028 | when 'z' => | |
1029 | No_Main_Subprogram := True; | |
1030 | ||
1031 | -- Any other small letter is an illegal switch | |
1032 | ||
1033 | when others => | |
1034 | if C in 'a' .. 'z' then | |
1035 | Bad_Switch (Switch_Chars); | |
1036 | ||
1037 | else | |
1038 | Success := False; | |
1039 | end if; | |
958a816e VC |
1040 | end case; |
1041 | end Check_Switch; | |
1042 | end if; | |
43ff4547 GB |
1043 | end Scan_Make_Switches; |
1044 | ||
1045 | end Switch.M; |