OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [i-cstrin.adb] - Blame information for rev 716

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                 I N T E R F A C E S . C . S T R I N G S                  --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 1992-2010, 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
------------------------------------------------------------------------------
31
 
32
with System; use System;
33
with System.Storage_Elements; use System.Storage_Elements;
34
 
35
with Ada.Unchecked_Conversion;
36
 
37
package body Interfaces.C.Strings is
38
 
39
   --  Note that the type chars_ptr has a pragma No_Strict_Aliasing in the
40
   --  spec, to prevent any assumptions about aliasing for values of this type,
41
   --  since arbitrary addresses can be converted, and it is quite likely that
42
   --  this type will in fact be used for aliasing values of other types.
43
 
44
   function To_chars_ptr is
45
      new Ada.Unchecked_Conversion (System.Parameters.C_Address, chars_ptr);
46
 
47
   function To_Address is
48
      new Ada.Unchecked_Conversion (chars_ptr, System.Parameters.C_Address);
49
 
50
   -----------------------
51
   -- Local Subprograms --
52
   -----------------------
53
 
54
   function Peek (From : chars_ptr) return char;
55
   pragma Inline (Peek);
56
   --  Given a chars_ptr value, obtain referenced character
57
 
58
   procedure Poke (Value : char; Into : chars_ptr);
59
   pragma Inline (Poke);
60
   --  Given a chars_ptr, modify referenced Character value
61
 
62
   function "+" (Left : chars_ptr; Right : size_t) return chars_ptr;
63
   pragma Inline ("+");
64
   --  Address arithmetic on chars_ptr value
65
 
66
   function Position_Of_Nul (Into : char_array) return size_t;
67
   --  Returns position of the first Nul in Into or Into'Last + 1 if none
68
 
69
   --  We can't use directly System.Memory because the categorization is not
70
   --  compatible, so we directly import here the malloc and free routines.
71
 
72
   function Memory_Alloc (Size : size_t) return chars_ptr;
73
   pragma Import (C, Memory_Alloc, System.Parameters.C_Malloc_Linkname);
74
 
75
   procedure Memory_Free (Address : chars_ptr);
76
   pragma Import (C, Memory_Free, "__gnat_free");
77
 
78
   ---------
79
   -- "+" --
80
   ---------
81
 
82
   function "+" (Left : chars_ptr; Right : size_t) return chars_ptr is
83
   begin
84
      return To_chars_ptr (To_Address (Left) + Storage_Offset (Right));
85
   end "+";
86
 
87
   ----------
88
   -- Free --
89
   ----------
90
 
91
   procedure Free (Item : in out chars_ptr) is
92
   begin
93
      if Item = Null_Ptr then
94
         return;
95
      end if;
96
 
97
      Memory_Free (Item);
98
      Item := Null_Ptr;
99
   end Free;
100
 
101
   --------------------
102
   -- New_Char_Array --
103
   --------------------
104
 
105
   function New_Char_Array (Chars : char_array) return chars_ptr is
106
      Index   : size_t;
107
      Pointer : chars_ptr;
108
 
109
   begin
110
      --  Get index of position of null. If Index > Chars'Last,
111
      --  nul is absent and must be added explicitly.
112
 
113
      Index := Position_Of_Nul (Into => Chars);
