#LyX 2.3 created this file. For more info see http://www.lyx.org/ \lyxformat 544 \begin_document \begin_header \save_transient_properties true \origin unavailable \textclass article \use_default_options true \maintain_unincluded_children false \language english \language_package default \inputencoding utf8 \fontencoding global \font_roman "lmodern" "default" \font_sans "lmss" "default" \font_typewriter "lmtt" "default" \font_math "auto" "auto" \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 100 \font_tt_scale 100 100 \use_microtype false \use_dash_ligatures true \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize 12 \spacing single \use_hyperref true \pdf_bookmarks false \pdf_bookmarksnumbered false \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder true \pdf_colorlinks false \pdf_backref page \pdf_pdfusetitle true \papersize a4paper \use_geometry true \use_package amsmath 1 \use_package amssymb 1 \use_package cancel 1 \use_package esint 1 \use_package mathdots 1 \use_package mathtools 1 \use_package mhchem 1 \use_package stackrel 1 \use_package stmaryrd 1 \use_package undertilde 1 \cite_engine natbib \cite_engine_type numerical \biblio_style plainnat \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \justification true \use_refstyle 0 \use_minted 0 \index Index \shortcut idx \color #008000 \end_index \leftmargin 2cm \topmargin 2cm \rightmargin 2cm \bottommargin 2cm \secnumdepth 3 \tocdepth 1 \paragraph_separation indent \paragraph_indentation default \is_math_indent 0 \math_numbering_side default \quotes_style english \dynamic_quotes 0 \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Title libHX 3.24 \begin_inset Newline newline \end_inset Documentation \end_layout \begin_layout Standard \begin_inset VSpace defskip \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Introduction \end_layout \begin_layout Standard libHX collects many useful day-to-day functions, intended to reduce the amount of otherwise repeatedly open-coded instructions. \end_layout \begin_layout Section Overview \end_layout \begin_layout Itemize Maps (key-value pairs) (section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:maps" \end_inset ) \begin_inset Newline newline \end_inset Originally created to provide a data structure like Perl's associative arrays. Different map types and characteristics are available, such as hash-based or the traditional rbtree. \end_layout \begin_layout Itemize Deques (section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:deque" \end_inset ) \begin_inset Newline newline \end_inset Double-ended queues, implemented as a doubly-linked list with sentinels, are suitable for both providing stack and queue functionality. \end_layout \begin_layout Itemize Inline doubly-linked list, uncounted and counted (sections \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:list" \end_inset and \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:clist" \end_inset ) \begin_inset Newline newline \end_inset Light-weight linked lists as used in the Linux kernel. \end_layout \begin_layout Itemize Common string operations (section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:strings" \end_inset ) \begin_inset Newline newline \end_inset basename, chomp, dirname, getl(ine), split, strlcat/strlcpy, strlower/-upper, str*trim, strsep, etc. \end_layout \begin_layout Itemize Memory containers, auto-sizing string operations (section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:mc" \end_inset ) \begin_inset Newline newline \end_inset Scripting-like invocation for string handling \begin_inset space ~ \end_inset — automatically doing (re)allocations as needed. \end_layout \begin_layout Itemize String formatter (section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:format" \end_inset ) \begin_inset Newline newline \end_inset HXfmt is a small template system for by-name variable expansion. It can be used to substitute placeholders in format strings supplied by the user by appropriate expanded values defined by the program. \end_layout \begin_layout Itemize Directory creation, traversal, removal, and file copying (sections \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:dir-ops1" \end_inset , \begin_inset CommandInset ref LatexCommand ref reference "sec:dir-ops2" \end_inset and \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:file-ops" \end_inset ) \end_layout \begin_layout Itemize Option parsing (section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:option" \end_inset ) \begin_inset Newline newline \end_inset Table-/callback-based option parser that works similar to Perl's \family typewriter Getopt::Long \family default \begin_inset space ~ \end_inset — no open-coding but a single \begin_inset Quotes eld \end_inset atomic \begin_inset Quotes erd \end_inset invocation. \end_layout \begin_layout Itemize Shell-style config parser (section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:shconf" \end_inset ) \begin_inset Newline newline \end_inset Configuration file reader for Shell-style \begin_inset Quotes eld \end_inset configuration \begin_inset Quotes erd \end_inset files with key-value pairs, as usually foudn in \family typewriter /etc\SpecialChar breakableslash sysconfig \family default . \end_layout \begin_layout Itemize Random number gathering (section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:random" \end_inset ) \begin_inset Newline newline \end_inset Convenient wrapper that uses kernel-provided RNG devices when available. \end_layout \begin_layout Itemize External process invocation (section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:proc" \end_inset ) \begin_inset Newline newline \end_inset Setting up pipes for the standard file descriptors for sending/capturing data to/from a program. \end_layout \begin_layout Itemize \shape italic a bit more beyond that ... Miscellaneous \end_layout \begin_layout Section Resources \end_layout \begin_layout Standard As of this writing, the repository is located at \end_layout \begin_layout Itemize \begin_inset Flex URL status open \begin_layout Plain Layout git://libhx.git.sf.net/gitroot/libhx/libhx \end_layout \end_inset \begin_inset space ~ \end_inset — clone URL \end_layout \begin_layout Itemize \begin_inset Flex URL status open \begin_layout Plain Layout http://libhx.git.sf.net/ \end_layout \end_inset \begin_inset space ~ \end_inset — gitweb interface \end_layout \begin_layout Itemize \begin_inset Flex URL status open \begin_layout Plain Layout http://libhx.sf.net/ \end_layout \end_inset \begin_inset space ~ \end_inset — home page (and link to tarballs) \end_layout \begin_layout Itemize \begin_inset Flex URL status open \begin_layout Plain Layout http://freecode.com/projects/libhx/ \end_layout \end_inset \begin_inset space ~ \end_inset — Freecode page (useful for automatic notification of new releases) \end_layout \begin_layout Section Installation \end_layout \begin_layout Standard libHX uses GNU autotools as a build environment, which means that all you have to run as a end-user is the \family typewriter configure \family default with any options that you need, plus the usual \family typewriter make \family default and \family typewriter make install \family default as desired. \end_layout \begin_layout Standard Pay attention to multi-lib Linux distributions where you most likely need to specify a different libdir instead of using the default \begin_inset Quotes eld \end_inset lib \begin_inset Quotes erd \end_inset . In case of the Debian-style multi-arch/multi-lib proposal ( \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://wiki.debian.org/Multiarch \end_layout \end_inset ): \end_layout \begin_layout LyX-Code $ \series bold ./configure --libdir='${prefix}/lib/x86_64-linux-gnu' \end_layout \begin_layout Standard and the classic-style 32-64 2-lib distributions: \end_layout \begin_layout LyX-Code $ \series bold ./configure --libdir='${prefix}/lib64' \end_layout \begin_layout Subsection Requirements \end_layout \begin_layout Itemize GNU C Compiler 3.3.5 or newer. Other compilers (non-GCC) have not been tested in months \begin_inset space ~ \end_inset — use at your own risk. \end_layout \begin_layout Itemize approximately 80–160 \begin_inset space ~ \end_inset KB of disk space on Linux for the shared library (depends on platform) and header files. \end_layout \begin_layout Standard A C++ compiler is only needed if you want to build the C++ test programs that come with libHX. By default, if there is no C++ compiler present, these will not be built. \end_layout \begin_layout Itemize No external libraries are needed for compilation of libHX. Helper files, like \family typewriter libxml_\SpecialChar softhyphen helper.h \family default , may reference their include files, but they are not used during compilation. \end_layout \begin_layout Section Portability notice \end_layout \begin_layout Standard libHX runs on contemporary versions of Linux, Solaris and the three BSD distributions. It might even work on Microsoft Windows, but this is not tested very often, if at all. Overly old systems, especially Unices, are not within focus. While AIX \begin_inset space ~ \end_inset 5.3 might still classify as contemporary, strangelets like \begin_inset Quotes eld \end_inset Ultrix \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset Dynix \begin_inset Quotes erd \end_inset you can find in the autotools-related file \family typewriter config.guess \family default are some that are definitely not. \end_layout \begin_layout Standard Furthermore, a compiler that understands the C99 or GNU89 standard is required. The integer type \begin_inset Quotes eld \end_inset int \begin_inset Quotes erd \end_inset should at best have 32 bits at least. There is no ultra-portable version as of this writing, but feel free to start one akin to the \begin_inset Quotes eld \end_inset p \begin_inset Quotes erd \end_inset variants of OpenBSD software such as OpenSSH. \end_layout \begin_layout Section History \end_layout \begin_layout Standard The origins of libHX trace back, even crossing a language boundary, to when the author started on using Perl in 1999. Some tasks were just too damn useful to be open-coded every time. Two such examples are what is these days known as \family typewriter HX_basename \family default and \family typewriter HX_mkdir \family default . The name does not relate to anyone's initials; it is a result of a truncation of the author's nick used years ago. \end_layout \begin_layout Standard Around the beginning of 2003, the author also started on the C programming language and soon the small library was converted from Perl to C. The libHX library as of today is the result of working with C ever since, and naturally grew from there to support whatever the author was in need of. \end_layout \begin_layout Standard The \begin_inset Quotes eld \end_inset correct \begin_inset Quotes erd \end_inset name for libHX is with an uppercase \begin_inset Quotes eld \end_inset H \begin_inset Quotes erd \end_inset and uppercase \begin_inset Quotes eld \end_inset X \begin_inset Quotes erd \end_inset , and the same is used for filenames, such as \begin_inset Quotes eld \end_inset libHX.so \begin_inset Quotes erd \end_inset \begin_inset Foot status open \begin_layout Plain Layout Software projects may choose to entirely lowercase the project name for use in filenames, such as the Linux kernel which is released as \family typewriter linux-${ \family default \shape italic version \family typewriter \shape default }.tar.bz2 \family default , or the project may choose to keep the name for filenames, like Mesa and SDL do. libHX is of the latter. \end_layout \end_inset . \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Part General \end_layout \begin_layout Standard Many functions are prefixed with \begin_inset Quotes eld \end_inset \family typewriter HX_ \family default \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset \family typewriter HXsubsys_ \family default \begin_inset Quotes erd \end_inset , as are structures (sometimes without underscores, be sure to check the syntax and names), to avoid name clashes with possibly existing files. Functions that are not tied to a specific data structure such as most of the string functions (see chapter \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:strings" \end_inset ) use the subsystem-less prefix, \begin_inset Quotes eld \end_inset \family typewriter HX_ \family default \begin_inset Quotes erd \end_inset . Functions from a clearly-defined subsystem, such as map or deque, augment the base prefix by a suffix, forming e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset \begin_inset Quotes eld \end_inset \family typewriter HXmap_ \family default \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Section Initialization \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_init( \series bold void \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX_init \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HX_exit( \series bold void \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX_exit \end_layout \end_inset \end_layout \begin_layout Standard Before using the library's functions, \family typewriter HX_init \family default must be called. This function will initialize any needed state libHX needs for itself, if any. It is designed to be invoked multiple times, such as for example, from different libraries linking to libHX itself, and will refcount. On success, >0 is returned. If there was an error, it will return a negative error code or zero. \family typewriter HX_exit \family default is the logical counterpart of notifying that the library is no longer used. \end_layout \begin_layout Section Type-checking casts \end_layout \begin_layout Standard The C++ language provides so-called \begin_inset Quotes eld \end_inset new-style casts \begin_inset Quotes erd \end_inset , referring to the four template-looking invocations \family typewriter static_cast<> \family default , \family typewriter const_cast<> \family default , \family typewriter reinterpret_cast<> \family default and \family typewriter dynamic_cast<> \family default . No such blessing was given to the C language, but still, even using macros that expand to the olde cast make it much easier to find casts in source code and annotate why something was casted, which is already an improvement. \begin_inset space ~ \end_inset — Actually, it \shape italic is \shape default possible to do a some type checking, using some GCC extensions, which augments these macros from their documentary nature to an actual safety measure. \end_layout \begin_layout Subsection \family typewriter reinterpret_cast \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter reinterpret_cast \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter reinterpret_cast() \family default maps directly to the old-style typecast, \family typewriter (type)(expr) \family default , and causes the bit pattern for the expr rvalue to be \begin_inset Quotes eld \end_inset reinterpreted \begin_inset Quotes erd \end_inset as a new type. You will notice that \begin_inset Quotes eld \end_inset reinterpret \begin_inset Quotes erd \end_inset is the longest of all the \family typewriter *_cast \family default names, and can easily cause your line to grow to 80 columns (the good maximum in many style guides). As a side effect, it is a good indicator that something potentially dangerous might be going on, for example converting intergers from/to pointer. \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/defs.h \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold \begin_inset Newline newline \end_inset int \series default i; \begin_inset Newline newline \end_inset \series bold /* \family roman \series default \shape italic Tree with numeric keys \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset tree = HXhashmap_init(0); \begin_inset Newline newline \end_inset \series bold for \series default (i = 0; i < 6; ++i) \begin_inset Newline newline \end_inset HXmap_add(tree, \series bold reinterpret_cast \series default ( \series bold void * \series default , \begin_inset Newline newline \end_inset \series bold static_cast \series default ( \series bold long \series default , i)), my_data); \end_layout \begin_layout Subsection \family typewriter signed_cast \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter signed_cast \end_layout \end_inset \end_layout \begin_layout Standard This tag is for annotating that the cast was solely done to change the signednes s of pointers to char \begin_inset space ~ \end_inset — and only those. No integers etc. The intention is to facilitate working with libraries that use \family typewriter unsigned char \begin_inset space ~ \end_inset * \family default pointers, such as libcrypto and libssl (from the OpenSSL project) or libxml2, for example. See table \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "tab:defs-signed_cast" \end_inset for the allowed conversions. C++ does \shape italic not \shape default actually have a \family typewriter signed_cast<> \family default , and one would have to use \family typewriter reinterpret_cast<> \family default to do the conversion, because \family typewriter static_cast<> \family default does not allow conversion from \family typewriter const char \begin_inset space ~ \end_inset * \family default to \family typewriter const unsigned char \begin_inset space ~ \end_inset * \family default , for example. (libHX's \family typewriter static_cast() \family default would also throw at least a compiler warning about the different signedness.) libHX does provide a \family typewriter signed_cast<> \family default for C++ though. This is where \family typewriter signed_cast \family default comes in. \end_layout \begin_layout Standard \begin_inset Float table wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout \series bold From \backslash To \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold c* \series default section \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold sc* \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold uc* \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Cc* \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Csc* \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Cuc* \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter \series bold char * \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter \series bold signed char * \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter \series bold unsigned char * \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter \series bold const char * \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout – \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout – \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout – \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter \series bold const signed char * \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout – \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout – \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout – \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter \series bold const unsigned char * \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout – \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout – \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout – \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\checkmark$ \end_inset \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "tab:defs-signed_cast" \end_inset Accepted conversions for \family typewriter signed_cast() \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Subsection \family typewriter static_cast \begin_inset CommandInset label LatexCommand label name "subsec:defs-static_cast" \end_inset \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter static_cast \end_layout \end_inset \end_layout \begin_layout Standard Just like C++'s \family typewriter static_cast<> \family default , libHX's \family typewriter static_cast() \family default verifies that \family typewriter expr \family default can be implicitly converted to the new type (by a simple \family typewriter b \begin_inset space ~ \end_inset = \begin_inset space ~ \end_inset a \family default ). Such is mainly useful for forcing a specific type, as is needed in varargs functions such as \family typewriter printf \family default , and where the conversion actually incurs other side effects, such as truncatio n or promotion: \end_layout \begin_layout LyX-Code \series bold /* \family roman \series default \shape italic Convert to a type printf knows about \family default \series bold \shape default */ \begin_inset Newline newline \end_inset uint64_t \series default x = something; \begin_inset Newline newline \end_inset printf("%llu \backslash n", \series bold static_cast \series default ( \series bold unsigned long long \series default , x)); \end_layout \begin_layout Standard Because there is no format specifier for \family typewriter uint64_t \family default for \family typewriter printf \family default , a conversion to an accepted type is necessary to not cause undefined behavior. The author has seen code that did, for example, \family typewriter printf("%u") \family default on a \begin_inset Quotes eld \end_inset long \begin_inset Quotes erd \end_inset , which only works on architectures where \family typewriter sizeof(unsigned int) \family default happens to equal \family typewriter sizeof(unsigned long) \family default , such as x86_32. On x86_64, an \family typewriter unsigned long \family default is usually twice as big as an \family typewriter unsigned int \family default , so that 8 bytes are pushed onto the stack, but \family typewriter printf \family default only unshifts 4 bytes because the developer used \begin_inset Quotes eld \end_inset \family typewriter %u \family default \begin_inset Quotes erd \end_inset , leading to misreading the next variable on the stack. \end_layout \begin_layout LyX-Code \series bold /* \family roman \series default \shape italic Force promotion \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset \series bold double \series default a_quarter = \series bold static_cast \series default ( \series bold double \series default , 1) / 4; \end_layout \begin_layout Standard Were \begin_inset Quotes eld \end_inset 1 \begin_inset Quotes erd \end_inset not promoted to double, the result in \family typewriter q \family default would be zero because 1/4 is just an integer division, yielding zero. By making one of the operands a floating-point quantity, the compiler will instruct the FPU to compute the result. Of course, one could have also written \begin_inset Quotes eld \end_inset \family typewriter 1.0 \family default \begin_inset Quotes erd \end_inset instead of \family typewriter static_cast(double, 1) \family default , but this is left for the programmer to decide which style s/he prefers. \end_layout \begin_layout LyX-Code \series bold /* \family roman \series default \shape italic Force truncation before invoking second sqrt \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset \series bold double \series default f = sqrt( \series bold static_cast \series default ( \series bold int \series default , 10 * sqrt(3.0 / 4))); \end_layout \begin_layout Standard And here, the conversion from \family typewriter double \family default to \family typewriter int \family default incurs a (wanted) truncation of the decimal fraction, that is, rounding down for positive numbers, and rounding up for negative numbers. \end_layout \begin_layout Subsubsection Allowed conversions \end_layout \begin_layout Itemize \series bold Numbers \series default \begin_inset Newline newline \end_inset Conversion between numeric types, such as \family typewriter char \family default , \family typewriter short \family default , \family typewriter int \family default , \family typewriter long \family default , \family typewriter long long \family default , \family typewriter int \shape italic N \shape default _t \family default , both their signed and unsigned variants, \family typewriter float \family default and \family typewriter double \family default . \end_layout \begin_layout Itemize \series bold Generic Pointer \series default \begin_inset Newline newline \end_inset Conversion from \family typewriter type \begin_inset space ~ \end_inset * \family default to and from \family typewriter void \begin_inset space ~ \end_inset * \family default . (Where \family typewriter type \family default may very well be a type with further indirection.) \end_layout \begin_layout Itemize \series bold Generic Pointer (const) \begin_inset Newline newline \end_inset \series default Conversion from \family typewriter const type \begin_inset space ~ \end_inset * \family default to and from \family typewriter const void \begin_inset space ~ \end_inset * \family default . \end_layout \begin_layout Subsection \family typewriter const_cast \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter const_cast \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter const_cast \family default allows to add or remove \begin_inset Quotes eld \end_inset const \begin_inset Quotes erd \end_inset qualifiers from the type a pointer is pointing to. Due to technical limitations, it could not be implemented to support arbitrary indirection. Instead, \family typewriter const_cast \family default comes in three variants, to be used for indirection levels of 1 to 3: \end_layout \begin_layout Itemize \family typewriter \series bold const_cast \series default 1( \series bold type \begin_inset space ~ \end_inset * \series default , expr) \family default with \family typewriter \series bold typeof \series default (expr) \begin_inset space ~ \end_inset = \series bold type \begin_inset space ~ \end_inset * \family default \series default . (Similarly for any combinations of const.) \end_layout \begin_layout Itemize \family typewriter \series bold const_cast \series default 2( \series bold type \begin_inset space ~ \end_inset ** \series default , expr) with \series bold typeof \series default (expr) \begin_inset space ~ \end_inset = \series bold type \begin_inset space ~ \end_inset ** \family default \series default (and all combinations of const in all possible locations). \end_layout \begin_layout Itemize \family typewriter \series bold const_cast \series default 3( \series bold type \begin_inset space ~ \end_inset *** \series default , expr) with \series bold typeof \series default (expr) \begin_inset space ~ \end_inset = \series bold type \begin_inset space ~ \end_inset *** \family default \series default (and all combinations...). \end_layout \begin_layout Standard As indirection levels above 3 are really unlikely \begin_inset Foot status open \begin_layout Plain Layout See \begin_inset Quotes eld \end_inset Three Star Programmer \begin_inset Quotes erd \end_inset \end_layout \end_inset , having only these three type-checking cast macros was deemed sufficient. The only place where libHX even uses a level\SpecialChar nobreakdash 3 indirection is in the option parser. \end_layout \begin_layout Standard \begin_inset Float table placement H wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout \family typewriter int ** \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter int *const * \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter const int ** \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter const int *const * \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout Accepted expr/target types for \family typewriter const_cast2 \family default ; example for the \begin_inset Quotes eld \end_inset int \begin_inset Quotes erd \end_inset type \end_layout \end_inset \end_layout \begin_layout Plain Layout \align center Conversion is permitted when expression and target type are from the table. \end_layout \end_inset \end_layout \begin_layout Standard It is currently not possible to use \family typewriter const_cast \family default 1/2/3 on pointers to structures whose member structure is unknown. \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Macros \end_layout \begin_layout Standard All macros in this section are available through \family typewriter #include \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/defs.h \end_layout \end_inset . \end_layout \begin_layout Subsection Preprocessor \end_layout \begin_layout LyX-Code \series bold #define \series default HX_STRINGIFY(s) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_STRINGIFY \end_layout \end_inset \end_layout \begin_layout Standard Transforms the expansion of the argument \family typewriter s \family default into a C string. \end_layout \begin_layout Subsection Sizes \end_layout \begin_layout LyX-Code \series bold #define \series default HXSIZEOF_Z16 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXSIZEOF_Z16 \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold #define \series default HXSIZEOF_Z32 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXSIZEOF_Z32 \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold #define \series default HXSIZEOF_Z64 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXSIZEOF_Z64 \end_layout \end_inset \end_layout \begin_layout Standard Expands to the size needed for a buffer (including ' \family typewriter \backslash 0 \family default ') to hold the base-10 string representation of a 16\SpecialChar nobreakdash , 32\SpecialChar nobreakdash or 64\SpecialChar nobreakdash bit integer. \end_layout \begin_layout Subsection Locators \end_layout \begin_layout LyX-Code \series bold long \series default offsetof(type, member); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter offsetof \end_layout \end_inset \begin_inset Newline newline \end_inset output_type \series bold * \series default containerof( \series bold input_type * \series default ptr, output_type, member); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter containerof \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold size_t \series default FIELD_SIZEOF(struct_type, member); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter FIELD_SIZEOF \end_layout \end_inset \begin_inset Newline newline \end_inset output_type HXtypeof_member(struct_type, member); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXtypeof_member \end_layout \end_inset \end_layout \begin_layout Standard In case \family typewriter offsetof \family default and \family typewriter containerof \family default have not already defined by inclusion of another header file, libHX's defs.h will define these accessors. \family typewriter offsetof \family default is defined in \family typewriter stddef.h \family default (for C) or \family typewriter cstddef \family default (C++), but inclusion of these is not necessary if you have included \family typewriter defs.h \family default . \family typewriter defs.h \family default will use GCC's \family typewriter __builtin_\SpecialChar softhyphen offsetof \family default if available, which does some extra sanity checks in C++ mode. \end_layout \begin_layout Standard \family typewriter offsetof \family default calculates the offset of the specified member in the type, which needs to be a struct or union. \end_layout \begin_layout Standard \family typewriter containerof \family default will return a pointer to the struct in which \family typewriter ptr \family default is contained as the given member. \end_layout \begin_layout LyX-Code \series bold struct \series default foo { \begin_inset Newline newline \end_inset \series bold int \series default bar; \begin_inset Newline newline \end_inset \series bold int \series default baz; \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static void \series default test( \series bold int * \series default ptr) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold struct \series default foo \series bold * \series default self = containerof(baz, \series bold struct \series default foo, baz); \begin_inset Newline newline \end_inset } \end_layout \begin_layout Standard \family typewriter FIELD_SIZEOF \family default (formerly \family typewriter HXsizeof_member \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXsizeof_member \end_layout \end_inset ) and \family typewriter HXtypeof_member \family default are convenient shortcuts to get the size or type of a named member in a given struct: \end_layout \begin_layout LyX-Code \series bold char \series default padding[FIELD_SIZEOF( \series bold struct \series default foo, baz)]; \end_layout \begin_layout Subsection Array size \end_layout \begin_layout LyX-Code \series bold size_t \series default ARRAY_SIZE( \series bold type \series default array \series bold [] \series default ); \series bold /* \family roman \series default \shape italic implemented as a macro \family default \series bold \shape default */ \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter ARRAY_SIZE \end_layout \end_inset \end_layout \begin_layout Standard Returns the number of elements in \family typewriter array \family default . This only works with true arrays ( \family typewriter type[] \family default ), and will not output a meaningful value when used with a pointer-to-element ( \family typewriter type \begin_inset space ~ \end_inset * \family default ), which is often used for array access too. \end_layout \begin_layout Subsection Compile-time build checks \end_layout \begin_layout LyX-Code \series bold int \series default BUILD_BUG_ON_EXPR( \series bold bool \series default condition); \series bold /* \family roman \series default \shape italic implemented as a macro \family default \series bold \shape default */ \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter BUILD_BUG_ON_EXPR \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default BUILD_BUG_ON( \series bold bool \series default condition); \series bold /* \family roman \series default \shape italic implemented as a macro \family default \series bold \shape default */ \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter BUILD_BUG_ON \end_layout \end_inset \end_layout \begin_layout Standard Causes the compiler to fail when \family typewriter condition \family default evaluates to true. If not implemented for a compiler, it will be a no-op. \family typewriter BUILD_BUG_ON \family default is meant to be used as a standalone statement, while \family typewriter BUILD_\SpecialChar softhyphen BUG_\SpecialChar softhyphen ON_\SpecialChar softhyphen EXPR \family default is for when a check is to occur within an expression, that latter of which is useful for within macros when one cannot, or does not want to use multiple statements. \end_layout \begin_layout LyX-Code type DEMOTE_TO_PTR(type expr); \series bold /* \family roman \series default \shape italic macro \family default \series bold \shape default */ \end_layout \begin_layout Standard Changes the type of expr to pointer type: If \family typewriter expr \family default of array type class, changes it to a pointer to the first element. If \family typewriter expr \family default of function type class, changes it to a pointer to the function. \end_layout \begin_layout LyX-Code \series bold int \series default main( \series bold void \series default ); \begin_inset Newline newline \end_inset \series bold int (* \series default fp \series bold ) \series default ( \series bold void \series default ); \begin_inset Newline newline \end_inset \series bold char \series default a \series bold [ \series default 123 \series bold ] \series default ; \begin_inset Newline newline \end_inset DEMOTE_TO_PTR(main); \series bold /* \family roman \series default \shape italic yields \series bold int (*) \series default ( \series bold void \series default ); \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset DEMOTE_TO_PTR(fp); \series bold /* \series default also yields \family roman \series bold \shape italic int (*) \series default ( \series bold void \series default ); \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset DEMOTE_TO_PTR(a); \series bold /* \series default yields \family roman \series bold \shape italic char * \family default \shape default */ \end_layout \begin_layout Subsection UNIX file modes \end_layout \begin_layout LyX-Code \series bold #define \series default S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter S_IRUGO \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold #define \series default S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter S_IWUGO \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold #define \series default S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter S_IXUGO \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold #define \series default S_IRWXUGO (S_IRUGO | S_IWUGO | S_IXUGO) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter S_IRWXUGO \end_layout \end_inset \end_layout \begin_layout Standard The defines make it vastly easier to specify permissions for large group of users. For example, if one wanted to create a file with the permissions \family typewriter rw-r--r-- \family default (ignoring the umask in this description), \family typewriter S_IRUSR \begin_inset space ~ \end_inset | S_IWUSR \family default can now be used instead of the longer \family typewriter S_IRUSR \begin_inset space ~ \end_inset | S_IWUSR \begin_inset space ~ \end_inset | S_IRGRP \begin_inset space ~ \end_inset | S_IROTH \family default . \end_layout \begin_layout Subsection VC runtime format specifiers \end_layout \begin_layout Standard The Microsoft Visual C runtime (a weak libc) uses non-standard format specifiers for certain types. Whereas C99 specifies \begin_inset Quotes eld \end_inset z \begin_inset Quotes erd \end_inset for \family typewriter size_t \family default and \begin_inset Quotes eld \end_inset ll \begin_inset Quotes erd \end_inset for long long, MSVCRT users must use \begin_inset Quotes eld \end_inset I \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset I64 \begin_inset Quotes erd \end_inset (forming \family typewriter %Id \family default instead of \family typewriter %zd \family default for \family typewriter ssize_t \family default , for example). libHX provides two convenience macros for this: \end_layout \begin_layout LyX-Code \series bold #define \series default HX_SIZET_FMT "z" \family roman \shape italic or \family default \shape default "I" \begin_inset Index idx status open \begin_layout Plain Layout HX_SIZET_FMT \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold #define \series default HX_LONGLONG_FMT "ll" \family roman \shape italic or \family default \shape default "I64" \begin_inset Index idx status open \begin_layout Plain Layout HX_LONGLONG_FMT \end_layout \end_inset \end_layout \begin_layout Standard These may be used together with printf or scanf: \end_layout \begin_layout LyX-Code printf("struct timespec is of size %" HX_SIZET_FMT "u \backslash n", \begin_inset Newline newline \end_inset \series bold sizeof \series default (struct timespec)); \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Miscellaneous functions \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/misc.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_ffs( \series bold unsigned long \series default z); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_ffs \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_fls( \series bold unsigned long \series default z); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_fls \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HX_hexdump( \series bold FILE * \series default fp, \series bold const void * \series default ptr, \series bold unsigned int \series default len); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_hexdump \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HX_zvecfree( \series bold char ** \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_zvecfree \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold unsigned int \series default HX_zveclen( \series bold const char *const * \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_zveclen \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HX_ffs \family default Finds the first (lowest-significant) bit in a value and returns its position, or -1 to indicate failure. \end_layout \begin_layout Description \family typewriter HX_fls \family default Finds the last (most-significant) bit in a value and returns its position, or -1 to indicate failure. \end_layout \begin_layout Description \family typewriter HX_hexdump \family default Outputs a nice pretty-printed hex and ASCII dump to the filedescriptor \family typewriter fp \family default . \family typewriter ptr \family default is the memory area, of which \family typewriter len \family default bytes will be dumped. \end_layout \begin_layout Description \family typewriter HX_zvecfree \family default Frees the supplied Z-vector array. (Frees all array elements from the first element to (excluding) the first \family typewriter NULL \family default element.) \end_layout \begin_layout Description \family typewriter HX_zveclen \family default Counts the number of array elements until the first \family typewriter NULL \family default array element is seen, and returns this number. \end_layout \begin_layout Section Time functions \end_layout \begin_layout Standard Time in POSIX systems is represented in \family typewriter struct timespec \family default . This structure is composed of two members: one integer for the number of full seconds in the time value, and one integer for the number of nanoseconds that remain when subtracting the full seconds from the time value. POSIX leaves it unspecified how negative time is to be represented with this structure, so I have devised an algebra for use with the same struct that gives negative time support. \end_layout \begin_layout Standard Since integers often cannot store negative zero (due to e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset use of 2s complements in the language implementation), we will store the minus sign in the nanosecond member if the integral second part is zero. This gives us the property that we can test for negative time by looking for whether at least one member of the structure is negative. Also, we want to avoid storing the minus in both members to somewhat aid the pretty-printing construct often seen, \end_layout \begin_layout LyX-Code printf("%ld.%09ld \backslash n", (long)ts.tv_sec, ts.tv_nsec); \end_layout \begin_layout Standard The number of combinations of a (non-zero) negative number, zero and a (non-zero ) positive number is small, so we can actually just exhaustively list them all. \begin_inset Separator latexpar \end_inset \end_layout \begin_layout Standard \noindent \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Representation \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Time value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout R \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout T \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout R \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout T \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\left\{ -1,-1\right\} $ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout illegal \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\left\{ 0,-1\right\} $ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout -0.1 \begin_inset space \thinspace{} \end_inset s \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\left\{ 1,-1\right\} $ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout illegal \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\left\{ -1,0\right\} $ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout -1.0 \begin_inset space \thinspace{} \end_inset s \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\left\{ 0,0\right\} $ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0.0 \begin_inset space \thinspace{} \end_inset s \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\left\{ 1,0\right\} $ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.0 \begin_inset space \thinspace{} \end_inset s \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\left\{ -1,1\right\} $ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout -1.1 \begin_inset space \thinspace{} \end_inset s \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\left\{ 0,1\right\} $ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0.1 \begin_inset space \thinspace{} \end_inset s \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Formula $\left\{ 1,1\right\} $ \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1.1 \begin_inset space \thinspace{} \end_inset s \end_layout \end_inset \end_inset \end_layout \begin_layout Standard The set of so-extended valid timespecs is therefore: \end_layout \begin_layout Standard \begin_inset Formula \[ K=\left\{ \left(i,f\right):i,f\in\mathbb{Z}\wedge i\neq0\wedge0\leq f<10^{9}\right\} \cup\left\{ \left(i,f\right):i=0\wedge f\in\mathbb{Z}\wedge-10^{9} \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HX_timespec_isneg( \series bold const struct \series default timespec \series bold * \series default p); \begin_inset Index idx status open \begin_layout Plain Layout HX_timespec_isneg \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default timespec \series bold * \series default HX_timespec_neg( \series bold struct \series default timespec \series bold * \series default result, \begin_inset Newline newline \end_inset \series bold const struct \series default timespec \series bold * \series default p); \begin_inset Index idx status open \begin_layout Plain Layout HX_timespec_neg \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default timespec \series bold * \series default HX_timespec_add( \series bold struct \series default timespec \series bold * \series default result, \begin_inset Newline newline \end_inset \series bold const struct \series default timespec \series bold * \series default p, \series bold const struct \series default timespec \series bold * \series default q); \begin_inset Index idx status open \begin_layout Plain Layout HX_timespec_add \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default timespec \series bold * \series default HX_timespec_sub( \series bold struct \series default timespec \series bold * \series default delta, \begin_inset Newline newline \end_inset \series bold const struct \series default timespec \series bold * \series default p, \series bold const struct \series default timespec \series bold * \series default q); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_timespec_sub \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default timespec \series bold * \series default HX_timespec_mul( \series bold struct \series default timespec \series bold * \series default delta, \begin_inset Newline newline \end_inset \series bold const struct \series default timespec \series bold * \series default p, \series bold int \series default f); \begin_inset Index idx status open \begin_layout Plain Layout HX_timespec_mul \end_layout \end_inset \end_layout \begin_layout LyX-Code \series bold struct \series default timespec \series bold * \series default HX_timespec_mulf( \series bold struct \series default timespec \series bold * \series default delta, \begin_inset Newline newline \end_inset \series bold const struct \series default timespec \series bold * \series default p, \series bold double \series default f); \begin_inset Index idx status open \begin_layout Plain Layout HX_timespec_mulf \end_layout \end_inset \end_layout \begin_layout LyX-Code \series bold struct \series default timeval \series bold * \series default HX_timeval_sub( \series bold struct \series default timeval \series bold * \series default delta, \begin_inset Newline newline \end_inset \series bold const struct \series default timeval \series bold * \series default p, \series bold const struct \series default timeval \series bold * \series default q); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_timeval_sub \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_time_compare( \series bold const struct \series default stat \series bold * \series default a, \series bold const struct \series default stat \series bold * \series default b, \series bold int \series default mode); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_time_compare \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HX_timespec_isneg \family default Determines whether a timespec structure represents (non-zero) negative time. \end_layout \begin_layout Description \family typewriter HX_timespec_neg \family default Computes the negation of the time specified by \family typewriter p \family default . \family typewriter result \family default and \family typewriter p \family default may point to the same structure. \end_layout \begin_layout Description \family typewriter HX_timespec_add \family default Calculates the sum of the two times specified by \family typewriter p \family default and \family typewriter q \family default , which are of type \family typewriter struct timespec \family default . Any of \family typewriter result \family default , \family typewriter p \family default and \family typewriter q \family default may point to the same structure. \end_layout \begin_layout Description \family typewriter HX_timespec_sub \family default Calculates the difference between the two timepoints p and q, which are of type \family typewriter struct timespec \family default (nanosecond granularity). \end_layout \begin_layout Description \family typewriter HX_timespec_mul \family default Multiplies the time quantum in \family typewriter p \family default by \family typewriter f \family default . \end_layout \begin_layout Description \family typewriter HX_timespec_mulf \family default Multiplies the time quantum in \family typewriter p \family default by \family typewriter f \family default . \end_layout \begin_layout Description \family typewriter HX_timeval_sub \family default Calculates the difference between the two timepoints p and q, which are of type \family typewriter struct timeval \family default (microsecnod granularity). \end_layout \begin_layout Description \family typewriter HX_time_compare \family default Compares the timestamps from two \family typewriter struct stat \family default s. \family typewriter mode \family default indicates which field is compared, which can either be \family typewriter 'a' \family default for the access time, \family typewriter 'c' \family default for the inode change time, \family typewriter 'm' \family default for the modification time, or \family typewriter 'o' \family default for the creation time (where available). Returns a negative number if the time in \family typewriter a \family default is less than \family typewriter b \family default , zero when they are equal, or a positive number greater than zero if \family typewriter a \family default is greater than \family typewriter b \family default . \end_layout \begin_layout Standard The macros \family typewriter HX_TIMESPEC_FMT \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_TIMESPEC_FMT \end_layout \end_inset and \family typewriter HX_TIMESPEC_EXP \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_TIMESPEC_EXP \end_layout \end_inset can be used for passing and printing a \family typewriter struct timespec \family default using the * \family typewriter printf \family default function family: \end_layout \begin_layout LyX-Code \series bold struct \series default timespec p; \begin_inset Newline newline \end_inset clock_gettime(CLOCK_MONOTONIC, &p); \begin_inset Newline newline \end_inset printf("Now: " HX_TIMESPEC_FMT, HX_TIMESPEC_EXP(&p)); \end_layout \begin_layout Standard Similarly, \family typewriter HX_TIMEVAL_FMT \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_TIMEVAL_FMT \end_layout \end_inset and \family typewriter HX_TIMEVAL_EXP \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_TIMEVAL_EXP \end_layout \end_inset exist for the older \family typewriter struct timeval \family default . \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Bitmaps \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold size_t \series default HXbitmap_size( \series bold type \series default array, \series bold unsigned int \series default bits); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXbitmap_size \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXbitmap_set( \series bold type * \series default bmap, \series bold unsigned int \series default bit); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXbitmap_set \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXbitmap_clear( \series bold type * \series default bmap, \series bold unsigned int \series default bit); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXbitmap_clear \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HXbitmap_test( \series bold type * \series default bmap, \series bold unsigned int \series default bit); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXbitmap_test \end_layout \end_inset \end_layout \begin_layout Standard All of these four are implemented as macros, so they can be used with any integer type that is desired to be used. \end_layout \begin_layout Description \family typewriter HXbitmap_size \family default Returns the amount of \begin_inset Quotes eld \end_inset type \begin_inset Quotes erd \end_inset -based integers that would be needed to hold an array of the requested amount of bits. \end_layout \begin_layout Description \family typewriter HXbitmap_set \family default Set the specific bit in the bitmap. \end_layout \begin_layout Description \family typewriter HXbitmap_clear \family default Clear the specific bit in this bitmap. \end_layout \begin_layout Description \family typewriter HXbitmap_test \family default Test for the specific bit and returns \family typewriter true \family default if it is set, otherwise \family typewriter false \family default . \end_layout \begin_layout Subsubsection Example \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default main( \series bold void \series default ) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold unsigned long \series default bitmap \series bold [ \series default HXbitmap_size( \series bold unsigned long \series default , 128) \series bold ] \series default ; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset memset(bitmap, 0, sizeof(bitmap)); \begin_inset Newline newline \end_inset HXbitmap_set(bitmap, 49); \begin_inset Newline newline \end_inset \series bold return \series default HXbitmap_get(bitmap, HX_irand(0, 128)) ? \begin_inset Newline newline \end_inset EXIT_SUCCESS : EXIT_FAILURE; \begin_inset Newline newline \end_inset } \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Part Data structures \end_layout \begin_layout Section Maps \begin_inset CommandInset label LatexCommand label name "sec:maps" \end_inset \end_layout \begin_layout Standard A map is a collection of key-value pairs. (Some languages, such as Perl, also call them \begin_inset Quotes eld \end_inset associative array \begin_inset Quotes erd \end_inset or just \begin_inset Quotes eld \end_inset hash \begin_inset Quotes erd \end_inset , however, the underlying storage mechanism may not be an array or a hash, however.) Each key is unique and has an associated value. Keys can be any data desired; HXmap allows to specify your own key and data handling functions so they can be strings, raw pointers, or complex structures. \end_layout \begin_layout Standard To access any map-related functions, \family typewriter #include \family default . \end_layout \begin_layout Subsection Structural definition \begin_inset CommandInset label LatexCommand label name "subsec:maps-def" \end_inset \end_layout \begin_layout Standard The \family typewriter HXmap \family default structure is a near-opaque type. Unlike the predecessor map implementation \family typewriter struct HXbtree \family default from libHX 2.x, the 3.x API exposes much less fields. \end_layout \begin_layout LyX-Code \series bold struct \series default HXmap { \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter struct HXmap \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold unsigned int \series default items, flags; \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Description \family typewriter items \family default The number of items in the tree. This field tracks the number of items in the map and is used to report the number of elements to the user, and is updated whenever an element is inserted or removed from the map. The field must not be changed by user. \end_layout \begin_layout Description \family typewriter flags \family default The current behavior flags for the map. While implementation-private bits are exposed, only \family typewriter HXMAP_NOREPLACE \family default is currently allowed to be (un)set by the developer while a map exists. \end_layout \begin_layout Standard For retrieving elements from a tree, some functions work with \family typewriter struct HXmap_node \family default , which is defined as follows: \end_layout \begin_layout LyX-Code \series bold struct \series default HXmap_node { \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter struct HXmap_node \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold union \series default { \begin_inset Newline newline \end_inset \series bold void * \series default key; \begin_inset Newline newline \end_inset \series bold const char *const \series default skey; \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \series bold union \series default { \begin_inset Newline newline \end_inset \series bold void * \series default data; \begin_inset Newline newline \end_inset \series bold char * \series default sdata; \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Description \family typewriter key \family default The so-called primary key, which uniquely identifies an element (a key-value pair) in the map. The memory portions that make up the key must not be modified. (If the key changes, so does its hash value and/or position index, and without taking that into account, writing to the key directly is going to end up with an inconsistent state. To change the key, you will need to delete the element and reinsert it with its new key.) \end_layout \begin_layout Description \family typewriter skey \family default A convenience type field for when the map's keys are C strings. It is useful for use with e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset \family typewriter printf \family default or other varargs function, which would otherwise require casting of the \family typewriter void \begin_inset space ~ \end_inset *key \family default member to \family typewriter const char \begin_inset space ~ \end_inset * \family default first. \end_layout \begin_layout Description \family typewriter data \family default The data associated with the key. \end_layout \begin_layout Description \family typewriter sdata \family default Convenience type field. \end_layout \begin_layout Subsection Map initialization \end_layout \begin_layout Standard During initialization, you specify the underlying storage type by selecting a given constructor function. All further operations are done through the unified HXmap API which uses a form of virtual calls internally. \end_layout \begin_layout Standard Currently, there are two distinct map types in libHX. There are a handful of selectable symbols, though. Abstract types are: \end_layout \begin_layout Description \family typewriter HXMAPT_DEFAULT \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAPT_DEFAULT \end_layout \end_inset No further preferences or guarantees; selects any map type that the libHX maintainer deemed fast. \end_layout \begin_layout Description \family typewriter HXMAPT_ORDERED \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAPT_ORDERED \end_layout \end_inset The map shall use a data structure that provides ordered traversal. \end_layout \begin_layout Standard Specific types include: \end_layout \begin_layout Description \family typewriter HXMAPT_HASH \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_MAPT_HASH \end_layout \end_inset Hash-based map \begin_inset space ~ \end_inset – Amortized \begin_inset Formula $\mathcal{O}\left(1\right)$ \end_inset insertion, lookup and deletion; unordered. \end_layout \begin_layout Description \family typewriter HXMAPT_RBTREE \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_MAPT_RBTREE \end_layout \end_inset Red-black binary tree \begin_inset space ~ \end_inset – \begin_inset Formula $\mathcal{O}\left(\log\left(n\right)\right)$ \end_inset insertion, lookup and deletion; ordered. \end_layout \begin_layout Standard These can then be used with the initialization functions: \end_layout \begin_layout LyX-Code \series bold struct \series default HXmap \series bold * \series default HXmap_init( \series bold unsigned int \series default type, \series bold unsigned int \series default flags); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_init \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXmap \series bold * \series default HXmap_init5( \series bold unsigned int \series default type, \series bold unsigned int \series default flags, \begin_inset Newline newline \end_inset \series bold const struct \series default HXmap_ops \series bold * \series default ops, \series bold size_t \series default key_size, \series bold size_t \series default data_size); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_init5 \end_layout \end_inset \end_layout \begin_layout Standard Both the \family typewriter *_init \family default and \family typewriter *_init5 \family default variant creates a new map; the latter function allows to specify the operations in detail as well as key and data size, which may become necessary when using data sets which have their own way of being managed. The \family typewriter flags \family default parameter can contain any of the following: \end_layout \begin_layout Description \family typewriter HXMAP_NONE \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_NONE \end_layout \end_inset This is just a mnemonic for the value 0, indicating no flags. \end_layout \begin_layout Description \family typewriter HXMAP_NOREPLACE \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_NOREPLACE \end_layout \end_inset If a key already exists and another add operation is attempted, the key's associated value will be replaced by the new value. If this flag is absent, \family typewriter -EEXIST \family default is returned. This flag is allowed to be subsequently changed by the developer if so desired, using bit logic such as \family typewriter map->flags &= ~HXMAP_NOREPLACE; \family default . \end_layout \begin_layout Description \family typewriter HXMAP_SKEY \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_SKEY \end_layout \end_inset Notifies the constructor that keys will be C-style strings. The flag presets the \family typewriter k_compare \family default operation to use \family typewriter strcmp \family default . In the flag's absence, direct value comparison will be used if the key size is specified as zero (e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset with the \family typewriter HXhashmap_\SpecialChar softhyphen init4 \family default function call), or \family typewriter memcmp \family default if the key size is non-zero. \end_layout \begin_layout Description \family typewriter HXMAP_CKEY \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_CKEY \end_layout \end_inset Instructs the map to make copies of keys when they are added to the map. This is required when the buffer holding the key changes or goes out of scope. The flag presets the \family typewriter k_clone \family default and \family typewriter k_free \family default operations to \family typewriter HX_memdup \family default and \family typewriter free \family default , and as such, the \family typewriter key_size \family default parameter must not be zero. If however, \family typewriter HXMAP_SKEY \family default is also specified, \family typewriter HX_strdup \family default and \family typewriter free \family default will be used and \family typewriter key_size \family default must be zero. \end_layout \begin_layout Description \family typewriter HXMAP_SDATA \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_SDATA \end_layout \end_inset Notifies the constructor that data will be C-style strings. This sets up the \family typewriter d_clone \family default and \family typewriter d_free \family default operations. \end_layout \begin_layout Description \family typewriter HXMAP_CDATA \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_CDATA \end_layout \end_inset Instructs the map to make copies of the data when new entries are added to the map. This is required when the buffer holding the data either goes out of scope, or you want to keep the original contents instead of just a pointer. \end_layout \begin_layout Description \family typewriter HXMAP_SCKEY \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_SCKEY \end_layout \end_inset Mnemonic for the combination of \family typewriter HXMAP_\SpecialChar softhyphen SKEY \family default OR'ed with \family typewriter HXMAP_\SpecialChar softhyphen CKEY \family default . \end_layout \begin_layout Description \family typewriter HXMAP_SCDATA \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_SCDATA \end_layout \end_inset Mnemonic for the combination of \family typewriter HXMAP_\SpecialChar softhyphen SDATA \family default OR'ed with \family typewriter HXMAP_\SpecialChar softhyphen SDATA \family default . \end_layout \begin_layout Description \family typewriter HXMAP_SINGULAR \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_SINGULAR \end_layout \end_inset Specifies that the \begin_inset Quotes eld \end_inset map \begin_inset Quotes erd \end_inset is only used as a set, i. \begin_inset space \thinspace{} \end_inset e. \begin_inset space \space{} \end_inset it does not store any values, only keys. Henceforth, the \family typewriter value \family default argument to \family typewriter HXmap_add \family default must always be \family typewriter NULL \family default . \end_layout \begin_layout Subsection Flag combinations \end_layout \begin_layout Standard This subsection highlights the way \family typewriter HXMAP_SKEY \family default interacts with \family typewriter HXMAP_CKEY \family default and the key size. The copy semantics are the same for \family typewriter HXMAP_SDATA \family default and \family typewriter HXMAP_CDATA \family default . \end_layout \begin_layout Subsubsection* \family typewriter HXMAP_SKEY \family default is unset, \family typewriter HXMAP_CKEY \family default is unset \end_layout \begin_layout Standard The \family typewriter key_size \family default parameter at the time of map construction is ignored. The pointer value of the \family typewriter key \family default parameter for the \family typewriter HXmap_add \family default call is directly stored in the tree, and this is the key that uniquely identifies the map entry and which is used for comparisons. This may be used if you intend to directly map pointer values. \end_layout \begin_layout LyX-Code static struct something *x = ..., *y = ...; \begin_inset Newline newline \end_inset HXmap_add(map, &x[0], "foo"); \begin_inset Newline newline \end_inset HXmap_add(map, &x[1], "bar"); \end_layout \begin_layout Subsubsection* \family typewriter HXMAP_SKEY \family default is set, \family typewriter HXMAP_CKEY \family default is unset \end_layout \begin_layout Standard The \family typewriter key_size \family default parameter at the time of map construction is ignored. The pointer value of the \family typewriter key \family default parameter for the \family typewriter HXmap_add \family default call is directly stored in the tree, but it is the C string \shape italic pointed to \shape default by the \family typewriter key \family default parameter that serves as the key. \end_layout \begin_layout Subsubsection* \family typewriter HXMAP_SKEY \family default is set, \family typewriter HXMAP_CKEY \family default is set \end_layout \begin_layout Standard The \family typewriter key_size \family default parameter at the time of map construction is ignored. The string pointed to by the key parameter will be duplicated, and the resulting pointer will be stored in the tree. Again, it is the pointed-to string that is the key. \end_layout \begin_layout Subsubsection* \family typewriter HXMAP_SKEY \family default is unset, \family typewriter HXMAP_CKEY \family default is set \end_layout \begin_layout Standard The memory block pointed to by the key parameter will be duplicated. The \family typewriter key_size \family default parameter must be non-zero for this to successfully work. \end_layout \begin_layout Subsubsection* With separate ops \end_layout \begin_layout Standard However, when a custom \family typewriter struct HXmap_ops \family default is provided in the call to \family typewriter HXmap_init5 \family default , any of these semantics can be overridden. Particularly, since your own ops can practically ignore \family typewriter key_size \family default , it could be set to any value. \end_layout \begin_layout Subsection Key-data operations \end_layout \begin_layout Standard The \family typewriter HXMAP_SKEY \family default \SpecialChar breakableslash \family typewriter CKEY \family default \SpecialChar breakableslash \family typewriter SDATA \family default \SpecialChar breakableslash \family typewriter CDATA \family default flags are generally sufficient to set up common maps where keys and/or data are C strings or simple binary data where \family typewriter memdup \family default / \family typewriter memcmp \family default is enough. Where the provided mechanisms are not cutting it, an extra \family typewriter HXmap_ops \family default structure with functions specialized in handling the keys and/or data has to be used as an argument to the initialization function call. \end_layout \begin_layout LyX-Code \series bold struct \series default HXmap_ops { \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter struct HXmap_ops \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int (* \series default k_compare \series bold ) \series default ( \series bold const void * \series default , \series bold const void * \series default , \series bold size_t \series default ); \begin_inset Newline newline \end_inset \series bold void *(* \series default k_clone \series bold ) \series default ( \series bold const void * \series default , \series bold size_t \series default ); \begin_inset Newline newline \end_inset \series bold void (* \series default k_free \series bold ) \series default ( \series bold void * \series default ); \begin_inset Newline newline \end_inset \series bold void *(* \series default d_clone \series bold ) \series default ( \series bold const void * \series default , \series bold size_t \series default ); \begin_inset Newline newline \end_inset \series bold void (* \series default d_free \series bold ) \series default ( \series bold void * \series default ); \begin_inset Newline newline \end_inset \series bold unsigned long (* \series default k_hash \series bold ) \series default ( \series bold const void * \series default , \series bold size_t \series default ); \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Description \family typewriter k_compare \family default Function to compare two keys. The return value is the same as that of \family typewriter memcmp \family default or \family typewriter strcmp \family default : negative values indicate that the first key is \begin_inset Quotes eld \end_inset less than \begin_inset Quotes erd \end_inset the second, zero indicates that both keys are equal, and positive values indicate that the first key is \begin_inset Quotes eld \end_inset greater than \begin_inset Quotes erd \end_inset the second. The size argument in third position is provided so that \family typewriter memcmp \family default , which wants a size parameter, can directly be used without having to write an own function. \end_layout \begin_layout Description \family typewriter k_clone \family default Function that will clone (duplicate) a key. This is used for keys that will be added to the tree, and potentially also for state-keeping during traversal of the map. It is valid that this clone function simply returns the value of the pointer it was actually passed; this is used by default for maps without \family typewriter HXMAP_CKEY \family default for example. \end_layout \begin_layout Description \family typewriter k_free \family default Function to free a key. In most cases it defaults to \family typewriter free \family default (3), but in case you are using complex structs, more cleanup may be needed. \end_layout \begin_layout Description \family typewriter d_clone \family default Same as \family typewriter k_clone \family default , but for data. \end_layout \begin_layout Description \family typewriter d_free \family default Same as \family typewriter k_free \family default , but for data. \end_layout \begin_layout Description \family typewriter k_hash \family default Specifies an alternate hash function. Only to be used with hash-based maps. Hashmaps default to using the DJB2 string hash function when \family typewriter HXMAP_SKEY \family default is given, or otherwise the Jenkins' lookup3 hash function. \end_layout \begin_layout Standard libHX exports two hash functions that you can select for \family typewriter struct HXmap_ops \family default 's \family typewriter k_hash \family default if the default for a given flag combination is not to your liking. \end_layout \begin_layout Description \family typewriter HXhash_jlookup3 \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXhash_jlookup3 \end_layout \end_inset Bob Jenkins's lookup3 hash. \end_layout \begin_layout Description \family typewriter HXhash_djb2 \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXhash_djb2 \end_layout \end_inset DJB2 string hash. \end_layout \begin_layout Subsection Map operations \end_layout \begin_layout LyX-Code \series bold int \series default HXmap_add( \series bold struct \series default HXmap \series bold * \series default , \series bold const void * \series default key, \series bold const void * \series default value); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_add \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold const struct \series default HXmap_node \series bold * \series default HXmap_find( \series bold const struct \series default HXmap \series bold * \series default , \series bold const void * \series default key); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_find \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void * \series default HXmap_get( \series bold const struct \series default HXmap \series bold * \series default , \series bold const void * \series default key); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_get \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void * \series default HXmap_del( \series bold struct \series default HXmap \series bold * \series default , \series bold const void * \series default key); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_del \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXmap_free( \series bold struct \series default HXmap \series bold * \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_free \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXmap_node \series bold * \series default HXmap_keysvalues( \series bold const struct \series default HXmap \series bold * \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_keysvalues \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HXmap_add \family default \family typewriter A \family default dds a new node to the tree using the given key and data. When an element is in the map, the key may not be modified, as doing so could possibly invalidate the internal location of the element, or its ordering with respect to other elements. If you need to change the key, you will have to delete the element from the tree and re-insert it. On error, \family typewriter -errno \family default will be returned. \begin_inset Newline newline \end_inset When \family typewriter HXMAP_SINGULAR \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_SINGULAR \end_layout \end_inset is in effect, \family typewriter value \family default must be \family typewriter NULL \family default , or \family typewriter -EINVAL \family default is returned. \end_layout \begin_layout Description \family typewriter HXmap_find \family default Finds the node for the given key. The key can be read from the node using \family typewriter node->key \family default or \family typewriter node->skey \family default (convenience alias for \family typewriter key \family default , but with a type of \family typewriter const char \begin_inset space ~ \end_inset * \family default ), and the data by using \family typewriter node->data \family default or \family typewriter node->sdata \family default . (see section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:maps-def" \end_inset ). \end_layout \begin_layout Description \family typewriter HXmap_get \family default Get is a find operation directly returning \family typewriter node->data \family default instead of the node itself. Since \family typewriter HXmap_get \family default may legitimately return \family typewriter NULL \family default if \family typewriter NULL \family default was stored in the tree as the data for a given key, only \family typewriter errno \family default will really tell whether the node was found or not; in the latter case, \family typewriter errno \family default is set to \family typewriter ENOENT \family default . \end_layout \begin_layout Description \family typewriter HXmap_del \family default Removes an element from the map and returns the data value that was associated with it. When an error occurred, or the element was not found, \family typewriter NULL \family default is returned. Because \family typewriter NULL \family default can be a valid data value, \family typewriter errno \family default can be checked for non-zero. \family typewriter errno \family default will be \family typewriter -ENOENT \family default if the element was not found, or zero when everything was ok. \end_layout \begin_layout Description \family typewriter HXmap_free \family default The function will delete all elements in the map and free memory it holds. \end_layout \begin_layout Description \family typewriter HXmap_keysvalues \family default Returns all key-value-pairs in an array of the size as many items were in the map ( \family typewriter map->items \family default ) at the time it was called. The memory must be freed using \family typewriter free \family default (3) when it is no longer needed. The order elements in the array follows the traverser notes (see below), unless otherwise specified. \end_layout \begin_layout Subsection Map traversal \end_layout \begin_layout LyX-Code \series bold struct \series default HXmap_trav \series bold * \series default HXmap_travinit( \series bold const struct \series default HXmap \series bold * \series default ); \begin_inset Newline newline \end_inset \series bold const struct \series default HXmap_node \series bold * \series default HXmap_traverse( \series bold struct \series default HXmap_trav \series bold * \series default iterator); \begin_inset Newline newline \end_inset \series bold void \series default HXmap_travfree( \series bold struct \series default HXmap_trav \series bold * \series default iterator); \begin_inset Newline newline \end_inset \series bold void \series default HXmap_qfe( \series bold const struct \series default HXmap \series bold * \series default , \series bold bool (* \series default fn \series bold ) \series default ( \series bold const struct \series default HXmap_node \series bold * \series default , \begin_inset Newline newline \end_inset \series bold void * \series default arg), \series bold void * \series default arg); \end_layout \begin_layout Description \family typewriter HXmap_travinit \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_travinit \end_layout \end_inset Initializes a traverser (a. \begin_inset space \thinspace{} \end_inset k. \begin_inset space \thinspace{} \end_inset a. \begin_inset space \space{} \end_inset iterator) for the map, and returns a pointer to it. \family typewriter NULL \family default will be returned in case of an error, such as memory allocation failure. Traversers are returned even if the map has zero elements. \end_layout \begin_layout Description \family typewriter HXmap_traverse \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_traverse \end_layout \end_inset Returns a pointer to a \family typewriter struct HXmap_node \family default for the next element \begin_inset space ~ \end_inset \SpecialChar breakableslash key-value pair from the map, or \family typewriter NULL \family default if there are no more entries. \end_layout \begin_layout Description \family typewriter HXmap_travfree \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_travfree \end_layout \end_inset Release the memory associated with a traverser. \end_layout \begin_layout Description \family typewriter HXmap_qfe \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmap_qfe \end_layout \end_inset The \begin_inset Quotes eld \end_inset quick foreach \begin_inset Quotes erd \end_inset . Iterates over all map elements in the fastest possible manner, but has the restriction that no modifications to the map are allowed. Furthermore, a separate function to handle each visited node, is required. (Hence this is also called \begin_inset Quotes eld \end_inset closed traversal \begin_inset Quotes erd \end_inset , because one cannot access the stack frame of the original function which called \family typewriter HXmap_qfe \family default .) The user-defined function returns a bool which indicates whether traversal shall continue or not. \end_layout \begin_layout Standard Flags for \family typewriter HXmap_travinit \family default : \end_layout \begin_layout Description \family typewriter HXMAP_NOFLAGS \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_NOFLAGS \end_layout \end_inset A mnemonic for no flags, and is defined to be \family typewriter 0 \family default . \end_layout \begin_layout Description \family typewriter HXMAP_DTRAV \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXMAP_DTRAV \end_layout \end_inset Enable support for deletion during traversal. As it can make traversal slower, it needs to be explicitly specified for cases where it is needed, to not penalize cases where it is not. \end_layout \begin_layout Standard WARNING: Modifying the map while a traverser is active is implementation-specifi c behavior! libHX generally ensures that there will be no undefined behavior (e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset crashes), but there is no guarantee that elements will be returned exactly once. There are fundamental cases that one should be aware of: \end_layout \begin_layout Itemize An element is inserted before where the traverser is currently positioned at. The element may not be returned in subsequent calls to \family typewriter HXmap_traverse \family default on an already-active traverser. \end_layout \begin_layout Itemize Insertion or deletion may cause internal data structure to re-layout. \begin_inset Separator latexpar \end_inset \end_layout \begin_deeper \begin_layout Itemize Traversers of ordered data structures may choose to rebuild their state. \end_layout \begin_layout Itemize Traversers of unordered data structures would run risk to return more than once, or not at all. \end_layout \end_deeper \begin_layout Standard Descriptions for different map types follow. \end_layout \begin_layout Description Hashmaps On \family typewriter HXmap_add \family default , an element may be inserted in a position that is before where the traverser is currently positioned. Such elements will not be returned in the remaining calls to \family typewriter HXmap_traverse \family default . The insertion or deletion of an element may cause the internal data structure to re-layout itself. When this happens, the traverser will stop, so as to not return entries twice. \end_layout \begin_layout Description Binary \begin_inset space ~ \end_inset trees Elements may be added before the traverser's position. These elements will not be returned in subsequent traversion calls. If the data structure changes as a result of an addition or deletion, the traverser will rebuild its state and continue traversal transparently. Because elements in a binary tree are ordered, that is, element positions may not change with respect to another when the tree is rebalanced, there is no risk of returning entries more than once. Nor will elements that are sorted after the current traverser's position not be returned (= \begin_inset space ~ \end_inset they will be returned, because they cannot get reordered to before the traverser like in a hash map). The HX rbtree implementation also has proper handling for when the node which is currently visiting is deleted. \end_layout \begin_layout Subsection RB-tree Limitations \end_layout \begin_layout Standard The implementation has a theoretical minimum on the maximum number of nodes, \begin_inset Formula $2^{24}=16{,}777{,}216$ \end_inset . A worst-case tree with this many elements already has a height of 48 ( \family typewriter RBT_MAXDEP \family default ), which is the maximum height currently supported. The larger the height is that HXrbtree is supposed to handle, the more memory (linear increase) it needs. All functions that build or keep a path reserve memory for \family typewriter RBT_MAXDEP \family default nodes; on x86_64 this is 9 bytes per \begin_inset Formula $\langle$ \end_inset node, direction \begin_inset Formula $\rangle$ \end_inset pair, amounting to 432 bytes for path tracking alone. It may not sound like a lot to many, but given that kernel people can limit their stack usage to 4096 bytes is impressive alone \end_layout \begin_layout Standard \begin_inset Foot status open \begin_layout Plain Layout Not always of course. Linux kernels are often configured to use an 8K stack because some components still use a lot of stack space, but even 8K is still damn good. \end_layout \end_inset . \end_layout \begin_layout Subsection Examples \end_layout \begin_layout Subsubsection Case-insensitive ordering \end_layout \begin_layout Standard The correct way: \end_layout \begin_layout LyX-Code \series bold static int \series default my_strcasecmp( \series bold const void * \series default a, \series bold const void * \series default b, \series bold size_t \series default z) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold return \series default strcasecmp(a, b); \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static const struct \series default HXmap_ops icase = { \begin_inset Newline newline \end_inset .k_compare = my_strcasecmp, \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset HXmap_init5(HXMAPT_RBTREE, HXMAP_SKEY, &icase, 0, \shape italic dsize \shape default ); \end_layout \begin_layout Standard A hackish way (which wholly depends on the C implementation and use of extra safeguards is a must): \end_layout \begin_layout LyX-Code \series bold static const struct \series default HXmap_ops icase = { \begin_inset Newline newline \end_inset .k_compare = ( \series bold void * \series default )strcasecmp, \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset BUILD_BUG_ON( \series bold sizeof \series default (DEMOTE_TO_PTR(strcasecmp)) > \series bold sizeof \series default (void *)); \begin_inset Newline newline \end_inset BUILD_BUG_ON( \series bold sizeof \series default (DEMOTE_TO_PTR(strcasecmp)) > \series bold sizeof \series default (icase.k_compare)); \begin_inset Newline newline \end_inset HXmap_init5(HXMAPT_RBTREE, HXMAP_SKEY, &icase, 0, \shape italic dsize \shape default ); \end_layout \begin_layout Subsubsection Reverse sorting order \end_layout \begin_layout Standard Any function that behaves like \family typewriter strcmp \family default can be used. It merely has to return negative when \begin_inset Formula $ab$ \end_inset . \end_layout \begin_layout LyX-Code \series bold static int \series default strcmp_rev( \series bold const void * \series default a, \series bold const void * \series default b, \series bold size_t \series default z) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold /* \family roman \series default \shape italic z is provided for cases when things are raw memory blocks. \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset \series bold return \series default strcmp(b, a); \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static const struct \series default HXmap_ops rev = { \begin_inset Newline newline \end_inset .k_compare = strcmp_rev, \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset HXmap_init5(HXMAPT_RBTREE, HXMAP_SKEY, &rev, 0, \shape italic dsize \shape default ); \end_layout \begin_layout Subsubsection Keys with non-unique data \begin_inset CommandInset label LatexCommand label name "subsec:maps-examples-bigkey" \end_inset \end_layout \begin_layout Standard Keys can actually store non-unique data, as long as this extra fields does not actually contribute to the logical key \begin_inset space ~ \end_inset — the parts that do uniquely identify it. In the following example, the \family typewriter notes \family default member may be part of struct package, which is the key as far as HXmap is concerned, but still, only the name and versions are used to identify it. \end_layout \begin_layout LyX-Code \series bold struct \series default package { \begin_inset Newline newline \end_inset \series bold char * \series default name; \begin_inset Newline newline \end_inset \series bold unsigned int \series default major_version; \begin_inset Newline newline \end_inset \series bold unsigned int \series default minor_version; \begin_inset Newline newline \end_inset \series bold char \series default notes \series bold [ \series default 64 \series bold ] \series default ; \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static int \series default package_cmp( \series bold const void * \series default a, \series bold const void * \series default b) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold const struct \series default package \series bold * \series default p = a, \series bold * \series default q = b; \begin_inset Newline newline \end_inset \series bold int \series default ret; \begin_inset Newline newline \end_inset ret = strcmp(p->name, q->name); \begin_inset Newline newline \end_inset \series bold if \series default (ret != 0) \begin_inset Newline newline \end_inset \series bold return \series default ret; \begin_inset Newline newline \end_inset ret = p->major_version - q->major_version; \begin_inset Newline newline \end_inset \series bold if \series default (ret != 0) \begin_inset Newline newline \end_inset \series bold return \series default ret; \begin_inset Newline newline \end_inset ret = p->minor_version - q->minor_version; \begin_inset Newline newline \end_inset \series bold if \series default (ret != 0) \begin_inset Newline newline \end_inset \series bold return \series default ret; \begin_inset Newline newline \end_inset \series bold return \series default 0; \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static const struct \series default HXmap_ops package_ops = { \begin_inset Newline newline \end_inset .k_compare = package_cmp, \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset HXmap_init5(HXMAPT_RBTREE, \shape italic flags \shape default , &package_ops, \begin_inset Newline newline \end_inset \series bold sizeof \series default ( \series bold struct \series default package), \shape italic dsize \shape default ); \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Doubly-linked list \begin_inset CommandInset label LatexCommand label name "sec:deque" \end_inset \end_layout \begin_layout Standard HXdeque is a data structure for a doubly-linked non-circular \family typewriter NULL \family default -sentineled list. Despite being named a deque, which is short for double-ended queue, and which may be implemented using an array, HXdeque is in fact using a linked list to provide its deque functionality. Furthermore, a dedicated root structure and decidated node structures with indirect data referencing are used. \end_layout \begin_layout Subsection Structural definition \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/deque.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXdeque { \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter struct HXdeque \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXdeque_node \series bold * \series default first, \series bold * \series default last; \begin_inset Newline newline \end_inset \series bold unsigned int \series default items; \begin_inset Newline newline \end_inset \series bold void * \series default ptr; \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXdeque_node { \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter struct HXdeque_node \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXdeque_node \series bold * \series default next, \series bold * \series default prev; \begin_inset Newline newline \end_inset \series bold struct \series default HXdeque \series bold * \series default parent; \begin_inset Newline newline \end_inset \series bold void * \series default ptr; \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Standard The \family typewriter ptr \family default member in \family typewriter struct HXdeque \family default provides room for an arbitrary custom user-supplied pointer. \family typewriter items \family default will reflect the number of elements in the list, and must not be modified. \family typewriter first \family default and \family typewriter last \family default provide entrypoints to the list's ends. \end_layout \begin_layout Standard \family typewriter ptr \family default within \family typewriter struct HXdeque_node \family default is the pointer to the user's data. It may be modified and used at will by the user. See example section \begin_inset space ~ \end_inset . \end_layout \begin_layout Subsection Constructor, destructors \end_layout \begin_layout LyX-Code \series bold struct \series default HXdeque \series bold * \series default HXdeque_init( \series bold void \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_init \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXdeque_free( \series bold struct \series default HXdeque \series bold * \series default dq); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_free \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXdeque_genocide( \series bold struct \series default HXdeque \series bold * \series default dq); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_genocide \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXdeque_genocide2( \series bold struct \series default HXdeque \series bold * \series default dq, \series bold void (* \series default xfree \series bold ) \series default ( \series bold void * \series default )); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_genocide2 \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void ** \series default HXdeque_to_vec( \series bold struct \series default HXdeque \series bold * \series default dq, \series bold unsigned int * \series default num); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_to_vec \end_layout \end_inset \end_layout \begin_layout Standard To allocate a new empty list, use \family typewriter HXdeque_init \family default . \family typewriter HXdeque_free \family default will free the list (including all nodes owned by the list), but not the data pointers. \end_layout \begin_layout Standard \family typewriter HXdeque_genocide \family default is a variant that will not only destroy the list, but also calls a freeing function \family typewriter free() \family default on all stored data pointers. This puts a number of restrictions on the characteristics of the list: all data pointers must have been obtained with \family typewriter malloc \family default , \family typewriter calloc \family default or \family typewriter realloc \family default before, and no data pointer must exist twice in the list. The function is more efficient than an open-coded loop over all nodes calling \family typewriter HXdeque_del \family default . \end_layout \begin_layout Standard A generic variant is available with \family typewriter HXdeque_genocide2 \family default , which takes a pointer to an appropriate freeing function. \family typewriter HXdeque_genocide \family default is thus equivalent to \family typewriter HXdeque_genocide2(dq, free) \family default . \end_layout \begin_layout Standard To convert a linked list to a \family typewriter NULL \family default -terminated array, \family typewriter HXdeque_to_vec \family default can be used. If \family typewriter num \family default is not \family typewriter NULL \family default , the number of elements excluding the \family typewriter NULL \family default sentinel, is stored in \family typewriter *num \family default . \end_layout \begin_layout Subsection Addition and removal \end_layout \begin_layout LyX-Code \series bold struct \series default HXdeque_node \series bold * \series default HXdeque_push( \series bold struct \series default HXdeque \series bold * \series default dq, \series bold void * \series default ptr); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_push \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXdeque_node \series bold * \series default HXdeque_unshift( \series bold struct \series default HXdeque \series bold * \series default dq, \series bold void * \series default ptr); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_unshift \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void * \series default HXdeque_pop( \series bold struct \series default HXdeque \series bold * \series default dq); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_pop \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void * \series default HXdeque_shift( \series bold struct \series default HXdeque \series bold * \series default dq); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_shift \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXdeque \series bold * \series default HXdeque_move( \series bold struct \series default HXdeque_node \series bold * \series default target, \begin_inset Newline newline \end_inset \series bold struct \series default HXdeque_node \series bold * \series default node); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_move \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void * \series default HXdeque_del( \series bold struct \series default HXdeque_node \series bold * \series default node); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_del \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter HXdeque_\SpecialChar softhyphen push \family default and \family typewriter HXdeque_\SpecialChar softhyphen unshift \family default add the data item in a new node at the end ( \begin_inset Quotes eld \end_inset push \begin_inset Quotes erd \end_inset ) or as the new first element ( \begin_inset Quotes eld \end_inset unshift \begin_inset Quotes erd \end_inset as Perl calls it), respectively. The functions will return the new node on success, or \family typewriter NULL \family default on failure and \family typewriter errno \family default will be set. The node is owned by the list. \end_layout \begin_layout Standard \family typewriter HXdeque_\SpecialChar softhyphen pop \family default and \family typewriter HXdeque_\SpecialChar softhyphen shift \family default remove the last ( \begin_inset Quotes eld \end_inset pop \begin_inset Quotes erd \end_inset ) or first ( \begin_inset Quotes eld \end_inset shift \begin_inset Quotes erd \end_inset ) node, respectively, and return the data pointer that was stored in the data. \end_layout \begin_layout Standard \family typewriter HXdeque_\SpecialChar softhyphen move \family default will unlink a node from its list, and reinsert it after the given target node, which may be in a different list. \end_layout \begin_layout Standard Deleting a node is accomplished by calling \family typewriter HXdeque_del \family default on it. The data pointer stored in the node is not freed, but returned. \end_layout \begin_layout Subsection Iteration \end_layout \begin_layout Standard Iterating over a HXdeque linked list is done manually and without additional overhead of function calls: \end_layout \begin_layout LyX-Code \series bold const struct \series default HXdeque_node \series bold * \series default node; \begin_inset Newline newline \end_inset \series bold for \series default (node = dq->first; node != NULL; node = node->next) \begin_inset Newline newline \end_inset do_something(node->ptr); \end_layout \begin_layout Subsection Searching \end_layout \begin_layout LyX-Code \series bold struct \series default HXdeque_node \series bold * \series default HXdeque_find( \series bold struct \series default HXdeque \series bold * \series default dq, \series bold const void * \series default ptr); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_find \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void * \series default HXdeque_get( \series bold struct \series default HXdeque \series bold * \series default dq, \series bold void * \series default ptr); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXdeque_get \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter HXdeque_find \family default searches for the node which contains \family typewriter ptr \family default , and does so by beginning at the start of the list. If no node is found, \family typewriter NULL \family default is returned. If a pointer is more than once in the list, any node may be returned. \end_layout \begin_layout Standard \family typewriter HXdeque_get \family default will further return the data pointer stored in the node \begin_inset space ~ \end_inset — however, since that is just what the \family typewriter ptr \family default argument is, the function practically only checks for existence of \family typewriter ptr \family default in the list. \end_layout \begin_layout Subsection Examples \end_layout \begin_layout Standard \series bold \begin_inset Float figure placement h wide false sideways false status open \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold \begin_inset Newline newline \end_inset int \series default main( \series bold void \series default ) \begin_inset Newline newline \end_inset { \series bold \begin_inset Newline newline \end_inset \series default \series bold struct \series default HXdeque \series bold * \series default dq = HXdeque_init(); \begin_inset Newline newline \end_inset \series bold struct \series default passwd *pw; \begin_inset Newline newline \end_inset \family typewriter \series bold unsigned int \series default elem; \begin_inset Newline newline \end_inset \series bold char ** \series default users; \family default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset setpwent(); \begin_inset Newline newline \end_inset \series bold while \series default ((pw = getpwent()) != NULL) \begin_inset Newline newline \end_inset HXdeque_push(dq, HX_strdup(pw->pw_name)); \begin_inset Newline newline \end_inset endpwent(); \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset users = \series bold reinterpret_cast \series default ( \series bold char ** \series default , HXdeque_to_vec(dq, &elem)); \begin_inset Newline newline \end_inset HXdeque_free(dq); \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset qsort(users, elem, \series bold sizeof \series default (*users), \series bold static_cast \series default ( \series bold void * \series default , strcmp)); \begin_inset Newline newline \end_inset return 0; \begin_inset Newline newline \end_inset } \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout Example use of HXdeque to store and sort a list \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard In this example, all usernames are obtained from NSS, and put into a list. \family typewriter HX_strdup \family default is used, because \family typewriter getpwent \family default will overwrite the buffer it uses to store its results. The list is then converted to an array, and the list is freed (because it is not need it anymore). \family typewriter HXdeque_genocide \family default must not be used here, because it would free all the data pointers (strings here) that were just inserted into the list. Finally, the list is sorted using the well-known \family typewriter qsort \family default function. Because \family typewriter strcmp \family default takes two \family typewriter const char \begin_inset space ~ \end_inset * \family default arguments, but \family typewriter qsort \family default mandates a function taking two \family typewriter const void \begin_inset space ~ \end_inset * \family default , a cast can be used to silence the compiler. This only works because we know that the array consists of a bunch of \family typewriter char \begin_inset space ~ \end_inset * \family default pointers, so \family typewriter strcmp \family default will work. \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Inline doubly-linked list \begin_inset CommandInset label LatexCommand label name "sec:list" \end_inset \end_layout \begin_layout Standard Classical linked-list implementations, such as HXdeque, either store the actual data within a node, or indirectly through a pointer, but the \begin_inset Quotes eld \end_inset inline doubly-linked list \begin_inset Quotes erd \end_inset instead does it reverse and has the list head within the data structure. \end_layout \begin_layout Standard \begin_inset Float figure placement h wide false sideways false status open \begin_layout LyX-Code \series bold struct \series default package_desc { \begin_inset Newline newline \end_inset \series bold char * \series default package_name; \begin_inset Newline newline \end_inset \series bold int \series default version; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code \series bold struct \series default classic_direct_node { \begin_inset Newline newline \end_inset \series bold struct \series default classic_direct_node \series bold * \series default next, \series bold * \series default prev; \begin_inset Newline newline \end_inset \series bold struct \series default package_desc direct_data; \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \series bold struct \series default classic_indirect_node { \begin_inset Newline newline \end_inset \series bold struct \series default classic_indirect_node \series bold * \series default next, \series bold * \series default prev; \begin_inset Newline newline \end_inset \series bold void * \series default indirect_data; \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout Classic linked-list implementations with direct/indirect data blocks. \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset Float figure placement H wide false sideways false status open \begin_layout LyX-Code \series bold struct \series default package_desc { \begin_inset Newline newline \end_inset \series bold struct \series default HXlist_head list; \begin_inset Newline newline \end_inset \series bold char * \series default package_name; \begin_inset Newline newline \end_inset \series bold int \series default version; \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout List head (next,prev pointers) inlined into the data block \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard At first glance, an inline list does not look much different from \family typewriter struct classic_\SpecialChar softhyphen direct_\SpecialChar softhyphen data \family default , it is mostly a viewpoint decision which struct is in the foreground. \end_layout \begin_layout Subsection Synopsis \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/list.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXlist_head { \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter struct HXlist_head \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold /* \family roman \series default \shape italic All fields considered private \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset HXLIST_HEAD_INIT(name); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXLIST_HEAD_INIT \end_layout \end_inset \begin_inset Newline newline \end_inset HXLIST_HEAD(name); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXLIST_HEAD \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXlist_init( \series bold struct \series default HXlist_head \series bold * \series default list); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_init \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXlist_add( \series bold struct \series default HXlist_head \series bold * \series default list, \series bold struct \series default HXlist_head \series bold * \series default elem); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_add \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXlist_add_tail( \series bold struct \series default HXlist_head \series bold * \series default list, \series bold struct \series default HXlist_head \series bold * \series default elem); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_add_tail \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXlist_del( \series bold struct \series default HXlist_head \series bold * \series default element); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_del \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HXlist_empty( \series bold const struct \series default HXlist_head \series bold * \series default list); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_empty \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HXLIST_HEAD_INIT \family default This macro expands to the static initializer for a list head. \end_layout \begin_layout Description \family typewriter HXLIST_HEAD \family default This macro expands to the definition of a list head (i. \begin_inset space \thinspace{} \end_inset e. \begin_inset space \space{} \end_inset \family typewriter struct HXlist_head name = HXLIST_HEAD_INIT; \family default ) \end_layout \begin_layout Description \family typewriter HXlist_init \family default Initializes the list head. This function is generally used when the list head is on the heap where the static initializer cannot be used. \end_layout \begin_layout Description \family typewriter HXlist_add \family default Adds \family typewriter elem \family default to the front of the list. \end_layout \begin_layout Description \family typewriter HXlist_add_tail \family default Adds \family typewriter elem \family default to the end of the list. \end_layout \begin_layout Description \family typewriter HXlist_del \family default Deletes the given element from the list. \end_layout \begin_layout Description \family typewriter HXlist_empty \family default Tests whether the list is empty. Note: For clists, you could also use \family typewriter clist->items == 0 \family default . \end_layout \begin_layout Subsection Traversal \end_layout \begin_layout Standard Traversal is implemented using macros that expand to for() statements which can syntactically be used like them, i. \begin_inset space \thinspace{} \end_inset e. \begin_inset space \space{} \end_inset curly braces may be omitted if only a single statement is in the body of the loop. \end_layout \begin_layout Standard The \family typewriter head \family default parameter specifies the list head ( \family typewriter struct HXlist_head \family default ), \family typewriter pos \family default specifies an iterator, also of type \family typewriter struct HXlist_head \family default . Lists can either be traversed in forward direction, or, using the \family typewriter _rev \family default variants, in reverse direction. The \family typewriter _safe \family default variants use a temporary \family typewriter n \family default to hold the next object in the list, which is needed when pos itself is going to be inaccessible at the end of the block, through, for example, freeing its encompassing object. \end_layout \begin_layout LyX-Code HXlist_for_each(pos, head) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_for_each \end_layout \end_inset \begin_inset Newline newline \end_inset HXlist_for_each_rev(pos, head) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_for_each_rev \end_layout \end_inset \begin_inset Newline newline \end_inset HXlist_for_each_safe(pos, n, head) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_for_each_safe \end_layout \end_inset \begin_inset Newline newline \end_inset HXlist_for_each_rev_safe(pos, n, head) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_for_each_rev_safe \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HXlist_for_each \family default Forward iteration over the list heads. \end_layout \begin_layout Description \family typewriter HXlist_for_each_rev \family default Reverse iteration over the list heads. \end_layout \begin_layout Description \family typewriter HXlist_for_each_safe \family default Forward iteration over the list heads that is safe against freeing \family typewriter pos \family default . \end_layout \begin_layout Description \family typewriter HXlist_for_each_rev_safe \family default Reverse iteration over the list heads that is safe against freeing \family typewriter pos \family default . \end_layout \begin_layout Standard The \family typewriter _entry \family default variants use an iterator \family typewriter pos \family default of the type of the encompassing object (e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset \family typewriter struct item \family default in below's example), so that the manual \family typewriter HXlist_entry \family default invocation is not needed. \family typewriter member \family default is the name of the list structure embedded into the item. \end_layout \begin_layout LyX-Code HXlist_for_each_entry(pos, head, member) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_for_each_entry \end_layout \end_inset \begin_inset Newline newline \end_inset HXlist_for_each_entry_rev(pos, head, member) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_for_each_entry_rev \end_layout \end_inset \begin_inset Newline newline \end_inset HXlist_for_each_entry_safe(pos, n, head, member) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXlist_for_each_entry_safe \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HXlist_for_each_entry \family default Forward iteration over the list elements. \end_layout \begin_layout Description \family typewriter HXlist_for_each_entry_rev \family default Reverse iteration over the list elements. \end_layout \begin_layout Description \family typewriter HXlist_for_each_entry_safe \family default Forward iteration over the list elements that is safe against freeing \family typewriter pos \family default . \end_layout \begin_layout Subsection Examples \end_layout \begin_layout LyX-Code \series bold struct \series default item { \begin_inset Newline newline \end_inset \series bold struct \series default HXlist_head anchor; \begin_inset Newline newline \end_inset \series bold char \series default name \series bold [ \series default 32 \series bold ] \series default ; \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXlist_head \series bold * \series default e; \begin_inset Newline newline \end_inset \series bold struct \series default item \series bold * \series default i, \series bold * \series default j; \begin_inset Newline newline \end_inset HXLIST_HEAD(list); \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset i = malloc( \series bold sizeof \series default ( \series bold * \series default i)); \begin_inset Newline newline \end_inset HXlist_init(&e->anchor); \begin_inset Newline newline \end_inset strcpy(i->name, "foo"); \begin_inset Newline newline \end_inset HXlist_add_tail(&list, &i->anchor); \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset i = malloc( \series bold sizeof \series default ( \series bold * \series default i)); \begin_inset Newline newline \end_inset HXlist_init(&e->anchor); \begin_inset Newline newline \end_inset strcpy(i->name, "bar"); \begin_inset Newline newline \end_inset HXlist_add_tail(&list, &i->anchor); \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset HXlist_for_each(e, &list) { \begin_inset Newline newline \end_inset i = HXlist_entry(e, \series bold typeof \series default ( \series bold * \series default i), anchor); \begin_inset Newline newline \end_inset printf("e=%p i=%p name=%s \backslash n", e, i, i->name); \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset HXlist_for_each_entry(i, &list, anchor) \begin_inset Newline newline \end_inset printf("i=%p name=%s \backslash n", i, i->name); \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset HXlist_for_each_entry_rev(i, &list, anchor) \begin_inset Newline newline \end_inset printf("i=%p name=%s \backslash n", i, i->name); \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset HXlist_for_each_entry_safe(i, j, &list, anchor) { \begin_inset Newline newline \end_inset printf("i=%p name=%s \backslash n", i, i->name); \begin_inset Newline newline \end_inset free(i); \begin_inset Newline newline \end_inset } \end_layout \begin_layout Subsection When to use HXdeque/HXlist \end_layout \begin_layout Standard The choice whether to use HXdeque or HXlist/HXclist depends on whether one wants the list head handling on the developer or on the library. Especially for \begin_inset Quotes eld \end_inset atomic \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset small \begin_inset Quotes erd \end_inset data, it might be easier to just let HXdeque do the management. Compare the following two code examples to store strings: \end_layout \begin_layout Standard \begin_inset Float figure placement H wide false sideways false status open \begin_layout LyX-Code \series bold int \series default main( \family typewriter \series bold int \series default argc, \series bold const char ** \series default argv) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold struct \series default HXdeque \series bold * \series default dq = HXdeque_init(); \begin_inset Newline newline \end_inset \series bold while \series default (--argc) \begin_inset Newline newline \end_inset HXdeque_push(dq, ++argv); \begin_inset Newline newline \end_inset \family default \series bold return \family typewriter \series default 0; \begin_inset Newline newline \end_inset } \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout Storing strings in a HXdeque \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset Float figure placement H wide false sideways false status open \begin_layout LyX-Code \series bold struct \series default element { \begin_inset Newline newline \end_inset \series bold struct \series default HXlist_head list; \begin_inset Newline newline \end_inset \series bold char * \family typewriter \series default data; \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default main( \series bold int \series default main, \series bold const char ** \series default argv) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset HXLIST_HEAD(lh); \begin_inset Newline newline \end_inset \series bold while \series default (--argc) { \begin_inset Newline newline \end_inset \series bold struct \series default element \series bold * \series default e = malloc( \family default \series bold sizeof \family typewriter \series default (*e)); \begin_inset Newline newline \end_inset e->data = *++argv; \begin_inset Newline newline \end_inset HXlist_init(&e->list); \begin_inset Newline newline \end_inset HXlist_add_tail(&e->list); \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \series bold return \series default 0; \begin_inset Newline newline \end_inset } \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout Storing strings in a HXlist \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard These examples assume that \family typewriter argv \family default is persistent, which, for the sample, is true. \end_layout \begin_layout Standard With HXlist, one needs to have a struct with a HXlist_head in it, and if one does not already have such a struct \begin_inset space ~ \end_inset —e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset by means of wanting to store more than just one value \begin_inset space ~ \end_inset — one will need to create it first, as shown, and this may lead to an expansion of code. \end_layout \begin_layout Standard This however does not mean that HXlist is the better solution over HXdeque for data already available in a struct. As each struct has a list_head that is unique to the node, it is not possible to share this data. Trying to add a HXlist_head to another list is not going to end well, while HXdeque has no problem with this as list heads are detached from the actual data in HXdeque. \end_layout \begin_layout Standard \begin_inset Float figure placement H wide false sideways false status open \begin_layout LyX-Code \series bold struct \series default point p = {15, 30}; \begin_inset Newline newline \end_inset HXdeque_push(dq, &p); \begin_inset Newline newline \end_inset HXdeque_push(dq, &p); \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout Data can be added multiple times in a HXdeque without ill effects \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard To support this, an extra allocation is needed on the other hand. In a HXlist, to store \begin_inset Formula $n$ \end_inset elements of compound data (e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset \family typewriter struct point \family default ), \begin_inset Formula $n$ \end_inset allocations are needed, assuming the list head is a stack object, and the points are not. HXdeque will need at least \begin_inset Formula $2n+1$ \end_inset allocations, \begin_inset Formula $n$ \end_inset for the nodes, \begin_inset Formula $n$ \end_inset for the points and another for the head. \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Counted inline doubly-linked list \begin_inset CommandInset label LatexCommand label name "sec:clist" \end_inset \end_layout \begin_layout Standard clist is the inline doubly-linked list from chapter \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "sec:list" \end_inset , extended by a counter to retrieve the number of elements in the list in \begin_inset Formula $\mathcal{O}\left(1\right)$ \end_inset time. This is also why all operations always require the list head. For traversal of clists, use the corresponding HXlist macros. \end_layout \begin_layout Subsection Synopsis \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/list.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXclist_head { \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter struct HXclist_head \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold /* \family roman \series default \shape italic public readonly: \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset \series bold unsigned int \series default items; \begin_inset Newline newline \end_inset \series bold /* \family roman \series default \shape italic Undocumented fields are considered \begin_inset Quotes eld \end_inset private \begin_inset Quotes erd \end_inset \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset HXCLIST_HEAD_INIT(name); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXCLIST_HEAD_INIT \end_layout \end_inset \begin_inset Newline newline \end_inset HXCLIST_HEAD(name); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXCLIST_HEAD \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXclist_init( \series bold struct \series default HXclist_head \series bold * \series default head); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXclist_init \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXclist_unshift( \series bold struct \series default HXclist_head \series bold * \series default head, \series bold struct \series default HXlist_head \series bold * \series default new_node); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXclist_unshift \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXclist_push( \series bold struct \series default HXclist_head \series bold * \series default head, \series bold struct \series default HXlist_head \series bold * \series default new_node); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXclist_push \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold type \series default HXclist_pop( \series bold struct \series default HXclist_head \series bold * \series default head, \series bold type \series default , member); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXclist_pop \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold type \series default HXclist_shift( \series bold struct \series default HXclist_head \series bold * \series default head, \series bold type \series default , member); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXclist_shift \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXclist_del( \series bold struct \series default HXclist_head \series bold * \series default head, \series bold struct \series default HXlist_chead \series bold * \series default node); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXclist_del \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HXCLIST_HEAD_INIT \family default Macro that expands to the static initializer for a clist. \end_layout \begin_layout Description \family typewriter HXCLIST_HEAD \family default Macro that expands to the definition of a clist head, with initialization. \end_layout \begin_layout Description \family typewriter HXclist_init \family default Initializes a clist. This function is generally used when the head has been allocated from the heap. \end_layout \begin_layout Description \family typewriter HXclist_unshift \family default Adds the node to the front of the list. \end_layout \begin_layout Description \family typewriter HXclist_push \family default Adds the node to the end of the list. \end_layout \begin_layout Description \family typewriter HXclist_pop \family default Removes the last node in the list and returns it. \end_layout \begin_layout Description \family typewriter HXclist_shift \family default Removes the first node in the list and returns it. \end_layout \begin_layout Description \family typewriter HXclist_del \family default Deletes the node from the list. \end_layout \begin_layout Standard The list count in the clist head is updated whenever a modification is done on the clist through these functions. \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Part Strings and memory \end_layout \begin_layout Section String operations \begin_inset CommandInset label LatexCommand label name "sec:strings" \end_inset \end_layout \begin_layout Standard Some string functions are merely present in libHX because they are otherwise unportable; some are only in the C libraries of the BSDs, some only in GNU libc. \end_layout \begin_layout Subsection Locating chars \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/string.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold void * \series default HX_memmem( \series bold const void * \series default haystack, \series bold size_t \series default hsize, \begin_inset Newline newline \end_inset \series bold const void * \series default needle, \series bold size_t \series default nsize); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_memmem \end_layout \end_inset \series bold \begin_inset Newline newline \end_inset char * \series default HX_strbchr( \series bold const char * \series default start, \series bold const char * \series default now, \series bold char \series default delimiter); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_strbchr \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strchr2( \series bold const char * \series default s, \series bold const char * \series default accept); \begin_inset Index idx status open \begin_layout Plain Layout HX_strchr2 \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold size_t \series default HX_strrcspn( \series bold const char * \series default s, \series bold const char * \series default reject); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_strccspn \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HX_memmem \family default Analogous to \family typewriter strstr \family default (3), \family typewriter memmem \family default tries to locate the memory block pointed to by \family typewriter needle \family default (which is of length \family typewriter nsize \family default ) in the block pointed to by \family typewriter haystack \family default (which is of size \family typewriter hsize \family default ). It returns a pointer to the first occurrence in \family typewriter haystack \family default , or \family typewriter NULL \family default when it was not found. \end_layout \begin_layout Description \family typewriter HX_strbchr \family default Searches the character specified by \family typewriter delimiter \family default in the range from \family typewriter now \family default to \family typewriter start \family default . It works like \family typewriter strrchr \family default (3) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter strrchr \end_layout \end_inset , but begins at \family typewriter now \family default rather than the end of the string. \end_layout \begin_layout Description \family typewriter HX_strchr2 \family default This function searches the string \family typewriter s \family default for any set of bytes that are not specified in the second argument, \family typewriter n \family default . In this regard, the function is the opposite to \family typewriter strpbrk \family default (3) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter strpbrk \end_layout \end_inset . \end_layout \begin_layout Description \family typewriter HX_strrcspn \family default Works like \family typewriter strcspn \family default (3) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none strcspn \end_layout \end_inset , but processes the string from end to start. \end_layout \begin_layout Subsection Extraction \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/string.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_basename( \series bold const char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_basename \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_basename_exact( \series bold const char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_basename_exact \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_dirname( \series bold const char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_dirname \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strmid( \series bold const char * \series default s, \series bold long \series default offset, \series bold long \series default length); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strmid \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HX_basename \family default Returns a pointer to the basename portion of the supplied path \family typewriter s \family default . The result of this function is never \family typewriter NULL \family default , and must never be freed either. Trailing slashes are not stripped, to avoid having to do an allocation. In other words, \family typewriter basename("/mnt/") \family default will return \begin_inset Quotes eld \end_inset \family typewriter mnt/ \family default \begin_inset Quotes erd \end_inset . If you need to have the slashes stripped, use \family typewriter HX_basename_exact \family default . A possible use for this function is, for example, to derive a logging prefix from \family typewriter argv[0] \family default . \end_layout \begin_layout LyX-Code \series bold int \series default main( \series bold int \series default argc, \series bold const char ** \series default argv) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold if \series default (foo()) \end_layout \begin_layout LyX-Code fprintf(stderr, "%s: Special condition occurred. \backslash n", \begin_inset Newline newline \end_inset HX_basename(argv[0])); \begin_inset Newline newline \end_inset \series bold return \series default 0; \begin_inset Newline newline \end_inset } \end_layout \begin_layout Description \family typewriter HX_basename_exact \family default The accurate and safe version of \family typewriter HX_basename \family default that deals with trailing slashes correctly and produces the same result as \family typewriter dirname \family default (3). It returns a pointer to a newly-allocated string that must be freed when done using. \family typewriter NULL \family default may be returned in case of an allocation error. \end_layout \begin_layout Description \family typewriter HX_dirname \family default Returns a pointer to a new string that contains the directory name portion (everything except basename). When done using the string, it must be freed to avoid memory leaks. \end_layout \begin_layout Description \family typewriter HX_strmid \family default Extract a substring of \family typewriter length \family default characters from \family typewriter s \family default , beginning at \family typewriter offset \family default . If \family typewriter offset \family default is negative, counting beings from the end of the string; \begin_inset Formula $-1$ \end_inset is the last character (not the \family typewriter ' \backslash 0' \family default byte). If \family typewriter length \family default is negative, it will leave out that many characters off the end. The function returns a pointer to a new string, and the user has to free it. \end_layout \begin_layout Subsection In-place transformations \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/string.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_chomp( \series bold char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_chomp \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold size_t \series default HX_strltrim( \series bold char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strltrim \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_stpltrim( \series bold const char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout HX_stpltrim \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strlower( \series bold char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strlower \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strrev( \series bold char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strrev \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold size_t \series default HX_strrtrim( \series bold char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strrtrim \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strupper( \series bold char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strupper \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HX_chomp \family default Removes the characters \family typewriter ' \backslash r' \family default and \family typewriter ' \backslash n' \family default from the right edge of the string. Returns the original argument. \end_layout \begin_layout Description \family typewriter HX_strltrim \family default Trim all whitespace (characters on which \family typewriter isspace \family default (3) return true) on the left edge of the string. Returns the number of characters that were stripped. \end_layout \begin_layout Description \family typewriter HX_stpltrim \family default Returns a pointer to the first non-whitespace character in \family typewriter s \family default . \end_layout \begin_layout Description \family typewriter HX_strlower \family default Transforms all characters in the string \family typewriter s \family default into lowercase using \family typewriter tolower \family default (3). Returns the original argument. \end_layout \begin_layout Description \family typewriter HX_strrev \family default Reverse the string in-place. Returns the original argument. \end_layout \begin_layout Description \family typewriter HX_strrtrim \family default Trim all whitespace on the right edge of the string. Returns the number of characters that were stripped. \end_layout \begin_layout Description \family typewriter HX_strupper \family default Transforms all characters in the string \family typewriter s \family default into uppercase using \family typewriter toupper \family default (3). Returns the original argument. \end_layout \begin_layout Subsection Out-of-place quoting transforms \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/string.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strquote( \series bold const char * \series default s, \series bold unsigned int \series default type, \series bold char ** \series default free_me); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_strquote \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter HX_strquote \family default will escape metacharacters in a string according to \family typewriter type \family default , and returns the escaped result. \end_layout \begin_layout Standard Possible values for \family typewriter type \family default : \end_layout \begin_layout Description \family typewriter HXQUOTE_SQUOTE \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXQUOTE_SQUOTE \end_layout \end_inset Escape all single quotes and backslashes in a string with a backslash. ( \begin_inset Quotes eld \end_inset Ol' \backslash Backslash \begin_inset Quotes erd \end_inset \begin_inset Formula $\rightarrow$ \end_inset \begin_inset Quotes eld \end_inset Ol \backslash ' \backslash \backslash Backslash \begin_inset Quotes erd \end_inset ) \end_layout \begin_layout Description \family typewriter HXQUOTE_DQUOTE \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXQUOTE_DQUOTE \end_layout \end_inset Escape all double quotes and backslahes in a string with the backslash method. ( \begin_inset Quotes eld \end_inset Ol \begin_inset Quotes erd \end_inset \backslash Backslash \begin_inset Quotes erd \end_inset \begin_inset Formula $\rightarrow$ \end_inset \begin_inset Quotes eld \end_inset Ol \backslash \begin_inset Quotes erd \end_inset \backslash \backslash Backslash \begin_inset Quotes erd \end_inset ) \end_layout \begin_layout Description \family typewriter HXQUOTE_HTML \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXQUOTE_HTML \end_layout \end_inset Escape ' \family typewriter < \family default ', ' \family typewriter > \family default ', ' \family typewriter & \family default ' and ' \family typewriter " \family default ' by their respective HTML entities \family typewriter < \family default , \family typewriter > \family default , \family typewriter & \family default and \family typewriter " \family default . \end_layout \begin_layout Description \family typewriter HXQUOTE_LDAPFLT \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXQUOTE_LDAPFLT \end_layout \end_inset Escape the string using backslash-plus-hexcode notation as described in RFC 4515 \begin_inset Foot status open \begin_layout Plain Layout \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://tools.ietf.org/html/rfc4515 \end_layout \end_inset \end_layout \end_inset , to make it suitable for use in an LDAP search filter. \end_layout \begin_layout Description \family typewriter HXQUOTE_LDAPRDN \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXQUOTE_LDAPRDN \end_layout \end_inset Escape the string using backslash-plus-hexcode notation as described in RFC 4514 \begin_inset Foot status open \begin_layout Plain Layout \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://tools.ietf.org/html/rfc4514 \end_layout \end_inset \end_layout \end_inset , to make it suitable for use in an LDAP Relative Distinguished Name. \end_layout \begin_layout Description \family typewriter HXQUOTE_BASE64 \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXQUOTE_BASE64 \end_layout \end_inset Transform the string to BASE64, as described in RFC 4648 \begin_inset Foot status open \begin_layout Plain Layout \begin_inset Flex URL status collapsed \begin_layout Plain Layout http://tools.ietf.org/html/rfc4648 \end_layout \end_inset \end_layout \end_inset . \end_layout \begin_layout Description \family typewriter HXQUOTE_URIENC \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXQUOTE_URIENC \end_layout \end_inset Escape the string so that it becomes a valid part for an URI. \end_layout \begin_layout Description \family typewriter HXQUOTE_SQLSQUOTE \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXQUOTE_SQLSQUOTE \end_layout \end_inset Escape all single quotes in the string by double single-quotes, as required for using it in a single-quoted SQL string. No surrounding quotes will be generated to facilitate concatenating of \family typewriter HX_strquote \family default results. \end_layout \begin_layout Description \family typewriter HXQUOTE_SQLBQUOTE \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXQUOTE_SQLBQUOTE \end_layout \end_inset Escape all backticks in the string by double backticks, as required for using it in a backtick-quoted SQL string (used for table names and columns). No surrounding ticks will be generated to facilitate concatenation. \end_layout \begin_layout Standard Specifying an unrecognized type will result in \family typewriter NULL \family default being returned and \family typewriter errno \family default be set to \family typewriter EINVAL \family default . \end_layout \begin_layout Standard If \family typewriter free_me \family default is \family typewriter NULL \family default , the function will always allocate memory, even if the string needs no quoting. The program then has to free the result: \end_layout \begin_layout LyX-Code \series bold char * \series default s = HX_strquote("", HXQUOTE_HTML, NULL); \begin_inset Newline newline \end_inset printf("%s \backslash n", s); \begin_inset Newline newline \end_inset free(s); \end_layout \begin_layout Standard If \family typewriter free_me \family default is not \family typewriter NULL \family default however, the function will put the pointer to the memory area into \family typewriter *free_me \family default , if the string needed quoting. The program then has to free that after it is done with the quoted result: \end_layout \begin_layout LyX-Code \series bold char * \series default tmp = NULL; \begin_inset Newline newline \end_inset \series bold char * \series default s = HX_strquote("head", HXQUOTE_HTML, &tmp); \begin_inset Newline newline \end_inset printf("%s \backslash n", s); \begin_inset Newline newline \end_inset free(tmp); \end_layout \begin_layout Standard \family typewriter tmp \family default could be \family typewriter NULL \family default , and since \family typewriter free(NULL) \family default is not an error, this is perfectly valid. Furthermore, if \family typewriter *free_me \family default is not \family typewriter NULL \family default by the time \family typewriter HX_strquote \family default is called, the function will free it. This makes it possible to call \family typewriter HX_strquote \family default in succession without \family typewriter free \family default s in between: \end_layout \begin_layout LyX-Code \series bold char * \series default tmp = NULL; \begin_inset Newline newline \end_inset printf("%s \backslash n", HX_strquote("", HXQUOTE_HTML, &tmp)); \begin_inset Newline newline \end_inset printf("%s \backslash n", HX_strquote("", HXQUOTE_HTML, &tmp)); \begin_inset Newline newline \end_inset free(tmp); \end_layout \begin_layout Subsection Tokenizing \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/string.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold char ** \series default HX_split( \series bold const char * \series default s, \series bold const char * \series default delimiters, \begin_inset Newline newline \end_inset \series bold size_t * \series default fields, \series bold int \series default max); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_split \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char ** \series default HX_split4( \series bold char * \series default s, \series bold const char * \series default delimiters, \series bold int * \series default fields, \series bold int \series default max); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_split4 \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_split5( \series bold char * \series default s, \series bold const char * \series default delimiters, \series bold int \series default max, \series bold char ** \series default stack); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_split5 \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strsep( \series bold char ** \series default sp, \series bold const char * \series default delimiters); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strsep \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strsep2( \series bold char ** \series default sp, \series bold const char * \series default dstr); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strsep2 \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HX_split \family default Split the string \family typewriter s \family default on any characters from the \begin_inset Quotes eld \end_inset \family typewriter delimiters \family default \begin_inset Quotes erd \end_inset string. Both the substrings and the array holding the pointers to these substrings will be allocated as required; the original string is not modified. If \family typewriter max \family default is larger than zero, produces no more than \family typewriter max \family default fields. If \family typewriter fields \family default is not \family typewriter NULL \family default , the number of elements produced will be stored in \family typewriter *fields \family default . The result is a \family typewriter NULL \family default -terminated array of \family typewriter char \begin_inset space ~ \end_inset * \family default , and the user needs to free it when done with it, using \family typewriter HX_zvecfree \family default or equivalent. An empty string (zero-length string) for \family typewriter s \family default yields a single field. \end_layout \begin_layout Description \family typewriter HX_split4 \family default Split the string \family typewriter s \family default in-place on any characters from the \begin_inset Quotes eld \end_inset \family typewriter delimiters \family default \begin_inset Quotes erd \end_inset string. The array that will be holding the pointers to the substrings will be allocated and needs to be freed by the user, using \family typewriter free \family default (3). The \family typewriter fields \family default and \family typewriter max \family default arguments work as with \family typewriter HX_split \family default . \end_layout \begin_layout Description \family typewriter HX_split5 \family default Split the string \family typewriter s \family default in-place on any characters from the \begin_inset Quotes eld \end_inset \family typewriter delimiters \family default \begin_inset Quotes erd \end_inset string. The array for the substring pointers must be provided by the user through the \family typewriter stack \family default argument. \family typewriter max \family default must be the number of elements in the array or less. The array will not be \family typewriter NULL \family default -terminated \begin_inset Foot status open \begin_layout Plain Layout An implementation may however decide to put NULL in the unassigned fields, but this is implementation and situation-specific. Do not rely on it. \end_layout \end_inset . The number of fields produced is returned. \end_layout \begin_layout Description \family typewriter HX_strsep \family default Extract tokens from a string. \begin_inset Newline newline \end_inset This implementation of \family typewriter strsep \family default has been added since the function is non-standard (according to the manpage, conforms to BSD4.4 only) and may not be available on every operating system. \begin_inset Newline newline \end_inset This function extracts tokens, separated by one of the characters in \family typewriter delimiters \family default . The string is modified in-place and thus must be writable. The delimiters in the string are then overwritten with \family typewriter ' \backslash 0' \family default , \family typewriter *sp \family default is advanced to the character after the delimiter, and the original pointer is returned. After the final token, \family typewriter strsep \family default will return \family typewriter NULL \family default . \end_layout \begin_layout Description \family typewriter HX_strsep2 \family default Like \family typewriter HX_strsep \family default , but \family typewriter dstr \family default is not an array of delimiting characters, but an entire substring that acts as a delimiter. \end_layout \begin_layout Subsection Size-bounded string ops \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout libHX/string.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strlcat( \series bold char * \series default dest, \series bold const char * \series default src, \series bold size_t \series default length); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strlcat \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strlcpy( \series bold char * \series default dest, \series bold const char * \series default src, \series bold size_t \series default length); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strlcpy \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strlncat( \series bold char * \series default dest, \series bold const char * \series default src, \series bold size_t \series default dlen, \series bold size_t \series default slen); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strlncat \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold size_t \series default HX_strnlen( \series bold const char * \series default src, \series bold size_t \series default max); \begin_inset Index idx status open \begin_layout Plain Layout HX_strnlen \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter HX_strlcat \family default and \family typewriter HX_strlcpy \family default provide implementations of the BSD-originating \family typewriter strlcat \family default (3) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter strlcat \end_layout \end_inset and \family typewriter strlcpy \family default (3) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter strlcpy \end_layout \end_inset . \family typewriter strlcat \family default and \family typewriter strlcpy \family default are less error-prone variants for \family typewriter strncat \family default and \family typewriter strncpy \family default as they always take the length of the entire buffer specified by \family typewriter dest \family default , instead of just the length that is to be written. The functions guarantee that the buffer is \family typewriter ' \backslash 0' \family default -terminated. \end_layout \begin_layout Standard \family typewriter HX_strnlen \family default will return the length of the input string or the upper bound given by \family typewriter max \family default , whichever is less. It will not attempt to access more than this many bytes in the input buffer. \end_layout \begin_layout Subsection Allocation-related \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/string.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold void * \series default HX_memdup( \series bold const void * \series default ptr, \series bold size_t \series default length); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_memdup \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strdup( \series bold const char * \series default str); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strdup \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default HX_strndup( \series bold const char * \series default str, \series bold size_t \series default max); \begin_inset Index idx status open \begin_layout Plain Layout HX_strndup \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold \begin_inset Note Greyedout status open \begin_layout Plain Layout \family typewriter \series bold char * \series default HX_strclone( \series bold char ** \series default pa, \series bold const char * \series default pb); \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_strclone \end_layout \end_inset \end_layout \end_inset \series default \begin_inset Newline newline \end_inset \series bold \begin_inset Newline newline \end_inset #ifdef \series default __cplusplus \begin_inset Newline newline \end_inset \series bold template type \series default HX_memdup( \series bold const void * \series default ptr, \series bold size_t \series default length); \begin_inset Newline newline \end_inset \series bold #endif \end_layout \begin_layout Description \family typewriter HX_memdup \family default Duplicates \family typewriter length \family default bytes from the memory area pointed to by \family typewriter ptr \family default and returns a pointer to the new memory block. \family typewriter ptr \family default may not be \family typewriter NULL \family default . \end_layout \begin_layout Description \family typewriter HX_strdup \family default Duplicates the string. The function is equivalent to \family typewriter strdup \family default , but the latter may not be available on all platforms. \family typewriter str \family default may be \family typewriter NULL \family default , in which case \family typewriter NULL \family default is also returned. \end_layout \begin_layout Description \family typewriter HX_strndup \family default Duplicates the input string, but copies at most \family typewriter max \family default characters. (The resulting string will be NUL-terminated of course.) \family typewriter str \family default may not be \family typewriter NULL \family default . \end_layout \begin_layout Description \family typewriter HX_strclone \family default Copies the string pointed to by \family typewriter pb \family default into \family typewriter *pa \family default . If \family typewriter *pa \family default was not \family typewriter NULL \family default by the time \family typewriter HX_strclone \family default was called, the string is freed before a new one is allocated. The function returns \family typewriter NULL \family default and sets \family typewriter errno \family default to \family typewriter EINVAL \family default if \family typewriter pb \family default is \family typewriter NULL \family default (this way it can be freed), or, if \family typewriter malloc \family default fails, returns \family typewriter NULL \family default and leaves \family typewriter errno \family default at what \family typewriter malloc \family default set it to. \begin_inset Newline newline \end_inset The use of this function is deprecated, albeit no replacement is proposed. \end_layout \begin_layout Subsection Examples \end_layout \begin_layout Subsubsection Using HX_split5 \begin_inset CommandInset label LatexCommand label name "subsec:string-ex-HX_split5" \end_inset \end_layout \begin_layout Standard \family typewriter HX_split5 \family default , where the \begin_inset Quotes eld \end_inset 5 \begin_inset Quotes erd \end_inset should be interpreted (with a bit of imagination and the knowledge of leetspeak ) as an \begin_inset Quotes eld \end_inset S \begin_inset Quotes erd \end_inset for stack, as \family typewriter HX_split5 \family default is often used only with on-stack variables and where the field count of interest is fixed, as the example for parsing \family typewriter /etc/passwd \family default shows: \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default field[8]; \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default line = NULL; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold while \series default (HX_getl(&line, fp) != NULL) { \begin_inset Newline newline \end_inset \series bold if \series default (HX_split5(line, ":", ARRAY_SIZE(field), field) < 7) { \begin_inset Newline newline \end_inset fprintf(stderr, "That does not look like a valid line. \backslash n"); \begin_inset Newline newline \end_inset \series bold continue \series default ; \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset printf("Username: %s \backslash n", field[0]); \begin_inset Newline newline \end_inset } \end_layout \begin_layout Subsubsection Using HX_split4 \end_layout \begin_layout Standard Where the number of fields is not previously known and/or estimatable, but the string can be modified in place, one uses \family typewriter HX_split4 \family default as follows: \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold while \series default (HX_getl(&line, fp) != NULL) { \begin_inset Newline newline \end_inset \series bold char ** \series default field = HX_split4(line, ":", NULL, 0); \begin_inset Newline newline \end_inset \series bold if \series default (field == NULL) { \begin_inset Newline newline \end_inset fprintf(stderr, "Badness! %s \backslash n", strerror(errno)); \begin_inset Newline newline \end_inset \series bold break \series default ; \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset printf("Username: %s \backslash n", field[0]); \begin_inset Newline newline \end_inset free(field); \begin_inset Newline newline \end_inset } \end_layout \begin_layout Subsubsection Using HX_split \end_layout \begin_layout Standard Where the string is not modifiable in-place, one has to resort to using the full-fledged \family typewriter HX_split \family default that allocates space for each substring. \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold while \series default (HX_getl(&line, fp) != NULL) { \begin_inset Newline newline \end_inset \series bold char ** \series default field = HX_split(line, ":", NULL, 0); \begin_inset Newline newline \end_inset \series bold if \series default (field == NULL) { \begin_inset Newline newline \end_inset fprintf(stderr, "Badness. %s \backslash n", strerror(errno)); \begin_inset Newline newline \end_inset break; \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset printf("Username: %s \backslash n", field[0]); \begin_inset Newline newline \end_inset \series bold /* \family roman \series default \shape italic Suppose \begin_inset Quotes eld \end_inset callme \begin_inset Quotes erd \end_inset needs the original string \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset callme(line); \begin_inset Newline newline \end_inset HX_zvecfree(field); \begin_inset Newline newline \end_inset } \end_layout \begin_layout Subsubsection Using HX_strsep \end_layout \begin_layout Standard \family typewriter HX_strsep \family default provides for thread- and reentrant-safe tokenizing a string where strtok from the C standard would otherwise fail. \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold char \series default line \series bold [] \series default = "root:x:0:0:root:/root:/bin/bash"; \begin_inset Newline newline \end_inset \series bold char * \series default wp, \series bold * \series default p; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset wp = line; \begin_inset Newline newline \end_inset \series bold while \series default ((p = HX_strsep(&wp, ":")) != NULL) \begin_inset Newline newline \end_inset printf("%s \backslash n", p) \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Memory containers \begin_inset CommandInset label LatexCommand label name "sec:mc" \end_inset \end_layout \begin_layout Standard The HXmc series of functions provide scripting-like semantics for strings, especially automatically resizing the buffer on demand. They can also be used to store a binary block of data together with its length. (Hence the name: mc = memory container.) \end_layout \begin_layout Standard The benefit of using the HXmc functions is that one does not have to meticulousl y watch buffer and string sizes anymore. \end_layout \begin_layout Standard \begin_inset Float figure placement H wide false sideways false status open \begin_layout Paragraph /* Step \begin_inset space ~ \end_inset 1 */ \end_layout \begin_layout LyX-Code \series bold char \series default buf \series bold [ \family roman \series default \shape italic whatever was believed to be long enough \family default \series bold \shape default ] \series default = "helloworld"; \end_layout \begin_layout LyX-Code \series bold if \series default (strlen(buf) + strlen(".txt") < \series bold sizeof \series default (buf)) \begin_inset Newline newline \end_inset strcat(s, ".txt"); \end_layout \begin_layout Paragraph /* Step \begin_inset space ~ \end_inset 2 */ \end_layout \begin_layout LyX-Code \series bold char \series default buf \series bold [ \family roman \series default \shape italic long_enough \family default \series bold \shape default ] \series default = "helloworld"; \end_layout \begin_layout LyX-Code strlcat(s, ".txt", \series bold sizeof \series default (buf)); \end_layout \begin_layout Paragraph /* Step \begin_inset space ~ \end_inset 3 */ \end_layout \begin_layout LyX-Code hxmc_t \series bold * \series default buf = HXmc_strinit("helloworld"); \begin_inset Newline newline \end_inset HXmc_strcat(&s, ".txt"); \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout Improvement of string safety over time \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard This makes it quite similar to the string operations (and append seems to be the most commonly used one to me) supported in scripting languages that also do without a size argument. The essential part of such memory containers is that their internal (hidden) metadata structure contains the length of the memory block in the container. For binary data this may be the norm, but for C-style strings, the stored and auto-updated length field serves as an accelerator cache. For more details, see \family typewriter HXmc_length \family default . \end_layout \begin_layout Standard Of course, the automatic management of memory comes with a bit of overhead as the string expands beyond its preallocated region. Such may be mitigated by doing explicit (re)sizing. \end_layout \begin_layout Subsection Structural overview \end_layout \begin_layout Standard HXmc functions do not actually return a pointer to the memory container (e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset \family typewriter struct \family default ) itself, but a pointer to the data block. Conversely, input parameters to HXmc functions will be the data block pointer. It is of type \family typewriter hxmc_t \begin_inset space ~ \end_inset * \family default , which is typedef'ed to \family typewriter char \begin_inset space ~ \end_inset * \family default and inherits all properties and privileges of \family typewriter char \begin_inset space ~ \end_inset * \family default . Pointer arithmetic is thus supported. It also means you can just pass it to functions that take a \family typewriter char \begin_inset space ~ \end_inset * \family default without having to do a member access like \family typewriter s.c_str \family default . The drawback is that many functions operating on the memory container need a \family typewriter hxmc_t \begin_inset space ~ \end_inset ** \family default (a level-two indirection), because not only does the memory block move, but also the memory container itself. This is due to the implementation of the container metadata which immediately and always precedes the writable memory block. \end_layout \begin_layout Standard HXmc ensures that the data block is terminated by a NUL ( \family typewriter ' \backslash 0' \family default ) byte (unless you trash it), so you do not have to, and of course, to be on the safe side. But, the automatic NUL byte is not part of the region allocated by the user. That is, when one uses the classic approach with \family typewriter malloc(4096) \family default , the user will have control of 4096 bytes and has to stuff the NUL byte in there somehow on his own; for strings this means the maximum string length is 4095. Requesting space for a 4096-byte sized HXmc container gives you the possibility to use all 4096 bytes for the string, because HXmc provides a NUL byte. \end_layout \begin_layout Standard By the way, \family typewriter hxmc_t \family default is the \shape italic only \shape default typedef in this entire library, to distinguish it from regular \family typewriter char \begin_inset space ~ \end_inset * \family default that does not have a backing memory cointainer. \end_layout \begin_layout Subsection Constructors, destructors \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/string.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_strinit( \series bold const char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmc_strinit \end_layout \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_meminit( \series bold const void * \series default ptr, \series bold size_t \series default size); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmc_meminit \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HXmc_strinit \family default Creates a new hxmc_t object from the supplied string and returns it. \end_layout \begin_layout Description \family typewriter HXmc_meminit \family default Creates a new hxmc_t object from the supplied memory buffer of the given size and returns it. \family typewriter HXmc_meminit(NULL, len) \family default may be used to obtain an empty container with a preallocated region of \family typewriter len \family default bytes (zero is accepted for \family typewriter len \family default ). \end_layout \begin_layout LyX-Code \series bold void \series default HXmc_free(hxmc_t \series bold * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmc_free \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXmc_zvecfree(hxmc_t \series bold ** \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmc_zvecfree \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HXmc_free \family default Frees the hxmc object. \end_layout \begin_layout Description \family typewriter HXmc_zvecfree \family default Frees all hxmc objects in the NULL-terminated array, and finally frees the array itself, similar to \family typewriter HX_zvecfree \family default . \end_layout \begin_layout Subsection Data manipulation \end_layout \begin_layout Subsubsection Binary-based \end_layout \begin_layout LyX-Code hxmc_t \series bold * \series default HXmc_trunc(hxmc_t \series bold ** \series default mc, \series bold size_t \series default len); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXmc_trunc \end_layout \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_setlen(hxmc_t \series bold ** \series default mc, \series bold size_t \series default len); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXmc_setlen \end_layout \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_memcpy(hxmc_t \series bold ** \series default mc, \series bold const void * \series default ptr, \series bold size_t \series default len); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXmc_memcpy \end_layout \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_memcat(hxmc_t \series bold ** \series default mc, \series bold const void * \series default ptr, \series bold size_t \series default len); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXmc_memcat \end_layout \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_mempcat(hxmc_t \series bold ** \series default mc, \series bold const void * \series default ptr, \series bold size_t \series default len); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXmc_mempcat \end_layout \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_memins(hxmc_t \series bold ** \series default mc, \series bold size_t \series default pos, \series bold const void * \series default ptr, \series bold size_t \series default len); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_memins \end_layout \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_memdel(hxmc_t \series bold ** \series default mc, \series bold size_t \series default pos, \series bold size_t \series default len); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_memdel \end_layout \end_inset \end_layout \begin_layout Standard When \family typewriter ptr \family default is \family typewriter NULL \family default , each call behaves as if \family typewriter len \family default would be zero. Specifically, no undefined behavior will result of the use of \family typewriter NULL \family default . \end_layout \begin_layout Description \family typewriter HXmc_trunc \family default Truncates the container's data to \family typewriter len \family default size. If \family typewriter len \family default is greater than the current data size of the container, the length is in fact \shape italic not \shape default updated, but a reallocation may be triggered, which can be used to do explicit allocation. \end_layout \begin_layout Description \family typewriter HXmc_setlen \family default Set the data length, doing a reallocation of the memory container if needed. The newly available bytes are uninitialized. Make use of this function when letting 3rd party functions write to the buffer, but it should not be used with \family typewriter HXmc_str* \family default (), \end_layout \begin_layout Description \family typewriter HXmc_memcpy \family default Truncates the container's data and copies \family typewriter len \family default bytes from the memory area pointed to by \family typewriter ptr \family default to the container. \end_layout \begin_layout Description \family typewriter HXmc_memcat \family default Concatenates (appends) \family typewriter len \family default bytes from the memory area pointed to by \family typewriter ptr \family default to the container's data. \end_layout \begin_layout Description \family typewriter HXmc_mempcat \family default Prepends \family typewriter len \family default bytes from the memory area pointed to by \family typewriter ptr \family default to the container's data. \end_layout \begin_layout Description \family typewriter HXmc_memins \family default Prepends \family typewriter len \family default bytes from the memory area pointed to by \family typewriter ptr \family default to the \family typewriter pos \family default 'th byte of the container's data. \end_layout \begin_layout Description \family typewriter HXmc_memdel \family default Deletes \family typewriter len \family default bytes from the container beginning at position \family typewriter pos \family default . \end_layout \begin_layout Standard In case of a memory allocation failure, the \family typewriter HXmc_* \family default functions will return \family typewriter NULL \family default . \end_layout \begin_layout Subsubsection String-based \end_layout \begin_layout Standard The string-based functions correspond to their binary-based equivalents with a \family typewriter len \family default argument of \family typewriter strlen(s) \family default . \end_layout \begin_layout LyX-Code hxmc_t \series bold * \series default HXmc_strcpy(hxmc_t \series bold ** \series default mc, \series bold const char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXmc_strcpy \end_layout \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_strcat(hxmc_t \series bold ** \series default mc, \series bold const char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXmc_strcat \end_layout \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_strpcat(hxmc_t \series bold ** \series default mc, \series bold const char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXmc_strpcat \end_layout \end_inset \begin_inset Newline newline \end_inset hxmc_t \series bold * \series default HXmc_strins(hxmc_t \series bold ** \series default mc, \series bold size_t \series default pos, \series bold const char * \series default s); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXmc_strins \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HXmc_strcpy \family default Copies the string pointed to by \family typewriter s \family default into the memory container given by \family typewriter mc \family default . If \family typewriter mc \family default is \family typewriter NULL \family default , the memory container will be deallocated, that is, \family typewriter *mc \family default becomes \family typewriter NULL \family default . \end_layout \begin_layout Subsubsection From auxiliary sources \end_layout \begin_layout LyX-Code hxmc_t \series bold * \series default HX_getl(hxmc_t \series bold ** \series default mc, FILE \series bold * \series default fp); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_getl \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HX_getl \family default Read the next line from \family typewriter fp \family default and store the result in the container. Returns \family typewriter NULL \family default on error, or when end of file occurs while no characters have been read. \end_layout \begin_layout Subsection Container properties \end_layout \begin_layout LyX-Code \series bold size_t \series default HXmc_length( \series bold const \series default hxmc_t \series bold ** \series default mc); \end_layout \begin_layout Description \family typewriter HXmc_length \family default Returns the length of the memory container. This is not always equal to the actual string length. For example, if \family typewriter HX_chomp \family default was used on an MC-backed string, \family typewriter strlen \family default will return less than \family typewriter HXmc_length \family default if newline control characters ( \family typewriter ' \backslash r' \family default and \family typewriter ' \backslash n' \family default ) were removed. \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Format templates \begin_inset CommandInset label LatexCommand label name "sec:format" \end_inset \end_layout \begin_layout Standard HXfmt is a small template system for by-name variable expansion. It can be used to substitute placeholders in format strings supplied by the user by appropriate expanded values defined by the program. Such can be used to allow for flexible configuration files that define key-value mappings such as \end_layout \begin_layout LyX-Code detect_peer = ping6 -c1 %(ADDR) \begin_inset Newline newline \end_inset #detect_peer = nmap -sP %(ADDR) | grep -Eq "appears to be up" \end_layout \begin_layout Standard Consider for example a monitoring daemon that allows the administrator to specify a program of his choice with which to detect whether a peer is alive or not. The user can choose any program that is desired, but evidently needs to pass the address to be tested to the program. This is where the daemon will do a substitution of the string \begin_inset Quotes eld \end_inset \family typewriter ping -c1 %(ADDR) \family default \begin_inset Quotes erd \end_inset it read from the config file, and put the actual address in it before finally executing the command. \end_layout \begin_layout Standard \begin_inset Float figure placement H wide false sideways false status open \begin_layout LyX-Code printf("%s has %u files \backslash n", user, num); \begin_inset Newline newline \end_inset printf("%2$u files belong to %1$s \backslash n", num, user); \end_layout \begin_layout Plain Layout \begin_inset Quotes eld \end_inset \family typewriter %s \family default \begin_inset Quotes erd \end_inset (or \begin_inset Quotes eld \end_inset \family typewriter %1$s \family default \begin_inset Quotes erd \end_inset here) specifies how large \begin_inset Quotes eld \end_inset user \begin_inset Quotes erd \end_inset is \begin_inset space ~ \end_inset — \family typewriter sizeof(const char *) \family default in this case. If that is missing, there is no way to know the offset of \begin_inset Quotes eld \end_inset \family typewriter num \family default \begin_inset Quotes erd \end_inset relative to \begin_inset Quotes eld \end_inset \family typewriter user \family default \begin_inset Quotes erd \end_inset , making varargs retrieval impossible. \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout \family typewriter printf \family default positional parameters \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter printf \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter printf \end_layout \end_inset , at least from GNU libc, has something vaguely similar: positional parameters \begin_inset Index idx status open \begin_layout Plain Layout positional parameters \end_layout \end_inset . They have inherent drawbacks, though. One is of course the question of portability, but there is a bigger issue. All parameters must be specified, otherwise there is no way to determine the location of all following objects following the missing one on the stack in a varargs-function like \family typewriter printf \family default ., which makes it unsuitable to be used with templates where omitting some placeholders is allowed. \end_layout \begin_layout Subsection Initialization, use and deallocation \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/option.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXformat_map \series bold * \series default HXformat_init( \series bold void \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXformat_init \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXformat_free( \series bold struct \series default HXformat_map \series bold * \series default table); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXformat_free \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HXformat_add( \series bold struct \series default HXformat_map \series bold * \series default table, \series bold const char * \series default key, \begin_inset Newline newline \end_inset \series bold const void * \series default ptr, \series bold unsigned int \series default ptr_type); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXformat_add \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter HXformat_init \family default will allocate and set up a simple string-to-string map that is used for the underlying storage, and returns it. \end_layout \begin_layout Standard To release the substitution table and memory associated with it, call \family typewriter HXformat_free \family default . \end_layout \begin_layout Standard \family typewriter HXformat_add \family default is used to add substitution entries. One can also specify other types such as numeral types. \family typewriter ptr_type \family default describes the type behind \family typewriter ptr \family default and are constants from \family typewriter option.h \family default (cf. \begin_inset space \space{} \end_inset section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:option-types" \end_inset ) \begin_inset space ~ \end_inset — not all constants can be used, though, and their meaning also differs from what \family typewriter HX_getopt \family default or \family typewriter HX_shconfig \family default use them for \begin_inset space ~ \end_inset — the two could be seen as \begin_inset Quotes eld \end_inset read \begin_inset Quotes erd \end_inset operations, while HXformat is a write operation. \end_layout \begin_layout Subsubsection Immediate types \end_layout \begin_layout Standard \begin_inset Quotes eld \end_inset Immediate types \begin_inset Quotes erd \end_inset are resolved when \family typewriter HXformat_add \family default is called, that is, they are copied and inserted into the tree, and are subsequently independent from any changes to variables in the program. Because the HXopt-originating type name, that is, \family typewriter HXTYPE_* \family default , is also used for deferred types, the constant \family typewriter HXFORMAT_IMMED \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXFORMAT_IMMED \end_layout \end_inset \family default needs to be specified on some types to denote an immediate value. \end_layout \begin_layout Itemize \family typewriter HXTYPE_STRING \family default \begin_inset space ~ \end_inset — \family typewriter ptr \family default is a \family typewriter const char * \family default . \end_layout \begin_layout Itemize \family typewriter HXTYPE_ \family default { \family typewriter U \family default ,}{ \family typewriter CHAR \family default , \family typewriter SHORT \family default , \family typewriter INT \family default , \family typewriter LONG \family default , \family typewriter LLONG \family default } \family typewriter | HXFORMAT_IMMED \family default \begin_inset space ~ \end_inset — mapping to the standard types \end_layout \begin_layout Subsubsection Deferred types \end_layout \begin_layout Standard \begin_inset Quotes eld \end_inset Deferred types \begin_inset Quotes erd \end_inset are resolved on every invocation of a formatter function ( \family typewriter HXformat_*printf \family default ). The expansions may be changed by modifying the underlying variable pointed to, but the pointer must remain valid and its pointee not go out of scope. Figure \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "fig:hxformat-immediate-deferred" \end_inset shows the difference in a code sample. \end_layout \begin_layout Itemize \family typewriter HXTYPE_STRP \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_STRP \end_layout \end_inset \begin_inset space ~ \end_inset — \family typewriter ptr \family default is a \family typewriter const char *const * \family default ; the pointer resolution is deferred until the formatter is called with one of the \family typewriter HXformat_*printf \family default functions. Deferred in the sense it is always resolved anew. \end_layout \begin_layout Itemize \family typewriter HXTYPE_BOOL \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_BOOL \end_layout \end_inset \begin_inset space ~ \end_inset — \family typewriter ptr \family default is a \family typewriter const int \begin_inset space ~ \end_inset * \family default . \end_layout \begin_layout Itemize \family typewriter HXTYPE_ \family default { \family typewriter U \family default ,}{ \family typewriter CHAR \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_CHAR \end_layout \end_inset \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_UCHAR \end_layout \end_inset , \family typewriter SHORT \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_SHORT \end_layout \end_inset \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_USHORT \end_layout \end_inset , \family typewriter INT \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_INT \end_layout \end_inset \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_UINT \end_layout \end_inset , \family typewriter LONG \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_LONG \end_layout \end_inset \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_ULONG \end_layout \end_inset , \family typewriter LLONG \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_LLONG \end_layout \end_inset \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_ULLONG \end_layout \end_inset } \begin_inset space ~ \end_inset — mapping to the standard types with one indirection (e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset \family typewriter int \begin_inset space ~ \end_inset * \family default ) \end_layout \begin_layout Itemize \family typewriter HXTYPE_ \family default { \family typewriter FLOAT \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_FLOAT \end_layout \end_inset , \family typewriter DOUBLE \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_DOUBLE \end_layout \end_inset } \begin_inset space ~ \end_inset — mapping to the two floating-point types with one indirection (e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset \family typewriter double \begin_inset space ~ \end_inset * \family default ) \end_layout \begin_layout Subsection Invoking the formatter \end_layout \begin_layout LyX-Code \series bold int \series default HXformat_aprintf( \series bold struct \series default HXformat_map \series bold * \series default table, hxmc_t \series bold ** \series default dest, \series bold const char * \series default template); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXformat_aprintf \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HXformat_sprintf( \series bold struct \series default HXformat_map \series bold * \series default table, \series bold char * \series default dest, \series bold size_t \series default size, \series bold const char * \series default template); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXformat_sprintf \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HXformat_fprintf( \series bold struct \series default HXformat_map \series bold * \series default table, FILE \series bold * \series default filp, \series bold const char * \series default template); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXformat_fprintf \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HXformat_aprintf \family default Substitute placeholders in \family typewriter template \family default using the given table. This will produce a string in a HX memory container ( \family typewriter hxmc_t \family default ), and the pointer is put into \family typewriter *dest \family default . The caller will be responsible for freeing it later when it is done using the result. \end_layout \begin_layout Description \family typewriter HXformat_sprintf \family default Do substitution and store the expanded result in the buffer \family typewriter dest \family default which is of size \family typewriter size \family default . \end_layout \begin_layout Description \family typewriter HXformat_fprintf \family default Do substituion and directly output the expansion to the given stdio stream. \end_layout \begin_layout Standard On success, the length of the expanded string is returned, excluding the trailing \family typewriter ' \backslash 0' \family default . While \family typewriter HXformat_sprintf \family default will not write more than \family typewriter size \family default bytes (including the \family typewriter ' \backslash 0' \family default ), the length it would have taken is returned, similar to what \family typewriter sprintf \family default does. On error, negative errno is returned. \end_layout \begin_layout Standard The HXformat function family recognizes make-style like functions and recursive expansion, described below. \end_layout \begin_layout Subsection Functions \end_layout \begin_layout Standard To expand a variable, one uses a syntax like \begin_inset Quotes eld \end_inset \family typewriter %(NAME) \family default \begin_inset Quotes erd \end_inset in the format string. Recursive expansion like \begin_inset Quotes eld \end_inset \family typewriter %(%(USER)) \family default \begin_inset Quotes erd \end_inset is supported; assuming \family typewriter %(USER) \family default would expand to \begin_inset Quotes eld \end_inset linux \begin_inset Quotes erd \end_inset , HXformat would try to resolve \begin_inset Quotes eld \end_inset \family typewriter %(linux) \family default \begin_inset Quotes erd \end_inset next. Besides these variable substitutions, HXformat also provides function calls whose syntax is \begin_inset Quotes eld \end_inset \family typewriter %(nameOfFunction parameters[...]) \family default \begin_inset Quotes erd \end_inset . Parameters can be any text, including variables. Paramters are separated from another by a delimiter specific to each function. See this list for details: \end_layout \begin_layout Itemize \family typewriter %(env \family default \shape italic variable \family typewriter \shape default ) \begin_inset Newline newline \end_inset \family default The \family typewriter env \family default function expands to the string that is stored in the environmental variable by the given name. \end_layout \begin_layout Itemize \family typewriter %(exec \family default \shape italic command \family typewriter \shape default \family default [ \shape italic args \shape default ...] \family typewriter ) \family default \begin_inset Newline newline \end_inset The \family typewriter exec \family default function expands to the standard output of the command. The command is directly run without shell invocation, so no special character expansion (wildcards, etc.) takes place. stdin is set to \family typewriter /dev\SpecialChar breakableslash null \family default . The parameter delimiter is the space character. To be able to use this function \begin_inset space ~ \end_inset — as it is relevant to security \begin_inset space ~ \end_inset — the fmt table needs to have a key called \begin_inset Quotes eld \end_inset \family typewriter /libhx/exec \family default \begin_inset Quotes erd \end_inset . See example \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "fig:hxformat-exec" \end_inset for details. \end_layout \begin_layout Itemize \family typewriter %(if \family default \shape italic condition \family typewriter \shape default , \family default [ \shape italic then \shape default ][ \family typewriter , \family default [ \shape italic else \shape default ]] \family typewriter ) \family default \begin_inset Newline newline \end_inset If the condition parameter expands to a string of non-zero length, the function expands to the \begin_inset Quotes eld \end_inset then \begin_inset Quotes erd \end_inset block, otherwise the \begin_inset Quotes eld \end_inset else \begin_inset Quotes erd \end_inset block. The delimiter used is a comma. \end_layout \begin_layout Itemize \family typewriter %(lower \family default \shape italic text \family typewriter \shape default ) \family default , \family typewriter %(upper \family default \shape italic text \family typewriter \shape default ) \family default \begin_inset Newline newline \end_inset Lowercases or uppercases the supplied argument. As these functions are meant to take only one argument, there is no delimiter defined that would need escaping if multiple arguments were supposed to be passed. \family typewriter %(lower a,b) \family default is equivalent to \family typewriter %(lower "a,b") \family default . \end_layout \begin_layout Itemize \family typewriter %(shell \family default \shape italic command \family typewriter \shape default \family default [ \shape italic args \shape default ...] \family typewriter ) \family default \begin_inset Newline newline \end_inset Similar to \family typewriter %(exec) \family default , but invokes the shell inbetween (i. \begin_inset space \thinspace{} \end_inset e. \begin_inset space \space{} \end_inset ` \family typewriter sh -c ' \family default \shape italic command \shape default ... \family typewriter ' \family default `) such that special characters, redirection, and so on can be used. \end_layout \begin_layout Itemize \family typewriter %(substr \family default \shape italic text \family typewriter \shape default , \family default \shape italic offset \shape default [ \family typewriter , \family default \shape italic length \shape default ] \family typewriter ) \family default \begin_inset Newline newline \end_inset Extracts a substring out of the given text, starting at \shape italic offset \shape default and running for the given length. If no length is given, will extract until the end of the string. If \shape italic offset \shape default is negative, it specifies the offset from the end of the string. If \shape italic length \shape default is negative, that many characters are left off the end. \end_layout \begin_layout Itemize \family typewriter %(snl \family default \shape italic text \family typewriter \shape default ) \family default \begin_inset Newline newline \end_inset Strips trailing newlines from text and replaces any other newline by a space. What happens implicity in Makefiles' \family typewriter $(shell \family default ... \family typewriter ) \family default statements usually is explicitly separate in libHX. \end_layout \begin_layout Subsection Examples \end_layout \begin_layout Standard \begin_inset Float figure placement H wide false sideways false status open \begin_layout LyX-Code \series bold const char * \series default b = "Hello World"; \begin_inset Newline newline \end_inset \family typewriter \series bold char \series default c \family default \series bold [] \family typewriter \series default = "Hello World"; \family default \begin_inset Newline newline \end_inset \family typewriter \series bold struct \series default HXformat_map \series bold * \series default table = HXformat_init(); \begin_inset Newline newline \end_inset HXformat_add(table, "%(GREETING1)", b, HXTYPE_STRING); \begin_inset Newline newline \end_inset HXformat_add(table, "%(GREETING2)", &c, HXTYPE_STRP); \begin_inset Newline newline \end_inset b = NULL; \begin_inset Newline newline \end_inset snprintf(c, \family default \series bold sizeof \family typewriter \series default (c), "Hello Home"); \begin_inset Newline newline \end_inset HXformat_aprintf(...); \end_layout \begin_layout Plain Layout Upon calling \family typewriter HXformat_*printf \family default , \family typewriter %(GREETING1) \family default will expand to \begin_inset Quotes eld \end_inset Hello World \begin_inset Quotes erd \end_inset whereas \family typewriter %(GREETING2) \family default will expand to \begin_inset Quotes eld \end_inset Hello Home \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:hxformat-immediate-deferred" \end_inset Immediate and deferred resolution \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout LyX-Code \series bold struct \series default HXformat_map \series bold * \series default table = HXformat_init(); \begin_inset Newline newline \end_inset HXformat_add(table, "/libhx/exec", NULL, HXTYPE_IMMED); \begin_inset Newline newline \end_inset HXformat_aprintf(table, &result, "%(exec uname -s)"); \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout \begin_inset CommandInset label LatexCommand label name "fig:hxformat-exec" \end_inset Using the \family typewriter %(exec) \family default function \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Part Filesystem operations \end_layout \begin_layout Section Dentry operations \end_layout \begin_layout Subsection Synopsis \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_readlink(hxmc_t \series bold ** \series default buf, \series bold const char * \series default path); \begin_inset Index idx status open \begin_layout Plain Layout HX_readlink \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_realpath(hxmc_t \series bold ** \series default buf, \series bold const char * \series default path, \series bold unsigned int \series default flags); \begin_inset Index idx status open \begin_layout Plain Layout HX_realpath \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter HX_readlink \family default calls through to \family typewriter readlink \family default to read the target of a symbolic link, and stores the result in the memory container referenced by \family typewriter *buf \family default (similar to \family typewriter HX_getl \family default semantics). If \family typewriter *buf \family default is \family typewriter NULL \family default , a new container will be allocated and a pointer to it stored in \family typewriter *buf \family default . The container's content is naturally zero-terminated automatically. The return value of the function will be the length of the link target, or negative to indicate the system error value. \end_layout \begin_layout Standard \family typewriter HX_realpath \family default will normalize the given path by transforming various path components into alternate descriptions. The \family typewriter flags \family default parameter controls its actions: \end_layout \begin_layout Description \family typewriter HX_REALPATH_DEFAULT \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_REALPATH_DEFAULT \end_layout \end_inset A mnemonic for a set of standard flags: \family typewriter HX_\SpecialChar softhyphen REALPATH_\SpecialChar softhyphen SELF \begin_inset space ~ \end_inset | HX_\SpecialChar softhyphen REALPATH_\SpecialChar softhyphen PARENT \family default . Note that \family typewriter HX_\SpecialChar softhyphen REALPATH_\SpecialChar softhyphen ABSOLUTE \family default , which would also be required to get libc's \family typewriter realpath \family default (3) behavior, is not included in the set. \end_layout \begin_layout Description \family typewriter HX_REALPATH_ABSOLUTE \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_REALPATH_ABSOLUTE \end_layout \end_inset Requests that the output path shall be absolute. In the absence of this flag, an absolute output path will only be produced if the input path is also absolute. \end_layout \begin_layout Description \family typewriter HX_REALPATH_SELF \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_REALPATH_SELF \end_layout \end_inset Request resolution of \begin_inset Quotes eld \end_inset . \begin_inset Quotes erd \end_inset path components. \end_layout \begin_layout Description \family typewriter HX_REALPATH_PARENT \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_REALPATH_PARENT \end_layout \end_inset Request resolution of \begin_inset Quotes eld \end_inset .. \begin_inset Quotes erd \end_inset path components. \end_layout \begin_layout Standard The result is stored in a memory container whose pointer is returned through \family typewriter *buf \family default . The return value of the function will be negative to indicate a possible system error, or be positive non-zero for success. \end_layout \begin_layout Section Directory traversal \begin_inset CommandInset label LatexCommand label name "sec:dir-ops1" \end_inset \end_layout \begin_layout Standard libHX provides a minimal readdir-style wrapper for cross-platform directory traversal. This is needed because the Win32 platforms does not have readdir, and there is some housekeeping to do on Unixish platforms, since the \family typewriter dirent \family default structure needs allocation of a path-specific size. \end_layout \begin_layout Subsection Synopsis \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/io.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXdir \series bold * \series default HXdir_open( \series bold const char * \series default directory); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXdir_open \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold const char * \series default HXdir_read( \series bold struct \series default HXdir \series bold * \series default handle); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXdir_read \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold void \series default HXdir_close( \series bold struct \series default HXdir \series bold * \series default handle); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXdir_close \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter HXdir_open \family default returns a pointer to its private data area, or \family typewriter NULL \family default upon failure, in which case \family typewriter errno \family default is preserved from the underlying system calls. \family typewriter HXdir_read \family default causes the next entry from the directory to be fetched. The pointer returned by \family typewriter HXdir_read \family default must not be freed, and the data is overwritten in subsequent calls to the same handle. If you want to keep it around, you will have to duplicate it yourself. \family typewriter HXdir_close \family default will close the directory and free the private data it held. \end_layout \begin_layout Subsection Example \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXdir \series bold * \series default dh; \begin_inset Newline newline \end_inset \series bold if \series default ((dh = HXdir_open(".")) == NULL) { \begin_inset Newline newline \end_inset fprintf(stderr, "Could not open directory: %s \backslash n", strerror(errno)); \begin_inset Newline newline \end_inset return; \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \series bold while \series default ((dentry = HXdir_read(dh)) != NULL) \begin_inset Newline newline \end_inset printf("%s \backslash n", dentry); \begin_inset Newline newline \end_inset HXdir_close(dh); \end_layout \begin_layout Standard This sample will open the current directory, and print out all entries as it iterates over them. \end_layout \begin_layout Section Directory operations \begin_inset CommandInset label LatexCommand label name "sec:dir-ops2" \end_inset \end_layout \begin_layout Subsection Synopsis \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/io.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_mkdir( \series bold const char * \series default path, \series bold unsigned int \series default mode); \begin_inset Index idx status open \begin_layout Plain Layout HX_mkdir \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_rrmdir( \series bold const char * \series default path); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_rrmdir \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter HX_mkdir \family default will create the directory given by \family typewriter path \family default and all its parents that do not exist yet using the given \family typewriter mode \family default . It is equivalent to the ` \family typewriter mkdir -p \family default ` shell command. It will return >0 for success, or \family typewriter -errno \family default on error. \end_layout \begin_layout Standard \family typewriter HX_rrmdir \family default also maps to an operation commonly done on the shell, ` \family typewriter rm -Rf \family default `, deleting the directory given by \family typewriter path \family default , including all files within it and its subdirectories. Errors during deletion are ignored, but if there was any, the errno value of the first one is returned negated. \end_layout \begin_layout Section File operations \begin_inset CommandInset label LatexCommand label name "sec:file-ops" \end_inset \end_layout \begin_layout Subsection Synopsis \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/io.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_copy_file( \series bold const char * \series default src, \series bold const char * \series default dest, \series bold unsigned int \series default flags, ...); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_copy_file \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_copy_dir( \series bold const char * \series default src, \series bold const char * \series default dest, \series bold unsigned int \series default flags, ...); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_copy_dir \end_layout \end_inset \end_layout \begin_layout Standard Possible flags that can be used with the functions: \end_layout \begin_layout Description \family typewriter HXF_KEEP \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXF_KEEP \end_layout \end_inset Do not overwrite existing files. \end_layout \begin_layout Description \family typewriter HXF_UID \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXF_UID \end_layout \end_inset Change the new file's owner to the UID given in the varargs section ( \family typewriter ... \family default ). \family typewriter HXF_UID \family default is processed before \family typewriter HXF_GID \family default . \end_layout \begin_layout Description \family typewriter HXF_GID \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXF_GID \end_layout \end_inset Change the new file's group owner to the GID given in the varargs section. This is processed after \family typewriter HXF_UID \family default . \end_layout \begin_layout Standard Error checking is flakey. \end_layout \begin_layout Standard \family typewriter HX_copy_file \family default will return >0 on success, or \family typewriter -errno \family default on failure. Errors can arise from the use of the syscalls \family typewriter open \family default , \family typewriter read \family default and \family typewriter write \family default . The return value of \family typewriter fchmod \family default , which is used to set the UID and GID, is actually ignored, which means verifying that the owner has been set cannot be detected with \family typewriter HX_copy_file \family default alone (historic negligience?). \end_layout \begin_layout Subsection Filedescriptor I/O \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/io.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold ssize_t \series default HXio_fullread( \series bold int \series default fd, \series bold void * \series default buf, \series bold size_t \series default size, \series bold unsigned int \series default flags); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXio_fullread \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold ssize_t \series default HXio_fullwrite( \series bold int \series default fd, \series bold const void * \series default buf, \series bold size_t \series default size, \series bold unsigned int \series default flags); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXio_fullwrite \end_layout \end_inset \end_layout \begin_layout Standard Since plain \family typewriter read \family default (2) and \family typewriter write \family default (2) may process only part of the buffer \begin_inset space ~ \end_inset — even more likely so with sockets \begin_inset space ~ \end_inset —, libHX provides two functions that calls these in a loop to retry said operations until the full amount has been processed. Since \family typewriter read \family default and \family typewriter write \family default can also be used with socket file descriptors, so can these. \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Part Options and Configuration Files \end_layout \begin_layout Section Option parsing \begin_inset CommandInset label LatexCommand label name "sec:option" \end_inset \end_layout \begin_layout Standard libHX uses a table-based approach like libpopt \begin_inset Foot status open \begin_layout Plain Layout The alternative would be an iterative, open-coded approach like \family typewriter getopt \family default (3) requires. \end_layout \end_inset . It provides for both long and short options and the different styles associated with them, such as absence or presence of an equals sign for long options ( \family typewriter --foo=bar \family default and \family typewriter --foo bar \family default ), bundling (writing \family typewriter -abc \family default for non-argument taking options \family typewriter -a -b -c \family default ), squashing (writing \family typewriter -fbar \family default for an argument-requiring option \family typewriter -f \begin_inset space ~ \end_inset bar \family default ). The \begin_inset Quotes eld \end_inset lone dash \begin_inset Quotes erd \end_inset that is often used to indicate standard input or standard output, is correctly handled \begin_inset Foot status open \begin_layout Plain Layout popt failed to do this for a long time. \end_layout \end_inset , as in \family typewriter -f \begin_inset space ~ \end_inset - \family default . \end_layout \begin_layout Standard A table-based approach allows for the parser to run as one atomic block of code (callbacks are, by definition, \begin_inset Quotes eld \end_inset special \begin_inset Quotes erd \end_inset exceptions), making it more opaque than an open-coded \family typewriter getopt \family default (3) loop. You give it your argument vector and the table, snip the finger (call the parser function once), and it is done. In getopt on the other hand, the \family typewriter getopt \family default function returns for every argument it parsed and needs to be called repeatedly. \end_layout \begin_layout Subsection Synopsis \begin_inset CommandInset label LatexCommand label name "subsec:option-synopsis" \end_inset \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/option.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXoption { \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter struct HXoption \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold const char \series default *ln; \begin_inset Newline newline \end_inset \series bold char \series default sh; \begin_inset Newline newline \end_inset \series bold unsigned int \series default type; \begin_inset Newline newline \end_inset \series bold void * \series default ptr, \series bold * \series default uptr; \begin_inset Newline newline \end_inset \series bold void (* \series default cb \series bold ) \series default ( \series bold const struct \series default HXoptcb \series bold * \series default ); \begin_inset Newline newline \end_inset \series bold int \series default val; \begin_inset Newline newline \end_inset \series bold const char * \series default help, \series bold * \series default htyp; \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_getopt( \series bold const struct \series default HXoption \series bold * \series default options_table, \series bold int * \series default argc, \begin_inset Newline newline \end_inset \series bold const char *** \series default argv, \series bold unsigned int \series default flags); \end_layout \begin_layout Standard The various fields of \family typewriter struct HXoption \family default are: \end_layout \begin_layout Description \family typewriter ln \family default The long option name, if any. May be \family typewriter NULL \family default if none is to be assigned for this entry. \end_layout \begin_layout Description \family typewriter sh \family default The short option name/character, if any. May be \family typewriter ' \backslash 0' \family default if none is to be assigned for this entry. \end_layout \begin_layout Description \family typewriter type \family default The type of the entry, essentially denoting the type of the target variable. \end_layout \begin_layout Description \family typewriter val \family default An integer value to be stored into \family typewriter *(int \begin_inset space ~ \end_inset *)ptr \family default when \family typewriter HXTYPE_IVAL \family default is used. \end_layout \begin_layout Description \family typewriter ptr \family default A pointer to the variable so that the option parser can store the requested data in it. The pointer may be \family typewriter NULL \family default in which case no data is stored (but \family typewriter cb \family default is still called if defined, with the data). \end_layout \begin_layout Description \family typewriter uptr \family default A user-supplied pointer. Its value is passed verbatim to the callback, and may be used for any purpose the user wishes. If \family typewriter type \family default is \family typewriter HXTYPE_SVAL \family default , it is the value in \family typewriter uptr \family default that will be used to populate \family typewriter *(const char \begin_inset space ~ \end_inset **)ptr \family default . (The original \family typewriter .sval \family default field has been removed in libHX 3.12.) \end_layout \begin_layout Description \family typewriter cb \family default If not \family typewriter NULL \family default , call out to the referenced function after the option has been parsed (and the results possibly be stored in \family typewriter ptr \family default ) \end_layout \begin_layout Description \family typewriter help \family default A help string that is shown for the option when the option table is dumped by request (e. \begin_inset space \thinspace{} \end_inset g. \begin_inset space \space{} \end_inset \family typewriter yourprgram --help \family default ) \end_layout \begin_layout Description \family typewriter htyp \family default String containing a keyword to aid the user in understanding the available options during dump. See examples. \end_layout \begin_layout Standard Due to the amount of fields, it is advised to use C99 named initializers to populate a struct, as they allow to omit unspecified fields, and assume no specific order of the members: \end_layout \begin_layout LyX-Code \series bold struct \series default HXoption e = {.sh = 'f', .help = "Force"}; \end_layout \begin_layout Standard It is a sad fact that C++ has not gotten around to implement these yet. It is advised to put the option parsing code into a separate \family typewriter .c \family default file that can then be compiled in C99 rather than C++ mode. \end_layout \begin_layout Subsection Type map \begin_inset CommandInset label LatexCommand label name "subsec:option-types" \end_inset \end_layout \begin_layout Description \family typewriter HXTYPE_NONE \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXTYPE_NONE \end_layout \end_inset \family default \series default The option does not take any argument, but the presence of the option may be record by setting the \family typewriter *(int \begin_inset space ~ \end_inset *)ptr \family default to 1. Other rules apply when \family typewriter HXOPT_\SpecialChar softhyphen INC \family default or \family typewriter HXOPT_\SpecialChar softhyphen DEC \family default are specified as flags (see section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:option-flags" \end_inset ). \end_layout \begin_layout Description \family typewriter HXTYPE_VAL \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXTYPE_VAL \end_layout \end_inset \family default \series default Use the integer value specified by \family typewriter ival \family default and store it in \family typewriter *(int \begin_inset space ~ \end_inset *)ptr \family default . \end_layout \begin_layout Description \family typewriter HXTYPE_SVAL \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXTYPE_SVAL \end_layout \end_inset \family default \series default Use the memory location specified by \family typewriter sval \family default and store it in \family typewriter *(const char \begin_inset space ~ \end_inset **)ptr \family default . \end_layout \begin_layout Description \family typewriter HXTYPE_BOOL \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXTYPE_BOOL \end_layout \end_inset \family default \series default Interpret the supplied argument as a boolean descriptive (must be \begin_inset Quotes eld \end_inset yes \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset no \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset on \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset off \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset true \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset false \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset 0 \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset 1 \begin_inset Quotes erd \end_inset ) and store the result in \family typewriter *(int \begin_inset space ~ \end_inset *)ptr \family default . \end_layout \begin_layout Description \family typewriter HXTYPE_STRING \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_STRING \end_layout \end_inset \family default The argument string is duplicated to a new memory region and the resulting pointer stored into \family typewriter *(char \begin_inset space ~ \end_inset **)ptr \family default . This incurs an allocation so that subsequently modifying the original argument string in any way will not falsely propagate. \end_layout \begin_layout Description \family typewriter HXTYPE_STRDQ \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXTYPE_STRDQ \end_layout \end_inset \family default \series default The argument string is duplicated to a new memory region and the resulting pointer is added to the given HXdeque. Note that you often need to use deferred initialization of the options table to avoid putting \family typewriter NULL \family default into the entry. See section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:option-pitfalls-static" \end_inset . \end_layout \begin_layout Standard The following table lists the types that map to the common integral and floating-point types. Signed and unsigned integeral types are processed using \family typewriter strtol \family default and \family typewriter strtoul \family default , respectively. \family typewriter strtol \family default and \family typewriter strtoul \family default will be called with automatic base detection. This usually means that a leading \begin_inset Quotes eld \end_inset 0 \begin_inset Quotes erd \end_inset indicates the string is given in octal (8) base, a leading \begin_inset Quotes eld \end_inset 0x \begin_inset Quotes erd \end_inset indicates hexadecimal (16) base, and decimal (10) otherwise. \family typewriter HXTYPE_\SpecialChar softhyphen LLONG \family default , \family typewriter HXTYPE_\SpecialChar softhyphen ULLONG \family default , \family typewriter HXTYPE_\SpecialChar softhyphen INT64 \family default and \family typewriter HXTYPE_\SpecialChar softhyphen UINT64 \family default use \family typewriter strtoll \family default and/or \family typewriter strtoull \family default , which may not be available on all platforms. \begin_inset Separator latexpar \end_inset \end_layout \begin_layout Standard \align center \begin_inset Float table placement H wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout \family typewriter \series bold type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Type of pointee \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \series bold Type of pointee \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_CHAR \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_CHAR \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter char \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_INT8 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_INT8 \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter int8_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_UCHAR \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_UCHAR \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter unsigned char \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_UINT8 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_UINT8 \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter uint8_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_SHORT \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_SHORT \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_INT16 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_INT16 \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter int16_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_USHORT \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_USHORT \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter unsigned short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_UINT16 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_UINT16 \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter uint16_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_INT \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_INT \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter int \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_INT32 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_INT32 \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter int32_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_UINT \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_UINT \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter unsigned int \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_UINT32 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_UINT32 \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter uint32_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_LONG \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_LONG \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_INT64 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_INT64 \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter int64_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_ULONG \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_ULONG \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter unsigned long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_UINT64 \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_UINT64 \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter uint64_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_LLONG \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_LLONG \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter long long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_FLOAT \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_FLOAT \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter float \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_ULLONG \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_ULLONG \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter unsigned long long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_DOUBLE \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_DOUBLE \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter HXTYPE_SIZE_T \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXTYPE_SIZE_T \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family typewriter size_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption Standard \begin_layout Plain Layout Integral and floating-point types for the libHX option parser \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter HXTYPE_\SpecialChar softhyphen FLOAT \family default and \family typewriter HXTYPE_\SpecialChar softhyphen DOUBLE \family default make use of \family typewriter strtod \family default ( \family typewriter strtof \family default is not used). A corresponding \family typewriter type \family default for the \begin_inset Quotes eld \end_inset long double \begin_inset Quotes erd \end_inset format is not specified, but may be implemented on behalf of the user via a callback (see section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:option-example-cb" \end_inset ). \end_layout \begin_layout Subsection Flags \begin_inset CommandInset label LatexCommand label name "subsec:option-flags" \end_inset \end_layout \begin_layout Standard Flags can be combined into the \family typewriter type \family default parameter by OR'ing them. It is valid to not specify any flags at all, but most flags collide with one another. \end_layout \begin_layout Description \family typewriter HXOPT_INC \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_INC \end_layout \end_inset \family default \series default Perform an increment on the memory location specified by the \family typewriter *(int \begin_inset space ~ \end_inset *)ptr \family default pointer. Make sure the referenced variable is initialized before! \end_layout \begin_layout Description \family typewriter HXOPT_DEC \family default \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXOPT_DEC \end_layout \end_inset \series default Perform a decrement on the pointee. \end_layout \begin_layout Standard Only one of \family typewriter HXOPT_\SpecialChar softhyphen INC \family default and \family typewriter HXOPT_\SpecialChar softhyphen DEC \family default may be specified at a time, and they require that the base type is \family typewriter HXTYPE_\SpecialChar softhyphen NONE \family default , or they will have no effect. An example may be found in section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:option-example-incdec" \end_inset . \end_layout \begin_layout Description \family typewriter HXOPT_NOT \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_NOT \end_layout \end_inset \family default \series default Binary negation of the argument directly after reading it from the command line into memory. Any of the three following operations are executed with the already-negated value. \end_layout \begin_layout Description \family typewriter HXOPT_OR \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXOPT_OR \end_layout \end_inset \family default \series default Binary \begin_inset Quotes eld \end_inset OR \begin_inset Quotes erd \end_inset s the pointee with the specified\SpecialChar breakableslash transformed value. \end_layout \begin_layout Description \family typewriter HXOPT_AND \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_AND \end_layout \end_inset \family default \series default Binary \begin_inset Quotes eld \end_inset AND \begin_inset Quotes erd \end_inset s the pointee with the specified\SpecialChar breakableslash transformed value. \end_layout \begin_layout Description \family typewriter HXOPT_XOR \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_XOR \end_layout \end_inset \family default \series default Binary \begin_inset Quotes eld \end_inset XOR \begin_inset Quotes erd \end_inset s the pointee with the specified\SpecialChar breakableslash transformed value. \end_layout \begin_layout Standard Only one of ( \family typewriter HXOPT_OR \family default , \family typewriter HXOPT_\SpecialChar softhyphen AND \family default , \family typewriter HXOPT_\SpecialChar softhyphen XOR \family default ) may be specified at a time, but they can be used with any integral \family typewriter type \family default ( \family typewriter HXTYPE_\SpecialChar softhyphen UINT \family default , \family typewriter HXTYPE_\SpecialChar softhyphen ULONG \family default , etc.). An example can be found in section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:option-example-mask" \end_inset . \end_layout \begin_layout Description \family typewriter HXOPT_OPTIONAL \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_OPTIONAL \end_layout \end_inset \family default \series default This flag allows for an option to take zero or one argument. Needless to say that this can be confusing to the user. \shape italic iptables \shape default 's \begin_inset Quotes eld \end_inset \family typewriter -L \family default \begin_inset Quotes erd \end_inset option for example is one of this kind (though it does not use the libHX option parser). When this flag is used, \begin_inset Quotes eld \end_inset \family typewriter -f -b \family default \begin_inset Quotes erd \end_inset is interpreted as \family typewriter -f \family default without an argument, as is \begin_inset Quotes eld \end_inset \family typewriter -f --bar \family default \begin_inset Quotes erd \end_inset \begin_inset space ~ \end_inset — things that look like an option take precedence over an option with an optional argument. \begin_inset Quotes eld \end_inset \family typewriter -f - \family default \begin_inset Quotes erd \end_inset of course denotes an option with an argument, as \begin_inset Quotes eld \end_inset \family typewriter - \family default \begin_inset Quotes erd \end_inset is used to indicate standard input/output. \end_layout \begin_layout Subsection Special entries \end_layout \begin_layout Standard HXopt provides two special entries via macros: \end_layout \begin_layout Description \family typewriter HXOPT_AUTOHELP \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_AUTOHELP \end_layout \end_inset \family default \series default Adds entries to recognize \begin_inset Quotes eld \end_inset \family typewriter -? \family default \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset \family typewriter --help \family default \begin_inset Quotes erd \end_inset that will display the (long-format) help screen, and \begin_inset Quotes eld \end_inset \family typewriter --usage \family default \begin_inset Quotes erd \end_inset that will display the short option syntax overview. All three options will exit the program afterwards. \end_layout \begin_layout Description \family typewriter HXOPT_TABLEEND \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_TABLEEND \end_layout \end_inset \family default \series default This sentinel marks the end of the table and is required on all tables. (See examples for details.) \end_layout \begin_layout Subsection Invoking the parser \end_layout \begin_layout LyX-Code \series bold int \series default HX_getopt( \series bold const struct \series default HXoption \series bold * \series default options_table, \series bold int * \series default argc, \begin_inset Newline newline \end_inset \series bold const char *** \series default argv, \series bold unsigned int \series default flags); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_getopt \end_layout \end_inset \end_layout \begin_layout Standard \family typewriter HX_getopt \family default is the actual parsing function. It takes the option table, and a pointer to your \family typewriter argc \family default and \family typewriter argv \family default variables that you get from the \family typewriter main \family default function. The parser will, unlike GNU getopt, literally \begin_inset Quotes eld \end_inset eat \begin_inset Quotes erd \end_inset all options and their arguments, leaving only non-options in \family typewriter argv \family default , and \family typewriter argc \family default updated, when finished. This is similar to how Perl's \begin_inset Quotes eld \end_inset Getopt::Long \begin_inset Quotes erd \end_inset module works. Additional flags can control the exact behavior of \family typewriter HX_getopt \family default : \end_layout \begin_layout Description \family typewriter HXOPT_PTHRU \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_PTHRU \end_layout \end_inset \family default \series default \begin_inset Quotes eld \end_inset Passthrough mode \begin_inset Quotes erd \end_inset . Any unknown options are not \begin_inset Quotes eld \end_inset eaten \begin_inset Quotes erd \end_inset and are instead passed back into the resulting \family typewriter argv \family default array. \end_layout \begin_layout Description \family typewriter HXOPT_QUIET \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_QUIET \end_layout \end_inset \family default \series default Do not print any diagnostics when encountering errors in the user's input. \end_layout \begin_layout Description \family typewriter HXOPT_HELPONERR \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXOPT_HELPONERR \end_layout \end_inset \family default \series default Display the (long-format) help when an error, such as an unknown option or a violation of syntax, is encountered. \end_layout \begin_layout Description \family typewriter HXOPT_USAGEONERR \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXOPT_USAGEONERR \end_layout \end_inset \family default \series default Display the short-format usage syntax when an error is encountered. \end_layout \begin_layout Description \family typewriter HXOPT_RQ_ORDER \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXOPT_RQ_ORDER \end_layout \end_inset Specifying this option terminates option processing when the first non-option argument in \family typewriter argv \family default is encountered. This behavior is also implicit when the environment variable \family typewriter POSIXLY_CORRECT \family default is set. \end_layout \begin_layout Standard The return value can be one of the following: \end_layout \begin_layout Description \family typewriter HXOPT_ERR_SUCCESS \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXOPT_ERR_SUCCESS \end_layout \end_inset Parsing was successful. \end_layout \begin_layout Description \family typewriter HXOPT_ERR_UNKN \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_ERR_UNKN \end_layout \end_inset \family default \series default An unknown option was encountered. \end_layout \begin_layout Description \family typewriter HXOPT_ERR_VOID \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_ERR_VOID \end_layout \end_inset \family default \series default An argument was given for an option which does not allow one. In practice this only happens with \begin_inset Quotes eld \end_inset \family typewriter --foo=bar \family default \begin_inset Quotes erd \end_inset when \family typewriter --foo \family default is of type \family typewriter HXTYPE_\SpecialChar softhyphen NONE \family default , \family typewriter HXTYPE_\SpecialChar softhyphen VAL \family default or \family typewriter HXTYPE_\SpecialChar softhyphen SVAL \family default . This does not affect \begin_inset Quotes eld \end_inset \family typewriter --foo bar \family default \begin_inset Quotes erd \end_inset , because this can be unambiguously interpreted as \begin_inset Quotes eld \end_inset \family typewriter bar \family default \begin_inset Quotes erd \end_inset being a remaining argument to the program. \end_layout \begin_layout Description \family typewriter HXOPT_ERR_MIS \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_ERR_MIS \end_layout \end_inset \family default \series default Missing argument for an option that requires one. \end_layout \begin_layout Description \family typewriter HXOPT_ERR_AMBIG \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXOPT_ERR_AMBIG \end_layout \end_inset \family default \series default An abbreviation of a long option was ambiguous. \end_layout \begin_layout Description negative \begin_inset space ~ \end_inset non-zero Failure on behalf of lower-level calls; errno. \end_layout \begin_layout Subsection Pitfalls \end_layout \begin_layout Subsubsection Staticness of tables \begin_inset CommandInset label LatexCommand label name "subsec:option-pitfalls-static" \end_inset \end_layout \begin_layout Standard The following is an example of a possible pitfall regarding \family typewriter HXTYPE_\SpecialChar softhyphen STRDQ \family default : \end_layout \begin_layout LyX-Code \series bold static struct \series default HXdeque \series bold * \series default dq; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static bool \series default get_options( \series bold int * \series default argc, \series bold const char *** \series default argv) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold static const struct \series default HXoption options_table \series bold [] \series default = { \begin_inset Newline newline \end_inset {.sh = 'N', .type = HXTYPE_STRDQ, .q_strdq = dq, \begin_inset Newline newline \end_inset .help = "Add name"}, \begin_inset Newline newline \end_inset HXOPT_TABLEEND, \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \series bold return \series default HX_getopt(options_table, argc, argv, HXOPT_USAGEONERR) == \begin_inset Newline newline \end_inset HXOPT_ERR_SUCCESS; \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default main( \series bold int \series default argc, \series bold const char ** \series default argv) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset dq = HXdeque_init(); \begin_inset Newline newline \end_inset get_options(&argc, &argv); \begin_inset Newline newline \end_inset \series bold return \series default 0; \begin_inset Newline newline \end_inset } \end_layout \begin_layout Standard The problem here is that \family typewriter options_\SpecialChar softhyphen table \family default is, due to the \family typewriter static \family default keyword, initialized at compile-time where \family typewriter dq \family default is still \family typewriter NULL \family default . To counter this problem and have it doing the right thing, you must remove the \family typewriter static \family default qualifier on the options table when used with \family typewriter HXTYPE_\SpecialChar softhyphen STRDQ \family default , so that it will be evaluated when it is first executed. \end_layout \begin_layout Standard It was not deemed worthwhile to have \family typewriter HXTYPE_\SpecialChar softhyphen STRDQ \family default take an indirect HXdeque ( \family typewriter struct HXdeque \begin_inset space ~ \end_inset ** \family default ) instead just to bypass this issue. (Live with it.) \end_layout \begin_layout Subsection Limitations \end_layout \begin_layout Standard The HX option parser has been influenced by both popt and Getopt::Long, but eventually, there are differences: \end_layout \begin_layout Itemize Long options with a single dash ( \begin_inset Quotes eld \end_inset \family typewriter -foo bar \family default \begin_inset Quotes erd \end_inset ). This unsupported syntax clashes very easily with support for option bundling or squashing. In case of bundling, \begin_inset Quotes eld \end_inset \family typewriter -foo \family default \begin_inset Quotes erd \end_inset might actually be \begin_inset Quotes eld \end_inset \family typewriter -f -o -o \family default \begin_inset Quotes erd \end_inset , or \begin_inset Quotes eld \end_inset \family typewriter -f oo \family default \begin_inset Quotes erd \end_inset in case of squashing. It also introduces redundant ways to specify options, which is not in the spirit of the author. \end_layout \begin_layout Itemize Options using a \begin_inset Quotes eld \end_inset \family typewriter + \family default \begin_inset Quotes erd \end_inset as a prefix, as in \begin_inset Quotes eld \end_inset \family typewriter +foo \family default \begin_inset Quotes erd \end_inset . Xterm for example uses it as a way to negate an option. In the author's opinion, using one character to specify options is enough \begin_inset space ~ \end_inset — by GNU standards, a negator is named \begin_inset Quotes eld \end_inset \family typewriter --no-foo \family default \begin_inset Quotes erd \end_inset . Even Microsoft stuck to a single option introducing character (that would be \begin_inset Quotes eld \end_inset \family typewriter / \family default \begin_inset Quotes erd \end_inset ). \end_layout \begin_layout Itemize Table nesting like implemented in popt. HXopt has no provision for nested tables, as the need has not come up yet. It does however support chained processing (see section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:option-example-chained" \end_inset ). You cannot do nested tables even with callbacks, as the new \family typewriter argv \family default array is only put in place shortly before \family typewriter HX_getopt \family default returns. \end_layout \begin_layout Subsection Examples \end_layout \begin_layout Subsubsection Basic example \end_layout \begin_layout Standard The following code snippet should provide an equivalent of the GNU getopt sample \begin_inset Foot status open \begin_layout Plain Layout \begin_inset Flex URL status open \begin_layout Plain Layout http://www.gnu.org/software/libtool/manual/libc/Example-of-Getopt.html \backslash #Example-of-Getopt \end_layout \end_inset \end_layout \end_inset . \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default main( \series bold int \series default argc, \series bold const char ** \series default argv) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold int \series default aflag = 0; \begin_inset Newline newline \end_inset \series bold int \series default bflag = 0; \begin_inset Newline newline \end_inset \series bold char * \series default cflag = NULL; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXoption options_table \series bold [] \series default = { \begin_inset Newline newline \end_inset {.sh = 'a', .type = HXTYPE_NONE, .ptr = &aflag}, \begin_inset Newline newline \end_inset {.sh = 'b', .type = HXTYPE_NONE, .ptr = &bflag}, \begin_inset Newline newline \end_inset {.sh = 'c', .type = HXTYPE_STRING, .ptr = &cflag}, \begin_inset Newline newline \end_inset HXOPT_AUTOHELP, \end_layout \begin_layout LyX-Code HXOPT_TABLEEND, \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold if \series default (HX_getopt(options_table, &argc, &argv, HXOPT_USAGEONERR) != \begin_inset Newline newline \end_inset HXOPT_ERR_SUCCESS) \end_layout \begin_layout LyX-Code \series bold return \series default EXIT_FAILURE; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset printf("aflag = %d, bflag = %d, cvalue = %s \backslash n", \begin_inset Newline newline \end_inset aflag, bflag, cvalue); \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold while \series default (*++argv != NULL) \begin_inset Newline newline \end_inset printf("Non-option argument %s \backslash n", *argv); \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold return \series default EXIT_SUCCESS; \begin_inset Newline newline \end_inset } \end_layout \begin_layout Subsubsection Verbosity levels \begin_inset CommandInset label LatexCommand label name "subsec:option-example-incdec" \end_inset \end_layout \begin_layout LyX-Code \series bold static int \series default verbosity = 1; \series bold /* \family roman \series default \shape italic somewhat silent by default \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset \series bold static const struct \series default HXoption options_table \series bold [] \series default = { \begin_inset Newline newline \end_inset {.sh = 'q', .type = HXTYPE_NONE | HXOPT_DEC, .q_int = &verbosity, \begin_inset Newline newline \end_inset .help = "Reduce verbosity"}, \begin_inset Newline newline \end_inset {.sh = 'v', .type = HXTYPE_NONE | HXOPT_INC, .q_int = &verbosity, \begin_inset Newline newline \end_inset .help = "Increase verbosity"}, \begin_inset Newline newline \end_inset HXOPT_TABLEEND, \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Standard This sample option table makes it possible to turn the verbosity of the program up or down, depending on whether the user specified \family typewriter -q \family default or \family typewriter -v \family default . By passing multiple \family typewriter -v \family default flags, the verbosity can be turned up even more. The range depends on the \begin_inset Quotes eld \end_inset \family typewriter int \family default \begin_inset Quotes erd \end_inset data type for your particular platform and compiler; if you want to have the verbosity capped at a specific level, you will need to use an extra callback: \end_layout \begin_layout LyX-Code \series bold static int \series default verbosity = 1; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static void \series default v_check( \series bold const struct \series default HXoptcb \series bold * \series default cbi) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold if \series default (verbosity < 0) \begin_inset Newline newline \end_inset verbosity = 0; \begin_inset Newline newline \end_inset \series bold else if \series default (verbosity > 4) \begin_inset Newline newline \end_inset verbosity = 4; \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static const struct \series default HXoption options_table \series bold [] \series default = { \begin_inset Newline newline \end_inset {.sh = 'q', .type = HXTYPE_NONE | HXOPT_DEC, .q_int = &verbosity, \begin_inset Newline newline \end_inset .cb = v_check, .help = "Lower verbosity"}, \begin_inset Newline newline \end_inset {.sh = 'v', .type = HXTYPE_NONE | HXOPT_INC, .q_int = &verbosity, \begin_inset Newline newline \end_inset .cb = v_check, .help = "Raise verbosity"}, \begin_inset Newline newline \end_inset HXOPT_TABLEEND, \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Subsubsection Mask operations \begin_inset CommandInset label LatexCommand label name "subsec:option-example-mask" \end_inset \end_layout \begin_layout LyX-Code \series bold /* \family roman \series default \shape italic run on all CPU cores by default \family default \series bold \shape default * \series default / \begin_inset Newline newline \end_inset \series bold static unsigned int \series default cpu_mask = ~0U \series bold ; \begin_inset Newline newline \end_inset /* \family roman \series default \shape italic use no network connections by default \family default \shape default \series bold */ \begin_inset Newline newline \end_inset static unsigned int \series default net_mask = 0; \series bold \begin_inset Newline newline \end_inset static struct \series default HXoption options_table \series bold [] \series default = { \begin_inset Newline newline \end_inset {.sh = 'c', .type = HXTYPE_UINT | HXOPT_NOT | HXOPT_AND, \begin_inset Newline newline \end_inset .q_uint = &cpu_mask, \begin_inset Newline newline \end_inset .help = "Mask of cores to exclude", .htyp = "cpu_mask"}, \begin_inset Newline newline \end_inset {.sh = 'n', .type = HXTYPE_UINT | HXOPT_OR, .q_uint = &net_mask, \end_layout \begin_layout LyX-Code .help = "Mask of network channels to additionally use", \begin_inset Newline newline \end_inset .htyp = "channel_mask"}, \begin_inset Newline newline \end_inset HXOPT_TABLEEND, \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Standard What this options table does is \family typewriter cpu_mask &= ~x \family default and \family typewriter net_mask |= y \family default , the classic operations of clearing and setting bits. \end_layout \begin_layout Subsubsection Support for non-standard actions \begin_inset CommandInset label LatexCommand label name "subsec:option-example-cb" \end_inset \end_layout \begin_layout Standard Supporting additional types or custom storage formats is easy, by simply using \family typewriter HXTYPE_\SpecialChar softhyphen STRING \family default , \family typewriter NULL \family default as the data pointer (usually by not specifying it at all), the pointer to your data in the user-specified pointer \family typewriter uptr \family default , and the callback function in \family typewriter cb \family default . \end_layout \begin_layout LyX-Code \series bold struct \series default fixed_point { \begin_inset Newline newline \end_inset \series bold int \series default integral; \begin_inset Newline newline \end_inset \series bold unsigned int \series default fraction; \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static struct \series default fixed_point number; \end_layout \begin_layout LyX-Code \begin_inset Newline newline \end_inset \series bold static void \series default fixed_point_parse \series bold (const struct \series default HXoptcb \series bold \series default *cbi) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold char * \series default end; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset number.integral = strtol(cbi->data, &end, 0); \begin_inset Newline newline \end_inset \series bold if \series default (*end == ' \backslash 0') \begin_inset Newline newline \end_inset number.fraction = 0; \begin_inset Newline newline \end_inset \series bold else if \series default (*end == '.') \begin_inset Newline newline \end_inset number.fraction = strtoul(end + 1, NULL, 0); \begin_inset Newline newline \end_inset \series bold else \series default \begin_inset Newline newline \end_inset fprintf(stderr, "Illegal input. \backslash n"); \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \series bold \begin_inset Newline newline \end_inset static const struct \series default HXoption options_table \series bold [] \series default = { \begin_inset Newline newline \end_inset {.sh = 'n', .type = HXTYPE_STRING, .cb = fixed_point_parse, \begin_inset Newline newline \end_inset .uptr = &number, .help = "Do this or that", \begin_inset Newline newline \end_inset HXOPT_TABLEEND, \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout Subsubsection Chained argument processing \begin_inset CommandInset label LatexCommand label name "subsec:option-example-chained" \end_inset \end_layout \begin_layout Standard On the first run, only \family typewriter --cake \family default and \family typewriter --fruit \family default is considered, which is then used to select the next set of accepted options. Note that \family typewriter HXOPT_\SpecialChar softhyphen DESTROY_\SpecialChar softhyphen OLD \family default is used here, which causes the argv that is produced by the first invocation of \family typewriter HX_getopt \family default in the \family typewriter get_options \family default function to be freed as it gets replaced by a new argv again by \family typewriter HX_getopt \family default in \family typewriter get_cakes \family default \SpecialChar breakableslash \family typewriter get_fruit \family default . \family typewriter HXOPT_\SpecialChar softhyphen DESTROY_\SpecialChar softhyphen OLD \family default is however \shape italic not \shape default specified in the first invocation, because the initial argv resides on the stack and cannot be freed. \end_layout \begin_layout LyX-Code \series bold static bool \series default get_cakes( \series bold int * \series default argc, \series bold const char *** \series default argv) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold struct \series default HXoption option_table \series bold [] \series default = { \begin_inset Newline newline \end_inset ... \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \series bold return \series default HX_getopt(cake_table, argc, argv, \begin_inset Newline newline \end_inset HXOPT_USAGEONERR | HXOPT_DESTROY_OLD) == HXOPT_ERR_SUCCESS; \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static bool \series default get_fruit( \series bold int * \series default argc, \series bold const char *** \series default argv) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold struct \series default HXoption fruit_table \series bold [] \series default = { \begin_inset Newline newline \end_inset ... \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \series bold return \series default HX_getopt(fruit_table, argc, argv, \begin_inset Newline newline \end_inset HXOPT_USAGEONERR | HXOPT_DESTROY_OLD) == HXOPT_ERR_SUCCESS; \begin_inset Newline newline \end_inset } \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold static bool \series default get_options( \series bold int * \series default argc, \series bold const char *** \series default argv) \begin_inset Newline newline \end_inset { \begin_inset Newline newline \end_inset \series bold int \series default cake = 0, fruit = 0; \begin_inset Newline newline \end_inset \series bold struct \series default HXoption option_table \series bold [] \series default = { \begin_inset Newline newline \end_inset {.ln = "cake", .type = HXTYPE_NONE, .ptr = &cake}, \begin_inset Newline newline \end_inset {.ln = "fruit", .type = HXTYPE_NONE, .ptr = &fruit}, \begin_inset Newline newline \end_inset HXOPT_TABLEEND, \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \series bold if \series default (HX_getopt(option_table, argc, argv, HXOPT_PTHRU) != \begin_inset Newline newline \end_inset HXOPT_ERR_SUCCESS) \begin_inset Newline newline \end_inset \series bold return \series default false; \begin_inset Newline newline \end_inset \series bold if \series default (cake) \begin_inset Newline newline \end_inset \series bold return \series default get_cakes(argc, argv); \begin_inset Newline newline \end_inset \series bold else if \series default (fruit) \begin_inset Newline newline \end_inset \series bold return \series default get_fruit(argc, argv); \begin_inset Newline newline \end_inset \series bold return \series default false; \begin_inset Newline newline \end_inset } \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Shell-style configuration file parser \begin_inset CommandInset label LatexCommand label name "sec:shconf" \end_inset \end_layout \begin_layout Standard libHX provides functions to read shell-style configuration files. Such files are common, for example, in \family typewriter /etc/sysconfig \family default on Linux systems. The format is pretty basic; it only knows about \begin_inset Quotes eld \end_inset \family typewriter key=value \family default \begin_inset Quotes erd \end_inset pairs and does not even have sections like INI files. Not relying on any features however makes them quite interchangable as the syntax is accepted by Unix Shells. \end_layout \begin_layout Standard Lines beginning with a hash mark ( \family typewriter # \family default ) are ignored, as are empty lines and unrecognized keys. \end_layout \begin_layout LyX-Code \series bold # Minimum / maximum values for automatic UID selection \series default \begin_inset Newline newline \end_inset UID_MIN=100 \begin_inset Newline newline \end_inset UID_MAX=65000 \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold # Home directory base \series default \begin_inset Newline newline \end_inset HOME="/home" \begin_inset Newline newline \end_inset #HOME="/export/home" \end_layout \begin_layout Standard Any form of variable or parameter substitution or expansion is highly implementa tion specific, and is not supported in libHX's reader. Even Shell users should not rely on it as you never know in which context the configuration files are evaluated. Still, you will have to escape specific sequences like you would need to in Shell. The use of single quotes is acceptable. That means: \end_layout \begin_layout LyX-Code AMOUNT="US \backslash $5" \begin_inset Newline newline \end_inset AMOUNT='US$5' \end_layout \begin_layout Subsection Synopsis \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/option.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_shconfig( \series bold const char * \series default file, \series bold const struct \series default HXoption \series bold * \series default table); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_shconfig \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_shconfig_pv( \series bold const char ** \series default path_vec, \series bold const char * \series default file, \begin_inset Newline newline \end_inset \series bold const struct \series default HXoption \series bold * \series default table, \series bold unsigned int \series default flags); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_shconfig_pv \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXmap \series bold * \series default HX_shconfig_map( \series bold const char * \series default file); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_shconfig_map \end_layout \end_inset \end_layout \begin_layout Standard The shconfig parser reuses \family typewriter struct HXoption \family default that fits very well in specifying name-pointer associations. \family typewriter HX_shconfig \family default will read the given file using the key-to-pointer mappings from the table to store the variable contents. Of \family typewriter struct HXoption \family default , described in section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:option-synopsis" \end_inset , only the \begin_inset Quotes eld \end_inset \family typewriter ln \family default \begin_inset Quotes erd \end_inset , \begin_inset Quotes eld \end_inset \family typewriter type \family default \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset \family typewriter ptr \family default \begin_inset Quotes erd \end_inset fields are used. The list of accepted types is described in section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:option-types" \end_inset . \end_layout \begin_layout Standard To parse a file, call \family typewriter HX_shconfig \family default function with the corresponding parameters. If you want to read configuration files from different paths, i. \begin_inset space \thinspace{} \end_inset e. \begin_inset space \space{} \end_inset to build up on default values, you can use \family typewriter HX_shconfig_pv \family default \begin_inset Foot status open \begin_layout Plain Layout pv = path vector \end_layout \end_inset , which is a variant for reading a file from multiple locations. Its purpose is to facilitate reading system-wide settings which are then overriden by a file in the users home directory, for example (per-setting-overr ide). It is also possible to do per-file-override, that is, a file in the home directory has higher precedence than a system-wide one in such a way that the system-wide configuration file is not even read. This is accomplished by traversing the paths in the \begin_inset Quotes eld \end_inset other \begin_inset Quotes erd \end_inset direction (actually you have to turn the array around) and stopping at the first existing file by use of the \family typewriter SHCONF_\SpecialChar softhyphen ONE \family default flag. \end_layout \begin_layout Standard \family typewriter HX_shconfig_map \family default will return all entries from the file in a HXmap, usable for parsing arbitrary keys without having to specify any static key table. \end_layout \begin_layout Description \family typewriter SHCONF_ONE \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium SHCONF_ONE \end_layout \end_inset \family default \series default Parsing files will stop after one file has been successfully parsed. This allows for a \begin_inset Quotes eld \end_inset personal overrides system config \begin_inset Quotes erd \end_inset style. \end_layout \begin_layout Standard The call to \family typewriter HX_shconfig \family default will either return >0 for success, 0 for no success (actually, this is never returned) and \family typewriter -errno \family default for an error. \end_layout \begin_layout Subsection Example \end_layout \begin_layout Subsubsection Per-setting-override \end_layout \begin_layout Standard This example sources key-value pairs from a configuration file in a system location ( \family typewriter /etc \family default ) first, before overriding specific keys with new values from the file in the home directory. \end_layout \begin_layout LyX-Code \series bold long \series default uid_min, uid_max; \begin_inset Newline newline \end_inset \series bold char * \series default passwd_file; \begin_inset Newline newline \end_inset \series bold struct \series default HXoption options_table \series bold [] \series default = { \begin_inset Newline newline \end_inset {.ln = "UID_MIN", .type = HXTYPE_LONG, .ptr = &uid_min}, \begin_inset Newline newline \end_inset {.ln = "UID_MAX", .type = HXTYPE_LONG, .ptr = &uid_max}, \begin_inset Newline newline \end_inset {.ln = "PWD_FILE", .type = HXTYPE_STRING, .ptr = &passwd_file}, \begin_inset Newline newline \end_inset HXOPT_TABLEEND, \begin_inset Newline newline \end_inset }; \begin_inset Newline newline \end_inset \series bold const char * \series default home = getenv("HOME"); \begin_inset Newline newline \end_inset \series bold const char * \series default paths \series bold [] \series default = {"/etc", home, NULL}; \begin_inset Newline newline \end_inset HX_shconfig(paths, "test.cf", options_table, 0); \end_layout \begin_layout Subsubsection Per-file-override \end_layout \begin_layout Standard This particular example reads from the file in the home directory first (if it exists), but stops after it has been successfull, so any subsequent locations listed in the \family typewriter paths \family default variable are not read. This has the effect that the file from the home directory has the highest priority too like in the previous example, but without any keys from the system files. Note the \family typewriter SHCONF_ONE \family default flag. \end_layout \begin_layout LyX-Code \series bold const char * \series default home = getenv("HOME"); \begin_inset Newline newline \end_inset \series bold const char * \series default paths \series bold [] \series default = {home, "/usr/local/etc", "/etc", NULL}; \begin_inset Newline newline \end_inset HX_shconfig_pv(paths, "test.cf", options_table, SHCONF_ONE); \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Part Systems-related components \end_layout \begin_layout Section Random numbers \begin_inset CommandInset label LatexCommand label name "sec:random" \end_inset \end_layout \begin_layout Subsection Function overview \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/misc.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HX_rand( \series bold void \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_rand \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold unsigned int \series default HX_irand( \series bold unsigned int \series default min, \series bold unsigned int \series default max); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_irand \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold double \series default HX_drand( \series bold double \series default min, \series bold double \series default max); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_drand \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HX_rand \family default Retrieve the next random number. \end_layout \begin_layout Description \family typewriter HX_irand \family default Retrieve the next random number and fold it so that \begin_inset Formula $\textit{min}\le n<\textit{max}$ \end_inset , where min and max are unsigned integers. \end_layout \begin_layout Description \family typewriter HX_drand \family default Retrieve the next random number and fold it so that \begin_inset Formula $\textit{min}\le n<\textit{max}$ \end_inset , where min and max are double-precision floating point numbers. \end_layout \begin_layout Subsection Implementation information \end_layout \begin_layout Standard On systems that provide operating system-level random number generators, predominantly Linux and Unix-alikes such as BSD and Solaris, these will be used when they are available and random numbers are requested through \family typewriter HX_rand \family default or \family typewriter HX_irand \family default . \end_layout \begin_layout Standard On Linux, Solaris and the BSDs, this is \family typewriter /dev/urandom \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter /dev/urandom \end_layout \end_inset . \end_layout \begin_layout Standard If no random number generating device is available (and libHX configured to use it), it will fall back to using the libc's \family typewriter rand \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter rand \end_layout \end_inset function. If libc is selected for random number generation, \family typewriter srand \family default will be called on library initialization with what is believed to be good defaults \begin_inset space ~ \end_inset — usually this will be before a program's \family typewriter main \family default function with normal linking, but may actually happen later when used with \family typewriter dlopen \family default . The initial seed would be the current microtime when \family typewriter gettimeofday \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter gettimeofday \end_layout \end_inset \family default is available, or just the seconds with \family typewriter time \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter time \end_layout \end_inset . To counter the problem of different programs potentially using the same seed within a time window of a second due to the limited granularity of standard \family typewriter time \family default , the seed is augmented by process ID and parent process ID where available. \end_layout \begin_layout Standard \family typewriter /dev/random \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter /dev/random \end_layout \end_inset \family default is not used on Linux because it may block during read, and \family typewriter /dev/urandom \family default is just as good when there is entropy available. If you need definitive PRNG \begin_inset Index idx status open \begin_layout Plain Layout PRNG \end_layout \end_inset security, perhaps use one from a crypto suite such as OpenSSL. \end_layout \begin_layout Standard \begin_inset Newpage clearpage \end_inset \end_layout \begin_layout Section Process management \begin_inset CommandInset label LatexCommand label name "sec:proc" \end_inset \end_layout \begin_layout Standard The process code is experimental at this stage (just moved from the pam_mount codebase). As it also relies on the POSIX functions \family typewriter fork \family default , \family typewriter execv \family default , \family typewriter execvp \family default and \family typewriter pipe \family default (2), so it may not be available everywhere. Where this is the case, the functions will return \family typewriter -ENOSYS \family default . \end_layout \begin_layout Subsection Process metadata structure \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/proc.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXproc { \begin_inset Newline newline \end_inset \series bold const struct \series default HXproc_ops \series bold * \series default p_ops; \begin_inset Newline newline \end_inset \series bold void * \series default p_data; \begin_inset Newline newline \end_inset \series bold unsigned int \series default p_flags; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold /* \family roman \series default \shape italic Following members should only be read \family default \series bold \shape default */ \series default \begin_inset Newline newline \end_inset \series bold int \series default p_stdin, p_stdout, p_stderr; \begin_inset Newline newline \end_inset \series bold int \series default p_pid; \begin_inset Newline newline \end_inset \series bold char \series default p_status; \begin_inset Newline newline \end_inset \series bold bool \series default p_exited, p_terminated; \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Standard When creating a new process with the intent of running it asynchronously (using \family typewriter HXproc_\SpecialChar softhyphen run_\SpecialChar softhyphen async \family default ), the first three fields must be filled in by the user. \end_layout \begin_layout Description \family typewriter p_ops \family default A table of callbacks, generally used for setting and/or restoring signals before/after execution. This member may be \family typewriter NULL \family default . \end_layout \begin_layout Description \family typewriter p_data \family default Free pointer for the user to supply. Will be passed to the callback functions when they are invoked. \end_layout \begin_layout Description \family typewriter p_flags \family default Process creation flags, see below. \end_layout \begin_layout Standard After the subprocess has been started, \family typewriter HXproc_run_async \family default will have filled in some fields: \end_layout \begin_layout Description \family typewriter p_stdin \family default If \family typewriter HXPROC_STDIN \family default was specified in \family typewriter p_flags \family default , \family typewriter p_stdin \family default will be assigned the write side file descriptor of the subprocess's to-be stdin. The subprocess will get the read side file descriptor in this member. This is so that the correct fd is used in when \family typewriter p_ops->p_postfork \family default is called. \end_layout \begin_layout Description \family typewriter p_stdout \family default If \family typewriter HXPROC_STDOUT \family default is specified in \family typewriter p_flags \family default , \family typewriter p_stdout \family default will be assigned the read side file descriptor of the subprocess's to-be stdout. The subprocess will get the write side file descriptor in this member. \end_layout \begin_layout Description \family typewriter p_stderr \family default If \family typewriter HXPROC_STDERR \family default is specified in \family typewriter p_flags \family default , \family typewriter p_stderr \family default will be assigned the read side file descriptor of the subprocess's to-be stderr, and the subprocess will get the write side fd. \end_layout \begin_layout Description \family typewriter p_pid \family default The process ID of the spawned process. \end_layout \begin_layout Standard Upon calling \family typewriter HXproc_wait \family default , further fields will have been filled when the function returns: \end_layout \begin_layout Description \family typewriter p_exited \family default Whether the process exited normally (cf. \begin_inset space \space{} \end_inset signalled\SpecialChar breakableslash terminated). \end_layout \begin_layout Description \family typewriter p_terminated \family default Whether the process was terminated (signalled). \end_layout \begin_layout Description \family typewriter p_status \family default The exit status of the process or the termination signal. \end_layout \begin_layout Subsubsection Flags \begin_inset CommandInset label LatexCommand label name "subsec:proc-pflags" \end_inset \end_layout \begin_layout Standard Possible values for the \family typewriter p_flags \family default member are: \end_layout \begin_layout Description \family typewriter HXPROC_STDIN \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXPROC_STDIN \end_layout \end_inset \family default \series default The subprocess's stdin file descriptor shall be connected to the master program, that is, not inherit the stdin of the master. Cannot be used for \family typewriter HXproc_\SpecialChar softhyphen run_\SpecialChar softhyphen sync \family default (because there would be no one to provide data in a sync operation). \end_layout \begin_layout Description \family typewriter HXPROC_STDOUT \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXPROC_STDOUT \end_layout \end_inset \family default \series default Connect the stdout file descriptor of the subprocess with the master. Cannot be used for \family typewriter HXproc_run_sync \family default . \end_layout \begin_layout Description \family typewriter HXPROC_STDERR \series medium \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \series medium HXPROC_STDERR \end_layout \end_inset \family default \series default Connect the stderr file descriptor of the subprocess with the master. Cannot be used for \family typewriter HXproc_run_sync \family default . \end_layout \begin_layout Description \family typewriter HXPROC_NULL_STDIN \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXPROC_NULL_STDIN \end_layout \end_inset The subprocess's stdin file descriptor shall be connected to \family typewriter /dev\SpecialChar breakableslash null \family default . \family typewriter HXPROC_\SpecialChar softhyphen STDIN \family default and \family typewriter HXPROC_\SpecialChar softhyphen NULL_\SpecialChar softhyphen STDIN \family default are mutually exclusive. \end_layout \begin_layout Description \family typewriter HXPROC_NULL_STDOUT \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXPROC_NULL_STDOUT \end_layout \end_inset Connect the stdout file descriptor of the subprocess to \family typewriter /dev\SpecialChar breakableslash null \family default , thereby essentially discarding its output. \family typewriter HXPROC_\SpecialChar softhyphen STDOUT \family default and \family typewriter HXPROC_\SpecialChar softhyphen NULL_\SpecialChar softhyphen STDOUT \family default are mutuall exclusive. \end_layout \begin_layout Description \family typewriter HXPROC_NULL_STDERR \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXPROC_NULL_STDERR \end_layout \end_inset Connect the stderr file descriptor of the subprocess to \family typewriter /dev\SpecialChar breakableslash null \family default , thereby essentially discarding its output. \family typewriter HXPROC_\SpecialChar softhyphen STDERR \family default and \family typewriter HXPROC_\SpecialChar softhyphen NULL_\SpecialChar softhyphen STDERR \family default are mutually exclusive. \end_layout \begin_layout Description \family typewriter HXPROC_VERBOSE \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXPROC_VERBOSE \end_layout \end_inset Have the subprocess print an error message to stderr if exec'ing returned an error. \end_layout \begin_layout Description \family typewriter HXPROC_A0 \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXPROC_A0 \end_layout \end_inset \family typewriter argv[0] \family default refers to program file, while \family typewriter argv[1] \family default to the program invocation name, with \family typewriter argv[2] \family default being the arguments. Without this flag, \family typewriter argv[0] \family default will be both the program file and program invocation name, and arguments begin at \family typewriter argv[1] \family default . \end_layout \begin_layout Description \family typewriter HXPROC_EXECV \family default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HXPROC_EXECV \end_layout \end_inset Normally, \family typewriter execvp \family default (3) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter execvp \end_layout \end_inset will be used which scans \family typewriter $PATH \family default for the program. Use this flag to use \family typewriter execv \family default (3) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter execv \end_layout \end_inset instead, which will not do such thing. \end_layout \begin_layout Subsection Callbacks \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold struct \series default HXproc_ops { \begin_inset Newline newline \end_inset \series bold void (* \series default p_prefork \series bold ) \series default ( \series bold void * \series default ); \begin_inset Newline newline \end_inset \series bold void (* \series default p_postfork \series bold ) \series default ( \series bold void * \series default ); \begin_inset Newline newline \end_inset \series bold void (* \series default p_complete \series bold ) \series default ( \series bold void * \series default ); \begin_inset Newline newline \end_inset }; \end_layout \begin_layout Standard \family typewriter struct HXproc_ops \family default provides a way to run user-specified functions just before the fork, after, and when the process has been waited for. They can be used to set and/or restore signals as needed, for example. The function pointers can be \family typewriter NULL \family default . The \family typewriter p_data \family default member is passed as an argument. \end_layout \begin_layout Description \family typewriter p_prefork \family default Run immediately before calling \family typewriter fork \family default (2). This is useful, for taking any action regarding signals, like setting \family typewriter SIGCHLD \family default to \family typewriter SIG_DFL \family default , or \family typewriter SIGPIPE \family default to \family typewriter SIG_IGN \family default , for example. \end_layout \begin_layout Description \family typewriter p_postfork \family default Run in the subprocess (and only there) after forking. Useful to do a \family typewriter setuid \family default (2) or other change in privilege level. \end_layout \begin_layout Description \family typewriter p_complete \family default Run in \family typewriter HXproc_wait \family default when the process has been waited for. Useful to restore the signal handler(s). \end_layout \begin_layout Subsection Process control \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Newline newline \end_inset \series bold \begin_inset Newline newline \end_inset int \series default HXproc_run_async( \series bold const char *const * \series default argv, \series bold struct \series default HXproc \series bold * \series default proc); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXproc_run_async \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HXproc_run_sync( \series bold const char *const * \series default argv, \series bold unsigned int \series default flags); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXproc_run_sync \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default HXproc_wait( \series bold struct \series default HXproc \series bold * \series default proc); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HXproc_wait \end_layout \end_inset \end_layout \begin_layout Description \family typewriter HXproc_run_async \family default Start a subprocess according to the parameters in \family typewriter proc \family default . Returns a negative errno code if something went wrong, or positive non-zero on success. \end_layout \begin_layout Description \family typewriter HXproc_run_sync \family default Start a subprocess synchronously, similar to calling \family typewriter system \family default (3) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter system \end_layout \end_inset , but with the luxury of being able to specify arguments as separate strings (via argv) rather than one big command line that is run through the shell. \family typewriter flags \family default is a value composed of the HXproc flags mentioned above in section \begin_inset space ~ \end_inset \begin_inset CommandInset ref LatexCommand ref reference "subsec:proc-pflags" \end_inset . \family typewriter HXPROC_STDIN \family default , \family typewriter HXPROC_STDOUT \family default and \family typewriter HXPROC_STDERR \family default are ignored because there would be no one in a synchronous execution that could supply data to these file descriptors or read from them \begin_inset Foot status open \begin_layout Plain Layout Even for threads, please just use the async model. \end_layout \end_inset . \end_layout \begin_layout Description \family typewriter HXproc_wait \family default Wait for a subprocess to terminate, if it has not already. It will also retrieve the exit status of the process and store it in the \family typewriter struct HXproc \family default . \end_layout \begin_layout Standard Return value will be positive non-zero on success, or negative on error. Underlying system function's errors are returned, plus: \end_layout \begin_layout Description \family sans EINVAL \family default Flags were not accepted. \end_layout \begin_layout Section Helper headers \end_layout \begin_layout Subsection ctype helpers \end_layout \begin_layout Standard Functions from the \family typewriter \family default header, including, but not limited to, \family typewriter isalpha \family default , \family typewriter tolower \family default , and so forth, are defined to take an \begin_inset Quotes eld \end_inset \family typewriter int \family default \begin_inset Quotes erd \end_inset as first argument. Strings used in C programs are usually \begin_inset Quotes eld \end_inset \family typewriter char \begin_inset space ~ \end_inset * \family default \begin_inset Quotes erd \end_inset , without any \begin_inset Quotes eld \end_inset \family typewriter signed \family default \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset \family typewriter unsigned \family default \begin_inset Quotes erd \end_inset qualifier. By a high-level view, which also matches daily common sense, characters (a. \begin_inset space \thinspace{} \end_inset k. \begin_inset space \thinspace{} \end_inset a. \begin_inset space \space{} \end_inset letters) have no notion of signedness \begin_inset space ~ \end_inset — there is no \begin_inset Quotes eld \end_inset positive \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset negative \begin_inset Quotes erd \end_inset \begin_inset Quotes eld \end_inset A \begin_inset Quotes erd \end_inset in at least the Latin alphabet that is mapped into the ASCII set. In fact, \family typewriter char \begin_inset space ~ \end_inset * \family default could either be \family typewriter signed char \begin_inset space ~ \end_inset * \family default or \family typewriter unsigned char \begin_inset space ~ \end_inset * \family default , depending on the compiler settings. Only when you start interpreting and using characters as a number does such become important. \end_layout \begin_layout Standard There come the problems. Characters are in the same class as numbers in C, that is, can be implicitly converted from or to a \begin_inset Quotes eld \end_inset number \begin_inset Quotes erd \end_inset (in this case, their ASCII code point) without causing a compiler warning. That may be practical in some cases, but is also a bit \begin_inset Quotes eld \end_inset unfortunate \begin_inset Quotes erd \end_inset . Characters, when interpreted as the 8-bit signed numeric quantity they are implicitly convertable to, run from 0 to 127 and \SpecialChar nobreakdash 128 to \SpecialChar nobreakdash 1. Since the \family typewriter isalpha \family default function and others from \family typewriter ctype.h \family default take a (signed) \family typewriter int \family default as argument means that values fed to \family typewriter isalpha \family default are sign-extended, preserving negative values. \end_layout \begin_layout LyX-Code \series bold /* \family roman \series default \shape italic \begin_inset Quotes eld \end_inset hyvää yötä \begin_inset Quotes erd \end_inset , UTF-8 encoded \family default \series bold \shape default */ \end_layout \begin_layout LyX-Code \series bold const char \series default h \series bold [] \series default = {'h', 'y', 'v', 0xc3, 0xa4, 0xc3, 0xa4, ' ', \begin_inset Newline newline \end_inset 'y', 0xc3, 0xb6, 't', 0xc3, 0xa4}; \end_layout \begin_layout Standard When you now pass \family typewriter h[3] \family default to \family typewriter isalpha \family default for example (regardless of whether doing so actually produces a meaningful result), the CPU is instructed to copy \begin_inset Quotes eld \end_inset 0xc3 \begin_inset Quotes erd \end_inset into a register and sign-extend it (because \begin_inset Quotes eld \end_inset char \begin_inset Quotes erd \end_inset is often \begin_inset Quotes eld \end_inset signed char \begin_inset Quotes erd \end_inset , see above), producing 0xffffffc3 (\SpecialChar nobreakdash 61). But passing \SpecialChar nobreakdash 61 is not what was intended. \end_layout \begin_layout Standard libHX's \family typewriter ctype_helper.h \family default therefore provides wrappers with a different function signature that uses zero extension (not sign extension) by means of using an \family typewriter unsigned \family default quantity. Currently this is \family typewriter unsigned char \family default , because \family typewriter isalpha \family default 's domain only goes from 0–255. The implication is that you cannot pass \family typewriter EOF \family default to \family typewriter HX_isalpha \family default . \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/ctype_helper.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HX_isalnum( \series bold unsigned char \series default c); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_isalnum \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HX_isalpha( \series bold unsigned char \series default c); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_isalpha \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HX_isdigit( \series bold unsigned char \series default c); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_isdigit \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HX_islower( \series bold unsigned char \series default c); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_islower \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HX_isprint( \series bold unsigned char \series default c); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_isprint \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HX_isspace( \series bold unsigned char \series default c); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_isspace \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HX_isupper( \series bold unsigned char \series default c); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter HX_isupper \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold bool \series default HX_isxdigit( \series bold unsigned char \series default c); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_isxdigit \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold unsigned char \series default HX_tolower( \series bold unsigned char \series default c); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_tolower \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold unsigned char \series default HX_toupper( \series bold unsigned char \series default c); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none HX_toupper \end_layout \end_inset \end_layout \begin_layout Standard The \family typewriter is* \family default functions also differ from ctype's in that they return \family typewriter bool \family default instead of \family typewriter int \family default . Not all functions from \family typewriter ctype.h \family default are present either; \family typewriter isascii \family default , \family typewriter isblank \family default , \family typewriter iscntrl \family default , \family typewriter isgraph \family default , \family typewriter ispunct \family default and \family typewriter isxdigit \family default have been omitted as the author has never needed them so far. \end_layout \begin_layout Subsection libxml2 helpers \end_layout \begin_layout Standard libxml2 uses an \begin_inset Quotes eld \end_inset \family typewriter xmlChar \family default \begin_inset Quotes erd \end_inset type as an underlying type for the strings that it reads and outputs. \family typewriter xmlChar \family default is typedef'ed to \family typewriter unsigned char \family default by libxml2, causing compiler warnings related to differing signedness whenever interacting with strings from the outside world, which are usually just a pointer to \family typewriter char \family default . Because casting would be a real chore, \family typewriter libxml_helper.h \family default will do it by providing some wrappers with better argument types. \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/libxml_helper.h \end_layout \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \series bold int \series default xml_strcmp( \series bold const \series default xmlChar \series bold * \series default a, \series bold const char * \series default b); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter xml_strcmp \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold int \series default xml_strcasecmp( \series bold const \series default xmlChar \series bold * \series default a, \series bold const char * \series default b); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter xml_strcasecmp \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold char * \series default xml_getprop(xmlNode \series bold * \series default node, \series bold const char * \series default attr); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter xml_getprop \end_layout \end_inset \begin_inset Newline newline \end_inset char *xml_getnsprop( \series bold xmlNode * \series default node, \series bold const char * \series default nsprefix, \series bold const char * \series default attr); \begin_inset Index idx status open \begin_layout Plain Layout xml_getnsprop \end_layout \end_inset \begin_inset Newline newline \end_inset xmlAttr \series bold * \series default xml_newprop(xmlNode \series bold * \series default node, \series bold const char * \series default attr); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter xml_newprop \end_layout \end_inset \begin_inset Newline newline \end_inset xmlNode \series bold * \series default xml_newnode(xmlNode \series bold * \series default parent, \series bold const char * \series default name, \series bold const char * \series default value); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none xml_newnode \end_layout \end_inset \begin_inset Newline newline \end_inset xmlAttr \series bold * \series default xml_setprop(xmlNode \series bold * \series default node, \series bold const char * \series default name, \series bold const char * \series default value); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter \size normal \color none xml_setprop \end_layout \end_inset \end_layout \begin_layout Standard The functions map to \family typewriter strcmp \family default (3) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter strcmp \end_layout \end_inset , \family typewriter strcasecmp \family default (3) \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter strcasecmp \end_layout \end_inset , \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter xmlGetProp \end_layout \end_inset \family typewriter xmlGetProp \family default , \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter xmlNewProp \end_layout \end_inset \family typewriter xmlNewProp \family default , \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter xmlNewTextNode \end_layout \end_inset \family typewriter xml\SpecialChar softhyphen New\SpecialChar softhyphen Text\SpecialChar softhyphen Node \family default and \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter xmlSetProp \end_layout \end_inset \family typewriter xml\SpecialChar softhyphen Set\SpecialChar softhyphen Prop \family default , respectively. \end_layout \begin_layout Standard \family typewriter xml_getnsprop \family default works similar to \family typewriter xmlGetNsProp \family default , but instead of taking a namespace URI, it does a lookup by namespace prefix. The argument order is also different compared to \family typewriter xmlGetNsProp \family default . \end_layout \begin_layout Subsection wxWidgets \end_layout \begin_layout LyX-Code \series bold #include \series default \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter libHX/wx_helper.hpp \end_layout \end_inset \end_layout \begin_layout Subsubsection Shortcut macros \end_layout \begin_layout Description \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxACV \end_layout \end_inset \family typewriter wxACV \family default Expands to \family typewriter \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxALIGN_CENTER_VERTICAL \end_layout \end_inset wxALIGN_CENTER_VERTICAL \end_layout \begin_layout Description \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxCDF \end_layout \end_inset \family typewriter wxCDF \family default Expands to a set of common dialog flags for \family typewriter wxDialog \family default s, which includes \family typewriter wxDEFAULT_\SpecialChar softhyphen FRAME_\SpecialChar softhyphen STYLE \family default and a flag such that the dialog does not create a new window in the task bar ( \family typewriter wxFRAME_\SpecialChar softhyphen NO_\SpecialChar softhyphen TASKBAR \family default ). \end_layout \begin_layout Description \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxDPOS \end_layout \end_inset \family typewriter wxDPOS \family default Expands to \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxDefaultPosition \end_layout \end_inset \family typewriter wxDefaultPosition \family default . \end_layout \begin_layout Description \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxDSIZE \end_layout \end_inset \family typewriter wxDSIZE \family default Expands to \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxDefaultSize \end_layout \end_inset \family typewriter wxDefaultSize \family default . \end_layout \begin_layout Description \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxDSPAN \end_layout \end_inset \family typewriter wxDSPAN \family default Expands to \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxDefaultSpan \end_layout \end_inset \family typewriter wxDefaultSpan \family default . \end_layout \begin_layout Subsubsection String conversion \end_layout \begin_layout LyX-Code wxString wxfu8( \series bold const char * \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxfu8 \end_layout \end_inset \begin_inset Newline newline \end_inset wxString wxfv8( \series bold const char * \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxfv8 \end_layout \end_inset \begin_inset Newline newline \end_inset \series bold const char * \series default wxtu8( \series bold const \series default wxString \series bold & \series default ); \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxtu8 \end_layout \end_inset \end_layout \begin_layout Description \family typewriter wxfu8 \family default Converts an UTF-8 string to a \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxString \end_layout \end_inset \family typewriter wxString \family default object. \end_layout \begin_layout Description \family typewriter wxfv8 \family default Converts an UTF-8 string to an entity usable by \begin_inset Index idx status open \begin_layout Plain Layout \family typewriter wxPrintf \end_layout \end_inset \family typewriter wxPrintf \family default . \end_layout \begin_layout Description \family typewriter wxtu8 \family default Converts a wxString to a pointer to char usable by \family typewriter printf \family default . Note that the validity of the pointer is very limited and usually does not extend the statement in which it is used. Hence storing the pointer in a variable ( \begin_inset Quotes eld \end_inset \family typewriter const char *p = wxtu8(s); \family default \begin_inset Quotes erd \end_inset ) will make \family typewriter p \family default pointing to an invalid region as soon as the assignment is done. \end_layout \begin_layout Part \start_of_appendix Appendix \end_layout \begin_layout Standard \begin_inset CommandInset index_print LatexCommand printindex type "idx" name "Index" literal "true" \end_inset \end_layout \end_body \end_document