---
name: "nval"
section: "3"
platform: "macos"
package: "ksh"
version: "42"
release: "macOS 26.5"
platforms: ["macos"]
url: "https://new.carta.tech/nval"
---

# nval(3)

the ksh name/value library

## NAME

**nval** - the ksh name/value library

## SYNOPSIS

### HEADERS/LIBRARIES

```
#include	<nval.h>
libshell.a	-lshell
```

### DATA TYPES

```
Namval_t;
Namfun_t;
Namarr_t;
Namdisc_t;
```

### OPENING/CLOSING

```
Namval_t 	*nv_open(const char *name, Dt_t *dict, int flags);
Namval_t	*nv_create(const char *name,  Dt_t *dict, int flags, Namfun_t *fp);
Namval_t	*nv_namptr(void *ptr, int indx);
void	nv_close(Namval_t *np);
void	nv_delete(Namval_t *np, Dt_t *dict, int nofree);
```

### GETTING AND SETTING VALUES

```
char	*nv_getval(Namval_t *np);
Sfdouble_t	nv_getnum(Namval_t *np);
char	*nv_name(Namval_t *np);
void	nv_putval(Namval_t *np, const char *val, int flags);
void	nv_unset(Namval_t *np, int flags);
int	nv_clone(Namval_t *src, Namval_t *dest, int flags);
```

### ATTRIBUTES AND SIZE

```
int	nv_isnull(Namval_t *np);
int	nv_setsize(Namval_t *np, int size);
int	nv_size(Namval_t *np);
unsigned nv_isattr(Namval_t *np, unsigned flags);
Namfun_t	*nv_isvtree(Namval_t *np);
unsigned nv_onattr(Namval_t *np, unsigned flags);
unsigned nv_offattr(Namval_t *np, unsigned flags);
void	nv_newattr(Namval_t *np, unsigned flags, int size);
```

### ARRAY HANDLING

```
unsigned nv_isarray(Namval_t *np);
Namarr_t	*nv_setarray(Namval_t *np,void*(*fun)(Namval_t*,const char*,int));
Namarr_t	*nv_arrayptr(Namval_t *np);
Namval_t	*nv_putsub(Namval_t *np, char *name, long mode);
Namval_t	*nv_opensub(Namval_t *np);
void	nv_setvec(Namval_t *np, int append, int argc, char *argv[]);
char	*nv_getsub(Namval_t *np);
int	nv_nextsub(Namval_t *np);
int	nv_aindex(Namval_t *np);
```

### DISCIPLINES

```
Namfun_t	*nv_disc(Namval_t *np, Namfun_t *fp, int flags);
Namfun_t	*nv_hasdisc(Namval_t *np, const Namdisc_t *dp);
char	*nv_getv(Namval_t *np, Namfun_t *fp);
Sfdouble_t	nv_getn(Namval_t *np, Namfun_t *fp);
void	nv_putv(Namval_t *np, const char *val, int flags, Namfun_t *fp);
char	*nv_setdisc(Namval_t *np, const char *a, Namval_t *f, Namfun_t *fp);
char	*nv_adddisc(Namval_t *np, const char **names);
const Namdisc_t	*nv_discfun(int which);
```

### TYPES

```
Namval_t	*nv_type(Namval_t  *np);
int	*nv_settype(Namval_t  *np, Namval_t *tp, int flags);
Namval_t	*nv_mkinttype(char *name, size_t sz, int us, const char *str, Namdisc_t *dp);
void	nv_addtype(Namval_t *np, const char *str, Optdisc_t* *op, size_t sz);
```

### MISCELLANEOUS FUNCTIONS

```
int	nv_scan(Dt_t *dict, void(*fn)(Namval_t*,void*), void *data, int mask, int flags);
Dt_t	*nv_dict(Namval_t *np);
void	nv_setvtree(Namval_t *np);
void	nv_setref(Namval_t *np, Dt_t *dp, int flags);
Namval_t	*nv_lastdict(void);
```

## DESCRIPTION

*Nval* is a library of functions for interacting with name-value pairs as used in ksh. It is built on top the container dictionary type library facility in libcdt. (See [cdt(3)](/cdt/3.md)). Each name-value pair is represented by a type named Namval\_t.  A Namval\_t contains the name, value and attributes of a variable. Some attributes can have an associated number that represents the field width, arithmetic base, or precision. Additionally, each name-value pair can be associated with one or more processing disciplines that affect its behavior.

