summaryrefslogtreecommitdiff
path: root/doc/libHX_Documentation.lyx
diff options
context:
space:
mode:
Diffstat (limited to 'doc/libHX_Documentation.lyx')
-rw-r--r--doc/libHX_Documentation.lyx24728
1 files changed, 24728 insertions, 0 deletions
diff --git a/doc/libHX_Documentation.lyx b/doc/libHX_Documentation.lyx
new file mode 100644
index 0000000..69ad84c
--- /dev/null
+++ b/doc/libHX_Documentation.lyx
@@ -0,0 +1,24728 @@
+#LyX 2.0 created this file. For more info see http://www.lyx.org/
+\lyxformat 413
+\begin_document
+\begin_header
+\textclass article
+\use_default_options true
+\maintain_unincluded_children false
+\language english
+\language_package default
+\inputencoding utf8
+\fontencoding global
+\font_roman lmodern
+\font_sans lmss
+\font_typewriter lmtt
+\font_default_family default
+\use_non_tex_fonts false
+\font_sc false
+\font_osf false
+\font_sf_scale 100
+\font_tt_scale 100
+
+\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_amsmath 1
+\use_esint 1
+\use_mhchem 1
+\use_mathdots 1
+\cite_engine natbib_numerical
+\use_bibtopic false
+\use_indices false
+\paperorientation portrait
+\suppress_date false
+\use_refstyle 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
+\quotes_language english
+\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.22
+\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 \slash{}
+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 \-
+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
+ <libHX/init.h>
+\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
+ <libHX/defs.h>
+\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
+<lyxtabular version="3" rows="7" columns="7">
+<features tabularvalignment="middle">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+From
+\backslash
+ To
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+c*
+\series default
+section
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+sc*
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+uc*
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+Cc*
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+Csc*
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+Cuc*
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+\series bold
+char *
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+\series bold
+signed char *
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+\series bold
+unsigned char *
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+\series bold
+const char *
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+--
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+--
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+--
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+\series bold
+const signed char *
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+--
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+--
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+--
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+\series bold
+const unsigned char *
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+--
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+--
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+--
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\checkmark$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+\begin_inset Caption
+
+\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 "sub: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
+<lyxtabular version="3" rows="2" columns="2">
+<features tabularvalignment="middle">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+int **
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+int *const *
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+const int **
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+const int *const *
+\end_layout
+
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+\begin_inset Caption
+
+\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 <libHX/defs.h>
+\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 \-
+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 \-
+BUG_\SpecialChar \-
+ON_\SpecialChar \-
+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
+ <libHX/misc.h>
+\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.
+\end_layout
+
+\begin_layout Standard
+\noindent
+\align center
+\begin_inset Tabular
+<lyxtabular version="3" rows="4" columns="6">
+<features tabularvalignment="middle">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+Representation
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+Time value
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+R
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+T
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+R
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+T
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\left\{ -1,-1\right\} $
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+illegal
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\left\{ 0,-1\right\} $
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+-0.1
+\begin_inset space \thinspace{}
+\end_inset
+
+s
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\left\{ 1,-1\right\} $
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+illegal
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\left\{ -1,0\right\} $
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+-1.0
+\begin_inset space \thinspace{}
+\end_inset
+
+s
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\left\{ 0,0\right\} $
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+0.0
+\begin_inset space \thinspace{}
+\end_inset
+
+s
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\left\{ 1,0\right\} $
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+1.0
+\begin_inset space \thinspace{}
+\end_inset
+
+s
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\left\{ -1,1\right\} $
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+-1.1
+\begin_inset space \thinspace{}
+\end_inset
+
+s
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\left\{ 0,1\right\} $
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+0.1
+\begin_inset space \thinspace{}
+\end_inset
+
+s
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+\begin_inset Formula $\left\{ 1,1\right\} $
+\end_inset
+
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+1.1
+\begin_inset space \thinspace{}
+\end_inset
+
+s
+\end_layout
+
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\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}<f<10^{9}\right\}
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsection
+Function list
+\end_layout
+
+\begin_layout LyX-Code
+
+\series bold
+#include
+\series default
+ <libHX/misc.h>
+\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
+ <libHX/misc.h>
+\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
+ <stdlib.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <string.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <libHX/misc.h>
+\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 <libHX\SpecialChar \slash{}
+map.h>
+\family default
+.
+\end_layout
+
+\begin_layout Subsection
+Structural definition
+\begin_inset CommandInset label
+LatexCommand label
+name "sub: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 \-
+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 \-
+SKEY
+\family default
+ OR'ed with
+\family typewriter
+HXMAP_\SpecialChar \-
+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 \-
+SDATA
+\family default
+ OR'ed with
+\family typewriter
+HXMAP_\SpecialChar \-
+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 \slash{}
+
+\family typewriter
+CKEY
+\family default
+\SpecialChar \slash{}
+
+\family typewriter
+SDATA
+\family default
+\SpecialChar \slash{}
+
+\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 "sub: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 \slash{}
+ 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.
+\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 $a<b$
+\end_inset
+
+, zero on
+\begin_inset Formula $a=b$
+\end_inset
+
+, and positive non-zero when
+\begin_inset Formula $a>b$
+\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 "sub: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
+ <libHX/deque.h>
+\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 \-
+push
+\family default
+ and
+\family typewriter
+HXdeque_\SpecialChar \-
+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 \-
+pop
+\family default
+ and
+\family typewriter
+HXdeque_\SpecialChar \-
+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 \-
+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
+ <stdio.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <stdlib.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <string.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <libHX/defs.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <libHX/deque.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <libHX/string.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <pwd.h>
+\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
+
+\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
+
+\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
+
+\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 \-
+direct_\SpecialChar \-
+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
+ <libHX/list.h>
+\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
+
+\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
+
+\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
+
+\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
+ <libHX/list.h>
+\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
+ <libHX/string.h>
+\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
+ <libHX/string.h>
+\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
+ <libHX/string.h>
+\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
+ <libHX/string.h>
+\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
+&lt;
+\family default
+,
+\family typewriter
+&gt;
+\family default
+,
+\family typewriter
+&amp;
+\family default
+ and
+\family typewriter
+&quot;
+\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("<head>", 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("<html>", HXQUOTE_HTML, &tmp));
+\begin_inset Newline newline
+\end_inset
+
+printf("%s
+\backslash
+n", HX_strquote("<head>", 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
+ <libHX/string.h>
+\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
+ <libHX/string.h>
+\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
+ <libHX/string.h>
+\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<typename type> 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 "sub: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
+ <stdio.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <libHX/string.h>
+\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
+ <errno.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <stdio.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <libHX/string.h>
+\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
+ <errno.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <stdio.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <libHX/string.h>
+\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
+ <stdio.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <libHX/string.h>
+\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
+
+\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
+ <libHX/string.h>
+\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
+
+\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
+ <libHX/option.h>
+\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 "sub: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 \slash{}
+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
+
+\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
+
+\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 <libHX/io.h>
+\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 \-
+REALPATH_\SpecialChar \-
+SELF
+\begin_inset space ~
+\end_inset
+
+| HX_\SpecialChar \-
+REALPATH_\SpecialChar \-
+PARENT
+\family default
+.
+ Note that
+\family typewriter
+HX_\SpecialChar \-
+REALPATH_\SpecialChar \-
+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 platforms such as do not have readdir (e.
+\begin_inset space \thinspace{}
+\end_inset
+
+g.
+\begin_inset space \space{}
+\end_inset
+
+Win32), or to work around peculiarities in the lower implementation.
+ Solaris's
+\family typewriter
+struct dirent
+\family default
+ for example is
+\begin_inset Quotes eld
+\end_inset
+
+too small
+\begin_inset Quotes erd
+\end_inset
+
+, that is,
+\family typewriter
+readdir
+\family default
+ will cause a buffer overrun when Linux code is directly ported to it without
+ anticipating for this scenario.
+ libHX's
+\family typewriter
+io.c
+\family default
+ mitigates this.
+\end_layout
+
+\begin_layout Subsection
+Synopsis
+\end_layout
+
+\begin_layout LyX-Code
+
+\series bold
+#include
+\series default
+ <libHX/io.h>
+\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
+ <errno.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <stdio.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <libHX/io.h>
+\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
+ <libHX/io.h>
+\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
+ <libHX/io.h>
+\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
+ <libHX/io.h>
+\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 "sub:option-synopsis"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout LyX-Code
+
+\series bold
+#include
+\series default
+ <libHX/option.h>
+\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 "sub: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 \-
+INC
+\family default
+ or
+\family typewriter
+HXOPT_\SpecialChar \-
+DEC
+\family default
+ are specified as flags (see section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "sub: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 "sub: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 \-
+LLONG
+\family default
+,
+\family typewriter
+ HXTYPE_\SpecialChar \-
+ULLONG
+\family default
+,
+\family typewriter
+ HXTYPE_\SpecialChar \-
+INT64
+\family default
+ and
+\family typewriter
+ HXTYPE_\SpecialChar \-
+UINT64
+\family default
+ use
+\family typewriter
+ strtoll
+\family default
+ and/or
+\family typewriter
+ strtoull
+\family default
+, which may not be available on all platforms.
+\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
+<lyxtabular version="3" rows="12" columns="4">
+<features tabularvalignment="middle">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="bottom" width="0">
+<column alignment="center" valignment="top" width="0">
+<column alignment="center" valignment="top" width="0">
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+\series bold
+type
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+Type of pointee
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+type
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+Type of pointee
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+char
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+int8_t
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+unsigned char
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+uint8_t
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+short
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+int16_t
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+unsigned short
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+uint16_t
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+int
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+int32_t
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+unsigned int
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+uint32_t
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+long
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+int64_t
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+unsigned long
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+uint64_t
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+long long
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+float
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+unsigned long long
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+double
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\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
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\family typewriter
+size_t
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+\begin_inset Caption
+
+\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 \-
+FLOAT
+\family default
+ and
+\family typewriter
+HXTYPE_\SpecialChar \-
+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 "sub:option-example-cb"
+
+\end_inset
+
+).
+\end_layout
+
+\begin_layout Subsection
+Flags
+\begin_inset CommandInset label
+LatexCommand label
+name "sub: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 \-
+INC
+\family default
+ and
+\family typewriter
+HXOPT_\SpecialChar \-
+DEC
+\family default
+ may be specified at a time, and they require that the base type is
+\family typewriter
+HXTYPE_\SpecialChar \-
+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 "sub: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 \slash{}
+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 \slash{}
+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 \slash{}
+transformed value.
+\end_layout
+
+\begin_layout Standard
+Only one of (
+\family typewriter
+HXOPT_OR
+\family default
+,
+\family typewriter
+HXOPT_\SpecialChar \-
+AND
+\family default
+,
+\family typewriter
+HXOPT_\SpecialChar \-
+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 \-
+UINT
+\family default
+,
+\family typewriter
+HXTYPE_\SpecialChar \-
+ULONG
+\family default
+, etc.).
+ An example can be found in section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "sub: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 \-
+NONE
+\family default
+,
+\family typewriter
+HXTYPE_\SpecialChar \-
+VAL
+\family default
+ or
+\family typewriter
+HXTYPE_\SpecialChar \-
+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
+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 "sub:option-pitfalls-static"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+The following is an example of a trap regarding
+\family typewriter
+HXTYPE_\SpecialChar \-
+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 \-
+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 \-
+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 \-
+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 "sub: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
+ <stdio.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <stdilb.h>
+\begin_inset Newline newline
+\end_inset
+
+
+\series bold
+#include
+\series default
+ <libHX/option.h>
+\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 "sub: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 "sub: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 "sub: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 \-
+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 "sub: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 \-
+DESTROY_\SpecialChar \-
+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 \slash{}
+
+\family typewriter
+get_fruit
+\family default
+.
+
+\family typewriter
+HXOPT_\SpecialChar \-
+DESTROY_\SpecialChar \-
+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
+ <libHX/option.h>
+\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 "sub: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 "sub: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 \-
+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
+ <libHX/misc.h>
+\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
+ <libHX/proc.h>
+\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 \-
+run_\SpecialChar \-
+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 \slash{}
+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 "sub: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 \-
+run_\SpecialChar \-
+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 \slash{}
+null
+\family default
+.
+
+\family typewriter
+HXPROC_\SpecialChar \-
+STDIN
+\family default
+ and
+\family typewriter
+HXPROC_\SpecialChar \-
+NULL_\SpecialChar \-
+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 \slash{}
+null
+\family default
+, thereby essentially discarding its output.
+
+\family typewriter
+HXPROC_\SpecialChar \-
+STDOUT
+\family default
+ and
+\family typewriter
+HXPROC_\SpecialChar \-
+NULL_\SpecialChar \-
+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 \slash{}
+null
+\family default
+, thereby essentially discarding its output.
+
+\family typewriter
+HXPROC_\SpecialChar \-
+STDERR
+\family default
+ and
+\family typewriter
+HXPROC_\SpecialChar \-
+NULL_\SpecialChar \-
+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
+ <libHX/proc.h>
+\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
+ <libHX/proc.h>
+\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 "sub: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
+<ctype.h>
+\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
+ <libHX/ctype_helper.h>
+\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
+ <libHX/libxml_helper.h>
+\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 \-
+New\SpecialChar \-
+Text\SpecialChar \-
+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 \-
+Set\SpecialChar \-
+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
+ <libHX/wx_helper.hpp>
+\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 \-
+FRAME_\SpecialChar \-
+STYLE
+\family default
+ and a flag such that the dialog does not create a new window in the task
+ bar (
+\family typewriter
+wxFRAME_\SpecialChar \-
+NO_\SpecialChar \-
+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"
+
+\end_inset
+
+
+\end_layout
+
+\end_body
+\end_document