114
      Pointer := Memory_Alloc ((Index - Chars'First + 1));
115
 
116
      --  If nul is present, transfer string up to and including nul
117
 
118
      if Index <= Chars'Last then
119
         Update (Item   => Pointer,
120
                 Offset => 0,
121
                 Chars  => Chars (Chars'First .. Index),
122
                 Check  => False);
123
      else
124
         --  If original string has no nul, transfer whole string and add
125
         --  terminator explicitly.
126
 
127
         Update (Item   => Pointer,
128
                 Offset => 0,
129
                 Chars  => Chars,
130
                 Check  => False);
131
         Poke (nul, Into => Pointer + size_t'(Chars'Length));
132
      end if;
133
 
134
      return Pointer;
135
   end New_Char_Array;
136
 
137
   ----------------
138
   -- New_String --
139
   ----------------
140
 
141
   function New_String (Str : String) return chars_ptr is
142
 
143
      --  It's important that this subprogram uses the heap directly to compute
144
      --  the result, and doesn't copy the string on the stack, otherwise its
145
      --  use is limited when used from tasks on large strings.
146
 
147
      Result : constant chars_ptr := Memory_Alloc (Str'Length + 1);
148
 
149
      Result_Array : char_array  (1 .. Str'Length + 1);
150
      for Result_Array'Address use To_Address (Result);
151
      pragma Import (Ada, Result_Array);
152
 
153
      Count : size_t;
154
 
155
   begin
156
      To_C
157
        (Item       => Str,
158
         Target     => Result_Array,
159
         Count      => Count,
160
         Append_Nul => True);
161
      return Result;
162
   end New_String;
163
 
164
   ----------
165
   -- Peek --
166
   ----------
167
 
168
   function Peek (From : chars_ptr) return char is
169
   begin
170
      return char (From.all);
171
   end Peek;
172
 
173
   ----------
174
   -- Poke --
175
   ----------
176
 
177
   procedure Poke (Value : char; Into : chars_ptr) is
178
   begin
179
      Into.all := Character (Value);
180
   end Poke;
181
 
182
   ---------------------
183
   -- Position_Of_Nul --
184
   ---------------------
185
 
186
   function Position_Of_Nul (Into : char_array) return size_t is
187
   begin
188
      for J in Into'Range loop
189
         if Into (J) = nul then
190
            return J;
191
         end if;
192
      end loop;
193
 
194
      return Into'Last + 1;
195
   end Position_Of_Nul;
196
 
197
   ------------
198
   -- Strlen --
199
   ------------
200
 
201
   function Strlen (Item : chars_ptr) return size_t is
202
      Item_Index : size_t := 0;
203
 
204
   begin
205
      if Item = Null_Ptr then
206
         raise Dereference_Error;
207
      end if;
208
 
209
      loop
210
         if Peek (Item + Item_Index) = nul then
211
            return Item_Index;
212
         end if;
213
 
214
         Item_Index := Item_Index + 1;
215
      end loop;
216
   end Strlen;
217
 
218
   ------------------
219
   -- To_Chars_Ptr --
220
   ------------------
221
 
222
   function To_Chars_Ptr
223
     (Item      : char_array_access;
224
      Nul_Check : Boolean := False) return chars_ptr
225
   is
226
   begin
227
      if Item = null then
228
         return Null_Ptr;
229
      elsif Nul_Check
230
        and then Position_Of_Nul (Into => Item.all) > Item'Last
231
      then
232
         raise Terminator_Error;
233
      else
234
         return To_chars_ptr (Item (Item'First)'Address);
235
      end if;
236
   end To_Chars_Ptr;
237
 
238
   ------------
239
   -- Update --
240
   ------------
241
 
242
   procedure Update
243
     (Item   : chars_ptr;
244
      Offset : size_t;
245
      Chars  : char_array;
246
      Check  : Boolean := True)
247
   is
248
      Index : chars_ptr := Item + Offset;
249
 
250
   begin
251
      if Check and then Offset + Chars'Length  > Strlen (Item) then
252
         raise Update_Error;
253
      end if;
254
 
255
      for J in Chars'Range loop
256
         Poke (Chars (J), Into => Index);
257
         Index := Index + size_t'(1);
258
      end loop;
259
   end Update;
260
 
261
   procedure Update
262
     (Item   : chars_ptr;
263
      Offset : size_t;
264
      Str    : String;
265
      Check  : Boolean := True)
266
   is
267
   begin
268
      --  Note: in RM 95, the Append_Nul => False parameter is omitted. But
269
      --  this has the unintended consequence of truncating the string after
270
      --  an update. As discussed in Ada 2005 AI-242, this was unintended,
271
      --  and should be corrected. Since this is a clear error, it seems
272
      --  appropriate to apply the correction in Ada 95 mode as well.
273
 
274
      Update (Item, Offset, To_C (Str, Append_Nul => False), Check);
275
   end Update;
276
 
277
   -----------
278
   -- Value --
279
   -----------
280
 
281
   function Value (Item : chars_ptr) return char_array is
282
      Result : char_array (0 .. Strlen (Item));
283
 
284
   begin
285
      if Item = Null_Ptr then
286
         raise Dereference_Error;
287
      end if;
288
 
289
      --  Note that the following loop will also copy the terminating Nul
290
 
291
      for J in Result'Range loop
292
         Result (J) := Peek (Item + J);
293
      end loop;
294
 
295
      return Result;
296
   end Value;
297
 
298
   function Value
299
     (Item   : chars_ptr;
300
      Length : size_t) return char_array
301
   is
302
   begin
303
      if Item = Null_Ptr then
304
         raise Dereference_Error;
305
      end if;
306
 
307
      --  ACATS cxb3010 checks that Constraint_Error gets raised when Length
308
      --  is 0. Seems better to check that Length is not null before declaring
309
      --  an array with size_t bounds of 0 .. Length - 1 anyway.
310
 
311
      if Length = 0 then
312
         raise Constraint_Error;
313
      end if;
314
 
315
      declare
316
         Result : char_array (0 .. Length - 1);
317
 
318
      begin
319
         for J in Result'Range loop
320
            Result (J) := Peek (Item + J);
321
 
322
            if Result (J) = nul then
323
               return Result (0 .. J);
324
            end if;
325
         end loop;
326
 
327
         return Result;
328
      end;
329
   end Value;
330
 
331
   function Value (Item : chars_ptr) return String is
332
   begin
333
      return To_Ada (Value (Item));
334
   end Value;
335
 
336
   function Value (Item : chars_ptr; Length : size_t) return String is
337
      Result : char_array (0 .. Length);
338
 
339
   begin
340
      --  As per AI-00177, this is equivalent to:
341
 
342
      --    To_Ada (Value (Item, Length) & nul);
343
 
344
      if Item = Null_Ptr then
345
         raise Dereference_Error;
346
      end if;
347
 
348
      for J in 0 .. Length - 1 loop
349
         Result (J) := Peek (Item + J);
350
 
351
         if Result (J) = nul then
352
            return To_Ada (Result (0 .. J));
353
         end if;
354
      end loop;
355
 
356
      Result (Length) := nul;
357
      return To_Ada (Result);
358
   end Value;
359
 
360
end Interfaces.C.Strings;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.