The function nv\_open() returns a pointer to a name-value pair corresponding to the given *name*. It can also assign a value and give attributes to a name-value pair. The argument *dict* defines the dictionary to search. A NULL value causes the shell global variable dictionary to be searched.

The *flags* argument consists of the bitwise-or of zero or more of the attributes listed later and zero or more of the following:

-

  NV\_VARNAME: An invalid variable name causes an error.

-

  NV\_IDENTIFIER: A variable name that is not an identifier causes an error.

-

  NV\_ASSIGN: The *name* argument can contain an assignment.

-

  NV\_NOARRAY: The *name* argument cannot contain a subscript.

-

  NV\_NOREF: Do not follow references when finding the name-value pair.

-

  NV\_NOADD: The name-value pair will not be added if it doesn't exist. Instead, a NULL pointer will be returned.

-

  NV\_NOSCOPE: Only the top level scope is used.

-

  NV\_NOFAIL: Just return NULL when an error occurs. By default an error message is displayed and the current command is aborted.

-

  If a name-value pair by this name does not already exist, it is created unless *flags* contains the NV\_NOADD flag. If NV\_VARNAME, NV\_IDENTIFIER and NV\_ASSIGN are all not specified, then no validity check is performed on the *name* argument and no further processing is performed. Otherwise, if NV\_ASSIGN is specified, then the characters up to the first = or += are used to find the name-value pair, and the characters after the = are used to define the value that will be assigned to this name-value pair. If *name* does not contain an =, than no assignment will be made. If the first identifier in *name* is a reference and is not preceded by a **.**, it will be replaced by the value of the reference to find the name of a variable. Unless *flags* contains the NV\_NOREF flag, if the name-value pair give by *name* has the NV\_REF attribute, it will be replaced by the variable whose name is the value of this name-value pair. If NV\_ASSIGN is set in the *flags* argument, the *name* variable can contain an = and a value that will be assigned to the name-value pair. Any attributes appearing in the *flags* argument will be applied to the name-value pair after any value is assigned.

It is possible for an application to create additional dictionaries with the cdt library and associate them with name-value pairs. The nv\_dict() function returns the dictionary associated with the specified name-value pair, or if no dictionary was specified, NULL is returned. The nv\_lastdict() function returns a pointer the the name-value pair that contains the last dictionary searched on the previous nv\_open().

Name-value pairs can also be allocated without belonging to a dictionary.  They will typically be looked up by a *create* discipline associated with a parent node.  In this case the node size will be NV\_MINSZ and *n* nodes can be allocated vial calloc(5NV\_MINSZ,*n*)*(3).* *The* nv\_namptr *function can be used on the pointer returned by* calloc *along with the element number to return the* *corresponding node.* *Each of these nodes must be given the* NV\_MINIMAL *attributes.*

*The* nv\_close() *indicates that the pointer returned by* nv\_open() *or* nv\_opensub() *will not be referenced again.  If the* *name-value pair is unset, and not referenced elsewhere,* *the name-value pair may be freed.*

*The* nv\_delete() *function will remove the node np from* *the dictionary dict.  Unless nofree is non-zero, the* *node np will also be freed.*

*The* nv\_name() *function returns the name of the given name-value* *pair np.* *The* nv\_setsize() *function returns the size of the field for* *justified variables, the arithmetic base for integer variables,* *and the precision or number of places after the decimal point* *for floating point variables.  If size is greater than or* *equal to zero, the current size is changed to this value.*  *The* nv\_size() *function is equivalent to* nv\_setsize() *with the second argument negative.*

*The* nv\_getval() *function returns the value of the given* *name-value pair as a string.  A* NULL *return value indicates* *that the name-value pair is unset.* *The* nv\_getnum() *function returns the value of the given* *name-value pair as a double precision number using the* Sfio *library  (See Sfio(3)) type* Sfdouble\_t*.* *For name-value pairs without the* NV\_INTEGER *attribute,* *the string value is evaluated as an arithmetic expression to* *arrive at a numerical value.*

