Change terminology from "active file" to "active dataset".
[pspp-builds.git] / doc / dev / concepts.texi
index 5876ce36ba5bd942b6e58fb0c5c839ca57bc4369..8d1e8ac0663604ba526332fa7c9bcf8653955f8e 100644 (file)
@@ -117,76 +117,88 @@ case when it processes it later.
 @subsection Runtime Typed Values
 
 When a value's type is only known at runtime, it is often represented
-as a @union{value}, defined in @file{data/value.h}.  @union{value} has
-two members: a @code{double} named @samp{f} to store a numeric value
-and an array of @code{char} named @samp{s} to a store a string value.
-A @union{value} does not identify the type or width of the data it
-contains.  Code that works with @union{values}s must therefore have
-external knowledge of its content, often through the type and width of
-a @struct{variable} (@pxref{Variables}).
-
-@cindex MAX_SHORT_STRING
-@cindex short string
-@cindex long string
-@cindex string value
-The array of @code{char} in @union{value} has only a small, fixed
-capacity of @code{MAX_SHORT_STRING} bytes.  A value that
-fits within this capacity is called a @dfn{short string}.  Any wider
-string value, which must be represented by more than one
-@union{value}, is called a @dfn{long string}.
-
-@deftypefn Macro int MAX_SHORT_STRING
-Maximum width of a short string value, never less than 8 bytes.  It is
-wider than 8 bytes on systems where @code{double} is either larger
-than 8 bytes or has stricter alignment than 8 bytes.
-@end deftypefn
+as a @union{value}, defined in @file{data/value.h}.  A @union{value}
+does not identify the type or width of the data it contains.  Code
+that works with @union{values}s must therefore have external knowledge
+of its content, often through the type and width of a
+@struct{variable} (@pxref{Variables}).
+
+@union{value} has one member that clients are permitted to access
+directly, a @code{double} named @samp{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{value}s.  The
+most useful are described below.  To use these functions, recall that
+a numeric value has a width of 0.
 
-@deftypefn Macro int MIN_LONG_STRING
-Minimum width of a long string value, that is, @code{MAX_SHORT_STRING
-+ 1}.
-@end deftypefn
+@deftypefun void value_init (union value *@var{value}, int @var{width})
+Initializes @var{value} as a value of the given @var{width}.  After
+initialization, the data in @var{value} are indeterminate; the caller
+is responsible for storing initial data in it.
+@end deftypefun
 
-Long string variables are slightly harder to work with than short
-string values, because they cannot be conveniently and efficiently
-allocated as block scope variables or structure members.  The PSPP
-language exposes this inconvenience to the user: there are many
-circumstances in PSPP syntax where short strings are allowed but not
-long strings.  Short string variables, for example, may have
-user-missing values, but long string variables may not (@pxref{Missing
-Observations,,,pspp, PSPP Users Guide}).
+@deftypefun void value_destroy (union value *@var{value}, int @var{width})
+Frees auxiliary storage associated with @var{value}, which must have
+the given @var{width}.
+@end deftypefun
 
-PSPP provides a few functions for working with @union{value}s.  The
-most useful are described below.  To use these functions, recall that
-a numeric value has a width of 0.
+@deftypefun bool value_needs_init (int @var{width})
+For some widths, @func{value_init} and @func{value_destroy} do not
+actually do anything, because no additional storage is needed beyond
+the size of @union{value}.  This function returns true if @var{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{value}s of such a width are to be initialized or destroyed.
 
-@deftypefun size_t value_cnt_from_width (int @var{width})
-Returns the number of consecutive @union{value}s that must be
-allocated to store a value of the given @var{width}.  For a numeric or
-short string value, the return value is 1; for long string
-variables, it is greater than 1.
+This function returns false if @func{value_init} and
+@func{value_destroy} are actually required for the given @var{width}.
+@end deftypefun
+
+@deftypefun double value_num (const union value *@var{value})
+Returns the numeric value in @var{value}, which must have been
+initialized as a numeric value.  Equivalent to @code{@var{value}->f}.
+@end deftypefun
+
+@deftypefun {const char *} value_str (const union value *@var{value}, int @var{width})
+@deftypefunx {char *} value_str_rw (union value *@var{value}, int @var{width})
+Returns the string value in @var{value}, which must have been
+initialized with positive width @var{width}.  The string returned is
+not null-terminated.  Only @var{width} bytes of returned data may be
+accessed.
+
+The two different functions exist only for @code{const}-correctness.
+Otherwise they are identical.
+
+It is important that @var{width} be the correct value that was passed
+to @func{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.
 @end deftypefun
 
 @deftypefun void value_copy (union value *@var{dst}, @
                              const union value *@var{src}, @
                              int @var{width})
-Copies a value of the given @var{width} from the @union{value} array
-starting at @var{src} to the one starting at @var{dst}.  The two
-arrays must not overlap.
+Copies the contents of @union{value} @var{src} to @var{dst}.  Both
+@var{dst} and @var{src} must have been initialized with the specified
+@var{width}.
 @end deftypefun
 
 @deftypefun void value_set_missing (union value *@var{value}, int @var{width})
 Sets @var{value} to @code{SYSMIS} if it is numeric or to all spaces if
-it is alphanumeric, according to @var{width}.  @var{value} must point
-to the start of a @union{value} array of the given @var{width}.
+it is alphanumeric, according to @var{width}.  @var{value} must have
+been initialized with the specified @var{width}.
 @end deftypefun
 
 @anchor{value_is_resizable}
 @deftypefun bool value_is_resizable (const union value *@var{value}, int @var{old_width}, int @var{new_width})
-Determines whether @var{value} may be resized from @var{old_width} to
-@var{new_width}.  Resizing is possible if the following criteria are
-met.  First, @var{old_width} and @var{new_width} must be both numeric
-or both string widths.  Second, if @var{new_width} is a short string
-width and less than @var{old_width}, resizing is allowed only if bytes
+Determines whether @var{value}, which must have been initialized with
+the specified @var{old_width}, may be resized to @var{new_width}.
+Resizing is possible if the following criteria are met.  First,
+@var{old_width} and @var{new_width} must be both numeric or both
+string widths.  Second, if @var{new_width} is a short string width and
+less than @var{old_width}, resizing is allowed only if bytes
 @var{new_width} through @var{old_width} in @var{value} contain only
 spaces.
 
@@ -196,9 +208,36 @@ These rules are part of those used by @func{mv_is_resizable} and
 
 @deftypefun void value_resize (union value *@var{value}, int @var{old_width}, int @var{new_width})
 Resizes @var{value} from @var{old_width} to @var{new_width}, which
-must be allowed by the rules stated above.  This has an effect only if
-@var{new_width} is greater than @var{old_width}, in which case the
-bytes newly added to @var{value} are cleared to spaces.
+must be allowed by the rules stated above.  @var{value} must have been
+initialized with the specified @var{old_width} before calling this
+function.  After resizing, @var{value} has width @var{new_width}.
+
+If @var{new_width} is greater than @var{old_width}, @var{value} will
+be padded on the right with spaces to the new width.  If
+@var{new_width} is less than @var{old_width}, the rightmost bytes of
+@var{value} are truncated.
+@end deftypefun
+
+@deftypefun bool value_equal (const union value *@var{a}, const union value *@var{b}, int @var{width})
+Compares of @var{a} and @var{b}, which must both have width
+@var{width}.  Returns true if their contents are the same, false if
+they differ.
+@end deftypefun
+
+@deftypefun int value_compare_3way (const union value *@var{a}, const union value *@var{b}, int @var{width})
+Compares of @var{a} and @var{b}, which must both have width
+@var{width}.  Returns -1 if @var{a} is less than @var{b}, 0 if they
+are equal, or 1 if @var{a} is greater than @var{b}.
+
+Numeric values are compared numerically, with @code{SYSMIS} comparing
+less than any real number.  String values are compared
+lexicographically byte-by-byte.
+@end deftypefun
+
+@deftypefun size_t value_hash (const union value *@var{value}, int @var{width}, unsigned int @var{basis})
+Computes and returns a hash of @var{value}, which must have the
+specified @var{width}.  The value in @var{basis} is folded into the
+hash.
 @end deftypefun
 
 @node Input and Output Formats
@@ -598,11 +637,6 @@ work with these global styles:
 Returns the numeric style for the given format @var{type}.
 @end deftypefun
 
-@deftypefun void fmt_check_style (const struct fmt_number_style *@var{style})
-Asserts that style is self consistent.
-@end deftypefun
-
-
 @deftypefun {const char *} fmt_name (enum fmt_type @var{type})
 Returns the name of the given format @var{type}.
 @end deftypefun
@@ -615,18 +649,17 @@ Returns the name of the given format @var{type}.
 These functions provide the ability to convert data fields into
 @union{value}s and vice versa.
 
-@deftypefun bool data_in (struct substring @var{input}, enum legacy_encoding @var{legacy_encoding}, enum fmt_type @var{type}, int @var{implied_decimals}, int @var{first_column}, union value *@var{output}, int @var{width})
+@deftypefun bool data_in (struct substring @var{input}, const char *@var{encoding}, enum fmt_type @var{type}, int @var{implied_decimals}, int @var{first_column}, const struct dictionary *@var{dict}, union value *@var{output}, int @var{width})
 Parses @var{input} as a field containing data in the given format
-@var{type}.  The resulting value is stored in @var{output}, which has
-the given @var{width}.  For consistency, @var{width} must be 0 if
+@var{type}.  The resulting value is stored in @var{output}, which the
+caller must have initialized with the given @var{width}.  For
+consistency, @var{width} must be 0 if
 @var{type} is a numeric format type and greater than 0 if @var{type}
 is a string format type.
-
-Ordinarily @var{legacy_encoding} should be @code{LEGACY_NATIVE},
-indicating that @var{input} is encoded in the character set
-conventionally used on the host machine.  It may be set to
-@code{LEGACY_EBCDIC} to cause @var{input} to be re-encoded from EBCDIC
-during data parsing.
+@var{encoding} should be set to indicate the character
+encoding of @var{input}.
+@var{dict} must be a pointer to the dictionary with which @var{output}
+is associated.
 
 If @var{input} is the empty string (with length 0), @var{output} is
 set to the value set on SET BLANKS (@pxref{SET BLANKS,,,pspp, PSPP
@@ -661,21 +694,15 @@ not propagated to the caller as errors.
 This function is declared in @file{data/data-in.h}.
 @end deftypefun
 
-@deftypefun void data_out (const union value *@var{input}, const struct fmt_spec *@var{format}, char *@var{output})
-@deftypefunx void data_out_legacy (const union value *@var{input}, enum legacy_encoding @var{legacy_encoding}, const struct fmt_spec *@var{format}, char *@var{output})
-Converts the data pointed to by @var{input} into a data field in
-@var{output} according to output format specifier @var{format}, which
-must be a valid output format.  Exactly @code{@var{format}->w} bytes
-are written to @var{output}.  The width of @var{input} is also
+@deftypefun char * data_out (const union value *@var{input}, const struct fmt_spec *@var{format})
+@deftypefunx char * data_out_legacy (const union value *@var{input}, const char *@var{encoding}, const struct fmt_spec *@var{format})
+Converts the data pointed to by @var{input} into a string value, which
+will be encoded in UTF-8,  according to output format specifier @var{format}.
+Format 
+must be a valid output format.   The width of @var{input} is
 inferred from @var{format} using an algorithm equivalent to
 @func{fmt_var_width}.
 
-If @func{data_out} is called, or @func{data_out_legacy} is called with
-@var{legacy_encoding} set to @code{LEGACY_NATIVE}, @var{output} will
-be encoded in the character set conventionally used on the host
-machine.  If @var{legacy_encoding} is set to @code{LEGACY_EBCDIC},
-@var{output} will be re-encoded from EBCDIC during data output.
-
 When @var{input} contains data that cannot be represented in the given
 @var{format}, @func{data_out} may output a message using @func{msg},
 @c (@pxref{msg}),
@@ -703,28 +730,7 @@ variable, is most conveniently executed through functions on
 A @struct{missing_values} is essentially a set of @union{value}s that
 have a common value width (@pxref{Values}).  For a set of
 missing values associated with a variable (the common case), the set's
-width is the same as the variable's width.  The contents of a set of
-missing values is subject to some restrictions.  Regardless of width,
-a set of missing values is allowed to be empty.  Otherwise, its
-possible contents depend on its width:
-
-@table @asis
-@item 0 (numeric values)
-Up to three discrete numeric values, or a range of numeric values
-(which includes both ends of the range), or a range plus one discrete
-numeric value.
-
-@item 1@dots{}@t{MAX_SHORT_STRING} - 1 (short string values)
-Up to three discrete string values (with the same width as the set).
-
-@item @t{MAX_SHORT_STRING}@dots{}@t{MAX_STRING} (long string values)
-Always empty.
-@end table
-
-These somewhat arbitrary restrictions are the same as those imposed by
-SPSS.  In PSPP we could easily eliminate these restrictions, but doing
-so would also require us to extend the system file format in an
-incompatible way, which we consider a bad tradeoff.
+width is the same as the variable's width.
 
 Function prototypes and other declarations related to missing values
 are declared in @file{data/missing-values.h}.
@@ -733,18 +739,37 @@ are declared in @file{data/missing-values.h}.
 Opaque type that represents a set of missing values.
 @end deftp
 
+The contents of a set of missing values is subject to some
+restrictions.  Regardless of width, a set of missing values is allowed
+to be empty.  A set of numeric missing values may contain up to three
+discrete numeric values, or a range of numeric values (which includes
+both ends of the range), or a range plus one discrete numeric value.
+A set of string missing values may contain up to three discrete string
+values (with the same width as the set), but ranges are not supported.
+
+In addition, values in string missing values wider than
+@code{MV_MAX_STRING} bytes may contain non-space characters only in
+their first @code{MV_MAX_STRING} bytes; all the bytes after the first
+@code{MV_MAX_STRING} must be spaces.  @xref{mv_is_acceptable}, for a
+function that tests a value against these constraints.
+
+@deftypefn Macro int MV_MAX_STRING
+Number of bytes in a string missing value that are not required to be
+spaces.  The current value is 8, a value which is fixed by the system
+file format.  In PSPP we could easily eliminate this restriction, but
+doing so would also require us to extend the system file format in an
+incompatible way, which we consider a bad tradeoff.
+@end deftypefn
+
 The most often useful functions for missing values are those for
 testing whether a given value is missing, described in the following
 section.  Several other functions for creating, inspecting, and
 modifying @struct{missing_values} objects are described afterward, but
-these functions are much more rarely useful.  No function for
-destroying a @struct{missing_values} is provided, because
-@struct{missing_values} does not contain any pointers or other
-references to resources that need deallocation.
+these functions are much more rarely useful.
 
 @menu
 * Testing for Missing Values::
-* Initializing User-Missing Value Sets::
+* Creating and Destroying User-Missing Values::
 * Changing User-Missing Value Set Width::
 * Inspecting User-Missing Value Sets::
 * Modifying User-Missing Value Sets::
@@ -796,8 +821,10 @@ missing.
 @end deftp
 @end deftypefun
 
-@node Initializing User-Missing Value Sets
-@subsection Initializing User-Missing Value Sets
+@node Creating and Destroying User-Missing Values
+@subsection Creation and Destruction
+
+These functions create and destroy @struct{missing_values} objects.
 
 @deftypefun void mv_init (struct missing_values *@var{mv}, int @var{width})
 Initializes @var{mv} as a set of user-missing values.  The set is
@@ -805,6 +832,10 @@ initially empty.  Any values added to it must have the specified
 @var{width}.
 @end deftypefun
 
+@deftypefun void mv_destroy (struct missing_values *@var{mv})
+Destroys @var{mv}, which must not be referred to again.
+@end deftypefun
+
 @deftypefun void mv_copy (struct missing_values *@var{mv}, const struct missing_values *@var{old})
 Initializes @var{mv} as a copy of the existing set of user-missing
 values @var{old}.
@@ -834,11 +865,9 @@ the required width, may be used instead.
 Tests whether @var{mv}'s width may be changed to @var{new_width} using
 @func{mv_resize}.  Returns true if it is allowed, false otherwise.
 
-If @var{new_width} is a long string width, @var{mv} may be resized
-only if it is empty.  Otherwise, if @var{mv} contains any missing
-values, then it may be resized only if each missing value may be
-resized, as determined by @func{value_is_resizable}
-(@pxref{value_is_resizable}).
+If @var{mv} contains any missing values, then it may be resized only
+if each missing value may be resized, as determined by
+@func{value_is_resizable} (@pxref{value_is_resizable}).
 @end deftypefun
 
 @anchor{mv_resize}
@@ -857,8 +886,8 @@ width.
 These functions inspect the properties and contents of
 @struct{missing_values} objects.
 
-The first set of functions inspects the discrete values that numeric
-and short string sets of user-missing values may contain:
+The first set of functions inspects the discrete values that sets of
+user-missing values may contain:
 
 @deftypefun bool mv_is_empty (const struct missing_values *@var{mv})
 Returns true if @var{mv} contains no user-missing values, false if it
@@ -883,11 +912,12 @@ values, that is, if @func{mv_n_values} would return nonzero for
 @var{mv}.
 @end deftypefun
 
-@deftypefun void mv_get_value (const struct missing_values *@var{mv}, union value *@var{value}, int @var{index})
-Copies the discrete user-missing value in @var{mv} with the given
-@var{index} into @var{value}.  The index must be less than the number
-of discrete user-missing values in @var{mv}, as reported by
-@func{mv_n_values}.
+@deftypefun {const union value *} mv_get_value (const struct missing_values *@var{mv}, int @var{index})
+Returns the discrete user-missing value in @var{mv} with the given
+@var{index}.  The caller must not modify or free the returned value or
+refer to it after modifying or freeing @var{mv}.  The index must be
+less than the number of discrete user-missing values in @var{mv}, as
+reported by @func{mv_n_values}.
 @end deftypefun
 
 The second set of functions inspects the single range of values that
@@ -909,7 +939,7 @@ include a range.
 These functions modify the contents of @struct{missing_values}
 objects.
 
-The first set of functions applies to all sets of user-missing values:
+The next set of functions applies to all sets of user-missing values:
 
 @deftypefun bool mv_add_value (struct missing_values *@var{mv}, const union value *@var{value})
 @deftypefunx bool mv_add_str (struct missing_values *@var{mv}, const char @var{value}[])
@@ -917,8 +947,8 @@ The first set of functions applies to all sets of user-missing values:
 Attempts to add the given discrete @var{value} to set of user-missing
 values @var{mv}.  @var{value} must have the same width as @var{mv}.
 Returns true if @var{value} was successfully added, false if the set
-could not accept any more discrete values.  (Always returns false if
-@var{mv} is a set of long string user-missing values.)
+could not accept any more discrete values or if @var{value} is not an
+acceptable user-missing value (see @func{mv_is_acceptable} below).
 
 These functions are equivalent, except for the form in which
 @var{value} is provided, so you may use whichever function is most
@@ -930,10 +960,22 @@ Removes a discrete value from @var{mv} (which must contain at least
 one discrete value) and stores it in @var{value}.
 @end deftypefun
 
-@deftypefun void mv_replace_value (struct missing_values *@var{mv}, const union value *@var{value}, int @var{index})
-Replaces the discrete value with the given @var{index} in @var{mv}
-(which must contain at least @var{index} + 1 discrete values) with
-@var{value}.
+@deftypefun bool mv_replace_value (struct missing_values *@var{mv}, const union value *@var{value}, int @var{index})
+Attempts to replace the discrete value with the given @var{index} in
+@var{mv} (which must contain at least @var{index} + 1 discrete values)
+by @var{value}.  Returns true if successful, false if @var{value} is
+not an acceptable user-missing value (see @func{mv_is_acceptable}
+below).
+@end deftypefun
+
+@deftypefun bool mv_is_acceptable (const union value *@var{value}, int @var{width})
+@anchor{mv_is_acceptable}
+Returns true if @var{value}, which must have the specified
+@var{width}, may be added to a missing value set of the same
+@var{width}, false if it cannot.  As described above, all numeric
+values and string values of width @code{MV_MAX_STRING} or less may be
+added, but string value of greater width may be added only if bytes
+beyond the first @code{MV_MAX_STRING} are all spaces.
 @end deftypefun
 
 The second set of functions applies only to numeric sets of
@@ -965,12 +1007,7 @@ All of the values in a set of value labels have the same width, which
 for a set of value labels owned by a variable (the common case) is the
 same as its variable.
 
-Numeric and short string sets of value labels may contain any number
-of entries.  Long string sets of value labels may not contain any
-value labels at all, due to a corresponding restriction in SPSS.  In
-PSPP we could easily eliminate this restriction, but doing so would
-also require us to extend the system file format in an incompatible
-way, which we consider a bad tradeoff.
+Sets of value labels may contain any number of entries.
 
 It is rarely necessary to interact directly with a @struct{val_labs}
 object.  Instead, the most common operation, looking up the label for
@@ -1051,31 +1088,24 @@ value in it may be resized to that width, as determined by
 Changes the width of @var{val_labs}'s values to @var{new_width}, which
 must be a valid new width as determined by
 @func{val_labs_can_set_width}.
-
-If @var{new_width} is a long string width, this function deletes all
-value labels from @var{val_labs}.
 @end deftypefun
 
 @node Value Labels Adding and Removing Labels
 @subsection Adding and Removing Labels
 
 These functions add and remove value labels from a @struct{val_labs}
-object.  These functions apply only to numeric and short string sets
-of value labels.  They have no effect on long string sets of value
-labels, since these sets are always empty.
+object.
 
 @deftypefun bool val_labs_add (struct val_labs *@var{val_labs}, union value @var{value}, const char *@var{label})
 Adds @var{label} to in @var{var_labs} as a label for @var{value},
 which must have the same width as the set of value labels.  Returns
-true if successful, false if @var{value} already has a label or if
-@var{val_labs} has long string width.
+true if successful, false if @var{value} already has a label.
 @end deftypefun
 
 @deftypefun void val_labs_replace (struct val_labs *@var{val_labs}, union value @var{value}, const char *@var{label})
 Adds @var{label} to in @var{var_labs} as a label for @var{value},
 which must have the same width as the set of value labels.  If
 @var{value} already has a label in @var{var_labs}, it is replaced.
-Has no effect if @var{var_labs} has long string width.
 @end deftypefun
 
 @deftypefun bool val_labs_remove (struct val_labs *@var{val_labs}, union value @var{value})
@@ -1088,75 +1118,65 @@ was removed, false otherwise.
 @subsection Iterating through Value Labels
 
 These functions allow iteration through the set of value labels
-represented by a @struct{val_labs} object.  They are usually used in
-the context of a @code{for} loop:
+represented by a @struct{val_labs} object.  They may be used in the
+context of a @code{for} loop:
 
 @example
 struct val_labs val_labs;
-struct val_labs_iterator *i;
-struct val_lab *vl;
+const struct val_lab *vl;
 
 @dots{}
 
-for (vl = val_labs_first (val_labs, &i); vl != NULL;
-     vl = val_labs_next (val_labs, &i))
+for (vl = val_labs_first (val_labs); vl != NULL;
+     vl = val_labs_next (val_labs, vl))
   @{
     @dots{}@r{do something with @code{vl}}@dots{}
   @}
 @end example
 
-The value labels in a @struct{val_labs} must not be modified as it is
-undergoing iteration.
-
-@deftp {Structure} {struct val_lab}
-Represents a value label for iteration purposes, with two
-client-visible members:
-
-@table @code
-@item union value value
-Value being labeled, of the same width as the @struct{val_labs} being
-iterated.
-
-@item const char *label
-The label, as a null-terminated string.
-@end table
-@end deftp
-
-@deftp {Structure} {struct val_labs_iterator}
-Opaque object that represents the current state of iteration through a
-set of value value labels.  Automatically destroyed by successful
-completion of iteration.  Must be destroyed manually in other
-circumstances, by calling @func{val_labs_done}.
-@end deftp
+Value labels should not be added or deleted from a @struct{val_labs}
+as it is undergoing iteration.
 
-@deftypefun {struct val_lab *} val_labs_first (const struct val_labs *@var{val_labs}, struct val_labs_iterator **@var{iterator})
-If @var{val_labs} contains at least one value label, starts an
-iteration through @var{val_labs}, initializes @code{*@var{iterator}}
-to point to a newly allocated iterator, and returns the first value
-label in @var{val_labs}.  If @var{val_labs} is empty, sets
-@code{*@var{iterator}} to null and returns a null pointer.
+@deftypefun {const struct val_lab *} val_labs_first (const struct val_labs *@var{val_labs})
+Returns the first value label in @var{var_labs}, if it contains at
+least one value label, or a null pointer if it does not contain any
+value labels.
+@end deftypefun
 
-This function creates iterators that traverse sets of value labels in
-no particular order.
+@deftypefun {const struct val_lab *} val_labs_next (const struct val_labs *@var{val_labs}, const struct val_labs_iterator **@var{vl})
+Returns the value label in @var{var_labs} following @var{vl}, if
+@var{vl} is not the last value label in @var{val_labs}, or a null
+pointer if there are no value labels following @var{vl}.
 @end deftypefun
 
-@deftypefun {struct val_lab *} val_labs_first_sorted (const struct val_labs *@var{val_labs}, struct val_labs_iterator **@var{iterator})
-Same as @func{val_labs_first}, except that the created iterator
-traverses the set of value labels in ascending order of value.
+@deftypefun {const struct val_lab **} val_labs_sorted (const struct val_labs *@var{val_labs})
+Allocates and returns an array of pointers to value labels, which are
+sorted in increasing order by value.  The array has
+@code{val_labs_count (@var{val_labs})} elements.  The caller is
+responsible for freeing the array with @func{free} (but must not free
+any of the @struct{val_lab} elements that the array points to).
 @end deftypefun
 
-@deftypefun {struct val_lab *} val_labs_next (const struct val_labs *@var{val_labs}, struct val_labs_iterator **@var{iterator})
-Advances an iterator created with @func{val_labs_first} or
-@func{val_labs_first_sorted} to the next value label, which is
-returned.  If the set of value labels is exhausted, returns a null
-pointer after freeing @code{*@var{iterator}} and setting it to a null
-pointer.
+The iteration functions above work with pointers to @struct{val_lab}
+which is an opaque data structure that users of @struct{val_labs} must
+not modify or free directly.  The following functions work with
+objects of this type:
+
+@deftypefun {const union value *} val_lab_get_value (const struct val_lab *@var{vl})
+Returns the value of value label @var{vl}.  The caller must not modify
+or free the returned value.  (To achieve a similar result, remove the
+value label with @func{val_labs_remove}, then add the new value with
+@func{val_labs_add}.)
+
+The width of the returned value cannot be determined directly from
+@var{vl}.  It may be obtained by calling @func{val_labs_get_width} on
+the @struct{val_labs} that @var{vl} is in.
 @end deftypefun
 
-@deftypefun void val_labs_done (struct val_labs_iterator **@var{iterator})
-Frees @code{*@var{iterator}} and sets it to a null pointer.  Does
-not need to be called explicitly if @func{val_labs_next} returns a
-null pointer, indicating that all value labels have been visited.
+@deftypefun {const char *} val_lab_get_label (const struct val_lab *@var{vl})
+Returns the label in @var{vl} as a null-terminated string.  The caller
+must not modify or free the returned string.  (Use
+@func{val_labs_replace} to change a value label.)
 @end deftypefun
 
 @node Variables
@@ -1200,12 +1220,12 @@ The following sections describe variable-related functions and macros.
 @node Variable Name
 @subsection Variable Name
 
-A variable name is a string between 1 and @code{VAR_NAME_LEN} bytes
+A variable name is a string between 1 and @code{ID_MAX_LEN} bytes
 long that satisfies the rules for PSPP identifiers
 (@pxref{Tokens,,,pspp, PSPP Users Guide}).  Variable names are
 mixed-case and treated case-insensitively.
 
-@deftypefn Macro int VAR_NAME_LEN
+@deftypefn Macro int ID_MAX_LEN
 Maximum length of a variable name, in bytes, currently 64.
 @end deftypefn
 
@@ -1228,23 +1248,6 @@ dictionary.  Use @func{dict_rename_var} instead (@pxref{Dictionary
 Renaming Variables}).
 @end deftypefun
 
-@anchor{var_is_plausible_name}
-@deftypefun {bool} var_is_valid_name (const char *@var{name}, bool @var{issue_error})
-@deftypefunx {bool} var_is_plausible_name (const char *@var{name}, bool @var{issue_error})
-Tests @var{name} for validity or ``plausibility.''  Returns true if
-the name is acceptable, false otherwise.  If the name is not
-acceptable and @var{issue_error} is true, also issues an error message
-explaining the violation.
-
-A valid name is one that fully satisfies all of the requirements for
-variable names (@pxref{Tokens,,,pspp, PSPP Users Guide}).  A
-``plausible'' name is simply a string whose length is in the valid
-range and that is not a reserved word.  PSPP accepts plausible but
-invalid names as variable names in some contexts where the character
-encoding scheme is ambiguous, as when reading variable names from
-system files.
-@end deftypefun
-
 @deftypefun {enum dict_class} var_get_dict_class (const struct variable *@var{var})
 Returns the dictionary class of @var{var}'s name (@pxref{Dictionary
 Class}).
@@ -1280,22 +1283,6 @@ Returns true if @var{var} is an alphanumeric (string) variable, false
 otherwise.
 @end deftypefun
 
-@deftypefun bool var_is_short_string (const struct variable *@var{var})
-Returns true if @var{var} is a string variable of width
-@code{MAX_SHORT_STRING} or less, false otherwise.
-@end deftypefun
-
-@deftypefun bool var_is_long_string (const struct variable *@var{var})
-Returns true if @var{var} is a string variable of width greater than
-@code{MAX_SHORT_STRING}, false otherwise.
-@end deftypefun
-
-@deftypefun size_t var_get_value_cnt (const struct variable *@var{var})
-Returns the number of @union{value}s needed to hold an instance of
-variable @var{var}.  @code{var_get_value_cnt (var)} is equivalent to
-@code{value_cnt_from_width (var_get_width (var))}.
-@end deftypefun
-
 @node Variable Missing Values
 @subsection Variable Missing Values
 
@@ -1313,8 +1300,8 @@ Tests whether @var{value} is a missing value of the given @var{class}
 for variable @var{var} and returns true if so, false otherwise.
 @func{var_is_num_missing} may only be applied to numeric variables;
 @func{var_is_str_missing} may only be applied to string variables.
-For string variables, @var{value} must contain exactly as many
-characters as @var{var}'s width.
+@var{value} must have been initialized with the same width as
+@var{var}.
 
 @code{var_is_@var{type}_missing (@var{var}, @var{value}, @var{class})}
 is equivalent to @code{mv_is_@var{type}_missing
@@ -1339,7 +1326,7 @@ resizable to @var{var}'s width (@pxref{mv_resize}).  The caller
 retains ownership of @var{miss}.
 @end deftypefun
 
-b@deftypefun void var_clear_missing_values (struct variable *@var{var})
+@deftypefun void var_clear_missing_values (struct variable *@var{var})
 Clears @var{var}'s missing values.  Equivalent to
 @code{var_set_missing_values (@var{var}, NULL)}.
 @end deftypefun
@@ -1360,11 +1347,13 @@ value:
 
 @deftypefun {const char *} var_lookup_value_label (const struct variable *@var{var}, const union value *@var{value})
 Looks for a label for @var{value} in @var{var}'s set of value labels.
-Returns the label if one exists, otherwise a null pointer.
+@var{value} must have the same width as @var{var}.  Returns the label
+if one exists, otherwise a null pointer.
 @end deftypefun
 
 @deftypefun void var_append_value_name (const struct variable *@var{var}, const union value *@var{value}, struct string *@var{str})
 Looks for a label for @var{value} in @var{var}'s set of value labels.
+@var{value} must have the same width as @var{var}.
 If a label exists, it will be appended to the string pointed to by @var{str}.
 Otherwise, it formats @var{value}
 using @var{var}'s print format (@pxref{Input and Output Formats}) 
@@ -1406,20 +1395,19 @@ the variable (making a second copy):
 
 @deftypefun bool var_add_value_label (struct variable *@var{var}, const union value *@var{value}, const char *@var{label})
 Attempts to add a copy of @var{label} as a label for @var{value} for
-the given @var{var}.  If @var{value} already has a label, then the old
-label is retained.  Returns true if a label is added, false if there
-was an existing label for @var{value} or if @var{var} is a long string
-variable.  Either way, the caller retains ownership of @var{value} and
-@var{label}.
+the given @var{var}.  @var{value} must have the same width as
+@var{var}.  If @var{value} already has a label, then the old label is
+retained.  Returns true if a label is added, false if there was an
+existing label for @var{value}.  Either way, the caller retains
+ownership of @var{value} and @var{label}.
 @end deftypefun
 
 @deftypefun void var_replace_value_label (struct variable *@var{var}, const union value *@var{value}, const char *@var{label})
 Attempts to add a copy of @var{label} as a label for @var{value} for
-the given @var{var}.  If @var{value} already has a label, then
+the given @var{var}.  @var{value} must have the same width as
+@var{var}.  If @var{value} already has a label, then
 @var{label} replaces the old label.  Either way, the caller retains
 ownership of @var{value} and @var{label}.
-
-If @var{var} is a long string variable, this function has no effect.
 @end deftypefun
 
 @node Variable Print and Write Formats
@@ -1759,7 +1747,7 @@ To delete a variable from a dictionary and destroy it, use
 @node Variable Short Names
 @subsection Variable Short Names
 
-PSPP variable names may be up to 64 (@code{VAR_NAME_LEN}) bytes long.
+PSPP variable names may be up to 64 (@code{ID_MAX_LEN}) bytes long.
 The system and portable file formats, however, were designed when
 variable names were limited to 8 bytes in length.  Since then, the
 system file format has been augmented with an extension record that
@@ -1824,7 +1812,7 @@ been assigned a short name.
 Sets @var{var}'s short name to @var{short_name}, or removes
 @var{var}'s short name if @var{short_name} is a null pointer.  If it
 is non-null, then @var{short_name} must be a plausible name for a
-variable (@pxref{var_is_plausible_name}).  The name will be truncated
+variable.  The name will be truncated
 to 8 bytes in length and converted to all-uppercase.
 @end deftypefun
 
@@ -1878,16 +1866,16 @@ associate data with a variable.
 
 To prevent multiple clients from attempting to use a variable's single
 auxiliary data field at the same time, we adopt the convention that
-use of auxiliary data in the active file dictionary is restricted to
+use of auxiliary data in the active dataset dictionary is restricted to
 the currently executing command.  In particular, transformations must
-not attach auxiliary data to a variable in the active file in the
-expectation that it can be used later when the active file is read and
+not attach auxiliary data to a variable in the active dataset in the
+expectation that it can be used later when the active dataset is read and
 the transformation is executed.  To help enforce this restriction,
-auxiliary data is deleted from all variables in the active file
+auxiliary data is deleted from all variables in the active dataset
 dictionary after the execution of each PSPP command.
 
 This convention for safe use of auxiliary data applies only to the
-active file dictionary.  Rules for other dictionaries may be
+active dataset dictionary.  Rules for other dictionaries may be
 established separately.
 
 Auxiliary data should be replaced by a more flexible mechanism at some
@@ -2096,17 +2084,23 @@ if through a call to @code{var_create} with those arguments
 of variables, and returns the new variable.
 @end deftypefun
 
-@deftypefun {struct variable *} dict_clone_var (struct dictionary *@var{dict}, const struct variable *@var{old_var}, const char *@var{name})
-@deftypefunx {struct variable *} dict_clone_var_assert (struct dictionary *@var{dict}, const struct variable *@var{old_var}, const char *@var{name})
+@deftypefun {struct variable *} dict_clone_var (struct dictionary *@var{dict}, const struct variable *@var{old_var})
+@deftypefunx {struct variable *} dict_clone_var_assert (struct dictionary *@var{dict}, const struct variable *@var{old_var})
 Creates a new variable as a clone of @var{var}, inserts the new
-variable into @var{dict}, and returns the new variable.  The new
-variable is named @var{name}.  Other properties of the new variable
-are copied from @var{old_var}, except for those not copied by
-@code{var_clone} (@pxref{var_clone}).
+variable into @var{dict}, and returns the new variable.  Other
+properties of the new variable are copied from @var{old_var}, except
+for those not copied by @code{var_clone} (@pxref{var_clone}).
 
 @var{var} does not need to be a member of any dictionary.
 @end deftypefun
 
+@deftypefun {struct variable *} dict_clone_var_as (struct dictionary *@var{dict}, const struct variable *@var{old_var}, const char *@var{name})
+@deftypefunx {struct variable *} dict_clone_var_as_assert (struct dictionary *@var{dict}, const struct variable *@var{old_var}, const char *@var{name})
+These functions are similar to @code{dict_clone_var} and
+@code{dict_clone_var_assert}, respectively, except that the new
+variable is named @var{name} instead of keeping @var{old_var}'s name.
+@end deftypefun
+
 @node Dictionary Deleting Variables
 @subsection Deleting Variables
 
@@ -2115,10 +2109,10 @@ variables.  They also destroy the removed variables and free their
 associated storage.
 
 Deleting a variable to which there might be external pointers is a bad
-idea.  In particular, deleting variables from the active file
+idea.  In particular, deleting variables from the active dataset
 dictionary is a risky proposition, because transformations can retain
 references to arbitrary variables.  Therefore, no variable should be
-deleted from the active file dictionary when any transformations are
+deleted from the active dataset dictionary when any transformations are
 active, because those transformations might reference the variable to
 be deleted.  The safest time to delete a variable is just after a
 procedure has been executed, as done by @cmd{DELETE VARIABLES}.
@@ -2250,7 +2244,7 @@ is null, then @var{dict}'s weighting variable, if any, is cleared.
 @node Dictionary Filter Variable
 @subsection Filter Variable
 
-When the active file is read by a procedure, cases can be excluded
+When the active dataset is read by a procedure, cases can be excluded
 from analysis based on the values of a @dfn{filter variable}.
 @xref{FILTER,,,pspp, PSPP Users Guide}, for a user view of filtering.
 
@@ -2296,7 +2290,7 @@ Sets @var{dict}'s case limit to @var{limit}.
 
 The user may use the @cmd{SPLIT FILE} command (@pxref{SPLIT
 FILE,,,pspp, PSPP Users Guide}) to select a set of variables on which
-to split the active file into groups of cases to be analyzed
+to split the active dataset into groups of cases to be analyzed
 independently in each statistical procedure.  The set of split
 variables is stored as part of the dictionary, although the effect on
 data analysis is implemented by each individual statistical procedure.