Merge from trunk @222673.
[official-gcc.git] / gcc / ada / i-c.adb
blob01d69122fcfa4b4424b815b378ead5491ee1df26
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-2009, 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 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. --
17 -- --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
21 -- --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
30 ------------------------------------------------------------------------------
32 package body Interfaces.C is
34 -----------------------
35 -- Is_Nul_Terminated --
36 -----------------------
38 -- Case of char_array
40 function Is_Nul_Terminated (Item : char_array) return Boolean is
41 begin
42 for J in Item'Range loop
43 if Item (J) = nul then
44 return True;
45 end if;
46 end loop;
48 return False;
49 end Is_Nul_Terminated;
51 -- Case of wchar_array
53 function Is_Nul_Terminated (Item : wchar_array) return Boolean is
54 begin
55 for J in Item'Range loop
56 if Item (J) = wide_nul then
57 return True;
58 end if;
59 end loop;
61 return False;
62 end Is_Nul_Terminated;
64 -- Case of char16_array
66 function Is_Nul_Terminated (Item : char16_array) return Boolean is
67 begin
68 for J in Item'Range loop
69 if Item (J) = char16_nul then
70 return True;
71 end if;
72 end loop;
74 return False;
75 end Is_Nul_Terminated;
77 -- Case of char32_array
79 function Is_Nul_Terminated (Item : char32_array) return Boolean is
80 begin
81 for J in Item'Range loop
82 if Item (J) = char32_nul then
83 return True;
84 end if;
85 end loop;
87 return False;
88 end Is_Nul_Terminated;
90 ------------
91 -- To_Ada --
92 ------------
94 -- Convert char to Character
96 function To_Ada (Item : char) return Character is
97 begin
98 return Character'Val (char'Pos (Item));
99 end To_Ada;
101 -- Convert char_array to String (function form)
103 function To_Ada
104 (Item : char_array;
105 Trim_Nul : Boolean := True) return String
107 Count : Natural;
108 From : size_t;
110 begin
111 if Trim_Nul then
112 From := Item'First;
114 loop
115 if From > Item'Last then
116 raise Terminator_Error;
117 elsif Item (From) = nul then
118 exit;
119 else
120 From := From + 1;
121 end if;
122 end loop;
124 Count := Natural (From - Item'First);
126 else
127 Count := Item'Length;
128 end if;
130 declare
131 R : String (1 .. Count);
133 begin
134 for J in R'Range loop
135 R (J) := To_Ada (Item (size_t (J) + (Item'First - 1)));
136 end loop;
138 return R;
139 end;
140 end To_Ada;
142 -- Convert char_array to String (procedure form)
144 procedure To_Ada
145 (Item : char_array;
146 Target : out String;
147 Count : out Natural;
148 Trim_Nul : Boolean := True)
150 From : size_t;
151 To : Positive;
153 begin
154 if Trim_Nul then
155 From := Item'First;
156 loop
157 if From > Item'Last then
158 raise Terminator_Error;
159 elsif Item (From) = nul then
160 exit;
161 else
162 From := From + 1;
163 end if;
164 end loop;
166 Count := Natural (From - Item'First);
168 else
169 Count := Item'Length;
170 end if;
172 if Count > Target'Length then
173 raise Constraint_Error;
175 else
176 From := Item'First;
177 To := Target'First;
179 for J in 1 .. Count loop
180 Target (To) := Character (Item (From));
181 From := From + 1;
182 To := To + 1;
183 end loop;
184 end if;
186 end To_Ada;
188 -- Convert wchar_t to Wide_Character
190 function To_Ada (Item : wchar_t) return Wide_Character is
191 begin
192 return Wide_Character (Item);
193 end To_Ada;
195 -- Convert wchar_array to Wide_String (function form)
197 function To_Ada
198 (Item : wchar_array;
199 Trim_Nul : Boolean := True) return Wide_String
201 Count : Natural;
202 From : size_t;
204 begin
205 if Trim_Nul then
206 From := Item'First;
208 loop
209 if From > Item'Last then
210 raise Terminator_Error;
211 elsif Item (From) = wide_nul then
212 exit;
213 else
214 From := From + 1;
215 end if;
216 end loop;
218 Count := Natural (From - Item'First);
220 else
221 Count := Item'Length;
222 end if;
224 declare
225 R : Wide_String (1 .. Count);
227 begin
228 for J in R'Range loop
229 R (J) := To_Ada (Item (size_t (J) + (Item'First - 1)));
230 end loop;
232 return R;
233 end;
234 end To_Ada;
236 -- Convert wchar_array to Wide_String (procedure form)
238 procedure To_Ada
239 (Item : wchar_array;
240 Target : out Wide_String;
241 Count : out Natural;
242 Trim_Nul : Boolean := True)
244 From : size_t;
245 To : Positive;
247 begin
248 if Trim_Nul then
249 From := Item'First;
250 loop
251 if From > Item'Last then
252 raise Terminator_Error;
253 elsif Item (From) = wide_nul then
254 exit;
255 else
256 From := From + 1;
257 end if;
258 end loop;
260 Count := Natural (From - Item'First);
262 else
263 Count := Item'Length;
264 end if;
266 if Count > Target'Length then
267 raise Constraint_Error;
269 else
270 From := Item'First;
271 To := Target'First;
273 for J in 1 .. Count loop
274 Target (To) := To_Ada (Item (From));
275 From := From + 1;
276 To := To + 1;
277 end loop;
278 end if;
279 end To_Ada;
281 -- Convert char16_t to Wide_Character
283 function To_Ada (Item : char16_t) return Wide_Character is
284 begin
285 return Wide_Character'Val (char16_t'Pos (Item));
286 end To_Ada;
288 -- Convert char16_array to Wide_String (function form)
290 function To_Ada
291 (Item : char16_array;
292 Trim_Nul : Boolean := True) return Wide_String
294 Count : Natural;
295 From : size_t;
297 begin
298 if Trim_Nul then
299 From := Item'First;
301 loop
302 if From > Item'Last then
303 raise Terminator_Error;
304 elsif Item (From) = char16_t'Val (0) then
305 exit;
306 else
307 From := From + 1;
308 end if;
309 end loop;
311 Count := Natural (From - Item'First);
313 else
314 Count := Item'Length;
315 end if;
317 declare
318 R : Wide_String (1 .. Count);
320 begin
321 for J in R'Range loop
322 R (J) := To_Ada (Item (size_t (J) + (Item'First - 1)));
323 end loop;
325 return R;
326 end;
327 end To_Ada;
329 -- Convert char16_array to Wide_String (procedure form)
331 procedure To_Ada
332 (Item : char16_array;
333 Target : out Wide_String;
334 Count : out Natural;
335 Trim_Nul : Boolean := True)
337 From : size_t;
338 To : Positive;
340 begin
341 if Trim_Nul then
342 From := Item'First;
343 loop
344 if From > Item'Last then
345 raise Terminator_Error;
346 elsif Item (From) = char16_t'Val (0) then
347 exit;
348 else
349 From := From + 1;
350 end if;
351 end loop;
353 Count := Natural (From - Item'First);
355 else
356 Count := Item'Length;
357 end if;
359 if Count > Target'Length then
360 raise Constraint_Error;
362 else
363 From := Item'First;
364 To := Target'First;
366 for J in 1 .. Count loop
367 Target (To) := To_Ada (Item (From));
368 From := From + 1;
369 To := To + 1;
370 end loop;
371 end if;
372 end To_Ada;
374 -- Convert char32_t to Wide_Wide_Character
376 function To_Ada (Item : char32_t) return Wide_Wide_Character is
377 begin
378 return Wide_Wide_Character'Val (char32_t'Pos (Item));
379 end To_Ada;
381 -- Convert char32_array to Wide_Wide_String (function form)
383 function To_Ada
384 (Item : char32_array;
385 Trim_Nul : Boolean := True) return Wide_Wide_String
387 Count : Natural;
388 From : size_t;
390 begin
391 if Trim_Nul then
392 From := Item'First;
394 loop
395 if From > Item'Last then
396 raise Terminator_Error;
397 elsif Item (From) = char32_t'Val (0) then
398 exit;
399 else
400 From := From + 1;
401 end if;
402 end loop;
404 Count := Natural (From - Item'First);
406 else
407 Count := Item'Length;
408 end if;
410 declare
411 R : Wide_Wide_String (1 .. Count);
413 begin
414 for J in R'Range loop
415 R (J) := To_Ada (Item (size_t (J) + (Item'First - 1)));
416 end loop;
418 return R;
419 end;
420 end To_Ada;
422 -- Convert char32_array to Wide_Wide_String (procedure form)
424 procedure To_Ada
425 (Item : char32_array;
426 Target : out Wide_Wide_String;
427 Count : out Natural;
428 Trim_Nul : Boolean := True)
430 From : size_t;
431 To : Positive;
433 begin
434 if Trim_Nul then
435 From := Item'First;
436 loop
437 if From > Item'Last then
438 raise Terminator_Error;
439 elsif Item (From) = char32_t'Val (0) then
440 exit;
441 else
442 From := From + 1;
443 end if;
444 end loop;
446 Count := Natural (From - Item'First);
448 else
449 Count := Item'Length;
450 end if;
452 if Count > Target'Length then
453 raise Constraint_Error;
455 else
456 From := Item'First;
457 To := Target'First;
459 for J in 1 .. Count loop
460 Target (To) := To_Ada (Item (From));
461 From := From + 1;
462 To := To + 1;
463 end loop;
464 end if;
465 end To_Ada;
467 ----------
468 -- To_C --
469 ----------
471 -- Convert Character to char
473 function To_C (Item : Character) return char is
474 begin
475 return char'Val (Character'Pos (Item));
476 end To_C;
478 -- Convert String to char_array (function form)
480 function To_C
481 (Item : String;
482 Append_Nul : Boolean := True) return char_array
484 begin
485 if Append_Nul then
486 declare
487 R : char_array (0 .. Item'Length);
489 begin
490 for J in Item'Range loop
491 R (size_t (J - Item'First)) := To_C (Item (J));
492 end loop;
494 R (R'Last) := nul;
495 return R;
496 end;
498 -- Append_Nul False
500 else
501 -- A nasty case, if the string is null, we must return a null
502 -- char_array. The lower bound of this array is required to be zero
503 -- (RM B.3(50)) but that is of course impossible given that size_t
504 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
505 -- Constraint_Error. This is also the appropriate behavior in Ada 95,
506 -- since nothing else makes sense.
508 if Item'Length = 0 then
509 raise Constraint_Error;
511 -- Normal case
513 else
514 declare
515 R : char_array (0 .. Item'Length - 1);
517 begin
518 for J in Item'Range loop
519 R (size_t (J - Item'First)) := To_C (Item (J));
520 end loop;
522 return R;
523 end;
524 end if;
525 end if;
526 end To_C;
528 -- Convert String to char_array (procedure form)
530 procedure To_C
531 (Item : String;
532 Target : out char_array;
533 Count : out size_t;
534 Append_Nul : Boolean := True)
536 To : size_t;
538 begin
539 if Target'Length < Item'Length then
540 raise Constraint_Error;
542 else
543 To := Target'First;
544 for From in Item'Range loop
545 Target (To) := char (Item (From));
546 To := To + 1;
547 end loop;
549 if Append_Nul then
550 if To > Target'Last then
551 raise Constraint_Error;
552 else
553 Target (To) := nul;
554 Count := Item'Length + 1;
555 end if;
557 else
558 Count := Item'Length;
559 end if;
560 end if;
561 end To_C;
563 -- Convert Wide_Character to wchar_t
565 function To_C (Item : Wide_Character) return wchar_t is
566 begin
567 return wchar_t (Item);
568 end To_C;
570 -- Convert Wide_String to wchar_array (function form)
572 function To_C
573 (Item : Wide_String;
574 Append_Nul : Boolean := True) return wchar_array
576 begin
577 if Append_Nul then
578 declare
579 R : wchar_array (0 .. Item'Length);
581 begin
582 for J in Item'Range loop
583 R (size_t (J - Item'First)) := To_C (Item (J));
584 end loop;
586 R (R'Last) := wide_nul;
587 return R;
588 end;
590 else
591 -- A nasty case, if the string is null, we must return a null
592 -- wchar_array. The lower bound of this array is required to be zero
593 -- (RM B.3(50)) but that is of course impossible given that size_t
594 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
595 -- Constraint_Error. This is also the appropriate behavior in Ada 95,
596 -- since nothing else makes sense.
598 if Item'Length = 0 then
599 raise Constraint_Error;
601 else
602 declare
603 R : wchar_array (0 .. Item'Length - 1);
605 begin
606 for J in size_t range 0 .. Item'Length - 1 loop
607 R (J) := To_C (Item (Integer (J) + Item'First));
608 end loop;
610 return R;
611 end;
612 end if;
613 end if;
614 end To_C;
616 -- Convert Wide_String to wchar_array (procedure form)
618 procedure To_C
619 (Item : Wide_String;
620 Target : out wchar_array;
621 Count : out size_t;
622 Append_Nul : Boolean := True)
624 To : size_t;
626 begin
627 if Target'Length < Item'Length then
628 raise Constraint_Error;
630 else
631 To := Target'First;
632 for From in Item'Range loop
633 Target (To) := To_C (Item (From));
634 To := To + 1;
635 end loop;
637 if Append_Nul then
638 if To > Target'Last then
639 raise Constraint_Error;
640 else
641 Target (To) := wide_nul;
642 Count := Item'Length + 1;
643 end if;
645 else
646 Count := Item'Length;
647 end if;
648 end if;
649 end To_C;
651 -- Convert Wide_Character to char16_t
653 function To_C (Item : Wide_Character) return char16_t is
654 begin
655 return char16_t'Val (Wide_Character'Pos (Item));
656 end To_C;
658 -- Convert Wide_String to char16_array (function form)
660 function To_C
661 (Item : Wide_String;
662 Append_Nul : Boolean := True) return char16_array
664 begin
665 if Append_Nul then
666 declare
667 R : char16_array (0 .. Item'Length);
669 begin
670 for J in Item'Range loop
671 R (size_t (J - Item'First)) := To_C (Item (J));
672 end loop;
674 R (R'Last) := char16_t'Val (0);
675 return R;
676 end;
678 else
679 -- A nasty case, if the string is null, we must return a null
680 -- char16_array. The lower bound of this array is required to be zero
681 -- (RM B.3(50)) but that is of course impossible given that size_t
682 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
683 -- Constraint_Error. This is also the appropriate behavior in Ada 95,
684 -- since nothing else makes sense.
686 if Item'Length = 0 then
687 raise Constraint_Error;
689 else
690 declare
691 R : char16_array (0 .. Item'Length - 1);
693 begin
694 for J in size_t range 0 .. Item'Length - 1 loop
695 R (J) := To_C (Item (Integer (J) + Item'First));
696 end loop;
698 return R;
699 end;
700 end if;
701 end if;
702 end To_C;
704 -- Convert Wide_String to char16_array (procedure form)
706 procedure To_C
707 (Item : Wide_String;
708 Target : out char16_array;
709 Count : out size_t;
710 Append_Nul : Boolean := True)
712 To : size_t;
714 begin
715 if Target'Length < Item'Length then
716 raise Constraint_Error;
718 else
719 To := Target'First;
720 for From in Item'Range loop
721 Target (To) := To_C (Item (From));
722 To := To + 1;
723 end loop;
725 if Append_Nul then
726 if To > Target'Last then
727 raise Constraint_Error;
728 else
729 Target (To) := char16_t'Val (0);
730 Count := Item'Length + 1;
731 end if;
733 else
734 Count := Item'Length;
735 end if;
736 end if;
737 end To_C;
739 -- Convert Wide_Character to char32_t
741 function To_C (Item : Wide_Wide_Character) return char32_t is
742 begin
743 return char32_t'Val (Wide_Wide_Character'Pos (Item));
744 end To_C;
746 -- Convert Wide_Wide_String to char32_array (function form)
748 function To_C
749 (Item : Wide_Wide_String;
750 Append_Nul : Boolean := True) return char32_array
752 begin
753 if Append_Nul then
754 declare
755 R : char32_array (0 .. Item'Length);
757 begin
758 for J in Item'Range loop
759 R (size_t (J - Item'First)) := To_C (Item (J));
760 end loop;
762 R (R'Last) := char32_t'Val (0);
763 return R;
764 end;
766 else
767 -- A nasty case, if the string is null, we must return a null
768 -- char32_array. The lower bound of this array is required to be zero
769 -- (RM B.3(50)) but that is of course impossible given that size_t
770 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
771 -- Constraint_Error.
773 if Item'Length = 0 then
774 raise Constraint_Error;
776 else
777 declare
778 R : char32_array (0 .. Item'Length - 1);
780 begin
781 for J in size_t range 0 .. Item'Length - 1 loop
782 R (J) := To_C (Item (Integer (J) + Item'First));
783 end loop;
785 return R;
786 end;
787 end if;
788 end if;
789 end To_C;
791 -- Convert Wide_Wide_String to char32_array (procedure form)
793 procedure To_C
794 (Item : Wide_Wide_String;
795 Target : out char32_array;
796 Count : out size_t;
797 Append_Nul : Boolean := True)
799 To : size_t;
801 begin
802 if Target'Length < Item'Length then
803 raise Constraint_Error;
805 else
806 To := Target'First;
807 for From in Item'Range loop
808 Target (To) := To_C (Item (From));
809 To := To + 1;
810 end loop;
812 if Append_Nul then
813 if To > Target'Last then
814 raise Constraint_Error;
815 else
816 Target (To) := char32_t'Val (0);
817 Count := Item'Length + 1;
818 end if;
820 else
821 Count := Item'Length;
822 end if;
823 end if;
824 end To_C;
826 end Interfaces.C;