The c Context


The c context is native to A+. It is not to be loaded.

The c context provides utilities for creating, manipulating, and examining C-language structures and pointers to data. Pointers are represented as scalar integers in A+. The representation of structures is more complicated, and is discussed below in "The Representation of C-Language Structures in A+". The definitions of the c-context functions for structures follow that section.

The Representation of C-Language Structures in A+

A C-language structure is represented in A+ by three vectors: a vector of symbols for member names that the user can choose; a vector of integers defining the length of each member; and a vector of symbols describing the storage type of each member. The symbols for specifying storage types are given in the table "A+ Symbols for Specifying C Data Types". The storage types `struct1, `struct2, `struct3, `struct4 are for members that are structures, and in these cases the corresponding element of the length vector is the length of the structure, in bytes. In all other cases the element of the length vector is the number of elements in the member; if the length is greater than 1, then the member is assumed to be an array, whereas if the length is 1 the element is assumed to be a scalar.

A C-language structure created from these vectors can be passed to C programs that have been dynamically loaded to the A+ session. Each C datatype is properly aligned in the structure for the machine on which A+ is running.
A+ Symbols for Specifying C Data Types
A+ SymbolC Data Type   A+ SymbolC Data Type
`charchar `struct1char aligned on one-byte boundary
`u_charunsigned char `struct2char aligned on two-byte boundary
`shortshort `struct4char aligned on four-byte boundary
`u_shortunsigned short `struct8char aligned on eight-byte boundary
`intint `pointervoid*
`u_intunsigned int `floatfloat
`longlong `doubledouble
`u_longunsigned long  

Functions that Modify Arguments

Functions in this chapter, e.g., c.structset, may modify one of their arguments. In such cases, the argument should have a name and the name should be used in the argument position, for then you can see the changes after the function has completed execution. In addition, you must be sure that other objects are not modified as well. The reason is that A+ manages reference counts on objects, meaning that at any point in an execution two or more names can actually share the same array value; sharing stops when the value of one of the objects changes in a normal A+ way. However, the modification of an array value by a function like c.structset is not a normal A+ value change, and all names that had previously shared the value will now shared the modified value, unless prevented. The remedy is to replace the named argument a with something like a0ū(Ņa)Ņa.

   Example

A simple example will serve to illustrate most of the functions in this chapter. Consider the C-language structures
     struct s1 {
       int        fieldA;
       short      fieldB[4];
     };

     struct s2 {
       int        field1;
       struct s1  field2;
       struct s1  *field3;
     };
The s1 structure is represented in A+ as:
     s1_membersū`fieldA`fieldB
     s1_lengthsū1 4
     s1_typesū`int`short
The function c.structdef produces another A+ representation that includes various information about the structure, such as offsets, and which is used to create the actual structures, insert values, and extract values:
     s1ūc.structdef{s1_members;s1_lengths;s1_types}
The second structure can now be represented:
     s2_membersū`field1`field2`field3
     s2_lengthsū1,(c.structsize s1),1
     s2_typesū`int,(c.structtype s1),`pointer
Structures with these definitions can now be realized:
     s1_dataūc.structcreate s1
     s2ūc.structdef{s2_members;s2_lengths;s2_types}
     s2_dataūc.structcreate s2
When you put data in the realized structures, the value returned by c.structset is the updated structure:
     c.structset{s1;s1_data;`fieldA`fieldB;(3;6 7 8 9)}
 3 393223 524297 0
     s1_data
 3 393223 524297 0
     c.structset{s2;s2_data;`field1;345}
 345 0 0 0 0 0
     c.structset{s2;s2_data;`field2`field3;
               (s1_data;c.pointer{s1;s1_data})}
 345 3 393223 524297 67120480 0
You use c.structget to retrieve the data:
     c.structget{s1;s1_data;`fieldB}
 6 7 8 9
     mūc.structget{s2;s2_data;`field2}
     c.structget{s1;m;`fieldB}
c.structget{s1;m;`fieldB}
     pūc.structget{s2;s2_data;`field3}
     nūc.struct_pointed_to_by{s1;p}
     c.structget{s1;n;`fieldB}
c.structget{s1;m;`fieldB}
Display the contents of the structures:
      c.structprint{s1;s1_data}
fieldA:(int): 3
fieldB:(short): 6 7 8 9
     c.structprint{s2;s2_data}
field1:(int): 345
field2:(struct4): ----
field3:(pointer): 67120480

Definitions of c-Context Functions

A+ Array to Character Vector Representation c.stuff{a}

   Argument and Result
The argument is an A+ array. The result is a character vector.
   Definition
