B.3.1 The Package Interfaces.C.Strings
1/3
{
AI05-0229-1}
The package Interfaces.C.Strings declares types and subprograms allowing
an Ada program to allocate, reference, update, and free C-style strings.
In particular, the private type chars_ptr corresponds to a common use
of “char *” in C programs, and an object of this type can
be passed to a subprogram to which
with
Import => True, Convention => C pragma
Import(C,...) has been
specified applied,
and for which “char *” is the type of the argument of the
C function.
Static Semantics
2
The library package
Interfaces.C.Strings has the following declaration:
3
package Interfaces.C.Strings
is
pragma Preelaborate(Strings);
4
type char_array_access
is access all char_array;
5/2
{
AI95-00161-01}
type chars_ptr
is private;
pragma Preelaborable_Initialization(chars_ptr);
6/2
{
AI95-00276-01}
type chars_ptr_array
is array (size_t
range <>)
of aliased chars_ptr;
7
Null_Ptr :
constant chars_ptr;
8
function To_Chars_Ptr (Item :
in char_array_access;
Nul_Check :
in Boolean := False)
return chars_ptr;
9
function New_Char_Array (Chars :
in char_array)
return chars_ptr;
10
function New_String (Str :
in String)
return chars_ptr;
11
procedure Free (Item :
in out chars_ptr);
12
Dereference_Error :
exception;
13
function Value (Item :
in chars_ptr)
return char_array;
14
function Value (Item :
in chars_ptr; Length :
in size_t)
return char_array;
15
function Value (Item :
in chars_ptr)
return String;
16
function Value (Item :
in chars_ptr; Length :
in size_t)
return String;
17
function Strlen (Item :
in chars_ptr)
return size_t;
18
procedure Update (Item :
in chars_ptr;
Offset :
in size_t;
Chars :
in char_array;
Check :
in Boolean := True);
19
procedure Update (Item :
in chars_ptr;
Offset :
in size_t;
Str :
in String;
Check :
in Boolean := True);
20
Update_Error :
exception;
21
private
... -- not specified by the language
end Interfaces.C.Strings;
21.a
Discussion: The string manipulation types
and subprograms appear in a child of Interfaces.C versus being there
directly, since it is useful to have Interfaces.C specified as
pragma
Pure.
21.b
Differently named functions New_String and New_Char_Array
are declared, since if there were a single overloaded function a call
with a string literal as actual parameter would be ambiguous.
22
The type chars_ptr is C-compatible and corresponds
to the use of C's “char *” for a pointer to the first char
in a char array terminated by nul. When an object of type chars_ptr is
declared, its value is by default set to Null_Ptr, unless the object
is imported (see
B.1).
22.a
Discussion: The type char_array_access
is not necessarily C-compatible, since an object of this type may carry
“dope” information. The programmer should convert from char_array_access
to chars_ptr for objects imported from, exported to, or passed to C.
23
function To_Chars_Ptr (Item : in char_array_access;
Nul_Check : in Boolean := False)
return chars_ptr;
24/3
{
8652/0061}
{
AI95-00140-01}
{
AI05-0264-1}
If Item is
null, then To_Chars_Ptr returns Null_Ptr.
If
Item is not null, Otherwise, if
Nul_Check is True
, and Item.
all does
not contain nul, then the function propagates Terminator_Error;
otherwise, if
Nul_Check is True and Item.all does contain nul, To_Chars_Ptr
performs a pointer conversion with no allocation of memory.
25
function New_Char_Array (Chars : in char_array) return chars_ptr;
26
This function returns a pointer to an allocated
object initialized to Chars(Chars'First .. Index) & nul, where
27
Index = Chars'Last if Chars does not contain
nul, or
28
Index is the smallest size_t value I such
that Chars(I+1) = nul.
28.1
Storage_Error
is propagated if the allocation fails.
29
function New_String (Str : in String) return chars_ptr;
30
This function is
equivalent to New_Char_Array(To_C(Str)).
31
procedure Free (Item : in out chars_ptr);
32
If Item is Null_Ptr,
then Free has no effect. Otherwise, Free releases the storage occupied
by Value(Item), and resets Item to Null_Ptr.
33
function Value (Item : in chars_ptr) return char_array;
34/3
{
AI05-0264-1}
If Item = Null_Ptr
, then Value propagates
Dereference_Error. Otherwise
, Value returns
the prefix of the array of chars pointed to by Item, up to and including
the first nul. The lower bound of the result is 0. If Item does not point
to a nul-terminated string, then execution of Value is erroneous.
35
function Value (Item : in chars_ptr; Length : in size_t)
return char_array;
36/3
{
8652/0062}
{
AI95-00139-01}
{
AI05-0264-1}
If Item = Null_Ptr
, then Value
(Item)
propagates Dereference_Error. Otherwise
,
Value returns the shorter of two arrays
, either:
the first Length chars pointed to by Item,
or and
Value(Item). The lower bound of the result is 0.
If
Length is 0, then Value propagates Constraint_Error.
36.a
Ramification: Value(New_Char_Array(Chars))
= Chars if Chars does not contain nul; else Value(New_Char_Array( Chars))
is the prefix of Chars up to and including the first nul.
37
function Value (Item : in chars_ptr) return String;
38
Equivalent to To_Ada(Value(Item),
Trim_Nul=>True).
39
function Value (Item : in chars_ptr; Length : in size_t)
return String;
40/1
41
function Strlen (Item : in chars_ptr) return size_t;
42
Returns Val'Length–1
where Val = Value(Item); propagates Dereference_Error if Item
= Null_Ptr.
42.a
Ramification: Strlen returns the number
of chars in the array pointed to by Item, up to and including the char
immediately before the first nul.
42.b
Strlen has the same possibility for erroneous
execution as Value, in cases where the string has not been nul-terminated.
42.c
Strlen has the effect of C's strlen function.
43
procedure Update (Item : in chars_ptr;
Offset : in size_t;
Chars : in char_array;
Check : Boolean := True);
44/1
{
8652/0064}
{
AI95-00039-01}
If Item = Null_Ptr, then Update propagates Dereference_Error.
Otherwise, t This procedure updates
the value pointed to by Item, starting at position Offset, using Chars
as the data to be copied into the array. Overwriting the nul terminator,
and skipping with the Offset past the nul terminator, are both prevented
if Check is True, as follows:
45
Let N = Strlen(Item). If Check is True,
then:
46
If Offset+Chars'Length>N, propagate
Update_Error.
47
Otherwise, overwrite the data in
the array pointed to by Item, starting at the char at position Offset,
with the data in Chars.
48
If Check
is False, then processing is as above, but with no check that Offset+Chars'Length>N.
48.a
Ramification: If Chars contains nul,
Update's effect may be to “shorten” the pointed-to char array.
49
procedure Update (Item : in chars_ptr;
Offset : in size_t;
Str : in String;
Check : in Boolean := True);
50/2
{
AI95-00242-01}
Equivalent to Update(Item, Offset, To_C(Str
, Append_Nul
=> False), Check).
50.a/2
Discussion: {
AI95-00242-01}
To truncate the Item to the length of Str, use
Update(Item, Offset, To_C(Str), Check) instead of Update(Item, Offset,
Str, Check). Note that when truncating Item, Item must be longer than
Str.
Erroneous Execution
51
Execution of any of the following
is erroneous if the Item parameter is not null_ptr and Item does not
point to a nul-terminated array of chars.
52
a Value function not taking a Length parameter,
53
the Free procedure,
54
the Strlen function.
55
Execution of Free(X) is also
erroneous if the chars_ptr X was not returned by New_Char_Array or New_String.
56
Reading or updating a freed char_array
is erroneous.
57
Execution of Update is erroneous
if Check is False and a call with Check equal to True would have propagated
Update_Error.
58
13 New_Char_Array and New_String might
be implemented either through the allocation function from the C environment
(“malloc”) or through Ada dynamic memory allocation (“new”).
The key points are
59
the returned value (a chars_ptr)
is represented as a C “char *” so that it may be passed to
C functions;
60
the allocated object should be freed
by the programmer via a call of Free, not by a called C function.
Inconsistencies With Ada 95
60.a/2
{
AI95-00242-01}
Amendment Correction:
Update for a String parameter is now defined to not add a nul character.
It did add a nul in Ada 95. This means that programs that used this behavior
of Update to truncate a string will no longer work (the string will not
be truncated). This change makes Update for a string consistent with
Update for a char_array (no implicit nul is added to the end of a char_array).
Extensions to Ada 95
60.b/2
{
AI95-00161-01}
Amendment Correction:
Added pragma
Preelaborable_Initialization to type chars_ptr, so that it can be used
in preelaborated units.
60.c/2
{
AI95-00276-01}
Amendment Correction: The components of
chars_ptr_array are aliased so that it can be used to instantiate Interfaces.C.Pointers
(that is its intended purpose, which is otherwise mysterious as it has
no operations).
Wording Changes from Ada 95
60.d/2
60.e/2
60.f/2
60.g/2
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe