[committed][RISC-V] Fix test expectations after recent late-combine changes
[official-gcc.git] / gcc / ada / libgnat / i-c.adb
blobdd5a1353dab410438a6f94bc43dc574a01e79aaa
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-2024, 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 -- Ghost code, loop invariants and assertions in this unit are meant for
33 -- analysis only, not for run-time checking, as it would be too costly
34 -- otherwise. This is enforced by setting the assertion policy to Ignore.
36 pragma Assertion_Policy (Ghost => Ignore,
37 Loop_Invariant => Ignore,
38 Assert => Ignore);
40 package body Interfaces.C
41 with SPARK_Mode
44 --------------------
45 -- C_Length_Ghost --
46 --------------------
48 function C_Length_Ghost (Item : char_array) return size_t is
49 begin
50 for J in Item'Range loop
51 if Item (J) = nul then
52 return J - Item'First;
53 end if;
55 pragma Loop_Invariant
56 (for all K in Item'First .. J => Item (K) /= nul);
57 end loop;
59 raise Program_Error;
60 end C_Length_Ghost;
62 function C_Length_Ghost (Item : wchar_array) return size_t is
63 begin
64 for J in Item'Range loop
65 if Item (J) = wide_nul then
66 return J - Item'First;
67 end if;
69 pragma Loop_Invariant
70 (for all K in Item'First .. J => Item (K) /= wide_nul);
71 end loop;
73 raise Program_Error;
74 end C_Length_Ghost;
76 function C_Length_Ghost (Item : char16_array) return size_t is
77 begin
78 for J in Item'Range loop
79 if Item (J) = char16_nul then
80 return J - Item'First;
81 end if;
83 pragma Loop_Invariant
84 (for all K in Item'First .. J => Item (K) /= char16_nul);
85 end loop;
87 raise Program_Error;
88 end C_Length_Ghost;
90 function C_Length_Ghost (Item : char32_array) return size_t is
91 begin
92 for J in Item'Range loop
93 if Item (J) = char32_nul then
94 return J - Item'First;
95 end if;
97 pragma Loop_Invariant
98 (for all K in Item'First .. J => Item (K) /= char32_nul);
99 end loop;
101 raise Program_Error;
102 end C_Length_Ghost;
104 -----------------------
105 -- Is_Nul_Terminated --
106 -----------------------
108 -- Case of char_array
110 function Is_Nul_Terminated (Item : char_array) return Boolean is
111 begin
112 for J in Item'Range loop
113 if Item (J) = nul then
114 return True;
115 end if;
117 pragma Loop_Invariant
118 (for all K in Item'First .. J => Item (K) /= nul);
119 end loop;
121 return False;
122 end Is_Nul_Terminated;
124 -- Case of wchar_array
126 function Is_Nul_Terminated (Item : wchar_array) return Boolean is
127 begin
128 for J in Item'Range loop
129 if Item (J) = wide_nul then
130 return True;
131 end if;
133 pragma Loop_Invariant
134 (for all K in Item'First .. J => Item (K) /= wide_nul);
135 end loop;
137 return False;
138 end Is_Nul_Terminated;
140 -- Case of char16_array
142 function Is_Nul_Terminated (Item : char16_array) return Boolean is
143 begin
144 for J in Item'Range loop
145 if Item (J) = char16_nul then
146 return True;
147 end if;
149 pragma Loop_Invariant
150 (for all K in Item'First .. J => Item (K) /= char16_nul);
151 end loop;
153 return False;
154 end Is_Nul_Terminated;
156 -- Case of char32_array
158 function Is_Nul_Terminated (Item : char32_array) return Boolean is
159 begin
160 for J in Item'Range loop
161 if Item (J) = char32_nul then
162 return True;
163 end if;
165 pragma Loop_Invariant
166 (for all K in Item'First .. J => Item (K) /= char32_nul);
167 end loop;
169 return False;
170 end Is_Nul_Terminated;
172 ------------
173 -- To_Ada --
174 ------------
176 -- Convert char to Character
178 function To_Ada (Item : char) return Character is
179 begin
180 return Character'Val (char'Pos (Item));
181 end To_Ada;
183 -- Convert char_array to String (function form)
185 function To_Ada
186 (Item : char_array;
187 Trim_Nul : Boolean := True) return String
189 Count : Natural;
190 From : size_t;
192 begin
193 if Trim_Nul then
194 From := Item'First;
196 loop
197 pragma Loop_Invariant (From in Item'Range);
198 pragma Loop_Invariant
199 (for some J in From .. Item'Last => Item (J) = nul);
200 pragma Loop_Invariant
201 (for all J in Item'First .. From when J /= From =>
202 Item (J) /= nul);
203 pragma Loop_Variant (Increases => From);
205 if From > Item'Last then
206 raise Terminator_Error;
207 elsif Item (From) = nul then
208 exit;
209 else
210 From := From + 1;
211 end if;
212 end loop;
214 pragma Assert (From = Item'First + C_Length_Ghost (Item));
216 Count := Natural (From - Item'First);
218 else
219 Count := Item'Length;
220 end if;
222 declare
223 Count_Cst : constant Natural := Count;
224 R : String (1 .. Count_Cst) with Relaxed_Initialization;
226 begin
227 for J in R'Range loop
228 R (J) := To_Ada (Item (size_t (J) - 1 + Item'First));
230 pragma Loop_Invariant (for all K in 1 .. J => R (K)'Initialized);
231 pragma Loop_Invariant
232 (for all K in 1 .. J =>
233 R (K) = To_Ada (Item (size_t (K) - 1 + Item'First)));
234 end loop;
236 return R;
237 end;
238 end To_Ada;
240 -- Convert char_array to String (procedure form)
242 procedure To_Ada
243 (Item : char_array;
244 Target : out String;
245 Count : out Natural;
246 Trim_Nul : Boolean := True)
248 From : size_t;
249 To : Integer;
251 begin
252 if Trim_Nul then
253 From := Item'First;
254 loop
255 pragma Loop_Invariant (From in Item'Range);
256 pragma Loop_Invariant
257 (for some J in From .. Item'Last => Item (J) = nul);
258 pragma Loop_Invariant
259 (for all J in Item'First .. From when J /= From =>
260 Item (J) /= nul);
261 pragma Loop_Variant (Increases => From);
263 if From > Item'Last then
264 raise Terminator_Error;
265 elsif Item (From) = nul then
266 exit;
267 else
268 From := From + 1;
269 end if;
270 end loop;
272 Count := Natural (From - Item'First);
274 else
275 Count := Item'Length;
276 end if;
278 if Count > Target'Length then
279 raise Constraint_Error;
281 else
282 From := Item'First;
283 To := Target'First;
285 for J in 1 .. Count loop
286 Target (To) := Character (Item (From));
288 pragma Loop_Invariant (From in Item'Range);
289 pragma Loop_Invariant (To in Target'Range);
290 pragma Loop_Invariant (To = Target'First + (J - 1));
291 pragma Loop_Invariant (From = Item'First + size_t (J - 1));
292 pragma Loop_Invariant
293 (for all J in Target'First .. To => Target (J)'Initialized);
294 pragma Loop_Invariant
295 (Target (Target'First .. To)'Initialized);
296 pragma Loop_Invariant
297 (for all K in Target'First .. To =>
298 Target (K) =
299 To_Ada (Item (size_t (K - Target'First) + Item'First)));
301 -- Avoid possible overflow when incrementing To in the last
302 -- iteration of the loop.
303 exit when J = Count;
305 From := From + 1;
306 To := To + 1;
307 end loop;
308 end if;
309 end To_Ada;
311 -- Convert wchar_t to Wide_Character
313 function To_Ada (Item : wchar_t) return Wide_Character is
314 begin
315 return Wide_Character (Item);
316 end To_Ada;
318 -- Convert wchar_array to Wide_String (function form)
320 function To_Ada
321 (Item : wchar_array;
322 Trim_Nul : Boolean := True) return Wide_String
324 Count : Natural;
325 From : size_t;
327 begin
328 if Trim_Nul then
329 From := Item'First;
331 loop
332 pragma Loop_Invariant (From in Item'Range);
333 pragma Loop_Invariant
334 (for some J in From .. Item'Last => Item (J) = wide_nul);
335 pragma Loop_Invariant
336 (for all J in Item'First .. From when J /= From =>
337 Item (J) /= wide_nul);
338 pragma Loop_Variant (Increases => From);
340 if From > Item'Last then
341 raise Terminator_Error;
342 elsif Item (From) = wide_nul then
343 exit;
344 else
345 From := From + 1;
346 end if;
347 end loop;
349 pragma Assert (From = Item'First + C_Length_Ghost (Item));
351 Count := Natural (From - Item'First);
353 else
354 Count := Item'Length;
355 end if;
357 declare
358 Count_Cst : constant Natural := Count;
359 R : Wide_String (1 .. Count_Cst) with Relaxed_Initialization;
361 begin
362 for J in R'Range loop
363 R (J) := To_Ada (Item (size_t (J) - 1 + Item'First));
365 pragma Loop_Invariant (for all K in 1 .. J => R (K)'Initialized);
366 pragma Loop_Invariant
367 (for all K in 1 .. J =>
368 R (K) = To_Ada (Item (size_t (K) - 1 + Item'First)));
369 end loop;
371 return R;
372 end;
373 end To_Ada;
375 -- Convert wchar_array to Wide_String (procedure form)
377 procedure To_Ada
378 (Item : wchar_array;
379 Target : out Wide_String;
380 Count : out Natural;
381 Trim_Nul : Boolean := True)
383 From : size_t;
384 To : Integer;
386 begin
387 if Trim_Nul then
388 From := Item'First;
389 loop
390 pragma Loop_Invariant (From in Item'Range);
391 pragma Loop_Invariant
392 (for some J in From .. Item'Last => Item (J) = wide_nul);
393 pragma Loop_Invariant
394 (for all J in Item'First .. From when J /= From =>
395 Item (J) /= wide_nul);
396 pragma Loop_Variant (Increases => From);
398 if From > Item'Last then
399 raise Terminator_Error;
400 elsif Item (From) = wide_nul then
401 exit;
402 else
403 From := From + 1;
404 end if;
405 end loop;
407 Count := Natural (From - Item'First);
409 else
410 Count := Item'Length;
411 end if;
413 if Count > Target'Length then
414 raise Constraint_Error;
416 else
417 From := Item'First;
418 To := Target'First;
420 for J in 1 .. Count loop
421 Target (To) := To_Ada (Item (From));
423 pragma Loop_Invariant (From in Item'Range);
424 pragma Loop_Invariant (To in Target'Range);
425 pragma Loop_Invariant (To = Target'First + (J - 1));
426 pragma Loop_Invariant (From = Item'First + size_t (J - 1));
427 pragma Loop_Invariant
428 (for all J in Target'First .. To => Target (J)'Initialized);
429 pragma Loop_Invariant
430 (Target (Target'First .. To)'Initialized);
431 pragma Loop_Invariant
432 (for all K in Target'First .. To =>
433 Target (K) =
434 To_Ada (Item (size_t (K - Target'First) + Item'First)));
436 -- Avoid possible overflow when incrementing To in the last
437 -- iteration of the loop.
438 exit when J = Count;
440 From := From + 1;
441 To := To + 1;
442 end loop;
443 end if;
444 end To_Ada;
446 -- Convert char16_t to Wide_Character
448 function To_Ada (Item : char16_t) return Wide_Character is
449 begin
450 return Wide_Character'Val (char16_t'Pos (Item));
451 end To_Ada;
453 -- Convert char16_array to Wide_String (function form)
455 function To_Ada
456 (Item : char16_array;
457 Trim_Nul : Boolean := True) return Wide_String
459 Count : Natural;
460 From : size_t;
462 begin
463 if Trim_Nul then
464 From := Item'First;
466 loop
467 pragma Loop_Invariant (From in Item'Range);
468 pragma Loop_Invariant
469 (for some J in From .. Item'Last => Item (J) = char16_nul);
470 pragma Loop_Invariant
471 (for all J in Item'First .. From when J /= From =>
472 Item (J) /= char16_nul);
473 pragma Loop_Variant (Increases => From);
475 if From > Item'Last then
476 raise Terminator_Error;
477 elsif Item (From) = char16_nul then
478 exit;
479 else
480 From := From + 1;
481 end if;
482 end loop;
484 pragma Assert (From = Item'First + C_Length_Ghost (Item));
486 Count := Natural (From - Item'First);
488 else
489 Count := Item'Length;
490 end if;
492 declare
493 Count_Cst : constant Natural := Count;
494 R : Wide_String (1 .. Count_Cst) with Relaxed_Initialization;
496 begin
497 for J in R'Range loop
498 R (J) := To_Ada (Item (size_t (J) - 1 + Item'First));
500 pragma Loop_Invariant (for all K in 1 .. J => R (K)'Initialized);
501 pragma Loop_Invariant
502 (for all K in 1 .. J =>
503 R (K) = To_Ada (Item (size_t (K) - 1 + Item'First)));
504 end loop;
506 return R;
507 end;
508 end To_Ada;
510 -- Convert char16_array to Wide_String (procedure form)
512 procedure To_Ada
513 (Item : char16_array;
514 Target : out Wide_String;
515 Count : out Natural;
516 Trim_Nul : Boolean := True)
518 From : size_t;
519 To : Integer;
521 begin
522 if Trim_Nul then
523 From := Item'First;
524 loop
525 pragma Loop_Invariant (From in Item'Range);
526 pragma Loop_Invariant
527 (for some J in From .. Item'Last => Item (J) = char16_nul);
528 pragma Loop_Invariant
529 (for all J in Item'First .. From when J /= From =>
530 Item (J) /= char16_nul);
531 pragma Loop_Variant (Increases => From);
533 if From > Item'Last then
534 raise Terminator_Error;
535 elsif Item (From) = char16_nul then
536 exit;
537 else
538 From := From + 1;
539 end if;
540 end loop;
542 Count := Natural (From - Item'First);
544 else
545 Count := Item'Length;
546 end if;
548 if Count > Target'Length then
549 raise Constraint_Error;
551 else
552 From := Item'First;
553 To := Target'First;
555 for J in 1 .. Count loop
556 Target (To) := To_Ada (Item (From));
558 pragma Loop_Invariant (From in Item'Range);
559 pragma Loop_Invariant (To in Target'Range);
560 pragma Loop_Invariant (To = Target'First + (J - 1));
561 pragma Loop_Invariant (From = Item'First + size_t (J - 1));
562 pragma Loop_Invariant
563 (for all J in Target'First .. To => Target (J)'Initialized);
564 pragma Loop_Invariant
565 (Target (Target'First .. To)'Initialized);
566 pragma Loop_Invariant
567 (for all K in Target'First .. To =>
568 Target (K) =
569 To_Ada (Item (size_t (K - Target'First) + Item'First)));
571 -- Avoid possible overflow when incrementing To in the last
572 -- iteration of the loop.
573 exit when J = Count;
575 From := From + 1;
576 To := To + 1;
577 end loop;
578 end if;
579 end To_Ada;
581 -- Convert char32_t to Wide_Wide_Character
583 function To_Ada (Item : char32_t) return Wide_Wide_Character is
584 begin
585 return Wide_Wide_Character'Val (char32_t'Pos (Item));
586 end To_Ada;
588 -- Convert char32_array to Wide_Wide_String (function form)
590 function To_Ada
591 (Item : char32_array;
592 Trim_Nul : Boolean := True) return Wide_Wide_String
594 Count : Natural;
595 From : size_t;
597 begin
598 if Trim_Nul then
599 From := Item'First;
601 loop
602 pragma Loop_Invariant (From in Item'Range);
603 pragma Loop_Invariant
604 (for some J in From .. Item'Last => Item (J) = char32_nul);
605 pragma Loop_Invariant
606 (for all J in Item'First .. From when J /= From =>
607 Item (J) /= char32_nul);
608 pragma Loop_Invariant (From <= Item'First + C_Length_Ghost (Item));
609 pragma Loop_Variant (Increases => From);
611 if From > Item'Last then
612 raise Terminator_Error;
613 elsif Item (From) = char32_nul then
614 exit;
615 else
616 From := From + 1;
617 end if;
618 end loop;
620 pragma Assert (From = Item'First + C_Length_Ghost (Item));
622 Count := Natural (From - Item'First);
624 else
625 Count := Item'Length;
626 end if;
628 declare
629 Count_Cst : constant Natural := Count;
630 R : Wide_Wide_String (1 .. Count_Cst) with Relaxed_Initialization;
632 begin
633 for J in R'Range loop
634 R (J) := To_Ada (Item (size_t (J) - 1 + Item'First));
636 pragma Loop_Invariant (for all K in 1 .. J => R (K)'Initialized);
637 pragma Loop_Invariant
638 (for all K in 1 .. J =>
639 R (K) = To_Ada (Item (size_t (K) - 1 + Item'First)));
640 end loop;
642 return R;
643 end;
644 end To_Ada;
646 -- Convert char32_array to Wide_Wide_String (procedure form)
648 procedure To_Ada
649 (Item : char32_array;
650 Target : out Wide_Wide_String;
651 Count : out Natural;
652 Trim_Nul : Boolean := True)
654 From : size_t;
655 To : Integer;
657 begin
658 if Trim_Nul then
659 From := Item'First;
660 loop
661 pragma Loop_Invariant (From in Item'Range);
662 pragma Loop_Invariant
663 (for some J in From .. Item'Last => Item (J) = char32_nul);
664 pragma Loop_Invariant
665 (for all J in Item'First .. From when J /= From =>
666 Item (J) /= char32_nul);
667 pragma Loop_Variant (Increases => From);
669 if From > Item'Last then
670 raise Terminator_Error;
671 elsif Item (From) = char32_nul then
672 exit;
673 else
674 From := From + 1;
675 end if;
676 end loop;
678 Count := Natural (From - Item'First);
680 else
681 Count := Item'Length;
682 end if;
684 if Count > Target'Length then
685 raise Constraint_Error;
687 else
688 From := Item'First;
689 To := Target'First;
691 for J in 1 .. Count loop
692 Target (To) := To_Ada (Item (From));
694 pragma Loop_Invariant (From in Item'Range);
695 pragma Loop_Invariant (To in Target'Range);
696 pragma Loop_Invariant (To = Target'First + (J - 1));
697 pragma Loop_Invariant (From = Item'First + size_t (J - 1));
698 pragma Loop_Invariant
699 (for all J in Target'First .. To => Target (J)'Initialized);
700 pragma Loop_Invariant
701 (Target (Target'First .. To)'Initialized);
702 pragma Loop_Invariant
703 (for all K in Target'First .. To =>
704 Target (K) =
705 To_Ada (Item (size_t (K - Target'First) + Item'First)));
707 -- Avoid possible overflow when incrementing To in the last
708 -- iteration of the loop.
709 exit when J = Count;
711 From := From + 1;
712 To := To + 1;
713 end loop;
714 end if;
715 end To_Ada;
717 ----------
718 -- To_C --
719 ----------
721 -- Convert Character to char
723 function To_C (Item : Character) return char is
724 begin
725 return char'Val (Character'Pos (Item));
726 end To_C;
728 -- Convert String to char_array (function form)
730 function To_C
731 (Item : String;
732 Append_Nul : Boolean := True) return char_array
734 begin
735 if Append_Nul then
736 declare
737 R : char_array (0 .. Item'Length) with Relaxed_Initialization;
739 begin
740 for J in Item'Range loop
741 R (size_t (J - Item'First)) := To_C (Item (J));
743 pragma Loop_Invariant
744 (for all K in 0 .. size_t (J - Item'First) =>
745 R (K)'Initialized);
746 pragma Loop_Invariant
747 (for all K in Item'First .. J =>
748 R (size_t (K - Item'First)) = To_C (Item (K)));
749 end loop;
751 R (R'Last) := nul;
753 pragma Assert
754 (for all J in Item'Range =>
755 R (size_t (J - Item'First)) = To_C (Item (J)));
757 return R;
758 end;
760 -- Append_Nul False
762 else
763 -- A nasty case, if the string is null, we must return a null
764 -- char_array. The lower bound of this array is required to be zero
765 -- (RM B.3(50)) but that is of course impossible given that size_t
766 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
767 -- Constraint_Error. This is also the appropriate behavior in Ada 95,
768 -- since nothing else makes sense.
770 if Item'Length = 0 then
771 raise Constraint_Error;
773 -- Normal case
775 else
776 declare
777 R : char_array (0 .. Item'Length - 1)
778 with Relaxed_Initialization;
780 begin
781 for J in Item'Range loop
782 R (size_t (J - Item'First)) := To_C (Item (J));
784 pragma Loop_Invariant
785 (for all K in 0 .. size_t (J - Item'First) =>
786 R (K)'Initialized);
787 pragma Loop_Invariant
788 (for all K in Item'First .. J =>
789 R (size_t (K - Item'First)) = To_C (Item (K)));
790 end loop;
792 return R;
793 end;
794 end if;
795 end if;
796 end To_C;
798 -- Convert String to char_array (procedure form)
800 procedure To_C
801 (Item : String;
802 Target : out char_array;
803 Count : out size_t;
804 Append_Nul : Boolean := True)
806 To : size_t;
808 begin
809 if Target'Length < Item'Length then
810 raise Constraint_Error;
812 else
813 To := Target'First;
814 for From in Item'Range loop
815 Target (To) := char (Item (From));
817 pragma Loop_Invariant (To in Target'Range);
818 pragma Loop_Invariant
819 (To - Target'First = size_t (From - Item'First));
820 pragma Loop_Invariant
821 (for all J in Target'First .. To => Target (J)'Initialized);
822 pragma Loop_Invariant
823 (Target (Target'First .. To)'Initialized);
824 pragma Loop_Invariant
825 (for all J in Item'First .. From =>
826 Target (Target'First + size_t (J - Item'First)) =
827 To_C (Item (J)));
829 To := To + 1;
830 end loop;
832 if Append_Nul then
833 if To > Target'Last then
834 raise Constraint_Error;
835 else
836 Target (To) := nul;
837 Count := Item'Length + 1;
838 end if;
840 else
841 Count := Item'Length;
842 end if;
843 end if;
844 end To_C;
846 -- Convert Wide_Character to wchar_t
848 function To_C (Item : Wide_Character) return wchar_t is
849 begin
850 return wchar_t (Item);
851 end To_C;
853 -- Convert Wide_String to wchar_array (function form)
855 function To_C
856 (Item : Wide_String;
857 Append_Nul : Boolean := True) return wchar_array
859 begin
860 if Append_Nul then
861 declare
862 R : wchar_array (0 .. Item'Length) with Relaxed_Initialization;
864 begin
865 for J in Item'Range loop
866 R (size_t (J - Item'First)) := To_C (Item (J));
868 pragma Loop_Invariant
869 (for all K in 0 .. size_t (J - Item'First) =>
870 R (K)'Initialized);
871 pragma Loop_Invariant
872 (for all K in Item'First .. J =>
873 R (size_t (K - Item'First)) = To_C (Item (K)));
874 end loop;
876 R (R'Last) := wide_nul;
878 pragma Assert
879 (for all J in Item'Range =>
880 R (size_t (J - Item'First)) = To_C (Item (J)));
882 return R;
883 end;
885 else
886 -- A nasty case, if the string is null, we must return a null
887 -- wchar_array. The lower bound of this array is required to be zero
888 -- (RM B.3(50)) but that is of course impossible given that size_t
889 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
890 -- Constraint_Error. This is also the appropriate behavior in Ada 95,
891 -- since nothing else makes sense.
893 if Item'Length = 0 then
894 raise Constraint_Error;
896 else
897 declare
898 R : wchar_array (0 .. Item'Length - 1)
899 with Relaxed_Initialization;
901 begin
902 for J in Item'Range loop
903 R (size_t (J - Item'First)) := To_C (Item (J));
905 pragma Loop_Invariant
906 (for all K in 0 .. size_t (J - Item'First) =>
907 R (K)'Initialized);
908 pragma Loop_Invariant
909 (for all K in Item'First .. J =>
910 R (size_t (K - Item'First)) = To_C (Item (K)));
911 end loop;
913 return R;
914 end;
915 end if;
916 end if;
917 end To_C;
919 -- Convert Wide_String to wchar_array (procedure form)
921 procedure To_C
922 (Item : Wide_String;
923 Target : out wchar_array;
924 Count : out size_t;
925 Append_Nul : Boolean := True)
927 To : size_t;
929 begin
930 if Target'Length < Item'Length then
931 raise Constraint_Error;
933 else
934 To := Target'First;
935 for From in Item'Range loop
936 Target (To) := To_C (Item (From));
938 pragma Loop_Invariant (To in Target'Range);
939 pragma Loop_Invariant
940 (To - Target'First = size_t (From - Item'First));
941 pragma Loop_Invariant
942 (for all J in Target'First .. To => Target (J)'Initialized);
943 pragma Loop_Invariant
944 (Target (Target'First .. To)'Initialized);
945 pragma Loop_Invariant
946 (for all J in Item'First .. From =>
947 Target (Target'First + size_t (J - Item'First)) =
948 To_C (Item (J)));
950 To := To + 1;
951 end loop;
953 pragma Assert
954 (for all J in Item'Range =>
955 Target (Target'First + size_t (J - Item'First)) =
956 To_C (Item (J)));
957 pragma Assert
958 (if Item'Length /= 0 then
959 Target (Target'First ..
960 Target'First + (Item'Length - 1))'Initialized);
962 if Append_Nul then
963 if To > Target'Last then
964 raise Constraint_Error;
965 else
966 Target (To) := wide_nul;
967 Count := Item'Length + 1;
968 end if;
970 else
971 Count := Item'Length;
972 end if;
973 end if;
974 end To_C;
976 -- Convert Wide_Character to char16_t
978 function To_C (Item : Wide_Character) return char16_t is
979 begin
980 return char16_t'Val (Wide_Character'Pos (Item));
981 end To_C;
983 -- Convert Wide_String to char16_array (function form)
985 function To_C
986 (Item : Wide_String;
987 Append_Nul : Boolean := True) return char16_array
989 begin
990 if Append_Nul then
991 declare
992 R : char16_array (0 .. Item'Length) with Relaxed_Initialization;
994 begin
995 for J in Item'Range loop
996 R (size_t (J - Item'First)) := To_C (Item (J));
998 pragma Loop_Invariant
999 (for all K in 0 .. size_t (J - Item'First) =>
1000 R (K)'Initialized);
1001 pragma Loop_Invariant
1002 (for all K in Item'First .. J =>
1003 R (size_t (K - Item'First)) = To_C (Item (K)));
1004 end loop;
1006 R (R'Last) := char16_nul;
1008 pragma Assert
1009 (for all J in Item'Range =>
1010 R (size_t (J - Item'First)) = To_C (Item (J)));
1012 return R;
1013 end;
1015 else
1016 -- A nasty case, if the string is null, we must return a null
1017 -- char16_array. The lower bound of this array is required to be zero
1018 -- (RM B.3(50)) but that is of course impossible given that size_t
1019 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
1020 -- Constraint_Error. This is also the appropriate behavior in Ada 95,
1021 -- since nothing else makes sense.
1023 if Item'Length = 0 then
1024 raise Constraint_Error;
1026 else
1027 declare
1028 R : char16_array (0 .. Item'Length - 1)
1029 with Relaxed_Initialization;
1031 begin
1032 for J in Item'Range loop
1033 R (size_t (J - Item'First)) := To_C (Item (J));
1035 pragma Loop_Invariant
1036 (for all K in 0 .. size_t (J - Item'First) =>
1037 R (K)'Initialized);
1038 pragma Loop_Invariant
1039 (for all K in Item'First .. J =>
1040 R (size_t (K - Item'First)) = To_C (Item (K)));
1041 end loop;
1043 return R;
1044 end;
1045 end if;
1046 end if;
1047 end To_C;
1049 -- Convert Wide_String to char16_array (procedure form)
1051 procedure To_C
1052 (Item : Wide_String;
1053 Target : out char16_array;
1054 Count : out size_t;
1055 Append_Nul : Boolean := True)
1057 To : size_t;
1059 begin
1060 if Target'Length < Item'Length then
1061 raise Constraint_Error;
1063 else
1064 To := Target'First;
1065 for From in Item'Range loop
1066 Target (To) := To_C (Item (From));
1068 pragma Loop_Invariant (To in Target'Range);
1069 pragma Loop_Invariant
1070 (To - Target'First = size_t (From - Item'First));
1071 pragma Loop_Invariant
1072 (for all J in Target'First .. To => Target (J)'Initialized);
1073 pragma Loop_Invariant
1074 (Target (Target'First .. To)'Initialized);
1075 pragma Loop_Invariant
1076 (for all J in Item'First .. From =>
1077 Target (Target'First + size_t (J - Item'First)) =
1078 To_C (Item (J)));
1080 To := To + 1;
1081 end loop;
1083 pragma Assert
1084 (for all J in Item'Range =>
1085 Target (Target'First + size_t (J - Item'First)) =
1086 To_C (Item (J)));
1087 pragma Assert
1088 (if Item'Length /= 0 then
1089 Target (Target'First ..
1090 Target'First + (Item'Length - 1))'Initialized);
1092 if Append_Nul then
1093 if To > Target'Last then
1094 raise Constraint_Error;
1095 else
1096 Target (To) := char16_nul;
1097 Count := Item'Length + 1;
1098 end if;
1100 else
1101 Count := Item'Length;
1102 end if;
1103 end if;
1104 end To_C;
1106 -- Convert Wide_Character to char32_t
1108 function To_C (Item : Wide_Wide_Character) return char32_t is
1109 begin
1110 return char32_t'Val (Wide_Wide_Character'Pos (Item));
1111 end To_C;
1113 -- Convert Wide_Wide_String to char32_array (function form)
1115 function To_C
1116 (Item : Wide_Wide_String;
1117 Append_Nul : Boolean := True) return char32_array
1119 begin
1120 if Append_Nul then
1121 declare
1122 R : char32_array (0 .. Item'Length) with Relaxed_Initialization;
1124 begin
1125 for J in Item'Range loop
1126 R (size_t (J - Item'First)) := To_C (Item (J));
1128 pragma Loop_Invariant
1129 (for all K in 0 .. size_t (J - Item'First) =>
1130 R (K)'Initialized);
1131 pragma Loop_Invariant
1132 (for all K in Item'First .. J =>
1133 R (size_t (K - Item'First)) = To_C (Item (K)));
1134 end loop;
1136 R (R'Last) := char32_nul;
1138 pragma Assert
1139 (for all J in Item'Range =>
1140 R (size_t (J - Item'First)) = To_C (Item (J)));
1142 return R;
1143 end;
1145 else
1146 -- A nasty case, if the string is null, we must return a null
1147 -- char32_array. The lower bound of this array is required to be zero
1148 -- (RM B.3(50)) but that is of course impossible given that size_t
1149 -- is unsigned. According to Ada 2005 AI-258, the result is to raise
1150 -- Constraint_Error.
1152 if Item'Length = 0 then
1153 raise Constraint_Error;
1155 else
1156 declare
1157 R : char32_array (0 .. Item'Length - 1)
1158 with Relaxed_Initialization;
1160 begin
1161 for J in Item'Range loop
1162 R (size_t (J - Item'First)) := To_C (Item (J));
1164 pragma Loop_Invariant
1165 (for all K in 0 .. size_t (J - Item'First) =>
1166 R (K)'Initialized);
1167 pragma Loop_Invariant
1168 (for all K in Item'First .. J =>
1169 R (size_t (K - Item'First)) = To_C (Item (K)));
1170 end loop;
1172 return R;
1173 end;
1174 end if;
1175 end if;
1176 end To_C;
1178 -- Convert Wide_Wide_String to char32_array (procedure form)
1180 procedure To_C
1181 (Item : Wide_Wide_String;
1182 Target : out char32_array;
1183 Count : out size_t;
1184 Append_Nul : Boolean := True)
1186 To : size_t;
1188 begin
1189 if Target'Length < Item'Length + (if Append_Nul then 1 else 0) then
1190 raise Constraint_Error;
1192 else
1193 To := Target'First;
1194 for From in Item'Range loop
1195 Target (To) := To_C (Item (From));
1197 pragma Loop_Invariant (To in Target'Range);
1198 pragma Loop_Invariant
1199 (To - Target'First = size_t (From - Item'First));
1200 pragma Loop_Invariant
1201 (for all J in Target'First .. To => Target (J)'Initialized);
1202 pragma Loop_Invariant
1203 (Target (Target'First .. To)'Initialized);
1204 pragma Loop_Invariant
1205 (for all J in Item'First .. From =>
1206 Target (Target'First + size_t (J - Item'First)) =
1207 To_C (Item (J)));
1209 To := To + 1;
1210 end loop;
1212 pragma Assert
1213 (for all J in Item'Range =>
1214 Target (Target'First + size_t (J - Item'First)) =
1215 To_C (Item (J)));
1216 pragma Assert
1217 (if Item'Length /= 0 then
1218 Target (Target'First ..
1219 Target'First + (Item'Length - 1))'Initialized);
1221 if Append_Nul then
1222 Target (To) := char32_nul;
1223 Count := Item'Length + 1;
1224 else
1225 Count := Item'Length;
1226 end if;
1227 end if;
1228 end To_C;
1229 pragma Annotate (CodePeer, False_Positive, "validity check",
1230 "Count is only uninitialized on abnormal return.");
1232 end Interfaces.C;