The result is a character vector representation of the of the A+ array a.

Note: The functions sys.exp and sys.imp should be used in place of c.stuff and c.unstuff.

A+ Array Header c.AHeader{a}

   Argument and Result
The argument is any A+ array. The result is a five-element nested vector.
   Definition
The result contains all the information in the internal header of an A+ array. The meaning of the elements of the result are in the tables "The Result of the Function c.AHeader" and "A+ Types vs. the Type Specification in c.AHeader Result".
The Result of the Function c.AHeader
Element IndexDescription
0An enclosed integer scalar holding the reference count of the array.
1An enclosed character vector representing the type of the array (see next table).
2An enclosed integer scalar holding the rank of the array.
3An enclosed integer scalar holding the element count of the array.
4An enclosed integer vector holding the shape of the array.
A+ Types vs. the Type Specification in c.AHeader Result
A+ Typec.AHeader Value   A+ Typec.AHeader Value
integer"It" derived function"Xt"
floating point"Ft" user defined function"Xt+1"
character"Ct" monadic operator"Xt+2"
nested, symbol, or function array"Et" dyadic operator"Xt+3"

Character Value at Pointer Location c.char_pointed_to_by{i}

   Argument and Result
The argument is a one-element integer array. The result is a character scalar.
   Definition
The integer i is a pointer to a C-language char value. The result is that value as an A+ scalar of type `char.

Character Vector at Pointer Location c.string_pointed_to_by{i}

   Argument and Result
The argument is a one-element integer array. The result is a character vector.
   Definition
The integer i is a pointer to a C-language char string. The result is that value as an A+ character vector.

Character Vector Representation to A+ Array c.unstuff{a}

   Argument and Result
The argument is an A+ character vector. The result is an A+ array.
   Definition
c.unstuff is a left inverse of c.stuff:

     c.unstuff c.stuff x
is identical to x for any A+ array x.

Note: The functions sys.exp and sys.imp should be used in place of c.stuff and c.unstuff.

Define a Structure c.structdef{f;l;t}

   Arguments and Result
The arguments f and t are vectors of symbols, while l is a vector of integers. All three vectors have the same length. The result is a general array of the form (g;m;u;o;c), where g is identical to the argument f, m is identical to the argument l, u is identical to the argument t, and o and c are integer vectors of length one more than the length of the argument vectors.
   Definition
The arguments f, t, and l represent a C-language structure (see "The Representation of C-Language Structures in A+"). For each integer i that is a valid index of the argument vectors f, l, and t, the triple f[i], l[i], and t[i] represents a member of the structure. The integer o[i] is the offset in bytes from the beginning of the structure to the beginning of this member. The integer c[i] is a type code representing the storage type of the member. If n is the number of elements in the argument vectors then o[n] and c[n] are both defined; o[n] is the size of the structure in bytes, and c[n] is the alignment factor for the structure.

The contents of o will be different for different computer architectures, so it is best not to store results of c.structdef in A+ script files.

Display the Contents of a Structure c.structprint{s;a}

   Arguments
The left argument s is a five-element nested vector and the right argument a is an integer vector.
   Definition
The argument s is a structure definition, i.e., a result of c.structdef. The argument a is a structure specified by s; at one point it was a result of c.structcreate, and most likely c.structset. The effect of this function is to display the contents of the structure a. Members that are structures are noted, but their values are not displayed.

Floating-Point Value at Pointer Location c.float_pointed_to_by{i}

   Argument and Result
The argument is a one-element integer array. The result is a floating-point scalar.
   Definition
The integer i is a pointer to a C-language float value. The result is that value as an A+ scalar of type `float.

Form c.form

   Definition
This function used to be in the d context; d is a relational data base toolkit in A, the predecessor of A+. The function is provided in A+ for migration purposes.

Get Values from a Structure c.structget{s;a;f}

   Arguments and Result
The argument s is a five-element nested vector and a is an integer vector. The argument f is either a one-element symbol array or a vector of symbols. If f has one element then the result is either a simple scalar or a simple vector with two or more elements; if f has more than one element, the result is a nested vector with the same number of elements as f, and each element of the result is either a simple scalar or a simple vector with two or more elements.
   Definition
The argument s is a structure definition, i.e., a result of c.structdef. The argument a is a structure specified by s; at one point it was a result of c.structcreate, and most likely c.structset. The result holds the values in the structure a for the members specified by f.

Integer Value at Pointer Location c.int_pointed_to_by{i}

   Argument and Result
The argument is a one-element integer array. The result is an integer scalar.
   Definition
