A+ Reference: The c Context

# The c Context

The Representation of C-Language Structures in A+

Table: A+ Symbols for Specifying C Data Types

Functions that Modify Arguments

Example

Definitions of c-Context Functions

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

Table: The Result of the Function c.AHeader
Table: A+ Types vs. the Type Specification in c.AHeader Result

Character Value at Pointer Location c.char_pointed_to_by{i}
Character Vector at Pointer Location c.string_pointed_to_by{i}
Character Vector Representation to A+ Array c.unstuff{a}
Define a Structure c.structdef{f;l;t}
Display the Contents of a Structure c.structprint{s;a}
Floating-Point Value at Pointer Location c.float_pointed_to_by{i}
Form c.form
Get Values from a Structure c.structget{s;a;f}
Integer Value at Pointer Location c.int_pointed_to_by{i}
Pointer to an A+ Array Value c.ptr{a}
Pointer to a Structure Value c.pointer{s;a}
Realize a Structure c.structcreate{s}
Set Values in a Structure c.structset{s;a;f;v}
Size of a Structure c.structsize{s}
Store a Character Value c.place_chars_at{a;i}
Store a Floating-Point Value c.place_floats_at{a;i}
Store an Integer Value c.place_ints_at{a;i}
Structure Value at Pointer Location c.struct_pointed_to_by{s;i}
Type Double Value at Pointer Location c.double_pointed_to_by{i}
Type Short Value at Pointer Location c.short_pointed_to_by{i}
Type of a Structure c.structtype{s}

> 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+ Symbol | C Data Type |  | A+ Symbol | C Data Type
> --- | --- | --- | --- | ---
> `char | char | `struct1 | char aligned on one-byte boundary
> `u_char | unsigned char | `struct2 | char aligned on two-byte boundary
> `short | short | `struct4 | char aligned on four-byte boundary
> `u_short | unsigned short | `struct8 | char aligned on eight-byte boundary
> `int | int | `pointer | void*
> `u_int | unsigned int | `float | float
> `long | long | `double | double
> `u_long | unsigned 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 Index | Description
> --- | ---
> 0 | An enclosed integer scalar holding the reference count of the array.
> | 1 | An enclosed character vector representing the type of the array (see next table). | 2 | An enclosed integer scalar holding the rank of the array. | 3 | An enclosed integer scalar holding the element count of the array. | 4 | An enclosed integer vector holding the shape of the array.

> A+ Types vs. the Type Specification in c.AHeader Result
> A+ Type | c.AHeader Value |  | A+ Type | c.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.