Argz and Envz Vectors

argz vectors are vectors of strings in a contiguous block of memory, each element separated from its neighbors by null-characters ('\0').

Envz vectors are an extension of argz vectors where each element is a name-value pair, separated by a '=' character (as in a Unix environment).

Argz Functions

Each argz vector is represented by a pointer to the first element, of type char *, and a size, of type size_t, both of which can be initialized to 0 to represent an empty argz vector. All argz functions accept either a pointer and a size argument, or pointers to them, if they will be modified.

The argz functions use malloc/realloc to allocate/grow argz vectors, and so any argz vector creating using these functions may be freed by using free; conversely, any argz function that may grow a string expects that string to have been allocated using malloc (those argz functions that only examine their arguments or modify them in place will work on any sort of memory). the section called “Unconstrained Allocation”.

All argz functions that do memory allocation have a return type of error_t, and return 0 for success, and ENOMEM if an allocation error occurs.

These functions are declared in the standard include file argz.h.

error_t function>argz_create/function> (char *const argv[], char **argz, size_t *argz_len) The argz_create function converts the Unix-style argument vector argv (a vector of pointers to normal C strings, terminated by (char *)0; the section called “Program Arguments”) into an argz vector with the same elements, which is returned in argz and argz_len.

error_t function>argz_create_sep/function> (const char *string, int sep, char **argz, size_t *argz_len) The argz_create_sep function converts the null-terminated string string into an argz vector (returned in argz and argz_len) by splitting it into elements at every occurrence of the character sep.

size_t function>argz_count/function> (const char *argz, size_t arg_len) Returns the number of elements in the argz vector argz and argz_len.

void function>argz_extract/function> (char *argz, size_t argz_len, char **argv) The argz_extract function converts the argz vector argz and argz_len into a Unix-style argument vector stored in argv, by putting pointers to every element in argz into successive positions in argv, followed by a terminator of 0. Argv must be pre-allocated with enough space to hold all the elements in argz plus the terminating (char *)0 ((argz_count (argz, argz_len) + 1) * sizeof (char *) bytes should be enough). Note that the string pointers stored into argv point into argz--they are not copies--and so argz must be copied if it will be changed while argv is still active. This function is useful for passing the elements in argz to an exec function (the section called “Executing a File”).

void function>argz_stringify/function> (char *argz, size_t len, int sep) The argz_stringify converts argz into a normal string with the elements separated by the character sep, by replacing each '\0' inside argz (except the last one, which terminates the string) with sep. This is handy for printing argz in a readable manner.

error_t function>argz_add/function> (char **argz, size_t *argz_len, const char *str) The argz_add function adds the string str to the end of the argz vector *argz, and updates *argz and *argz_len accordingly.

error_t function>argz_add_sep/function> (char **argz, size_t *argz_len, const char *str, int delim) The argz_add_sep function is similar to argz_add, but str is split into separate elements in the result at occurrences of the character delim. This is useful, for instance, for adding the components of a Unix search path to an argz vector, by using a value of ':' for delim.

error_t function>argz_append/function> (char **argz, size_t *argz_len, const char *buf, size_t buf_len) The argz_append function appends buf_len bytes starting at buf to the argz vector *argz, reallocating *argz to accommodate it, and adding buf_len to *argz_len.

error_t function>argz_delete/function> (char **argz, size_t *argz_len, char *entry) If entry points to the beginning of one of the elements in the argz vector *argz, the argz_delete function will remove this entry and reallocate *argz, modifying *argz and *argz_len accordingly. Note that as destructive argz functions usually reallocate their argz argument, pointers into argz vectors such as entry will then become invalid.

error_t function>argz_insert/function> (char **argz, size_t *argz_len, char *before, const char *entry) The argz_insert function inserts the string entry into the argz vector *argz at a point just before the existing element pointed to by before, reallocating *argz and updating *argz and *argz_len. If before is 0, entry is added to the end instead (as if by argz_add). Since the first element is in fact the same as *argz, passing in *argz as the value of before will result in entry being inserted at the beginning.

char * function>argz_next/function> (char *argz, size_t argz_len, const char *entry) The argz_next function provides a convenient way of iterating over the elements in the argz vector argz. It returns a pointer to the next element in argz after the element entry, or 0 if there are no elements following entry. If entry is 0, the first element of argz is returned.

This behavior suggests two styles of iteration:

    char *entry = 0;
    while ((entry = argz_next (argz, argz_len, entry)))
      action;

(the double parentheses are necessary to make some C compilers shut up about what they consider a questionable while-test) and:

    char *entry;
    for (entry = argz;
         entry;
         entry = argz_next (argz, argz_len, entry))
      action;

Note that the latter depends on argz having a value of 0 if it is empty (rather than a pointer to an empty block of memory); this invariant is maintained for argz vectors created by the functions here.

error_t function>argz_replace/function> (char **argz, size_t *argz_len, const char *str, const char *with, unsigned *replace_count) Replace any occurrences of the string str in argz with with, reallocating argz as necessary. If replace_count is non-zero, *replace_count will be incremented by number of replacements performed.

Envz Functions

Envz vectors are just argz vectors with additional constraints on the form of each element; as such, argz functions can also be used on them, where it makes sense.

Each element in an envz vector is a name-value pair, separated by a '=' character; if multiple '=' characters are present in an element, those after the first are considered part of the value, and treated like all other non-'\0' characters.

If no'=' characters are present in an element, that element is considered the name of a "null" entry, as distinct from an entry with an empty value: envz_get will return 0 if given the name of null entry, whereas an entry with an empty value would result in a value of ""; envz_entry will still find such entries, however. Null entries can be removed with envz_strip function.

As with argz functions, envz functions that may allocate memory (and thus fail) have a return type of error_t, and return either 0 or ENOMEM.

These functions are declared in the standard include file envz.h.

char * function>envz_entry/function> (const char *envz, size_t envz_len, const char *name) The envz_entry function finds the entry in envz with the name name, and returns a pointer to the whole entry--that is, the argz element which begins with name followed by a '=' character. If there is no entry with that name, 0 is returned.

char * function>envz_get/function> (const char *envz, size_t envz_len, const char *name) The envz_get function finds the entry in envz with the name name (like envz_entry), and returns a pointer to the value portion of that entry (following the '='). If there is no entry with that name (or only a null entry), 0 is returned.

error_t function>envz_add/function> (char **envz, size_t *envz_len, const char *name, const char *value) The envz_add function adds an entry to *envz (updating *envz and *envz_len) with the name name, and value value. If an entry with the same name already exists in envz, it is removed first. If value is 0, then the new entry will the special null type of entry (mentioned above).

error_t function>envz_merge/function> (char **envz, size_t *envz_len, const char *envz2, size_t envz2_len, int override) The envz_merge function adds each entry in envz2 to envz, as if with envz_add, updating *envz and *envz_len. If override is true, then values in envz2 will supersede those with the same name in envz, otherwise not.

Null entries are treated just like other entries in this respect, so a null entry in envz can prevent an entry of the same name in envz2 from being added to envz, if override is false.

void function>envz_strip/function> (char **envz, size_t *envz_len) The envz_strip function removes any null entries from envz, updating *envz and *envz_len.