Previous: , Up: Values   [Contents][Index]


2.1.3 Runtime Typed Values

When a value’s type is only known at runtime, it is often represented as a union value, defined in data/value.h. A union value does not identify the type or width of the data it contains. Code that works with union valuess must therefore have external knowledge of its content, often through the type and width of a struct variable (see Variables).

union value has one member that clients are permitted to access directly, a double named ‘f’ that stores the content of a numeric union value. It has other members that store the content of string union value, but client code should use accessor functions instead of referring to these directly.

PSPP provides some functions for working with union values. The most useful are described below. To use these functions, recall that a numeric value has a width of 0.

Function: void value_init (union value *value, int width)

Initializes value as a value of the given width. After initialization, the data in value are indeterminate; the caller is responsible for storing initial data in it.

Function: void value_destroy (union value *value, int width)

Frees auxiliary storage associated with value, which must have the given width.

Function: bool value_needs_init (int width)

For some widths, value_init and value_destroy do not actually do anything, because no additional storage is needed beyond the size of union value. This function returns true if width is such a width, which case there is no actual need to call those functions. This can be a useful optimization if a large number of union values of such a width are to be initialized or destroyed.

This function returns false if value_init and value_destroy are actually required for the given width.

Function: double value_num (const union value *value)

Returns the numeric value in value, which must have been initialized as a numeric value. Equivalent to value->f.

Function: const char * value_str (const union value *value, int width)
Function: char * value_str_rw (union value *value, int width)

Returns the string value in value, which must have been initialized with positive width width. The string returned is not null-terminated. Only width bytes of returned data may be accessed.

The two different functions exist only for const-correctness. Otherwise they are identical.

It is important that width be the correct value that was passed to value_init. Passing a smaller or larger value (e.g. because that number of bytes will be accessed) will not always work and should be avoided.

Function: void value_copy (union value *dst, const union value *src, int width)

Copies the contents of union value src to dst. Both dst and src must have been initialized with the specified width.

Function: void value_set_missing (union value *value, int width)

Sets value to SYSMIS if it is numeric or to all spaces if it is alphanumeric, according to width. value must have been initialized with the specified width.

Function: bool value_is_resizable (const union value *value, int old_width, int new_width)

Determines whether value, which must have been initialized with the specified old_width, may be resized to new_width. Resizing is possible if the following criteria are met. First, old_width and new_width must be both numeric or both string widths. Second, if new_width is a short string width and less than old_width, resizing is allowed only if bytes new_width through old_width in value contain only spaces.

These rules are part of those used by mv_is_resizable and val_labs_can_set_width.

Function: void value_resize (union value *value, int old_width, int new_width)

Resizes value from old_width to new_width, which must be allowed by the rules stated above. value must have been initialized with the specified old_width before calling this function. After resizing, value has width new_width.

If new_width is greater than old_width, value will be padded on the right with spaces to the new width. If new_width is less than old_width, the rightmost bytes of value are truncated.

Function: bool value_equal (const union value *a, const union value *b, int width)

Compares of a and b, which must both have width width. Returns true if their contents are the same, false if they differ.

Function: int value_compare_3way (const union value *a, const union value *b, int width)

Compares of a and b, which must both have width width. Returns -1 if a is less than b, 0 if they are equal, or 1 if a is greater than b.

Numeric values are compared numerically, with SYSMIS comparing less than any real number. String values are compared lexicographically byte-by-byte.

Function: size_t value_hash (const union value *value, int width, unsigned int basis)

Computes and returns a hash of value, which must have the specified width. The value in basis is folded into the hash.


Previous: , Up: Values   [Contents][Index]