1%-*-mode:latex-*-
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%
4% Copyright (C) 1996-2005 Jason Evans <jasone@canonware.com>.
5% All rights reserved.
6%
7% Redistribution and use in source and binary forms, with or without
8% modification, are permitted provided that the following conditions
9% are met:
10% 1. Redistributions of source code must retain the above copyright
11%    notice(s), this list of conditions and the following disclaimer
12%    unmodified other than the allowable addition of one or more
13%    copyright notices.
14% 2. Redistributions in binary form must reproduce the above copyright
15%    notice(s), this list of conditions and the following disclaimer in
16%    the documentation and/or other materials provided with the
17%    distribution.
18%
19% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
20% EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22% PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
23% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26% BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28% OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29% EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30%
31%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32%
33% Version: Onyx 5.1.2
34%
35% libonyx portion of Onyx Manual.
36%
37%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38
39\clearemptydoublepage
40\chapter{The libonyx library}
41\label{onyxlib}
42
43The \libname{libonyx} library implements an embeddable \htmlref{Onyx}{onyxlang}
44interpreter.  \libname{libonyx} is designed to allow multiple interpreter
45instances in the same program, though since Onyx is a multi-threaded language,
46in most cases it makes more sense to use a single interpreter instance with
47multiple threads.
48
49The Onyx language is described elsewhere in this manual, so this chapter
50documents the C API with as little information about the Onyx language as
51possible.
52
53A minimal program that runs the Onyx interpreter interactively looks like:
54\begin{verbatim}
55#include <libonyx/libonyx.h>
56
57int
58main(int argc, char **argv, char **envp)
59{
60    cw_nx_t nx;
61    cw_nxo_t thread, *nxo;
62
63    /* Initialize libonyx and the Onyx interpreter. */
64    libonyx_init(argc, argv, envp);
65    nx_new(&nx, NULL);
66
67    /* Create a thread. */
68    nxo_thread_new(&thread, &nx);
69
70    /* Set up stdin for evaluation. */
71    nxo = nxo_stack_push(nxo_thread_ostack_get(&thread));
72    nxo_dup(nxo, nxo_thread_stdin_get(&thread));
73    nxo_attr_set(nxo, NXOA_EXECUTABLE);
74
75    /* Start the thread. */
76    nxo_thread_start(&thread);
77
78    /* Clean up. */
79    nx_delete(&nx);
80    libonyx_shutdown();
81    return 0;
82}
83\end{verbatim}
84
85In many cases, an application will need to implement additional Onyx operators
86or handles (and make them accessible from within the Onyx interpreter) in order
87to make the application accessible/controllable from the Onyx interpreter.  If
88the application user interface is to be interaction with the Onyx interpreter,
89then little else needs to be done.  Note that Onyx supports loadable modules, so
90it is usually possible to extend Onyx via modules, though embedding
91\libname{libonyx} directly into the application also works.
92
93\section{Compilation}
94Use the following compiler command line to compile applications with
95\libname{libonyx}.
96\begin{verbatim}
97cc `onyx_config --cppflags` <file> `onyx_config --ldflags --libs`
98\end{verbatim}
99
100\section{Global variables}
101\libname{libonyx} defines the following global variables, which can be used by
102the application:
103\begin{description}
104\item[cw\_g\_mema: ] \htmlref{\classname{mema}}{mema} instance, wraps the
105generic global allocator (also accessible via the \htmlref{\classname{mem}}{mem}
106APIs).
107\item[cw\_g\_nxaa: ] \classname{mema} instance, wraps the global allocator that
108is tied to the garbage collector (also accessible via the
109\htmlref{\classname{nxa}}{nxa} APIs).
110\end{description}
111
112\section{Multiple interpreters}
113\libname{libonyx} supports running multiple interpreters (encapsulated by the
114\classname{nx} class) in the same process, though as already mentioned, it
115usually makes more sense to use threads.  The values associated with
116\htmlref{argv}{systemdict:argv} and \htmlref{envdict}{systemdict:envdict} are
117shared among all interpreters, but otherwise, no state is shared between
118interpreters by default.  However, since all interpreters share a single garbage
119collector, C code can create references to the same Onyx object in more than one
120interpreter, and no problems will result (normal object synchronization issues
121not withstanding).
122
123\section{Threads}
124\libname{libonyx} encapsulates each interpreter instance in an
125\htmlref{\classname{nx}}{nx} object.  An \classname{nx} object supports running
126multiple concurrent threads.  Each thread context is encapsulated by an
127\htmlref{\classname{nxo} thread}{nxo_thread} object.
128
129In general, each process thread should execute in its own \classname{nxo} thread
130object context, though the only explicit restriction placed on \classname{nxo}
131thread object operations is that only one thread can be executing in an
132\classname{nxo} thread object context at a time.  In other words, the
133\classname{nxo} thread class does not synchronize access to its internals, since
134there is normally no reason for multiple threads to execute in the same
135\classname{nxo} thread object context.
136
137\section{Garbage collection}
138Since there can be arbitrary threads executing in the interpreter concurrently,
139there are two ways to implement safe garbage collection: concurrent or atomic.
140\libname{libonyx} uses atomic garbage collection, which means that during the
141mark phase, the thread doing garbage collection suspends all other threads that
142are created via \cfunc{\htmlref{thd\_new}{thd_new}}{..., true}.  In order for
143this to work, the garbage collector must not do any locking while the other
144threads are suspended, or else there is a high probability of eventual deadlock.
145\libname{libonyx} itself meets these criteria, as must any C extensions to the
146interpreter that are executed by the garbage collector during the mark phase
147(reference iteration).
148
149\section{Exceptions}
150\libname{libonyx} reserves \htmlref{\classname{xep}}{xep} exception numbers 0 to
151127 and defines the following exceptions:
152\begin{description}
153\label{CW_ONYXX_OOM}
154\item[\cppdef{CW\_ONYXX\_OOM}: ]
155	Memory allocation error.
156\label{CW_ONYXX_CONTINUE}
157\item[\cppdef{CW\_ONYXX\_CONTINUE}: ]
158	Internal use, for the
159	\htmlref{\onyxop{}{continue}{}}{systemdict:continue} operator.
160\label{CW_ONYXX_ESCAPE}
161\item[\cppdef{CW\_ONYXX\_ESCAPE}: ]
162	Internal use, for the \htmlref{\onyxop{}{escape}{}}{systemdict:escape}
163	operator.
164\label{CW_ONYXX_EXIT}
165\item[\cppdef{CW\_ONYXX\_EXIT}: ]
166	Internal use, for the \htmlref{\onyxop{}{exit}{}}{systemdict:exit} operator.
167\label{CW_ONYXX_STOP}
168\item[\cppdef{CW\_ONYXX\_STOP}: ]
169	Internal use, for the \htmlref{\onyxop{}{stop}{}}{systemdict:stop}
170	operator.
171\label{CW_ONYXX_QUIT}
172\item[\cppdef{CW\_ONYXX\_QUIT}: ]
173	Internal use, for the \htmlref{\onyxop{}{quit}{}}{systemdict:quit}
174	operator.
175\end{description}
176
177\section{Integration issues}
178\subsection{Thread creation}
179\libname{libonyx}'s garbage collector uses the \htmlref{\classname{thd}}{thd}
180class to suspend and resume all other threads during the mark phase of atomic
181collection.  For this to work, all threads that have any contact with
182\libname{libonyx} must be created as suspensible threads using the
183\htmlref{\classname{thd}}{thd} class.
184
185This can cause integration headaches for existing threaded applications, but
186there is no other portable way to suspend and resume threads.  The only
187alternative is to assure that only one thread is executing in the interpreter
188and to disable timeout-based (asynchronous) collection.
189
190\subsection{Restarted interrupted system calls}
191As mentioned above, \libname{libonyx} uses thread suspension and resumption to
192implement garbage collection.  This has the side-effect of making restarted
193interrupted system calls a real possibility.  However, the operating system will
194return with a partial result if the system call was partially complete when it
195was interrupted.  In practice, what this means is that short reads and writes
196are possible where they otherwise wouldn't happen, so the application should not
197make any assumptions about interruptible system calls always completing with a
198full result.  See the \htmlref{\classname{thd}}{thd} class documentation for
199more details.
200
201\subsection{Signals}
202Depending on how \libname{libonyx} is built, \cvar{SIGUSR1} and \cvar{SIGUSR2}
203may be reserved by the \htmlref{\classname{thd}}{thd} class for thread
204suspension and resumption.  Additionally, the \cvar{SIGPIPE} signal is ignored
205by default, since socket operations can cause \cvar{SIGPIPE} signals, for which
206the library has no use.
207
208\section{Guidelines for writing extensions}
209When embedding \libname{libonyx} in an application, it is usually desirable to
210add some operators so that the interpreter can interact with the rest of the
211application.  The \libname{libonyx} source code contains hundreds of operators
212that can be used as examples when writing new operators.  However, there are
213some very important rules that operators must follow, some of which may not be
214obvious when reading the code.
215
216\begin{itemize}
217\item{Manually managed (\cfunc{malloc}{}/\cfunc{free}{}) memory should not be
218allocated unless the code is very careful.  If a function recurses into the
219interpreter (this includes calls to functions such as
220\htmlref{\cfunc{nxo\_thread\_nerror}{}}{nxo_thread_nerror}), there is the very
221real possibility that control will never return to the operator due to an
222exception.  Code must either catch all exceptions and clean up allocations, or
223not recurse into the interpreter.}
224
225\item{Composite objects should never be allocated on the C stack.  The garbage
226collector has no knowledge of such objects, so if the only reference to an
227object is on the C stack, the object may be collected, which will lead to
228unpredictable program behavior.  Instead of allocating objects on the C stack,
229use tstack, available via
230\htmlref{\cfunc{nxo\_thread\_tstack\_get}{}}{nxo_thread_tstack_get}, which is a
231per-thread stack that the garbage collector scans.}
232
233\item{For an object to be safe from garbage collection, there must always be at
234least one reference to it inside the interpreter.  So, if C code obtains a
235pointer to a composite object, then destroys the last known internal Onyx
236reference (pops it off a stack, redefines it in a dict, replaces an element of
237an array, etc.), the pointer is no longer safe to use.  The \libname{libonyx}
238API is structured such that it is invalid to do such a thing, for this reason.}
239
240\item{tstack must be cleaned up before returning from a function.  This
241constraint is placed on the code in order to avoid leaking space on tstack.  In
242debug versions of \libname{libonyx}, this is enforced by assertions.  The one
243exception to this rule has to do with \htmlref{\classname{xep}}{xep} exceptions,
244in which case the catchers of the exceptions are responsible for cleaning up
245tstack.  Therefore, it is not necessary to catch exceptions merely to avoid
246tstack leakage.}
247\end{itemize}
248
249Since Onyx type checking is dynamic, it is the responsibility of the operators
250to assure objects are the correct type before calling any of the type-specific
251\cfunc{nxo\_*}{} functions.  Failure to do so will result in unpredictable
252behavior and likely crashes.
253
254\section{API}
255\begin{capi}
256\label{libonyx_init}
257\index{libonyx_init@\cfunc{libonyx\_init}{}}
258\citem{\cfunc[void]{libonyx\_init}{int a\_argc, char **a\_argv, char **a\_envp}}
259	\begin{capilist}
260	\item[Input(s): ]
261		\begin{description}\item[]
262		\item[a\_argc: ]
263			Number of command line arguments.
264		\item[a\_argv: ]
265			Pointer to an array of command line argument strings.
266		\item[a\_envp: ]
267			Pointer to an array of environment variable strings.
268		\end{description}
269	\item[Output(s): ] None.
270	\item[Exception(s): ]
271		\begin{description}\item[]
272		\item[\htmlref{CW\_ONYXX\_OOM}{CW_ONYXX_OOM}.]
273		\end{description}
274	\item[Description: ]
275		Initialize various global state.
276	\end{capilist}
277\label{libonyx_shutdown}
278\index{libonyx_shutdown@\cfunc{libonyx\_shutdown}{}}
279\citem{\cfunc[void]{libonyx\_shutdown}{void}}
280	\begin{capilist}
281	\item[Input(s): ] None.
282	\item[Output(s): ] None.
283	\item[Exception(s): ] None.
284	\item[Description: ]
285		Clean up the global variables that are initialized by
286		\cfunc{libonyx\_init}{}.
287	\end{capilist}
288\label{libonyx_argv_get}
289\index{libonyx_argv_get@\cfunc{libonyx\_argv\_get}{}}
290\citem{\cfunc[cw\_nxo\_t *]{libonyx\_argv\_get}{void}}
291	\begin{capilist}
292	\item[Input(s): ] None.
293	\item[Output(s): ]
294		\begin{description}\item[]
295		\item[retval: ]
296			Pointer to the \classname{nxo} corresponding to
297			\onyxop{argv}{}.
298		\end{description}
299	\item[Exception(s): ] None.
300	\item[Description: ]
301		Return a pointer to the \classname{nxo} corresponding to
302		\onyxop{argv}{}.
303	\end{capilist}
304\label{libonyx_envdict_get}
305\index{libonyx_envdict_get@\cfunc{libonyx\_envdict\_get}{}}
306\citem{\cfunc[cw\_nxo\_t *]{libonyx\_\htmlref{envdict}{sec:envdict}\_get}{void}}
307	\begin{capilist}
308	\item[Input(s): ] None.
309	\item[Output(s): ]
310		\begin{description}\item[]
311		\item[retval: ]
312			Pointer to the \classname{nxo} corresponding to
313			\onyxop{envdict}{}.
314		\end{description}
315	\item[Exception(s): ] None.
316	\item[Description: ]
317		Return a pointer to the \classname{nxo} corresponding to
318		\onyxop{envdict}{}.
319	\end{capilist}
320\label{libonyx_gcdict_get}
321\index{libonyx_gcdict_get@\cfunc{libonyx\_gcdict\_get}{}}
322\citem{\cfunc[cw\_nxo\_t *]{libonyx\_\htmlref{gcdict}{sec:gcdict}\_get}{void}}
323	\begin{capilist}
324	\item[Input(s): ] None.
325	\item[Output(s): ]
326		\begin{description}\item[]
327		\item[retval: ]
328			Pointer to the \classname{nxo} corresponding to
329			\onyxop{gcdict}{}.
330		\end{description}
331	\item[Exception(s): ] None.
332	\item[Description: ]
333		Return a pointer to the \classname{nxo} corresponding to
334		\onyxop{gcdict}{}.
335	\end{capilist}
336\label{cw_opaque_alloc_t}
337\index{cw_opaque_alloc_t@\cfunc{cw\_opaque\_alloc\_t}{}}
338\citem{\cfunc[void *]{cw\_opaque\_alloc\_t}{void *a\_arg, size\_t a\_size,
339const char *a\_filename, uint32\_t a\_line\_num}}
340	\begin{capilist}
341	\item[Input(s): ]
342		\begin{description}\item[]
343		\item[a\_arg: ]
344			Opaque pointer.
345		\item[a\_size: ]
346			Size of memory range to allocate.
347		\item[a\_filename: ]
348			Should be \_\_FILE\_\_.
349		\item[a\_line\_num: ]
350			Should be \_\_LINE\_\_.
351		\end{description}
352	\item[Output(s): ]
353		\begin{description}\item[]
354		\item[retval: ]
355			Pointer to a memory range.
356		\end{description}
357	\item[Exception(s): ]
358		\begin{description}\item[]
359		\item[\htmlref{CW\_ONYXX\_OOM}{CW_ONYXX_OOM}.]
360		\end{description}
361	\item[Description: ]
362		Allocate \cvar{a\_size} of space and return a pointer to it.
363	\end{capilist}
364\label{cw_opaque_calloc_t}
365\index{cw_opaque_calloc_t@\cfunc{cw\_opaque\_calloc\_t}{}}
366\citem{\cfunc[void *]{cw\_opaque\_calloc\_t}{void *a\_arg, size\_t a\_number,
367size\_t a\_size, const char *a\_filename, uint32\_t
368a\_line\_num}}
369	\begin{capilist}
370	\item[Input(s): ]
371		\begin{description}\item[]
372		\item[a\_arg: ]
373			Opaque pointer.
374		\item[a\_number: ]
375			Number of elements to allocate.
376		\item[a\_size: ]
377			Size of each element to allocate.
378		\item[a\_filename: ]
379			Should be \_\_FILE\_\_.
380		\item[a\_line\_num: ]
381			Should be \_\_LINE\_\_.
382		\end{description}
383	\item[Output(s): ]
384		\begin{description}\item[]
385		\item[retval: ]
386			Pointer to a zeroed memory range.
387		\end{description}
388	\item[Exception(s): ]
389		\begin{description}\item[]
390		\item[\htmlref{CW\_ONYXX\_OOM}{CW_ONYXX_OOM}.]
391		\end{description}
392	\item[Description: ]
393		Allocate a zeroed array of \cvar{a\_number} objects, each
394		\cvar{a\_size} bytes long, and return a pointer to the array.
395	\end{capilist}
396\label{cw_opaque_realloc_t}
397\index{cw_opaque_realloc_t@\cfunc{cw\_opaque\_realloc\_t}{}}
398\citem{\cfunc[void *]{cw\_opaque\_realloc\_t}{void *a\_arg, void *a\_ptr,
399size\_t a\_size, size\_t a\_old\_size, const char *a\_filename, uint32\_t
400a\_line\_num}}
401	\begin{capilist}
402	\item[Input(s): ]
403		\begin{description}\item[]
404		\item[a\_arg: ]
405			Opaque pointer.
406		\item[a\_ptr: ]
407			Pointer to memory range to be reallocated.
408		\item[a\_size: ]
409			Size of memory range to allocate.
410		\item[a\_old\_size: ]
411			Size of memory range previously pointed to by
412			\cvar{a\_ptr}.
413		\item[a\_filename: ]
414			Should be \_\_FILE\_\_.
415		\item[a\_line\_num: ]
416			Should be \_\_LINE\_\_.
417		\end{description}
418	\item[Output(s): ]
419		\begin{description}\item[]
420		\item[retval: ]
421			Pointer to a memory range.
422		\end{description}
423	\item[Exception(s): ]
424		\begin{description}\item[]
425		\item[\htmlref{CW\_ONYXX\_OOM}{CW_ONYXX_OOM}.]
426		\end{description}
427	\item[Description: ]
428		Reallocate \cvar{a\_size} of space and return a pointer to it.
429	\end{capilist}
430\label{cw_opaque_dealloc_t}
431\index{cw_opaque_dealloc_t@\cfunc{cw\_opaque\_dealloc\_t}{}}
432\citem{\cfunc[void]{cw\_opaque\_dealloc\_t}{void *a\_mem, void *a\_ptr, size\_t
433a\_size, const char *a\_filename, uint32\_t a\_line\_num}}
434	\begin{capilist}
435	\item[Input(s): ]
436		\begin{description}\item[]
437		\item[a\_arg: ]
438			Opaque pointer.
439		\item[a\_ptr: ]
440			Pointer to to memory range to be freed.
441		\item[a\_size: ]
442			Sizef of memory range pointed to by \cvar{a\_ptr}.
443		\item[a\_filename: ]
444			Should be \_\_FILE\_\_.
445		\item[a\_line\_num: ]
446			Should be \_\_LINE\_\_.
447		\end{description}
448	\item[Output(s): ] None.
449	\item[Exception(s): ] None.
450	\item[Description: ]
451		Deallocate the memory pointed to by \cvar{a\_ptr}.
452	\end{capilist}
453\label{cw_opaque_alloc}
454\index{cw_opaque_alloc@\cfunc{cw\_opaque\_alloc}{}}
455\citem{\cppmacro[void *]{cw\_opaque\_alloc}{cw\_opaque\_alloc\_t *a\_func, void
456*a\_arg, size\_t a\_size}}
457	\begin{capilist}
458	\item[Input(s): ]
459		\begin{description}\item[]
460		\item[a\_func: ]
461			Opaque allocator function pointer.
462		\item[a\_arg: ]
463			Opaque pointer.
464		\item[a\_size: ]
465			Size of memory range to allocate.
466		\end{description}
467	\item[Output(s): ]
468		\begin{description}\item[]
469		\item[retval: ]
470			Pointer to a memory range.
471		\end{description}
472	\item[Exception(s): ]
473		\begin{description}\item[]
474		\item[\htmlref{CW\_ONYXX\_OOM}{CW_ONYXX_OOM}.]
475		\end{description}
476	\item[Description: ]
477		Allocate \cvar{a\_size} of space and return a pointer to it.
478	\end{capilist}
479\label{cw_opaque_calloc}
480\index{cw_opaque_calloc@\cfunc{cw\_opaque\_calloc}{}}
481\citem{\cppmacro[void *]{cw\_opaque\_calloc}{cw\_opaque\_calloc\_t *a\_func,
482void *a\_arg, size\_t a\_number, size\_t a\_size}}
483	\begin{capilist}
484	\item[Input(s): ]
485		\begin{description}\item[]
486		\item[a\_func: ]
487			Opaque allocator function pointer.
488		\item[a\_arg: ]
489			Opaque pointer.
490		\item[a\_number: ]
491			Number of elements to allocate.
492		\item[a\_size: ]
493			Size of each element to allocate.
494		\end{description}
495	\item[Output(s): ]
496		\begin{description}\item[]
497		\item[retval: ]
498			Pointer to a zeroed memory range.
499		\end{description}
500	\item[Exception(s): ]
501		\begin{description}\item[]
502		\item[\htmlref{CW\_ONYXX\_OOM}{CW_ONYXX_OOM}.]
503		\end{description}
504	\item[Description: ]
505		Allocate a zeroed array of \cvar{a\_number} objects, each
506		\cvar{a\_size} bytes long, and return a pointer to the array.
507	\end{capilist}
508\label{cw_opaque_realloc}
509\index{cw_opaque_realloc@\cfunc{cw\_opaque\_realloc}{}}
510\citem{\cppmacro[void *]{cw\_opaque\_realloc}{cw\_opaque\_realloc\_t *a\_func,
511void *a\_arg, void *a\_ptr, size\_t a\_size, size\_t a\_old\_size}}
512	\begin{capilist}
513	\item[Input(s): ]
514		\begin{description}\item[]
515		\item[a\_func: ]
516			Opaque allocator function pointer.
517		\item[a\_arg: ]
518			Opaque pointer.
519		\item[a\_ptr: ]
520			Pointer to memory range to be reallocated.
521		\item[a\_size: ]
522			Size of memory range to allocate.
523		\item[a\_old\_size: ]
524			Size of memory range previously pointed to by
525			\cvar{a\_ptr}.
526		\end{description}
527	\item[Output(s): ]
528		\begin{description}\item[]
529		\item[retval: ]
530			Pointer to a memory range.
531		\end{description}
532	\item[Exception(s): ]
533		\begin{description}\item[]
534		\item[\htmlref{CW\_ONYXX\_OOM}{CW_ONYXX_OOM}.]
535		\end{description}
536	\item[Description: ]
537		Reallocate \cvar{a\_size} of space and return a pointer to it.
538	\end{capilist}
539\label{cw_opaque_dealloc}
540\index{cw_opaque_dealloc@\cfunc{cw\_opaque\_dealloc}{}}
541\citem{\cppmacro[void]{cw\_opaque\_dealloc}{cw\_opaque\_dealloc\_t *a\_func,
542void *a\_mem, void *a\_ptr, size\_t a\_size}}
543	\begin{capilist}
544	\item[Input(s): ]
545		\begin{description}\item[]
546		\item[a\_func: ]
547			Opaque allocator function pointer.
548		\item[a\_arg: ]
549			Opaque pointer.
550		\item[a\_ptr: ]
551			Pointer to to memory range to be freed.
552		\item[a\_size: ]
553			Sizef of memory range pointed to by \cvar{a\_ptr}.
554		\end{description}
555	\item[Output(s): ] None.
556	\item[Exception(s): ] None.
557	\item[Description: ]
558		Deallocate the memory pointed to by \cvar{a\_ptr}.
559	\end{capilist}
560\label{cw_onyx_code}
561\index{cw_onyx_code@\cppmacro{cw\_onyx\_code}{}}
562\citem{\cppmacro[void]{cw\_onyx\_code}{cw\_nxo\_t *a\_thread, const char
563*a\_code}}
564	\begin{capilist}
565	\item[Input(s): ]
566		\begin{description}\item[]
567		\item[a\_thread: ]
568			Pointer to a thread \classname{nxo}.
569		\item[a\_code: ]
570			A "-delimited string constant.
571		\end{description}
572	\item[Output(s): ] None.
573	\item[Exception(s): ] Depends on actions of a\_code.
574	\item[Description: ]
575		Convenience macro for static embedded \htmlref{Onyx}{onyxlang}
576		code.
577	\end{capilist}
578\label{cw_assert}
579\index{cw_assert@\cppmacro{cw\_assert}{}}
580\citem{\cppmacro[void]{cw\_assert}{expression}}
581	\begin{capilist}
582	\item[Input(s): ]
583		\begin{description}\item[]
584		\item[expression: ]
585			C expression that evaluates to zero or non-zero.
586		\end{description}
587	\item[Output(s): ]
588			Possible error printed to \cvar{stderr}.
589	\item[Exception(s): ] None.
590	\item[Description: ]
591		If the expression evaluates to zero, print an error message to
592		\cvar{stderr} and \cfunc{abort}{}.
593
594		Note: This macro is only active if the \cppdef{CW\_ASSERT} cpp
595		macro is defined.
596	\end{capilist}
597\label{cw_dassert}
598\index{cw_dassert@\cppmacro{cw\_dassert}{}}
599\citem{\cppmacro[void]{cw\_dassert}{expression}}
600	\begin{capilist}
601	\item[Input(s): ]
602		\begin{description}\item[]
603		\item[expression: ]
604			C expression that evaluates to zero or non-zero.
605		\end{description}
606	\item[Output(s): ]
607			Possible error printed to \cvar{stderr}.
608	\item[Exception(s): ] None.
609	\item[Description: ]
610		If the expression evaluates to zero, print an error message to
611		\cvar{stderr} and \cfunc{abort}{}.
612
613		Note: This macro is only active if the \cppdef{CW\_ASSERT} and
614		\cppdef{CW\_DBG} cpp macros are defined.
615	\end{capilist}
616\label{cw_not_reached}
617\index{cw_not_reached@\cppmacro{cw\_not\_reached}{}}
618\citem{\cppmacro[void]{cw\_not\_reached}{void}}
619	\begin{capilist}
620	\item[Input(s): ] None.
621	\item[Output(s): ]
622		Error printed to \cvar{stderr}.
623	\item[Exception(s): ] None.
624	\item[Description: ]
625		Abort with an error message.
626
627		Note: This macro is only active if the \cppdef{CW\_ASSERT} cpp
628		macro is defined.
629	\end{capilist}
630\label{cw_check_ptr}
631\index{cw_check\_ptr@\cppmacro{cw\_check\_ptr}{}}
632\citem{\cppmacro[void]{cw\_check\_ptr}{a\_pointer}}
633	\begin{capilist}
634	\item[Input(s): ]
635		\begin{description}\item[]
636		\item[a\_pointer: ]
637			A pointer.
638		\end{description}
639	\item[Output(s): ]
640			Possible error printed to \cvar{stderr}.
641	\item[Exception(s): ] None.
642	\item[Description: ]
643		If \cvar{a\_pointer} is NULL, print an error message to
644		\cvar{stderr} and \cfunc{abort}{}.
645
646		Note: This macro is only active if the \cppdef{CW\_ASSERT} cpp
647		macro is defined.
648	\end{capilist}
649\label{cw_error}
650\index{cw_error@\cppmacro{cw\_error}{}}
651\citem{\cppmacro[void]{cw\_error}{const char *a\_str}}
652	\begin{capilist}
653	\item[Input(s): ]
654		\begin{description}\item[]
655		\item[a\_str: ]
656			Pointer to a NULL-terminated character array.
657		\end{description}
658	\item[Output(s): ]
659		Contents of \cvar{a\_str}, followed by a carriage return,
660		printed to \cvar{stderr}.
661	\item[Exception(s): ] None.
662	\item[Description: ]
663		Print the contents of \cvar{a\_str}, followed by a carriage
664		return, to \cvar{stderr}.
665	\end{capilist}
666\label{cw_ntohq}
667\index{cw_ntohq@\cppmacro{cw\_ntohq}{}}
668\citem{\cppmacro[uint64\_t]{cw\_ntohq}{uint64\_t a\_val}}
669	\begin{capilist}
670	\item[Input(s): ]
671		\begin{description}\item[]
672		\item[a\_val: ]
673			64 bit integer.
674		\end{description}
675	\item[Output(s): ]
676		\begin{description}\item[]
677		\item[retval: ]
678			64 bit integer.
679		\end{description}
680	\item[Exception(s): ] None.
681	\item[Description: ]
682		Convert \cvar{a\_val} from network byte order to host byte order
683		and return the result.
684	\end{capilist}
685\label{cw_htonq}
686\index{cw_htonq@\cppmacro{cw\_htonq}{}}
687\citem{\cppmacro[uint64\_t]{cw\_htonq}{uint64\_t a\_val}}
688	\begin{capilist}
689	\item[Input(s): ]
690		\begin{description}\item[]
691		\item[a\_val: ]
692			64 bit integer.
693		\end{description}
694	\item[Output(s): ]
695		\begin{description}\item[]
696		\item[retval: ]
697			64 bit integer.
698		\end{description}
699	\item[Exception(s): ] None.
700	\item[Description: ]
701		Convert \cvar{a\_val} from host byte order to network byte order
702		and return the result.
703	\end{capilist}
704\label{cw_offsetof}
705\index{cw_offsetof@\cppmacro{cw\_offsetof}{}}
706\citem{\cppmacro[uint32\_t]{cw\_offsetof}{{\lt}type{\gt} a\_type,
707{\lt}field\_name{\gt} a\_field}}
708	\begin{capilist}
709	\item[Input(s): ]
710		\begin{description}\item[]
711		\item[a\_type: ]
712			C structure type name.
713		\item[a\_field: ]
714			Name of a field within \cvar{a\_type}.
715		\end{description}
716	\item[Output(s): ]
717		\begin{description}\item[]
718		\item[retval: ]
719			Offset of \cvar{a\_field} into \cvar{a\_type}.
720		\end{description}
721	\item[Exception(s): ] None.
722	\item[Description: ]
723		Calculate the offset of \cvar{a\_field} into \cvar{a\_type}
724		and return the result.
725	\end{capilist}
726\end{capi}
727
728\section{Classes}
729\input{@abs_srcroot@/lib/libonyx/doc/latex/ch}
730\input{@abs_srcroot@/lib/libonyx/doc/latex/cnd}
731\input{@abs_srcroot@/lib/libonyx/doc/latex/dch}
732\input{@abs_srcroot@/lib/libonyx/doc/latex/mb}
733\input{@abs_srcroot@/lib/libonyx/doc/latex/mem}
734\input{@abs_srcroot@/lib/libonyx/doc/latex/mq}
735\input{@abs_srcroot@/lib/libonyx/doc/latex/mtx}
736\input{@abs_srcroot@/lib/libonyx/doc/latex/nx}
737\input{@abs_srcroot@/lib/libonyx/doc/latex/nxa}
738\input{@abs_srcroot@/lib/libonyx/doc/latex/nxm}
739\input{@abs_srcroot@/lib/libonyx/doc/latex/nxn}
740\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo}
741\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_array}
742\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_boolean}
743\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_class}
744\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_condition}
745\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_dict}
746\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_file}
747\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_fino}
748\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_handle}
749\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_instance}
750\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_integer}
751\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_mark}
752\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_mutex}
753\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_name}
754\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_no}
755\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_null}
756\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_operator}
757\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_pmark}
758\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_real}
759\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_regex}
760\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_regsub}
761\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_stack}
762\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_string}
763\input{@abs_srcroot@/lib/libonyx/doc/latex/nxo_thread}
764\input{@abs_srcroot@/lib/libonyx/doc/latex/ql}
765\input{@abs_srcroot@/lib/libonyx/doc/latex/qr}
766\input{@abs_srcroot@/lib/libonyx/doc/latex/qs}
767\input{@abs_srcroot@/lib/libonyx/doc/latex/thd}
768\input{@abs_srcroot@/lib/libonyx/doc/latex/tsd}
769\input{@abs_srcroot@/lib/libonyx/doc/latex/xep}
770
771\section{Dictionaries}
772\input{@abs_srcroot@/lib/libonyx/doc/latex/gcdict}
773\input{@abs_srcroot@/lib/libonyx/doc/latex/systemdict}
774