re PR rtl-optimization/34522 (inefficient code for long long multiply when only low...
[official-gcc.git] / gcc / ada / i-c.adb
blob82687568b95463024caed441d6338b9d40e2e265
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- I N T E R F A C E S . C --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2005, 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, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
21 -- --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
28 -- --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 -- --
32 ------------------------------------------------------------------------------
34 package body Interfaces.C is
36 -----------------------
37 -- Is_Nul_Terminated --
38 -----------------------
40 -- Case of char_array
42 function Is_Nul_Terminated (Item : char_array) return Boolean is
43 begin
44 for J in Item'Range loop
45 if Item (J) = nul then
46 return True;
47 end if;
48 end loop;
50 return False;
51 end Is_Nul_Terminated;
53 -- Case of wchar_array
55 function Is_Nul_Terminated (Item : wchar_array) return Boolean is
56 begin
57 for J in Item'Range loop
58 if Item (J) = wide_nul then
59 return True;
60 end if;
61 end loop;
63 return False;
64 end Is_Nul_Terminated;
66 -- Case of char16_array
68 function Is_Nul_Terminated (Item : char16_array) return Boolean is
69 begin
70 for J in Item'Range loop
71 if Item (J) = char16_nul then
72 return True;
73 end if;
74 end loop;
76 return False;
77 end Is_Nul_Terminated;
79 -- Case of char32_array
81 function Is_Nul_Terminated (Item : char32_array) return Boolean is
82 begin
83 for J in Item'Range loop
84 if Item (J) = char32_nul then
85 return True;
86 end if;
87 end loop;
89 return False;
90 end Is_Nul_Terminated;
92 ------------
93 -- To_Ada --
94 ------------
96 -- Convert char to Character
98 function To_Ada (Item : char) return Character is
99 begin
100 return Character'Val (char'Pos (Item));
101 end To_Ada;
103 -- Convert char_array to String (function form)
105 function To_Ada
106 (Item : char_array;
107 Trim_Nul : Boolean := True) return String
109 Count : Natural;
110 From : size_t;
112 begin
113 if Trim_Nul then
114 From := Item'First;
116 loop
117 if From > Item'Last then
118 raise Terminator_Error;
119 elsif Item (From) = nul then
120 exit;
121 else
122 From := From + 1;
123 end if;
124 end loop;
126 Count := Natural (From - Item'First);
128 else
129 Count := Item'Length;
130 end if;
132 declare
133 R : String (1 .. Count);
135 begin
136 for J in R'Range loop
137 R (J) := To_Ada (Item (size_t (J) + (Item'First - 1)));
138 end loop;
140 return R;
141 end;
142 end To_Ada;
144 -- Convert char_array to String (procedure form)
146 procedure To_Ada
147 (Item : char_array;
148 Target : out String;
149 Count : out Natural;
150 Trim_Nul : Boolean := True)
152 From : size_t;
153 To : Positive;
155 begin
156 if Trim_Nul then
157 From := Item'First;
158 loop
159 if From > Item'Last then
160 raise Terminator_Error;
161 elsif Item (From) = nul then
162 exit;
163 else
164 From := From + 1;
165 end if;
166 end loop;
168 Count := Natural (From - Item'First);
170 else
171 Count := Item'Length;
172 end if;
174 if Count > Target'Length then
175 raise Constraint_Error;
177 else
178 From := Item'First;
179 To := Target'First;
181 for J in 1 .. Count loop
182 Target (To) := Character (Item (From));
183 From := From + 1;
184 To := To + 1;
185 end loop;
186 end if;
188 end To_Ada;
190 -- Convert wchar_t to Wide_Character
192 function To_Ada (Item : wchar_t) return Wide_Character is
193 begin
194 return Wide_Character (Item);
195 end To_Ada;
197 -- Convert wchar_array to Wide_String (function form)
199 function To_Ada
200 (Item : wchar_array;
201 Trim_Nul : Boolean := True) return Wide_String
203 Count : Natural;
204 From : size_t;
206 begin
207 if Trim_Nul then
208 From := Item'First;
210 loop
211 if From > Item'Last then
212 raise Terminator_Error;
213 elsif Item (From) = wide_nul then
214 exit;
215 else
216 From := From + 1;
217 end if;
218 end loop;
220 Count := Natural (From - Item'First);
222 else
223 Count := Item'Length;
224 end if;
226 declare
227 R : Wide_String (1 .. Count);
229 begin
230 for J in R'Range loop
231 R (J) := To_Ada (Item (size_t (J) + (Item'First - 1)));
232 end loop;
234 return R;
235 end;
236 end To_Ada;
238 -- Convert wchar_array to Wide_String (procedure form)
240 procedure To_Ada
241 (Item : wchar_array;
242 Target : out Wide_String;
243 Count : out Natural;
244 Trim_Nul : Boolean := True)
246 From : size_t;
247 To : Positive;
249 begin
250 if Trim_Nul then
251 From := Item'First;
252 loop
253 if From > Item'Last then
254 raise Terminator_Error;
255 elsif Item (From) = wide_nul then
256 exit;
257 else
258 From := From + 1;
259 end if;
260 end loop;
262 Count := Natural (From - Item'First);
264 else
265 Count := Item'Length;
266 end if;
268 if Count > Target'Length then
269 raise Constraint_Error;
271 else
272 From := Item'First;
273 To := Target'First;
275 for J in 1 .. Count loop
276 Target (To) := To_Ada (Item (From));
277 From := From + 1;
278 To := To + 1;
279 end loop;
280 end if;
281 end To_Ada;
283 -- Convert char16_t to Wide_Character
285 function To_Ada (Item : char16_t) return Wide_Character is
286 begin
287 return Wide_Character'Val (char16_t'Pos (Item));
288 end To_Ada;
290 -- Convert char16_array to Wide_String (function form)
292 function To_Ada
293 (Item : char16_array;
294 Trim_Nul : Boolean := True) return Wide_String
296 Count : Natural;
297 From : size_t;
299 begin
300 if Trim_Nul then
301 From := Item'First;
303 loop
304 if From > Item'Last then
305 raise Terminator_Error;
306 elsif Item (From) = char16_t'Val (0) then
307 exit;
308 else
309 From := From + 1;
310 end if;
311 end loop;
313 Count := Natural (From - Item'First);
315 else
316 Count := Item'Length;
317 end if;
319 declare
320 R : Wide_String (1 .. Count);
322 begin
323 for J in R'Range loop
324 R (J) := To_Ada (Item (size_t (J) + (Item'First - 1)));
325 end loop;
327 return R;
328 end;
329 end To_Ada;
331 -- Convert char16_array to Wide_String (procedure form)
333 procedure To_Ada
334 (Item : char16_array;
335 Target : out Wide_String;
336 Count : out Natural;
337 Trim_Nul : Boolean := True)
339 From : size_t;
340 To : Positive;
342 begin
343 if Trim_Nul then
344 From := Item'First;
345 loop
346 if From > Item'Last then
347 raise Terminator_Error;
348 elsif Item (From) = char16_t'Val (0) then
349 exit;
350 else
351 From := From + 1;
352 end if;
353 end loop;
355 Count := Natural (From - Item'First);
357 else
358 Count := Item'Length;
359 end if;
361 if Count > Target'Length then
362 raise Constraint_Error;
364 else
365 From := Item'First;
366 To := Target'First;
368 for J in 1 .. Count loop
369 Target (To) := To_Ada (Item (From));
370 From := From + 1;
371 To := To + 1;
372 end loop;
373 end if;
374 end To_Ada;
376 -- Convert char32_t to Wide_Wide_Character
378 function To_Ada (Item : char32_t) return Wide_Wide_Character is
379 begin
380 return Wide_Wide_Character'Val (char32_t'Pos (Item));
381 end To_Ada;
383 -- Convert char32_array to Wide_Wide_String (function form)
385 function To_Ada
386 (Item : char32_array;
387 Trim_Nul : Boolean := True) return Wide_Wide_String
389 Count : Natural;
390 From : size_t;
392 begin
393 if Trim_Nul then
394 From := Item'First;
396 loop
397 if From > Item'Last then
398 raise Terminator_Error;
399 elsif Item (From) = char32_t'Val (0) then
400 exit;
401 else
402 From := From + 1;
403 end if;
404 end loop;
406 Count := Natural (From - Item'First);
408 else
409 Count := Item'Length;
410 end if;
412 declare
413 R : Wide_Wide_String (1 .. Count);
415 begin
416 for J in R'Range loop
417 R (J) := To_Ada (Item (size_t (J) + (Item'First - 1)));
418 end loop;
420 return R;
421 end;
422 end To_Ada;
424 -- Convert char32_array to Wide_Wide_String (procedure form)
426 procedure To_Ada
427 (Item : char32_array;
428 Target : out Wide_Wide_String;
429 Count : out Natural;
430 Trim_Nul : Boolean := True)
432 From : size_t;
433 To : Positive;
435 begin
436 if Trim_Nul then
437 From := Item'First;
438 loop
439 if From > Item'Last then
440 raise Terminator_Error;
441 elsif Item (From) = char32_t'Val (0) then
442 exit;
443 else
444 From := From + 1;
445 end if;
446 end loop;
448 Count := Natural (From - Item'First);
450 else
451 Count := Item'Length;
452 end if;
454 if Count > Target'Length then
455 raise Constraint_Error;
457 else
458 From := Item'First;
459 To := Target'First;
461 for J in 1 .. Count loop
462 Target (To) := To_Ada (Item (From));
463 From := From + 1;
464 To := To + 1;
465 end loop;
466 end if;
467 end To_Ada;
469 ----------
470 -- To_C --
471 ----------
473 -- Convert Character to char
475 function To_C (Item : Character) return char is
476 begin
477 return char'Val (Character'Pos (Item));
478 end To_C;
480 -- Convert String to char_array (function form)
482 function To_C
483 (Item : String;
484 Append_Nul : Boolean := True) return char_array
486 begin
487 if Append_Nul then
488 declare
489 R : char_array (0 .. Item'Length);
491 begin
492 for J in Item'Range loop
493 R (size_t (J - Item'First)) := To_C (Item (J));
494 end loop;
496 R (R'Last) := nul;
497 return R;
498 end;
500 -- Append_Nul False
502 else
503 -- A nasty case, if the string is null, we must return a null
504 -- char_array. The lower bound of this array is required to be zero
505 -- (RM B.3(50)) but that is of course impossible given that size_t
506 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
507 -- Constraint_Error. This is also the appropriate behavior in Ada 95,
508 -- since nothing else makes sense.
510 if Item'Length = 0 then
511 raise Constraint_Error;
513 -- Normal case
515 else
516 declare
517 R : char_array (0 .. Item'Length - 1);
519 begin
520 for J in Item'Range loop
521 R (size_t (J - Item'First)) := To_C (Item (J));
522 end loop;
524 return R;
525 end;
526 end if;
527 end if;
528 end To_C;
530 -- Convert String to char_array (procedure form)
532 procedure To_C
533 (Item : String;
534 Target : out char_array;
535 Count : out size_t;
536 Append_Nul : Boolean := True)
538 To : size_t;
540 begin
541 if Target'Length < Item'Length then
542 raise Constraint_Error;
544 else
545 To := Target'First;
546 for From in Item'Range loop
547 Target (To) := char (Item (From));
548 To := To + 1;
549 end loop;
551 if Append_Nul then
552 if To > Target'Last then
553 raise Constraint_Error;
554 else
555 Target (To) := nul;
556 Count := Item'Length + 1;
557 end if;
559 else
560 Count := Item'Length;
561 end if;
562 end if;
563 end To_C;
565 -- Convert Wide_Character to wchar_t
567 function To_C (Item : Wide_Character) return wchar_t is
568 begin
569 return wchar_t (Item);
570 end To_C;
572 -- Convert Wide_String to wchar_array (function form)
574 function To_C
575 (Item : Wide_String;
576 Append_Nul : Boolean := True) return wchar_array
578 begin
579 if Append_Nul then
580 declare
581 R : wchar_array (0 .. Item'Length);
583 begin
584 for J in Item'Range loop
585 R (size_t (J - Item'First)) := To_C (Item (J));
586 end loop;
588 R (R'Last) := wide_nul;
589 return R;
590 end;
592 else
593 -- A nasty case, if the string is null, we must return a null
594 -- wchar_array. The lower bound of this array is required to be zero
595 -- (RM B.3(50)) but that is of course impossible given that size_t
596 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
597 -- Constraint_Error. This is also the appropriate behavior in Ada 95,
598 -- since nothing else makes sense.
600 if Item'Length = 0 then
601 raise Constraint_Error;
603 else
604 declare
605 R : wchar_array (0 .. Item'Length - 1);
607 begin
608 for J in size_t range 0 .. Item'Length - 1 loop
609 R (J) := To_C (Item (Integer (J) + Item'First));
610 end loop;
612 return R;
613 end;
614 end if;
615 end if;
616 end To_C;
618 -- Convert Wide_String to wchar_array (procedure form)
620 procedure To_C
621 (Item : Wide_String;
622 Target : out wchar_array;
623 Count : out size_t;
624 Append_Nul : Boolean := True)
626 To : size_t;
628 begin
629 if Target'Length < Item'Length then
630 raise Constraint_Error;
632 else
633 To := Target'First;
634 for From in Item'Range loop
635 Target (To) := To_C (Item (From));
636 To := To + 1;
637 end loop;
639 if Append_Nul then
640 if To > Target'Last then
641 raise Constraint_Error;
642 else
643 Target (To) := wide_nul;
644 Count := Item'Length + 1;
645 end if;
647 else
648 Count := Item'Length;
649 end if;
650 end if;
651 end To_C;
653 -- Convert Wide_Character to char16_t
655 function To_C (Item : Wide_Character) return char16_t is
656 begin
657 return char16_t'Val (Wide_Character'Pos (Item));
658 end To_C;
660 -- Convert Wide_String to char16_array (function form)
662 function To_C
663 (Item : Wide_String;
664 Append_Nul : Boolean := True) return char16_array
666 begin
667 if Append_Nul then
668 declare
669 R : char16_array (0 .. Item'Length);
671 begin
672 for J in Item'Range loop
673 R (size_t (J - Item'First)) := To_C (Item (J));
674 end loop;
676 R (R'Last) := char16_t'Val (0);
677 return R;
678 end;
680 else
681 -- A nasty case, if the string is null, we must return a null
682 -- char16_array. The lower bound of this array is required to be zero
683 -- (RM B.3(50)) but that is of course impossible given that size_t
684 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
685 -- Constraint_Error. This is also the appropriate behavior in Ada 95,
686 -- since nothing else makes sense.
688 if Item'Length = 0 then
689 raise Constraint_Error;
691 else
692 declare
693 R : char16_array (0 .. Item'Length - 1);
695 begin
696 for J in size_t range 0 .. Item'Length - 1 loop
697 R (J) := To_C (Item (Integer (J) + Item'First));
698 end loop;
700 return R;
701 end;
702 end if;
703 end if;
704 end To_C;
706 -- Convert Wide_String to char16_array (procedure form)
708 procedure To_C
709 (Item : Wide_String;
710 Target : out char16_array;
711 Count : out size_t;
712 Append_Nul : Boolean := True)
714 To : size_t;
716 begin
717 if Target'Length < Item'Length then
718 raise Constraint_Error;
720 else
721 To := Target'First;
722 for From in Item'Range loop
723 Target (To) := To_C (Item (From));
724 To := To + 1;
725 end loop;
727 if Append_Nul then
728 if To > Target'Last then
729 raise Constraint_Error;
730 else
731 Target (To) := char16_t'Val (0);
732 Count := Item'Length + 1;
733 end if;
735 else
736 Count := Item'Length;
737 end if;
738 end if;
739 end To_C;
741 -- Convert Wide_Character to char32_t
743 function To_C (Item : Wide_Wide_Character) return char32_t is
744 begin
745 return char32_t'Val (Wide_Wide_Character'Pos (Item));
746 end To_C;
748 -- Convert Wide_Wide_String to char32_array (function form)
750 function To_C
751 (Item : Wide_Wide_String;
752 Append_Nul : Boolean := True) return char32_array
754 begin
755 if Append_Nul then
756 declare
757 R : char32_array (0 .. Item'Length);
759 begin
760 for J in Item'Range loop
761 R (size_t (J - Item'First)) := To_C (Item (J));
762 end loop;
764 R (R'Last) := char32_t'Val (0);
765 return R;
766 end;
768 else
769 -- A nasty case, if the string is null, we must return a null
770 -- char32_array. The lower bound of this array is required to be zero
771 -- (RM B.3(50)) but that is of course impossible given that size_t
772 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
773 -- Constraint_Error.
775 if Item'Length = 0 then
776 raise Constraint_Error;
778 else
779 declare
780 R : char32_array (0 .. Item'Length - 1);
782 begin
783 for J in size_t range 0 .. Item'Length - 1 loop
784 R (J) := To_C (Item (Integer (J) + Item'First));
785 end loop;
787 return R;
788 end;
789 end if;
790 end if;
791 end To_C;
793 -- Convert Wide_Wide_String to char32_array (procedure form)
795 procedure To_C
796 (Item : Wide_Wide_String;
797 Target : out char32_array;
798 Count : out size_t;
799 Append_Nul : Boolean := True)
801 To : size_t;
803 begin
804 if Target'Length < Item'Length then
805 raise Constraint_Error;
807 else
808 To := Target'First;
809 for From in Item'Range loop
810 Target (To) := To_C (Item (From));
811 To := To + 1;
812 end loop;
814 if Append_Nul then
815 if To > Target'Last then
816 raise Constraint_Error;
817 else
818 Target (To) := char32_t'Val (0);
819 Count := Item'Length + 1;
820 end if;
822 else
823 Count := Item'Length;
824 end if;
825 end if;
826 end To_C;
828 end Interfaces.C;