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