*The* nv\_putval() *function is used to assign a value to* *the name-value pair np.* *The flags argument consists zero or more of the bitwise-or* *of* NV\_LONG*,* NV\_SHORT*,* NV\_DOUBLE*,* NV\_INTEGER*,* NV\_RDONLY*,* NV\_REF*,* NV\_BINARY*, and* NV\_NOFREE*.* *The presence of* NV\_RDONLY *allows the assignment to occur* *even if the name-value pair has the* NV\_RDONLY *attribute.* *The presence of* NV\_INTEGER *indicates that the value* *argument is actually a pointer to a numerical type.* *By default this type is* long*, but can be modified with* NV\_LONG*,* NV\_SHORT*, and* NV\_DOUBLE *to represent* long long*,* short*,* double*,* long double*,* *and* float*.* *The presence of* NV\_REF *indicates that the value* *argument is actually a pointer to a name-value pair* *and* np *should become a reference to this name-value pair.* *If* NV\_NOFREE *is specified, value itself becomes* *the value of the name-value pair np.* *Otherwise, a  copy of the value is stored* *as the value for np.*

*The* nv\_unset() *function clears out the value and attributes* *of the given name-value function but does not free the name-value* *pair.* *If called from the* putval *discipline function, use the flags* *argument as the flags to*  nv\_unset()*.  Otherwise, use 0.*

*The following attributes can be associated with a name-value pair:*

-

  NV\_EXPORT*:* *The export attribute.*

-

  NV\_RDONLY*:* *The readonly attribute.*

-

  NV\_LTOU*:* *Lower case characters are converted to upper case characters.*

-

  NV\_UTOL*:* *Upper case characters are converted to lower case characters.*

-

  NV\_RJUST*:* *Right justify and blank fill.* *This attribute has an associated size that defines the* *string length of the value.*

-

  NV\_LJUST*:* *Left justify and blank fill.* *This attribute has an associated size that defines the* *string length of the value.*

-

  NV\_ZFILL*:* *Without* NV\_LJUST*, right justifies and fills with leading zeros.* *With* NV\_LJUST*, left justify and strip leading zeros.* *Left justify and blank fill.* *This attribute has an associated size that defines the* *string length of the value.*

-

  NV\_TAGGED*:* *Indicates the tagged attribute.*

-

  NV\_INTEGER*:* *Causes value to be represented by a number.* *This attribute has an associated number that defines the* *arithmetic base to be used when the value is expanded as a string.*

-

  NV\_DOUBLE*:* *Used in conjunction with* NV\_INTEGER *to cause value* *to be stored as a double precision floating point number.* *This attribute has an associated number that defines the* *number of places after the decimal point to be used when* *the value is expanded as a string.*

-

  NV\_EXPNOTE*:* *Used in conjunction with* NV\_INTEGER *and* NV\_DOUBLE *to* *cause the value to be represented in scientific notation when* *expanded as a string.* *This attribute has an associated number that defines the* *the precision of the mantissa.*

-

  NV\_HEXFLOAT*:* *Used in conjunction with* NV\_INTEGER *and* NV\_DOUBLE *to* *cause the value to be represented in C99 %a format when expanded as* *a string.*

-

  NV\_BINARY*:* *The name-value pair contains a buffer of binary data and* nv\_size() *is the number of bytes for this data.  By default the value* *will be represented by the base64 encoding of the buffer.* *The* NV\_LJUST *flag may also be specified and causes the buffer* *size to be fixed and data either truncated or filled with* 0 *bytes.*

-

  NV\_REF*:* *The name-value pair is a name reference variable.*

-

  NV\_MINIMAL*:* *The name-value pair node is not embedded in a dictionary* *and is minimal size,* NV\_MINSZ*.*

-

  NV\_NODISC*:* *All discipline functions are ignored when performing assignments* *and lookups.*

*The* nv\_isattr() *function can test whether or not any of* *the attributes given by flags is set.* *The* nv\_onattr() *and* nv\_offattr() *functions turn attributes* *on or off respectively.  Only attributes that do not affect the* *value can be set in this way.* *The* nv\_newattr() *function can be used to change the* *attributes and size of the given name-value pair which may result* *in the value being changed to conform to the new attributes and size.* *The size argument is needed for attributes that require* *an additional argument such as justifies variables.* *Changing the attribute may require changing the value* *to agree with the new attributes.* *For an array variable, the values for each of the* *subscripts will be changed.*

*The* nv\_isvtree() *function returns a pointer to the compound* *variable discipline if the node np is a compound variable* *or* NULL *otherwise.*

