#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.21
\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
 HX_strquote results.
\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.
\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
