111
|
1 ------------------------------------------------------------------------------
|
|
2 -- --
|
|
3 -- GNAT COMPILER COMPONENTS --
|
|
4 -- --
|
|
5 -- S W I T C H - B --
|
|
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 Bindgen;
|
|
27 with Debug; use Debug;
|
|
28 with Osint; use Osint;
|
|
29 with Opt; use Opt;
|
|
30
|
|
31 with System.OS_Lib; use System.OS_Lib;
|
|
32 with System.WCh_Con; use System.WCh_Con;
|
|
33
|
|
34 package body Switch.B is
|
|
35
|
|
36 --------------------------
|
|
37 -- Scan_Binder_Switches --
|
|
38 --------------------------
|
|
39
|
|
40 procedure Scan_Binder_Switches (Switch_Chars : String) is
|
|
41 Max : constant Integer := Switch_Chars'Last;
|
|
42 Ptr : Integer := Switch_Chars'First;
|
|
43 C : Character := ' ';
|
|
44
|
|
45 function Get_Optional_Filename return String_Ptr;
|
|
46 -- If current character is '=', return a newly allocated string that
|
|
47 -- contains the remainder of the current switch (after the '='), else
|
|
48 -- return null.
|
|
49
|
|
50 function Get_Stack_Size (S : Character) return Int;
|
|
51 -- Used for -d and -D to scan stack size including handling k/m. S is
|
|
52 -- set to 'd' or 'D' to indicate the switch being scanned.
|
|
53
|
|
54 ---------------------------
|
|
55 -- Get_Optional_Filename --
|
|
56 ---------------------------
|
|
57
|
|
58 function Get_Optional_Filename return String_Ptr is
|
|
59 Result : String_Ptr;
|
|
60
|
|
61 begin
|
|
62 if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
|
|
63 if Ptr = Max then
|
|
64 Bad_Switch (Switch_Chars);
|
|
65 else
|
|
66 Result := new String'(Switch_Chars (Ptr + 1 .. Max));
|
|
67 Ptr := Max + 1;
|
|
68 return Result;
|
|
69 end if;
|
|
70 end if;
|
|
71
|
|
72 return null;
|
|
73 end Get_Optional_Filename;
|
|
74
|
|
75 --------------------
|
|
76 -- Get_Stack_Size --
|
|
77 --------------------
|
|
78
|
|
79 function Get_Stack_Size (S : Character) return Int is
|
|
80 Result : Int;
|
|
81
|
|
82 begin
|
|
83 Scan_Pos (Switch_Chars, Max, Ptr, Result, S);
|
|
84
|
|
85 -- In the following code, we enable overflow checking since the
|
|
86 -- multiplication by K or M may cause overflow, which is an error.
|
|
87
|
|
88 declare
|
|
89 pragma Unsuppress (Overflow_Check);
|
|
90
|
|
91 begin
|
|
92 -- Check for additional character 'k' (for kilobytes) or 'm' (for
|
|
93 -- Megabytes), but only if we have not reached the end of the
|
|
94 -- switch string. Note that if this appears before the end of the
|
|
95 -- string we will get an error when we test to make sure that the
|
|
96 -- string is exhausted (at the end of the case).
|
|
97
|
|
98 if Ptr <= Max then
|
|
99 if Switch_Chars (Ptr) = 'k' then
|
|
100 Result := Result * 1024;
|
|
101 Ptr := Ptr + 1;
|
|
102
|
|
103 elsif Switch_Chars (Ptr) = 'm' then
|
|
104 Result := Result * (1024 * 1024);
|
|
105 Ptr := Ptr + 1;
|
|
106 end if;
|
|
107 end if;
|
|
108
|
|
109 exception
|
|
110 when Constraint_Error =>
|
|
111 Osint.Fail ("numeric value out of range for switch: " & S);
|
|
112 end;
|
|
113
|
|
114 return Result;
|
|
115 end Get_Stack_Size;
|
|
116
|
|
117 -- Start of processing for Scan_Binder_Switches
|
|
118
|
|
119 begin
|
|
120 -- Skip past the initial character (must be the switch character)
|
|
121
|
|
122 if Ptr = Max then
|
|
123 Bad_Switch (Switch_Chars);
|
|
124 else
|
|
125 Ptr := Ptr + 1;
|
|
126 end if;
|
|
127
|
|
128 -- A little check, "gnat" at the start of a switch is not allowed except
|
|
129 -- for the compiler
|
|
130
|
|
131 if Max >= Ptr + 3
|
|
132 and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
|
|
133 then
|
|
134 Osint.Fail ("invalid switch: """ & Switch_Chars & """"
|
|
135 & " (gnat not needed here)");
|
|
136 end if;
|
|
137
|
|
138 -- Loop to scan through switches given in switch string
|
|
139
|
|
140 Check_Switch : begin
|
|
141 C := Switch_Chars (Ptr);
|
|
142
|
|
143 case C is
|
|
144
|
|
145 -- Processing for a switch
|
|
146
|
|
147 when 'a' =>
|
|
148 Ptr := Ptr + 1;
|
|
149 Use_Pragma_Linker_Constructor := True;
|
|
150
|
|
151 -- Processing for A switch
|
|
152
|
|
153 when 'A' =>
|
|
154 Ptr := Ptr + 1;
|
|
155 Output_ALI_List := True;
|
|
156 ALI_List_Filename := Get_Optional_Filename;
|
|
157
|
|
158 -- Processing for b switch
|
|
159
|
|
160 when 'b' =>
|
|
161 Ptr := Ptr + 1;
|
|
162 Brief_Output := True;
|
|
163
|
|
164 -- Processing for c switch
|
|
165
|
|
166 when 'c' =>
|
|
167 Ptr := Ptr + 1;
|
|
168 Check_Only := True;
|
|
169
|
|
170 -- Processing for d switch
|
|
171
|
|
172 when 'd' =>
|
|
173
|
|
174 if Ptr = Max then
|
|
175 Bad_Switch (Switch_Chars);
|
|
176 end if;
|
|
177
|
|
178 Ptr := Ptr + 1;
|
|
179 C := Switch_Chars (Ptr);
|
|
180
|
|
181 -- Case where character after -d is a digit (default stack size)
|
|
182
|
|
183 if C in '0' .. '9' then
|
|
184
|
|
185 -- In this case, we process the default primary stack size
|
|
186
|
|
187 Default_Stack_Size := Get_Stack_Size ('d');
|
|
188
|
|
189 -- Case where character after -d is not digit (debug flags)
|
|
190
|
|
191 else
|
|
192 -- Note: for the debug switch, the remaining characters in this
|
|
193 -- switch field must all be debug flags, since all valid switch
|
|
194 -- characters are also valid debug characters. This switch is
|
|
195 -- not documented on purpose because it is only used by the
|
|
196 -- implementors.
|
|
197
|
|
198 -- Loop to scan out debug flags
|
|
199
|
|
200 loop
|
|
201 C := Switch_Chars (Ptr);
|
|
202
|
|
203 if C in 'a' .. 'z' or else C in 'A' .. 'Z' then
|
|
204 Set_Debug_Flag (C);
|
|
205 else
|
|
206 Bad_Switch (Switch_Chars);
|
|
207 end if;
|
|
208
|
|
209 Ptr := Ptr + 1;
|
|
210 exit when Ptr > Max;
|
|
211 end loop;
|
|
212 end if;
|
|
213
|
|
214 -- Processing for D switch
|
|
215
|
|
216 when 'D' =>
|
|
217 if Ptr = Max then
|
|
218 Bad_Switch (Switch_Chars);
|
|
219 end if;
|
|
220
|
|
221 Ptr := Ptr + 1;
|
|
222 Default_Sec_Stack_Size := Get_Stack_Size ('D');
|
|
223
|
|
224 -- Processing for e switch
|
|
225
|
|
226 when 'e' =>
|
|
227 Ptr := Ptr + 1;
|
|
228 Elab_Dependency_Output := True;
|
|
229
|
|
230 -- Processing for E switch
|
|
231
|
|
232 when 'E' =>
|
|
233
|
|
234 -- -E is equivalent to -Ea (see below)
|
|
235
|
|
236 Exception_Tracebacks := True;
|
|
237 Ptr := Ptr + 1;
|
|
238
|
|
239 if Ptr <= Max then
|
|
240 case Switch_Chars (Ptr) is
|
|
241
|
|
242 -- -Ea sets Exception_Tracebacks
|
|
243
|
|
244 when 'a' => null;
|
|
245
|
|
246 -- -Es sets both Exception_Tracebacks and
|
|
247 -- Exception_Tracebacks_Symbolic.
|
|
248
|
|
249 when 's' => Exception_Tracebacks_Symbolic := True;
|
|
250 when others => Bad_Switch (Switch_Chars);
|
|
251 end case;
|
|
252
|
|
253 Ptr := Ptr + 1;
|
|
254 end if;
|
|
255
|
|
256 -- Processing for f switch
|
|
257
|
|
258 when 'f' =>
|
|
259 if Ptr = Max then
|
|
260 Bad_Switch (Switch_Chars);
|
|
261 end if;
|
|
262
|
|
263 Force_Elab_Order_File :=
|
|
264 new String'(Switch_Chars (Ptr + 1 .. Max));
|
|
265
|
|
266 Ptr := Max + 1;
|
|
267
|
|
268 if not Is_Read_Accessible_File (Force_Elab_Order_File.all) then
|
|
269 Osint.Fail (Force_Elab_Order_File.all & ": file not found");
|
|
270 end if;
|
|
271
|
|
272 -- Processing for F switch
|
|
273
|
|
274 when 'F' =>
|
|
275 Ptr := Ptr + 1;
|
|
276 Force_Checking_Of_Elaboration_Flags := True;
|
|
277
|
|
278 -- Processing for g switch
|
|
279
|
|
280 when 'g' =>
|
|
281 Ptr := Ptr + 1;
|
|
282
|
|
283 if Ptr <= Max then
|
|
284 C := Switch_Chars (Ptr);
|
|
285
|
|
286 if C in '0' .. '3' then
|
|
287 Debugger_Level :=
|
|
288 Character'Pos
|
|
289 (Switch_Chars (Ptr)) - Character'Pos ('0');
|
|
290 Ptr := Ptr + 1;
|
|
291 end if;
|
|
292
|
|
293 else
|
|
294 Debugger_Level := 2;
|
|
295 end if;
|
|
296
|
|
297 -- Processing for h switch
|
|
298
|
|
299 when 'h' =>
|
|
300 Ptr := Ptr + 1;
|
|
301 Usage_Requested := True;
|
|
302
|
|
303 -- Processing for i switch
|
|
304
|
|
305 when 'i' =>
|
|
306 if Ptr = Max then
|
|
307 Bad_Switch (Switch_Chars);
|
|
308 end if;
|
|
309
|
|
310 Ptr := Ptr + 1;
|
|
311 C := Switch_Chars (Ptr);
|
|
312
|
|
313 if C in '1' .. '5'
|
|
314 or else C = '8'
|
|
315 or else C = 'p'
|
|
316 or else C = 'f'
|
|
317 or else C = 'n'
|
|
318 or else C = 'w'
|
|
319 then
|
|
320 Identifier_Character_Set := C;
|
|
321 Ptr := Ptr + 1;
|
|
322 else
|
|
323 Bad_Switch (Switch_Chars);
|
|
324 end if;
|
|
325
|
|
326 -- Processing for K switch
|
|
327
|
|
328 when 'K' =>
|
|
329 Ptr := Ptr + 1;
|
|
330 Output_Linker_Option_List := True;
|
|
331
|
|
332 -- Processing for l switch
|
|
333
|
|
334 when 'l' =>
|
|
335 Ptr := Ptr + 1;
|
|
336 Elab_Order_Output := True;
|
|
337
|
|
338 -- Processing for m switch
|
|
339
|
|
340 when 'm' =>
|
|
341 if Ptr = Max then
|
|
342 Bad_Switch (Switch_Chars);
|
|
343 end if;
|
|
344
|
|
345 Ptr := Ptr + 1;
|
|
346 Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Messages, C);
|
|
347
|
|
348 -- Processing for n switch
|
|
349
|
|
350 when 'n' =>
|
|
351 Ptr := Ptr + 1;
|
|
352 Bind_Main_Program := False;
|
|
353
|
|
354 -- Note: The -L option of the binder also implies -n, so
|
|
355 -- any change here must also be reflected in the processing
|
|
356 -- for -L that is found in Gnatbind.Scan_Bind_Arg.
|
|
357
|
|
358 -- Processing for o switch
|
|
359
|
|
360 when 'o' =>
|
|
361 Ptr := Ptr + 1;
|
|
362
|
|
363 if Output_File_Name_Present then
|
|
364 Osint.Fail ("duplicate -o switch");
|
|
365 else
|
|
366 Output_File_Name_Present := True;
|
|
367 end if;
|
|
368
|
|
369 -- Processing for O switch
|
|
370
|
|
371 when 'O' =>
|
|
372 Ptr := Ptr + 1;
|
|
373 Output_Object_List := True;
|
|
374 Object_List_Filename := Get_Optional_Filename;
|
|
375
|
|
376 -- Processing for p switch
|
|
377
|
|
378 when 'p' =>
|
|
379 Ptr := Ptr + 1;
|
|
380 Pessimistic_Elab_Order := True;
|
|
381
|
|
382 -- Processing for P switch
|
|
383
|
|
384 when 'P' =>
|
|
385 Ptr := Ptr + 1;
|
|
386 CodePeer_Mode := True;
|
|
387
|
|
388 -- Processing for q switch
|
|
389
|
|
390 when 'q' =>
|
|
391 Ptr := Ptr + 1;
|
|
392 Quiet_Output := True;
|
|
393
|
|
394 -- Processing for Q switch
|
|
395
|
|
396 when 'Q' =>
|
|
397 if Ptr = Max then
|
|
398 Bad_Switch (Switch_Chars);
|
|
399 end if;
|
|
400
|
|
401 Ptr := Ptr + 1;
|
131
|
402 Scan_Nat
|
111
|
403 (Switch_Chars, Max, Ptr,
|
|
404 Quantity_Of_Default_Size_Sec_Stacks, C);
|
|
405
|
|
406 -- Processing for r switch
|
|
407
|
|
408 when 'r' =>
|
|
409 Ptr := Ptr + 1;
|
|
410 List_Restrictions := True;
|
|
411
|
|
412 -- Processing for R switch
|
|
413
|
|
414 when 'R' =>
|
|
415 Ptr := Ptr + 1;
|
|
416 List_Closure := True;
|
|
417
|
|
418 if Ptr <= Max and then Switch_Chars (Ptr) = 'a' then
|
|
419 Ptr := Ptr + 1;
|
|
420 List_Closure_All := True;
|
|
421 end if;
|
|
422
|
|
423 -- Processing for s switch
|
|
424
|
|
425 when 's' =>
|
|
426 Ptr := Ptr + 1;
|
|
427 All_Sources := True;
|
|
428 Check_Source_Files := True;
|
|
429
|
|
430 -- Processing for t switch
|
|
431
|
|
432 when 't' =>
|
|
433 Ptr := Ptr + 1;
|
|
434 Tolerate_Consistency_Errors := True;
|
|
435
|
|
436 -- Processing for T switch
|
|
437
|
|
438 when 'T' =>
|
|
439 if Ptr = Max then
|
|
440 Bad_Switch (Switch_Chars);
|
|
441 end if;
|
|
442
|
|
443 Ptr := Ptr + 1;
|
|
444 Time_Slice_Set := True;
|
|
445 Scan_Nat (Switch_Chars, Max, Ptr, Time_Slice_Value, C);
|
|
446 Time_Slice_Value := Time_Slice_Value * 1_000;
|
|
447
|
|
448 -- Processing for u switch
|
|
449
|
|
450 when 'u' =>
|
|
451 if Ptr = Max then
|
|
452 Bad_Switch (Switch_Chars);
|
|
453 end if;
|
|
454
|
|
455 Ptr := Ptr + 1;
|
|
456 Dynamic_Stack_Measurement := True;
|
|
457 Scan_Nat
|
|
458 (Switch_Chars,
|
|
459 Max,
|
|
460 Ptr,
|
|
461 Dynamic_Stack_Measurement_Array_Size,
|
|
462 C);
|
|
463
|
|
464 -- Processing for v switch
|
|
465
|
|
466 when 'v' =>
|
|
467 Ptr := Ptr + 1;
|
|
468 Verbose_Mode := True;
|
|
469
|
|
470 -- Processing for V switch
|
|
471
|
|
472 when 'V' =>
|
|
473 declare
|
|
474 Eq : Integer;
|
|
475 begin
|
|
476 Ptr := Ptr + 1;
|
|
477 Eq := Ptr;
|
|
478 while Eq <= Max and then Switch_Chars (Eq) /= '=' loop
|
|
479 Eq := Eq + 1;
|
|
480 end loop;
|
|
481 if Eq = Ptr or else Eq = Max then
|
|
482 Bad_Switch (Switch_Chars);
|
|
483 end if;
|
|
484 Bindgen.Set_Bind_Env
|
|
485 (Key => Switch_Chars (Ptr .. Eq - 1),
|
|
486 Value => Switch_Chars (Eq + 1 .. Max));
|
|
487 Ptr := Max + 1;
|
|
488 end;
|
|
489
|
|
490 -- Processing for w switch
|
|
491
|
|
492 when 'w' =>
|
|
493 if Ptr = Max then
|
|
494 Bad_Switch (Switch_Chars);
|
|
495 end if;
|
|
496
|
|
497 -- For the binder we only allow suppress/error cases
|
|
498
|
|
499 Ptr := Ptr + 1;
|
|
500
|
|
501 case Switch_Chars (Ptr) is
|
|
502 when 'e' =>
|
|
503 Warning_Mode := Treat_As_Error;
|
|
504
|
|
505 when 'E' =>
|
|
506 Warning_Mode := Treat_Run_Time_Warnings_As_Errors;
|
|
507
|
|
508 when 's' =>
|
|
509 Warning_Mode := Suppress;
|
|
510
|
|
511 when others =>
|
|
512 Bad_Switch (Switch_Chars);
|
|
513 end case;
|
|
514
|
|
515 Ptr := Ptr + 1;
|
|
516
|
|
517 -- Processing for W switch
|
|
518
|
|
519 when 'W' =>
|
|
520 Ptr := Ptr + 1;
|
|
521
|
|
522 if Ptr > Max then
|
|
523 Bad_Switch (Switch_Chars);
|
|
524 end if;
|
|
525
|
|
526 begin
|
|
527 Wide_Character_Encoding_Method :=
|
|
528 Get_WC_Encoding_Method (Switch_Chars (Ptr));
|
|
529 exception
|
|
530 when Constraint_Error =>
|
|
531 Bad_Switch (Switch_Chars);
|
|
532 end;
|
|
533
|
|
534 Wide_Character_Encoding_Method_Specified := True;
|
|
535
|
|
536 Upper_Half_Encoding :=
|
|
537 Wide_Character_Encoding_Method in WC_Upper_Half_Encoding_Method;
|
|
538
|
|
539 Ptr := Ptr + 1;
|
|
540
|
|
541 -- Processing for x switch
|
|
542
|
|
543 when 'x' =>
|
|
544 Ptr := Ptr + 1;
|
|
545 All_Sources := False;
|
|
546 Check_Source_Files := False;
|
|
547
|
|
548 -- Processing for X switch
|
|
549
|
|
550 when 'X' =>
|
|
551 if Ptr = Max then
|
|
552 Bad_Switch (Switch_Chars);
|
|
553 end if;
|
|
554
|
|
555 Ptr := Ptr + 1;
|
|
556 Scan_Pos (Switch_Chars, Max, Ptr, Default_Exit_Status, C);
|
|
557
|
|
558 -- Processing for y switch
|
|
559
|
|
560 when 'y' =>
|
|
561 Ptr := Ptr + 1;
|
|
562 Leap_Seconds_Support := True;
|
|
563
|
|
564 -- Processing for z switch
|
|
565
|
|
566 when 'z' =>
|
|
567 Ptr := Ptr + 1;
|
|
568 No_Main_Subprogram := True;
|
|
569
|
|
570 -- Processing for Z switch
|
|
571
|
|
572 when 'Z' =>
|
|
573 Ptr := Ptr + 1;
|
|
574 Zero_Formatting := True;
|
|
575
|
|
576 -- Processing for --RTS
|
|
577
|
|
578 when '-' =>
|
|
579
|
|
580 if Ptr + 4 <= Max and then
|
|
581 Switch_Chars (Ptr + 1 .. Ptr + 3) = "RTS"
|
|
582 then
|
|
583 Ptr := Ptr + 4;
|
|
584
|
|
585 if Switch_Chars (Ptr) /= '=' or else Ptr = Max then
|
|
586 Osint.Fail ("missing path for --RTS");
|
|
587
|
|
588 else
|
|
589 -- Valid --RTS switch
|
|
590
|
|
591 Opt.No_Stdinc := True;
|
|
592 Opt.RTS_Switch := True;
|
|
593
|
|
594 declare
|
|
595 Src_Path_Name : constant String_Ptr :=
|
|
596 Get_RTS_Search_Dir
|
|
597 (Switch_Chars (Ptr + 1 .. Max),
|
|
598 Include);
|
|
599 Lib_Path_Name : constant String_Ptr :=
|
|
600 Get_RTS_Search_Dir
|
|
601 (Switch_Chars (Ptr + 1 .. Max),
|
|
602 Objects);
|
|
603
|
|
604 begin
|
|
605 if Src_Path_Name /= null and then
|
|
606 Lib_Path_Name /= null
|
|
607 then
|
|
608 -- Set the RTS_*_Path_Name variables, so that the
|
|
609 -- correct directories will be set when a subsequent
|
|
610 -- call Osint.Add_Default_Search_Dirs is made.
|
|
611
|
|
612 RTS_Src_Path_Name := Src_Path_Name;
|
|
613 RTS_Lib_Path_Name := Lib_Path_Name;
|
|
614
|
|
615 Ptr := Max + 1;
|
|
616
|
|
617 elsif Src_Path_Name = null
|
|
618 and then Lib_Path_Name = null
|
|
619 then
|
|
620 Osint.Fail
|
|
621 ("RTS path not valid: missing adainclude and "
|
|
622 & "adalib directories");
|
|
623 elsif Src_Path_Name = null then
|
|
624 Osint.Fail
|
|
625 ("RTS path not valid: missing adainclude directory");
|
|
626 elsif Lib_Path_Name = null then
|
|
627 Osint.Fail
|
|
628 ("RTS path not valid: missing adalib directory");
|
|
629 end if;
|
|
630 end;
|
|
631 end if;
|
|
632
|
|
633 else
|
|
634 Bad_Switch (Switch_Chars);
|
|
635 end if;
|
|
636
|
|
637 -- Anything else is an error (illegal switch character)
|
|
638
|
|
639 when others =>
|
|
640 Bad_Switch (Switch_Chars);
|
|
641 end case;
|
|
642
|
|
643 if Ptr <= Max then
|
|
644 Bad_Switch (Switch_Chars);
|
|
645 end if;
|
|
646 end Check_Switch;
|
|
647 end Scan_Binder_Switches;
|
|
648
|
|
649 end Switch.B;
|