*The* nv\_isarray() *function returns a non-zero value if the specified* *name-value pair is an array.*

*The* nv\_scan() *function is used to walk through* *all name-value pairs in the dictionary given by dict.* *If the* flags *variable contains the* NV\_NOSCOPE *flag, then only the top scope will be examined.* *The remaining flags will be used in conjunction with mask* *to further restrict the walk.* *If mask is non-zero, only the nodes for which*  nv\_isattr(*node*,*mask*) *is equal to flags will be visited.* *If fn is non-zero, then this function will be executed* *for each name-value pair in the walk.*  *The arguments to fn will be a pointer to the name-value pair* *and the data pointer passed to* nv\_scan()*.* *The number of elements visited will be returned.*

*The* nv\_clone() *function is used make a copy of the contents of* *name-value pair src to another name-value pair dest.*

*Disciplines provide a way to* *intercept the lookup and assignment operations,* *to manage the creation of sub-variables,* *and to extend the operations permitted on a name-value pair.* *A discipline consists of a set of one or more functions and related* *data that are used to override and extend the operations* *on a name-value pair.*  *A discipline is defined by the types* Namfun\_t *and* Namdisc\_t*.* *The* Namdisc\_t *is not modified by any of these functions and* *can therefore be shared by several name-value pairs.*  *It contains following public fields in the order listed:*

```
      size_t	dsize;
      void	(*putval)(Namval_t*,const char*,int,Namfun_t*);
      char	*(*getval)(Namval_t*,Namfun_t*);
      double	(*getnum)(Namval_t*,Namfun_t*);
      char	*(*setdisc)(Namval_t*,const char*,Namval_t*,Namfun_t*);
      Namval_t	*(*createf)(Namval_t*,const char*,Namfun_t*);
      Namfun_t	*(*clonef)(Namval_t*,Namval_t*,int,Namfun_t*);
      char	*(*namef)(Namval_t*,Namfun_t*);
      Namval_t	*(*nextf)(Namval_t*,Dt_t*,Namfun_t*);
      Namval_t	*(*typef)(Namval_t*,Namfun_t*);
```

*The* Namfun\_t *type contains a member named* disc *which points to a* Namdisc\_t *structure.* *To create a discipline with additional user data,* *define a structure with an instance of* Namfun\_t *as the first element.* *An application must initialize the* Namfun\_t *portion of* *the structure to zero and then set the disc field to point* *to the* Namdisc\_t *structure.* *The* dsize *field of the* Namdisc\_t *structure must be* *the size of this structure.  A value of 0,* *indicates that there are no additional fields and is equivalent* *to* sizeof(Namfun\_t)*.* *If different instances of this structure uses different sizes, then* *the* size *field in the* Namfun\_t *can must be set to* *this size and overrides the value in the* Namdisc\_t *structure.*

*When a variable is referenced by calling the* nv\_getval() *function,* *and the* NV\_NODISC *attribute is not set,* *the* getval() *discipline function is called with a pointer* *to the name-value pair, np, and a pointer to the discipline,* *fp.* *Inside the* getval() *function, the* nv\_getv() *function* *can be called to get the value of the name-value pair that* *would have resulted if the discipline were not used.* *The* getnum() *discipline is called whenever a numerical* *value is needed for the name-value pair np* *and the* NV\_NODISC *attribute is not set,* *The* nv\_getn() *function can be called from within* *the* getnum() *discipline to get the value that would* *have resulted if there were no* getnum() *discipline.*

*The* putval() *discipline function is used to* *override the assignment of values* *to a name-value pair.* *It is called whenever a value is assigned with* nv\_putval() *and the* NV\_NODISC *attribute is not set,* *or when a name-value pair is unset with* nv\_unset()*.* *When a name-value pair is unset,* putval() *is called with value set to* NULL*.*  *The* nv\_putv() *function is used within the* putval() *to perform the assignment or unset that would have occurred* *if the discipline had not been installed.*

*The* createf() *discipline function is called from* nv\_open() *or* nv\_create() *when the name-value pair preceding a* **.** *is found.* *This function is passed the name-value pointer plus the remaining string and* *the current flags argument.* *The* createf() *discipline function* *must return the created name-value pair, otherwise the default action* *will be taken.* *If the name-value pair that is returned is the same as the* *one given, then the the behavior will be the same as if* *an invalid name had been given to* nv\_open()*.* *The* nv\_create() *function may be called within* *the* createf() *discipline function* *to perform the action that would have occurred* *by an earlier* nv\_open() *function.*