The integer i is a pointer to a C-language int value. The result is that value as an A+ scalar of type `int.

Pointer to an A+ Array Value c.ptr{a}

   Argument and Result
The argument is any A+ array. The result is a scalar integer.
   Definition
The result is a pointer to the data area of the A+ array a.

Pointer to a Structure Value c.pointer{s;a}

   Arguments and Result
The left argument s is a five-element nested vector and the right argument a is an integer vector. The result is a scalar integer.
   Definition
The argument s is a structure definition, i.e., a result of c.structdef. The argument a is a structure specified by s; at one point it was a result of c.structcreate, and most likely c.structset. The result is a pointer to the beginning of the actual data of the structure (in the data area of a).

Realize a Structure c.structcreate{s}

   Argument and Result
The argument s is a five-element nested vector. The result is an integer vector.
   Definition
The argument s is a structure definition, i.e., a result of c.structdef. The result is an integer vector large enough to hold a structure defined by s, and initialized to 0. The result is called a structure initialization.

Set Values in a Structure c.structset{s;a;f;v}

   Arguments and Result
The argument s is a five-element nested vector and a is an integer vector. The argument f is either a one- element symbol array or a vector of symbols. If f has one element, then the argument v is a simple array. If f has more than one element, then v is a nested array of depth 1 with the same number of elements as f. This function directly modifies the value of the argument a (see "Functions that Modify Arguments"). The result is an integer vector.
   Definition
The argument s is a structure definition, i.e., a result of c.structdef. The argument a is a structure specified by s; at one point it was a result of c.structcreate. The argument f specifies members of the structure a, and v specifies values for those members. The effect of this function is to assign these values to those members of a. A value in v can have a different number of elements than is defined for that member. If it has more elements, only as many as needed are inserted in a. If it has fewer, then the contents of the member beyond the values supplied by v may be unpredictable.

All values in v that correspond to integer or floating-point members in the structure should be of A+ type `int or `float, respectively. Values in v that correspond to structure members should be results of c.structset for those structures. The result of this function is the modified argument a.

Size of a Structure c.structsize{s}

   Argument and Result
The argument s is a five-element nested vector. The result is an integer scalar.
   Definition
The argument s is a structure definition, i.e., a result of c.structdef. The result is the size, in bytes, of the structure defined by s.

Similarly to c.structdef, the result of c.structsize will be different for different computer architectures, so it is best not to store these results in A+ script files.

Store a Character Value c.place_chars_at{a;i}

   Arguments
The left argument a is a character array. The right argument i is a scalar integer.
   Definition
The integer i is a pointer to a list of C-language char values. The effect of this function is put the elements of a in that list (in ,a order).

Store a Floating-Point Value c.place_floats_at{a;i}

   Arguments
The left argument a is a floating-point array. The right argument i is a scalar integer.
   Definition
The integer i is a pointer to a list of C-language double values. The effect of this function is put the elements of a in that list (in ,a order).

Store an Integer Value c.place_ints_at{a;i}

   Arguments
The left argument a is an integer array. The right argument i is a scalar integer.
   Definition
The integer i is a pointer to a list of C-language int values. The effect of this function is put the elements of a in that list (in ,a order).

Structure Value at Pointer Location c.struct_pointed_to_by{s;i}

   Arguments and Result
The left argument s is a five-element nested vector. The right argument i is a one-element integer array. The result is an integer vector.
   Definition
The argument s is a structure definition, i.e., a result of c.structdef. The integer i is a pointer to a C-language structure that is equivalent to one defined by s. The result is an integer vector holding a copy of that structure.

Type Double Value at Pointer Location c.double_pointed_to_by{i}

   Argument and Result
The argument is a one-element integer array. The result is a floating-point scalar.
   Definition
The integer i is a pointer to a C-language double value. The result is that value as an A+ scalar of type `float.

Type Short Value at Pointer Location c.short_pointed_to_by{i}

   Argument and Result
The argument is a one-element integer array. The result is a integer scalar.
   Definition
The integer i is a pointer to a C-language short value. The result is that value as an A+ scalar of type `int.

Type of a Structure c.structtype{s}

   Arguments and Result
The argument s is a five-element nested vector. The result is a symbol scalar or the integer 0.
   Definition
The argument s is a structure definition, i.e., a result of c.structdef. The result is the type of the structure, i.e., one of `struct1, `struct2, `struct4, or `struct8, depending on whether the structure definition contains at most one-byte members, two-byte, four-byte, or eight-byte, respectively. Otherwise the result is 0, which would most likely indicate a damaged structure definition.

doc@aplusdev.org© Copyright 1995–2008 Morgan Stanley Dean Witter & Co. All rights reserved.