*The* setdisc() *discipline function is used* *to extend the set of available shell level discipline functions* *associated with a name-value pair by allowing* *builtins or functions whose name is of the* *form varname*.*action to be defined.* *By default, each name-value pair can have a* get*,* set*, and* unset *discipline associated with it.* *Whenever a builtin or function whose name is of the*  *form varname*.*action is defined or is unset,* *and action is not* get*,* set*, or* unset*, the setdisc*() *function is invoked* *with the same argument format as* nv\_setdisc()*.* *The argument f points to the name-value pair associated* *with the function being defined, or* NULL *if the function is* *being unset.* *If the given action a is not known by this discipline,* *it should return the value returned by calling* nv\_setdisc(*np*,*a*,*f*,*fp*) *so that it can be searched for in previously stacked disciplines.* *Otherwise, the setdisc*() *function should save the function* *name-value pair pointer, and return a non-*NULL *value.* *The name-value pointer to the function can be used to invoke* *the function at an application defined point.* *If the action a is* NULL*, then f points to* *an action name instead of a name-value pair pointer.* *The setdisc*() *must return the* *name of the action that follows the action name given by* *f.  If f is also* NULL*, the name of the first action* *must be returned.* *This allows an application to get the list of valid discipline* *action names allowed by a given name-value pair.*

*The* nv\_adddisc() *function is a higher level function that* *adds a setdisc discipline to the name-value pair that allows* *shell level disciplines to be created for each of the name specified* *in* names*.*

*The* nv\_discfun() *function can be used to get a pointer to* *discipline functions that are provided by the library.* *Currently, the only one that is provided is the ones used to* *implement* nv\_adddisc() *which can be returned with an* *argument of* NV\_DCADD*.*

*The* clonef() *discipline function is called by* nv\_clone() *when making a copy of the* Namfun\_t *discipline to the new node.*   *The first argument is the original node, the second argument is* *the new node, and the third argument is the flags that were passed* *down to* nv\_clone()*.* *It must return a new instance of the* Namfun\_t\* fp*.* *If omitted, then memory whose size is determinated by the* size *field of* fp*, if non-zero, or* fp-\>disc*, will be allocated* *and copied from* fp*.*

*The* namef() *discipline function returns the name for this name-value pair.*

*The* nextf() *is used for walking through the list of sub-variables* *associated with this name-value pair.  If the dictionary argument is* NULL*, it must return the first sub-variable.  Otherwise,* *it must return the next sub-variable, or* NULL *if there are* *no more variables.*

*A discipline is installed or removed with the* nv\_disc() *function.* *The following flags can be specified:*

-

  NV\_FIRST*:* *If fp is non-*NULL*, the discipline is moved to the top* *of the stack or pushed onto the top of the stack of disciplines* *associated with the given name-value* *pair np if not already present.* *Otherwise, the top of the discipline stack is returned.*

-

  NV\_LAST*:* *If fp is non-*NULL*, the discipline is moved to the bottom* *of the stack or pushed onto the bottom of the stack of disciplines* *associated with the given name-value* *pair np if not already present.* *Otherwise, the bottom of the discipline stack is returned.*

-

  NV\_POP*:* *If fp is non-*NULL *and it is on the stack,* *it is removed and fp is returned.  If  fp is non-*NULL *and is not on the stack,* NULL *is returned.* *Otherwise, the the top discipline is popped* *and returned.*

-

  NV\_CLONE*:* *If fp is non-*NULL *and it is on the stack,* *it is replace by a copy created by* malloc*(3).* *The* nofree *field is set to* 0*.* *The new discipline is returned.* *Otherwise,* NULL *is returned.*

-

  0*:* *If fp is non-*NULL *then it is equivalent to* NV\_FIRST*.* *Otherwise, it is equivalent to* NV\_POP*.*

*The* nv\_hasdisc() *function can be used to tell whether a discipline* *whose discipline functions are those defined in dp.* *A pointer to this discipline is returned.*

*The* nv\_aindex() *function returns* *the current index for* *the indexed array given by the name-value pair pointer np.*  *The return value is negative if np refers to* *an associative array.*

*The* nv\_setarray() *function is used to create an associative array* *from a name-value pair node.* *The function fun defines the semantics of the associative* *array.* *Using fun equal to* nv\_associative() *implements the default* *associative array semantics* *that are used with* typeset -A*.* *The function fun will be called with third argument as follows:*

-

  NV\_AINIT*:* *This will be called at initialization.* *The function you supply must return a pointer to a structure* *that contains the type* Namarr\_t *as the first element.* *All other calls receive this value as an argument.*

-

  NV\_AFREE*:* *This will be called after all elements of the name-value pair have been* *deleted and the array is to be freed.*

-

  NV\_ADELETE*:* *The current element should be deleted.*

-

  NV\_ANEXT*:* *This means that the array subscript should be advanced to the* *next subscript.  A* NULL *return indicates that there are* *no more subscripts.*

-

  NV\_ANAME*:* *The name of the current subscript must be returned.*

-

  NV\_ACURRENT*:* *Returns a pointer to a name-value pair corresponding to the* *current subscript, or* NULL *if this array type doesn't* *create represent each element as a name-value pair.*

-

  NV\_ASETSUB*:* *Set the current subscript to the name-value pair passed in* *as the second argument.*

*If np refers to an array,* nv\_arrayptr() *returns a pointer to* *the array discipline structure* Namarr\_t*.* *Otherwise* nv\_arrayptr() *returns* NULL*.*

*If np refers to an array,* *the* nv\_getsub() *returns a pointer to* *the name of the current subscript.* *Otherwise,* nv\_getsub() *returns* NULL*.*

*The* nv\_opensub() *function returns* *a pointer to the name-value pair corresponding* *to the current subscript in an associative array.* *Note that the* nv\_close() *function should be called* *when the pointer is no longer needed.*

*The* nv\_putsub() *function is used to* *set the subscript for the next reference to* np*.* *If the* name *argument is not* NULL*,* *it defines the value of the next subscript.*  *The* mode *argument can contain one or more of the following flags:*

-

  ARRAY\_ADD*:* *Add the subscript if not found.* *Otherwise,* nv\_putsub() *returns* NULL *if the* *given subscript is not found.*

-

  ARRAY\_SCAN*:* *Begin a walk through the subscripts starting at the subscript* *given by* name*.  If* name *is* NULL *the walk is started from the beginning.*

-

  ARRAY\_UNDEF*:* *This causes any current scan to terminate and leaves the* *subscript in an undefined state.*

*If* ARRAY\_ADD *is not given and the subscript* *does not exist, a* NULL *value is returned.*

*The* nv\_nextsub() *function is used to advance to the* *next subscript.* *It returns 0 if there are no more subscripts or if called* *when not in a scan.*

*The* nv\_setref() *function makes the name-value pair* np *into a reference to the variable whose name is given by* *the value of* np*.  The* nv\_open() *open function is* *called with this name, the dictionary given by* dp*,* *and the* flags *argument.* *A* NULL *value causes the shell global variable dictionary to be searched.*

*The* nv\_setvtree() *function makes the name-value pair* np *into a tree structured variable so that* nv\_getval() *will return a string containing all the names and values of* *children nodes in a format that can be used in* *a shell compound assignment.*

*The* nv\_type() *function returns a name\_value pair pointer* *that contains the type definition for the specified name-value pair.* *The nvname field contains the name for the type.*

*The* nv\_settype() *function converts the name-value pair* *given by np into the type given by tp.*

*The* nv\_addtype() *function adds the name of the type given by* *np to the list of declaration built-ins.  The str* *argument contains the string used by* optget*(3) to generate* *the man page and process the options.  The op argument* *specifies the callback discipline used by*  optget*(3) and* *sz specifies the size of the callback information so* *that the  discipline* **optget***(3) can be extended with private* *data used by the callback function.*

*The* nv\_mkinttype() *function creates named integer types* *of the specified name.  The size parameter is the size* *in bytes of the integer variable and  us is non-zero* *for unsigned integer types.  If dp is specified then integer* *variables of this type will all use this discipline.*

## SEE ALSO

*[calloc(3)](/calloc/3.md)* *[cdt(3)](/cdt/3.md)* *[shell(3)](/shell/3.md)* *[optget(3)](/optget/3.md)*

## AUTHOR

*David G. Korn (dgk@research.att.com).*
