diff options
Diffstat (limited to 'doc/libHX_Documentation.lyx')
-rw-r--r-- | doc/libHX_Documentation.lyx | 24663 |
1 files changed, 0 insertions, 24663 deletions
diff --git a/doc/libHX_Documentation.lyx b/doc/libHX_Documentation.lyx deleted file mode 100644 index 9e2e9f5..0000000 --- a/doc/libHX_Documentation.lyx +++ /dev/null @@ -1,24663 +0,0 @@ -#LyX 2.3 created this file. For more info see http://www.lyx.org/ -\lyxformat 544 -\begin_document -\begin_header -\save_transient_properties true -\origin unavailable -\textclass article -\use_default_options true -\maintain_unincluded_children false -\language english -\language_package default -\inputencoding utf8 -\fontencoding global -\font_roman "lmodern" "default" -\font_sans "lmss" "default" -\font_typewriter "lmtt" "default" -\font_math "auto" "auto" -\font_default_family default -\use_non_tex_fonts false -\font_sc false -\font_osf false -\font_sf_scale 100 100 -\font_tt_scale 100 100 -\use_microtype false -\use_dash_ligatures true -\graphics default -\default_output_format default -\output_sync 0 -\bibtex_command default -\index_command default -\paperfontsize 12 -\spacing single -\use_hyperref true -\pdf_bookmarks false -\pdf_bookmarksnumbered false -\pdf_bookmarksopen false -\pdf_bookmarksopenlevel 1 -\pdf_breaklinks false -\pdf_pdfborder true -\pdf_colorlinks false -\pdf_backref page -\pdf_pdfusetitle true -\papersize a4paper -\use_geometry true -\use_package amsmath 1 -\use_package amssymb 1 -\use_package cancel 1 -\use_package esint 1 -\use_package mathdots 1 -\use_package mathtools 1 -\use_package mhchem 1 -\use_package stackrel 1 -\use_package stmaryrd 1 -\use_package undertilde 1 -\cite_engine natbib -\cite_engine_type numerical -\biblio_style plainnat -\use_bibtopic false -\use_indices false -\paperorientation portrait -\suppress_date false -\justification true -\use_refstyle 0 -\use_minted 0 -\index Index -\shortcut idx -\color #008000 -\end_index -\leftmargin 2cm -\topmargin 2cm -\rightmargin 2cm -\bottommargin 2cm -\secnumdepth 3 -\tocdepth 1 -\paragraph_separation indent -\paragraph_indentation default -\is_math_indent 0 -\math_numbering_side default -\quotes_style english -\dynamic_quotes 0 -\papercolumns 1 -\papersides 1 -\paperpagestyle default -\tracking_changes false -\output_changes false -\html_math_output 0 -\html_css_as_file 0 -\html_be_strict false -\end_header - -\begin_body - -\begin_layout Title -libHX 3.25 -\begin_inset Newline newline -\end_inset - -Documentation -\end_layout - -\begin_layout Standard -\begin_inset VSpace defskip -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset CommandInset toc -LatexCommand tableofcontents - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Newpage clearpage -\end_inset - - -\end_layout - -\begin_layout Section -Introduction -\end_layout - -\begin_layout Standard -libHX collects many useful day-to-day functions, intended to reduce the - amount of otherwise repeatedly open-coded instructions. -\end_layout - -\begin_layout Section -Overview -\end_layout - -\begin_layout Itemize -Maps (key-value pairs) (section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:maps" - -\end_inset - -) -\begin_inset Newline newline -\end_inset - -Originally created to provide a data structure like Perl's associative arrays. - Different map types and characteristics are available, such as hash-based - or the traditional rbtree. -\end_layout - -\begin_layout Itemize -Deques (section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:deque" - -\end_inset - -) -\begin_inset Newline newline -\end_inset - -Double-ended queues, implemented as a doubly-linked list with sentinels, - are suitable for both providing stack and queue functionality. -\end_layout - -\begin_layout Itemize -Inline doubly-linked list, uncounted and counted (sections -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:list" - -\end_inset - - and -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:clist" - -\end_inset - -) -\begin_inset Newline newline -\end_inset - -Light-weight linked lists as used in the Linux kernel. -\end_layout - -\begin_layout Itemize -Common string operations (section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:strings" - -\end_inset - -) -\begin_inset Newline newline -\end_inset - -basename, chomp, dirname, getl(ine), split, strlcat/strlcpy, strlower/-upper, - str*trim, strsep, etc. -\end_layout - -\begin_layout Itemize -Memory containers, auto-sizing string operations (section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:mc" - -\end_inset - -) -\begin_inset Newline newline -\end_inset - -Scripting-like invocation for string handling -\begin_inset space ~ -\end_inset - -— automatically doing (re)allocations as needed. -\end_layout - -\begin_layout Itemize -String formatter (section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:format" - -\end_inset - -) -\begin_inset Newline newline -\end_inset - -HXfmt is a small template system for by-name variable expansion. - It can be used to substitute placeholders in format strings supplied by - the user by appropriate expanded values defined by the program. -\end_layout - -\begin_layout Itemize -Directory creation, traversal, removal, and file copying (sections -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:dir-ops1" - -\end_inset - -, -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:dir-ops2" - -\end_inset - - and -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:file-ops" - -\end_inset - -) -\end_layout - -\begin_layout Itemize -Option parsing (section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:option" - -\end_inset - -) -\begin_inset Newline newline -\end_inset - -Table-/callback-based option parser that works similar to Perl's -\family typewriter -Getopt::Long -\family default - -\begin_inset space ~ -\end_inset - -— no open-coding but a single -\begin_inset Quotes eld -\end_inset - -atomic -\begin_inset Quotes erd -\end_inset - - invocation. -\end_layout - -\begin_layout Itemize -Shell-style config parser (section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:shconf" - -\end_inset - -) -\begin_inset Newline newline -\end_inset - -Configuration file reader for Shell-style -\begin_inset Quotes eld -\end_inset - -configuration -\begin_inset Quotes erd -\end_inset - - files with key-value pairs, as usually foudn in -\family typewriter -/etc\SpecialChar breakableslash -sysconfig -\family default -. -\end_layout - -\begin_layout Itemize -Random number gathering (section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:random" - -\end_inset - -) -\begin_inset Newline newline -\end_inset - -Convenient wrapper that uses kernel-provided RNG devices when available. -\end_layout - -\begin_layout Itemize -External process invocation (section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:proc" - -\end_inset - -) -\begin_inset Newline newline -\end_inset - -Setting up pipes for the standard file descriptors for sending/capturing - data to/from a program. -\end_layout - -\begin_layout Itemize - -\shape italic -a bit more beyond that ... - Miscellaneous -\end_layout - -\begin_layout Section -Resources -\end_layout - -\begin_layout Standard -As of this writing, the repository is located at -\end_layout - -\begin_layout Itemize -\begin_inset Flex URL -status open - -\begin_layout Plain Layout - -git://libhx.git.sf.net/gitroot/libhx/libhx -\end_layout - -\end_inset - - -\begin_inset space ~ -\end_inset - -— clone URL -\end_layout - -\begin_layout Itemize -\begin_inset Flex URL -status open - -\begin_layout Plain Layout - -http://libhx.git.sf.net/ -\end_layout - -\end_inset - - -\begin_inset space ~ -\end_inset - -— gitweb interface -\end_layout - -\begin_layout Itemize -\begin_inset Flex URL -status open - -\begin_layout Plain Layout - -http://libhx.sf.net/ -\end_layout - -\end_inset - - -\begin_inset space ~ -\end_inset - -— home page (and link to tarballs) -\end_layout - -\begin_layout Itemize -\begin_inset Flex URL -status open - -\begin_layout Plain Layout - -http://freecode.com/projects/libhx/ -\end_layout - -\end_inset - - -\begin_inset space ~ -\end_inset - -— Freecode page (useful for automatic notification of new releases) -\end_layout - -\begin_layout Section -Installation -\end_layout - -\begin_layout Standard -libHX uses GNU autotools as a build environment, which means that all you - have to run as a end-user is the -\family typewriter -configure -\family default - with any options that you need, plus the usual -\family typewriter -make -\family default - and -\family typewriter -make install -\family default - as desired. -\end_layout - -\begin_layout Standard -Pay attention to multi-lib Linux distributions where you most likely need - to specify a different libdir instead of using the default -\begin_inset Quotes eld -\end_inset - -lib -\begin_inset Quotes erd -\end_inset - -. - In case of the Debian-style multi-arch/multi-lib proposal ( -\begin_inset Flex URL -status collapsed - -\begin_layout Plain Layout - -http://wiki.debian.org/Multiarch -\end_layout - -\end_inset - -): -\end_layout - -\begin_layout LyX-Code -$ -\series bold -./configure --libdir='${prefix}/lib/x86_64-linux-gnu' -\end_layout - -\begin_layout Standard -and the classic-style 32-64 2-lib distributions: -\end_layout - -\begin_layout LyX-Code -$ -\series bold -./configure --libdir='${prefix}/lib64' -\end_layout - -\begin_layout Subsection -Requirements -\end_layout - -\begin_layout Itemize -GNU C Compiler 3.3.5 or newer. - Other compilers (non-GCC) have not been tested in months -\begin_inset space ~ -\end_inset - -— use at your own risk. -\end_layout - -\begin_layout Itemize -approximately 80–160 -\begin_inset space ~ -\end_inset - -KB of disk space on Linux for the shared library (depends on platform) and - header files. -\end_layout - -\begin_layout Standard -A C++ compiler is only needed if you want to build the C++ test programs - that come with libHX. - By default, if there is no C++ compiler present, these will not be built. -\end_layout - -\begin_layout Itemize -No external libraries are needed for compilation of libHX. - Helper files, like -\family typewriter -libxml_\SpecialChar softhyphen -helper.h -\family default -, may reference their include files, but they are not used during compilation. -\end_layout - -\begin_layout Section -Portability notice -\end_layout - -\begin_layout Standard -libHX runs on contemporary versions of Linux, Solaris and the three BSD - distributions. - It might even work on Microsoft Windows, but this is not tested very often, - if at all. - Overly old systems, especially Unices, are not within focus. - While AIX -\begin_inset space ~ -\end_inset - -5.3 might still classify as contemporary, strangelets like -\begin_inset Quotes eld -\end_inset - -Ultrix -\begin_inset Quotes erd -\end_inset - - or -\begin_inset Quotes eld -\end_inset - -Dynix -\begin_inset Quotes erd -\end_inset - - you can find in the autotools-related file -\family typewriter -config.guess -\family default - are some that are definitely not. -\end_layout - -\begin_layout Standard -Furthermore, a compiler that understands the C99 or GNU89 standard is required. - The integer type -\begin_inset Quotes eld -\end_inset - -int -\begin_inset Quotes erd -\end_inset - - should at best have 32 bits at least. - There is no ultra-portable version as of this writing, but feel free to - start one akin to the -\begin_inset Quotes eld -\end_inset - -p -\begin_inset Quotes erd -\end_inset - - variants of OpenBSD software such as OpenSSH. -\end_layout - -\begin_layout Section -History -\end_layout - -\begin_layout Standard -The origins of libHX trace back, even crossing a language boundary, to when - the author started on using Perl in 1999. - Some tasks were just too damn useful to be open-coded every time. - Two such examples are what is these days known as -\family typewriter -HX_basename -\family default - and -\family typewriter -HX_mkdir -\family default -. - The name does not relate to anyone's initials; it is a result of a truncation - of the author's nick used years ago. -\end_layout - -\begin_layout Standard -Around the beginning of 2003, the author also started on the C programming - language and soon the small library was converted from Perl to C. - The libHX library as of today is the result of working with C ever since, - and naturally grew from there to support whatever the author was in need - of. -\end_layout - -\begin_layout Standard -The -\begin_inset Quotes eld -\end_inset - -correct -\begin_inset Quotes erd -\end_inset - - name for libHX is with an uppercase -\begin_inset Quotes eld -\end_inset - -H -\begin_inset Quotes erd -\end_inset - - and uppercase -\begin_inset Quotes eld -\end_inset - -X -\begin_inset Quotes erd -\end_inset - -, and the same is used for filenames, such as -\begin_inset Quotes eld -\end_inset - -libHX.so -\begin_inset Quotes erd -\end_inset - - -\begin_inset Foot -status open - -\begin_layout Plain Layout -Software projects may choose to entirely lowercase the project name for - use in filenames, such as the Linux kernel which is released as -\family typewriter -linux-${ -\family default -\shape italic -version -\family typewriter -\shape default -}.tar.bz2 -\family default -, or the project may choose to keep the name for filenames, like Mesa and - SDL do. - libHX is of the latter. -\end_layout - -\end_inset - -. -\end_layout - -\begin_layout Standard -\begin_inset Newpage clearpage -\end_inset - - -\end_layout - -\begin_layout Part -General -\end_layout - -\begin_layout Standard -Many functions are prefixed with -\begin_inset Quotes eld -\end_inset - - -\family typewriter -HX_ -\family default - -\begin_inset Quotes erd -\end_inset - - or -\begin_inset Quotes eld -\end_inset - - -\family typewriter -HXsubsys_ -\family default - -\begin_inset Quotes erd -\end_inset - -, as are structures (sometimes without underscores, be sure to check the - syntax and names), to avoid name clashes with possibly existing files. - Functions that are not tied to a specific data structure such as most of - the string functions (see chapter -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:strings" - -\end_inset - -) use the subsystem-less prefix, -\begin_inset Quotes eld -\end_inset - - -\family typewriter -HX_ -\family default - -\begin_inset Quotes erd -\end_inset - -. - Functions from a clearly-defined subsystem, such as map or deque, augment - the base prefix by a suffix, forming e. -\begin_inset space \thinspace{} -\end_inset - -g. -\begin_inset space \space{} -\end_inset - - -\begin_inset Quotes eld -\end_inset - - -\family typewriter -HXmap_ -\family default - -\begin_inset Quotes erd -\end_inset - -. -\end_layout - -\begin_layout Section -Initialization -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<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 Standard - -\begin_layout Plain Layout -\begin_inset CommandInset label -LatexCommand label -name "tab:defs-signed_cast" - -\end_inset - -Accepted conversions for -\family typewriter -signed_cast() -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Subsection - -\family typewriter -static_cast -\begin_inset CommandInset label -LatexCommand label -name "subsec:defs-static_cast" - -\end_inset - - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -static_cast -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -Just like C++'s -\family typewriter -static_cast<> -\family default -, libHX's -\family typewriter -static_cast() -\family default - verifies that -\family typewriter -expr -\family default - can be implicitly converted to the new type (by a simple -\family typewriter -b -\begin_inset space ~ -\end_inset - -= -\begin_inset space ~ -\end_inset - -a -\family default -). - Such is mainly useful for forcing a specific type, as is needed in varargs - functions such as -\family typewriter -printf -\family default -, and where the conversion actually incurs other side effects, such as truncatio -n or promotion: -\end_layout - -\begin_layout LyX-Code - -\series bold -/* -\family roman -\series default -\shape italic -Convert to a type printf knows about -\family default -\series bold -\shape default - */ -\begin_inset Newline newline -\end_inset - -uint64_t -\series default - x = something; -\begin_inset Newline newline -\end_inset - -printf("%llu -\backslash -n", -\series bold -static_cast -\series default -( -\series bold -unsigned long long -\series default -, x)); -\end_layout - -\begin_layout Standard -Because there is no format specifier for -\family typewriter -uint64_t -\family default - for -\family typewriter -printf -\family default -, a conversion to an accepted type is necessary to not cause undefined behavior. - The author has seen code that did, for example, -\family typewriter -printf("%u") -\family default - on a -\begin_inset Quotes eld -\end_inset - -long -\begin_inset Quotes erd -\end_inset - -, which only works on architectures where -\family typewriter -sizeof(unsigned int) -\family default - happens to equal -\family typewriter -sizeof(unsigned long) -\family default -, such as x86_32. - On x86_64, an -\family typewriter -unsigned long -\family default - is usually twice as big as an -\family typewriter -unsigned int -\family default -, so that 8 bytes are pushed onto the stack, but -\family typewriter -printf -\family default - only unshifts 4 bytes because the developer used -\begin_inset Quotes eld -\end_inset - - -\family typewriter -%u -\family default - -\begin_inset Quotes erd -\end_inset - -, leading to misreading the next variable on the stack. -\end_layout - -\begin_layout LyX-Code - -\series bold -/* -\family roman -\series default -\shape italic -Force promotion -\family default -\series bold -\shape default - */ -\series default - -\begin_inset Newline newline -\end_inset - - -\series bold -double -\series default - a_quarter = -\series bold -static_cast -\series default -( -\series bold -double -\series default -, 1) / 4; -\end_layout - -\begin_layout Standard -Were -\begin_inset Quotes eld -\end_inset - -1 -\begin_inset Quotes erd -\end_inset - - not promoted to double, the result in -\family typewriter -q -\family default - would be zero because 1/4 is just an integer division, yielding zero. - By making one of the operands a floating-point quantity, the compiler will - instruct the FPU to compute the result. - Of course, one could have also written -\begin_inset Quotes eld -\end_inset - - -\family typewriter -1.0 -\family default - -\begin_inset Quotes erd -\end_inset - - instead of -\family typewriter -static_cast(double, 1) -\family default -, but this is left for the programmer to decide which style s/he prefers. -\end_layout - -\begin_layout LyX-Code - -\series bold -/* -\family roman -\series default -\shape italic -Force truncation before invoking second sqrt -\family default -\series bold -\shape default - */ -\series default - -\begin_inset Newline newline -\end_inset - - -\series bold -double -\series default - f = sqrt( -\series bold -static_cast -\series default -( -\series bold -int -\series default -, 10 * sqrt(3.0 / 4))); -\end_layout - -\begin_layout Standard -And here, the conversion from -\family typewriter -double -\family default - to -\family typewriter -int -\family default - incurs a (wanted) truncation of the decimal fraction, that is, rounding - down for positive numbers, and rounding up for negative numbers. -\end_layout - -\begin_layout Subsubsection -Allowed conversions -\end_layout - -\begin_layout Itemize - -\series bold -Numbers -\series default - -\begin_inset Newline newline -\end_inset - -Conversion between numeric types, such as -\family typewriter -char -\family default -, -\family typewriter -short -\family default -, -\family typewriter -int -\family default -, -\family typewriter -long -\family default -, -\family typewriter -long long -\family default -, -\family typewriter -int -\shape italic -N -\shape default -_t -\family default -, both their signed and unsigned variants, -\family typewriter -float -\family default - and -\family typewriter -double -\family default -. -\end_layout - -\begin_layout Itemize - -\series bold -Generic Pointer -\series default - -\begin_inset Newline newline -\end_inset - -Conversion from -\family typewriter -type -\begin_inset space ~ -\end_inset - -* -\family default - to and from -\family typewriter -void -\begin_inset space ~ -\end_inset - -* -\family default -. - (Where -\family typewriter -type -\family default - may very well be a type with further indirection.) -\end_layout - -\begin_layout Itemize - -\series bold -Generic Pointer (const) -\begin_inset Newline newline -\end_inset - - -\series default -Conversion from -\family typewriter -const type -\begin_inset space ~ -\end_inset - -* -\family default - to and from -\family typewriter -const void -\begin_inset space ~ -\end_inset - -* -\family default -. -\end_layout - -\begin_layout Subsection - -\family typewriter -const_cast -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -const_cast -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard - -\family typewriter -const_cast -\family default - allows to add or remove -\begin_inset Quotes eld -\end_inset - -const -\begin_inset Quotes erd -\end_inset - - qualifiers from the type a pointer is pointing to. - Due to technical limitations, it could not be implemented to support arbitrary - indirection. - Instead, -\family typewriter -const_cast -\family default - comes in three variants, to be used for indirection levels of 1 to 3: -\end_layout - -\begin_layout Itemize - -\family typewriter -\series bold -const_cast -\series default -1( -\series bold -type -\begin_inset space ~ -\end_inset - -* -\series default -, expr) -\family default - with -\family typewriter -\series bold -typeof -\series default -(expr) -\begin_inset space ~ -\end_inset - -= -\series bold -type -\begin_inset space ~ -\end_inset - -* -\family default -\series default -. - (Similarly for any combinations of const.) -\end_layout - -\begin_layout Itemize - -\family typewriter -\series bold -const_cast -\series default -2( -\series bold -type -\begin_inset space ~ -\end_inset - -** -\series default -, expr) with -\series bold -typeof -\series default -(expr) -\begin_inset space ~ -\end_inset - -= -\series bold -type -\begin_inset space ~ -\end_inset - -** -\family default -\series default - (and all combinations of const in all possible locations). -\end_layout - -\begin_layout Itemize - -\family typewriter -\series bold -const_cast -\series default -3( -\series bold -type -\begin_inset space ~ -\end_inset - -*** -\series default -, expr) with -\series bold -typeof -\series default -(expr) -\begin_inset space ~ -\end_inset - -= -\series bold -type -\begin_inset space ~ -\end_inset - -*** -\family default -\series default - (and all combinations...). -\end_layout - -\begin_layout Standard -As indirection levels above 3 are really unlikely -\begin_inset Foot -status open - -\begin_layout Plain Layout -See -\begin_inset Quotes eld -\end_inset - -Three Star Programmer -\begin_inset Quotes erd -\end_inset - - -\end_layout - -\end_inset - -, having only these three type-checking cast macros was deemed sufficient. - The only place where libHX even uses a level\SpecialChar nobreakdash -3 indirection is in the option - parser. -\end_layout - -\begin_layout Standard -\begin_inset Float table -placement H -wide false -sideways false -status open - -\begin_layout Plain Layout -\align center -\begin_inset Tabular -<lyxtabular version="3" rows="2" columns="2"> -<features tabularvalignment="middle"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<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 Standard - -\begin_layout Plain Layout -Accepted expr/target types for -\family typewriter -const_cast2 -\family default -; example for the -\begin_inset Quotes eld -\end_inset - -int -\begin_inset Quotes erd -\end_inset - - type -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\align center -Conversion is permitted when expression and target type are from the table. -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -It is currently not possible to use -\family typewriter -const_cast -\family default -1/2/3 on pointers to structures whose member structure is unknown. -\end_layout - -\begin_layout Standard -\begin_inset Newpage clearpage -\end_inset - - -\end_layout - -\begin_layout Section -Macros -\end_layout - -\begin_layout Standard -All macros in this section are available through -\family typewriter -#include <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 -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 - HXsizeof_member(struct_type, member); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXsizeof_member -\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 - -\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 -HXsizeof_member -\family default - and -\family typewriter -HXtypeof_member -\family default - are shortcuts (mainly for the C language) 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 Standard -In C++, one can simply use -\family typewriter -sizeof(foo::baz) -\family default - and -\family typewriter -decltype(foo::baz) -\family default -. -\end_layout - -\begin_layout Subsection -Array size -\end_layout - -\begin_layout LyX-Code - -\series bold -size_t -\series default - ARRAY_SIZE( -\series bold -type -\series default - array -\series bold -[] -\series default -); -\series bold -/* -\family roman -\series default -\shape italic -implemented as a macro -\family default -\series bold -\shape default - */ -\series default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -ARRAY_SIZE -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -Returns the number of elements in -\family typewriter -array -\family default -. - This only works with true arrays ( -\family typewriter -type[] -\family default -), and will not output a meaningful value when used with a pointer-to-element - ( -\family typewriter -type -\begin_inset space ~ -\end_inset - -* -\family default -), which is often used for array access too. -\end_layout - -\begin_layout Subsection -Compile-time build checks -\end_layout - -\begin_layout LyX-Code - -\series bold -int -\series default - BUILD_BUG_ON_EXPR( -\series bold -bool -\series default - condition); -\series bold -/* -\family roman -\series default -\shape italic -implemented as a macro -\family default -\series bold -\shape default - */ -\series default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -BUILD_BUG_ON_EXPR -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -void -\series default - BUILD_BUG_ON( -\series bold -bool -\series default - condition); -\series bold -/* -\family roman -\series default -\shape italic -implemented as a macro -\family default -\series bold -\shape default - */ -\series default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -BUILD_BUG_ON -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -Causes the compiler to fail when -\family typewriter -condition -\family default - evaluates to true. - If not implemented for a compiler, it will be a no-op. - -\family typewriter -BUILD_BUG_ON -\family default - is meant to be used as a standalone statement, while -\family typewriter -BUILD_\SpecialChar softhyphen -BUG_\SpecialChar softhyphen -ON_\SpecialChar softhyphen -EXPR -\family default - is for when a check is to occur within an expression, that latter of which - is useful for within macros when one cannot, or does not want to use multiple - statements. -\end_layout - -\begin_layout LyX-Code -type DEMOTE_TO_PTR(type expr); -\series bold -/* -\family roman -\series default -\shape italic -macro -\family default -\series bold -\shape default - */ -\end_layout - -\begin_layout Standard -Changes the type of expr to pointer type: If -\family typewriter -expr -\family default - of array type class, changes it to a pointer to the first element. - If -\family typewriter -expr -\family default - of function type class, changes it to a pointer to the function. -\end_layout - -\begin_layout LyX-Code - -\series bold -int -\series default - main( -\series bold -void -\series default -); -\begin_inset Newline newline -\end_inset - - -\series bold -int (* -\series default -fp -\series bold -) -\series default -( -\series bold -void -\series default -); -\begin_inset Newline newline -\end_inset - - -\series bold -char -\series default - a -\series bold -[ -\series default -123 -\series bold -] -\series default -; -\begin_inset Newline newline -\end_inset - -DEMOTE_TO_PTR(main); -\series bold -/* -\family roman -\series default -\shape italic -yields -\series bold -int (*) -\series default -( -\series bold -void -\series default -); -\family default -\series bold -\shape default - */ -\series default - -\begin_inset Newline newline -\end_inset - -DEMOTE_TO_PTR(fp); -\series bold -/* -\series default -also yields -\family roman -\series bold -\shape italic -int (*) -\series default -( -\series bold -void -\series default -); -\family default -\series bold -\shape default - */ -\series default - -\begin_inset Newline newline -\end_inset - -DEMOTE_TO_PTR(a); -\series bold -/* -\series default -yields -\family roman -\series bold -\shape italic -char * -\family default -\shape default - */ -\end_layout - -\begin_layout Subsection -UNIX file modes -\end_layout - -\begin_layout LyX-Code - -\series bold -#define -\series default - S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -S_IRUGO -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -#define -\series default - S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -S_IWUGO -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -#define -\series default - S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -S_IXUGO -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -#define -\series default - S_IRWXUGO (S_IRUGO | S_IWUGO | S_IXUGO) -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -S_IRWXUGO -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -The defines make it vastly easier to specify permissions for large group - of users. - For example, if one wanted to create a file with the permissions -\family typewriter -rw-r--r-- -\family default - (ignoring the umask in this description), -\family typewriter -S_IRUSR -\begin_inset space ~ -\end_inset - -| S_IWUSR -\family default - can now be used instead of the longer -\family typewriter -S_IRUSR -\begin_inset space ~ -\end_inset - -| S_IWUSR -\begin_inset space ~ -\end_inset - -| S_IRGRP -\begin_inset space ~ -\end_inset - -| S_IROTH -\family default -. -\end_layout - -\begin_layout Subsection -VC runtime format specifiers -\end_layout - -\begin_layout Standard -The Microsoft Visual C runtime (a weak libc) uses non-standard format specifiers - for certain types. - Whereas C99 specifies -\begin_inset Quotes eld -\end_inset - -z -\begin_inset Quotes erd -\end_inset - - for -\family typewriter -size_t -\family default - and -\begin_inset Quotes eld -\end_inset - -ll -\begin_inset Quotes erd -\end_inset - - for long long, MSVCRT users must use -\begin_inset Quotes eld -\end_inset - -I -\begin_inset Quotes erd -\end_inset - - and -\begin_inset Quotes eld -\end_inset - -I64 -\begin_inset Quotes erd -\end_inset - - (forming -\family typewriter -%Id -\family default - instead of -\family typewriter -%zd -\family default - for -\family typewriter -ssize_t -\family default -, for example). - libHX provides two convenience macros for this: -\end_layout - -\begin_layout LyX-Code - -\series bold -#define -\series default - HX_SIZET_FMT "z" -\family roman -\shape italic - or -\family default -\shape default -"I" -\begin_inset Index idx -status open - -\begin_layout Plain Layout -HX_SIZET_FMT -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -#define -\series default - HX_LONGLONG_FMT "ll" -\family roman -\shape italic - or -\family default -\shape default -"I64" -\begin_inset Index idx -status open - -\begin_layout Plain Layout -HX_LONGLONG_FMT -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -These may be used together with printf or scanf: -\end_layout - -\begin_layout LyX-Code -printf("struct timespec is of size %" HX_SIZET_FMT "u -\backslash -n", -\begin_inset Newline newline -\end_inset - - -\series bold -sizeof -\series default -(struct timespec)); -\end_layout - -\begin_layout Standard -\begin_inset Newpage clearpage -\end_inset - - -\end_layout - -\begin_layout Section -Miscellaneous functions -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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. -\begin_inset Separator latexpar -\end_inset - - -\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"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<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 breakableslash -map.h> -\family default -. -\end_layout - -\begin_layout Subsection -Structural definition -\begin_inset CommandInset label -LatexCommand label -name "subsec:maps-def" - -\end_inset - - -\end_layout - -\begin_layout Standard -The -\family typewriter -HXmap -\family default - structure is a near-opaque type. - Unlike the predecessor map implementation -\family typewriter -struct HXbtree -\family default - from libHX 2.x, the 3.x API exposes much less fields. -\end_layout - -\begin_layout LyX-Code - -\series bold -struct -\series default - HXmap { -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -struct HXmap -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -unsigned int -\series default - items, flags; -\begin_inset Newline newline -\end_inset - -}; -\end_layout - -\begin_layout Description - -\family typewriter -items -\family default - The number of items in the tree. - This field tracks the number of items in the map and is used to report - the number of elements to the user, and is updated whenever an element - is inserted or removed from the map. - The field must not be changed by user. -\end_layout - -\begin_layout Description - -\family typewriter -flags -\family default - The current behavior flags for the map. - While implementation-private bits are exposed, only -\family typewriter -HXMAP_NOREPLACE -\family default - is currently allowed to be (un)set by the developer while a map exists. -\end_layout - -\begin_layout Standard -For retrieving elements from a tree, some functions work with -\family typewriter -struct HXmap_node -\family default -, which is defined as follows: -\end_layout - -\begin_layout LyX-Code - -\series bold -struct -\series default - HXmap_node { -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -struct HXmap_node -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -union -\series default - { -\begin_inset Newline newline -\end_inset - - -\series bold -void * -\series default -key; -\begin_inset Newline newline -\end_inset - - -\series bold -const char *const -\series default - skey; -\begin_inset Newline newline -\end_inset - - }; -\begin_inset Newline newline -\end_inset - - -\series bold -union -\series default - { -\begin_inset Newline newline -\end_inset - - -\series bold -void * -\series default -data; -\begin_inset Newline newline -\end_inset - - -\series bold -char * -\series default -sdata; -\begin_inset Newline newline -\end_inset - - }; -\begin_inset Newline newline -\end_inset - -}; -\end_layout - -\begin_layout Description - -\family typewriter -key -\family default - The so-called primary key, which uniquely identifies an element (a key-value - pair) in the map. - The memory portions that make up the key must not be modified. - (If the key changes, so does its hash value and/or position index, and - without taking that into account, writing to the key directly is going - to end up with an inconsistent state. - To change the key, you will need to delete the element and reinsert it - with its new key.) -\end_layout - -\begin_layout Description - -\family typewriter -skey -\family default - A convenience type field for when the map's keys are C strings. - It is useful for use with e. -\begin_inset space \thinspace{} -\end_inset - -g. -\begin_inset space \space{} -\end_inset - - -\family typewriter -printf -\family default - or other varargs function, which would otherwise require casting of the - -\family typewriter -void -\begin_inset space ~ -\end_inset - -*key -\family default - member to -\family typewriter -const char -\begin_inset space ~ -\end_inset - -* -\family default - first. -\end_layout - -\begin_layout Description - -\family typewriter -data -\family default - The data associated with the key. -\end_layout - -\begin_layout Description - -\family typewriter -sdata -\family default - Convenience type field. -\end_layout - -\begin_layout Subsection -Map initialization -\end_layout - -\begin_layout Standard -During initialization, you specify the underlying storage type by selecting - a given constructor function. - All further operations are done through the unified HXmap API which uses - a form of virtual calls internally. -\end_layout - -\begin_layout Standard -Currently, there are two distinct map types in libHX. - There are a handful of selectable symbols, though. - Abstract types are: -\end_layout - -\begin_layout Description - -\family typewriter -HXMAPT_DEFAULT -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAPT_DEFAULT -\end_layout - -\end_inset - - No further preferences or guarantees; selects any map type that the libHX - maintainer deemed fast. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAPT_ORDERED -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAPT_ORDERED -\end_layout - -\end_inset - - The map shall use a data structure that provides ordered traversal. -\end_layout - -\begin_layout Standard -Specific types include: -\end_layout - -\begin_layout Description - -\family typewriter -HXMAPT_HASH -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HX_MAPT_HASH -\end_layout - -\end_inset - - Hash-based map -\begin_inset space ~ -\end_inset - -– Amortized -\begin_inset Formula $\mathcal{O}\left(1\right)$ -\end_inset - - insertion, lookup and deletion; unordered. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAPT_RBTREE -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HX_MAPT_RBTREE -\end_layout - -\end_inset - - Red-black binary tree -\begin_inset space ~ -\end_inset - -– -\begin_inset Formula $\mathcal{O}\left(\log\left(n\right)\right)$ -\end_inset - - insertion, lookup and deletion; ordered. -\end_layout - -\begin_layout Standard -These can then be used with the initialization functions: -\end_layout - -\begin_layout LyX-Code - -\series bold -struct -\series default - HXmap -\series bold -* -\series default -HXmap_init( -\series bold -unsigned int -\series default - type, -\series bold -unsigned int -\series default - flags); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_init -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - HXmap -\series bold -* -\series default -HXmap_init5( -\series bold -unsigned int -\series default - type, -\series bold -unsigned int -\series default - flags, -\begin_inset Newline newline -\end_inset - - -\series bold -const struct -\series default - HXmap_ops -\series bold -* -\series default -ops, -\series bold -size_t -\series default - key_size, -\series bold -size_t -\series default - data_size); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_init5 -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -Both the -\family typewriter -*_init -\family default - and -\family typewriter -*_init5 -\family default - variant creates a new map; the latter function allows to specify the operations - in detail as well as key and data size, which may become necessary when - using data sets which have their own way of being managed. - The -\family typewriter -flags -\family default - parameter can contain any of the following: -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_NONE -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_NONE -\end_layout - -\end_inset - - This is just a mnemonic for the value 0, indicating no flags. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_NOREPLACE -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_NOREPLACE -\end_layout - -\end_inset - - If a key already exists and another add operation is attempted, the key's - associated value will be replaced by the new value. - If this flag is absent, -\family typewriter --EEXIST -\family default - is returned. - This flag is allowed to be subsequently changed by the developer if so - desired, using bit logic such as -\family typewriter -map->flags &= ~HXMAP_NOREPLACE; -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_SKEY -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_SKEY -\end_layout - -\end_inset - - Notifies the constructor that keys will be C-style strings. - The flag presets the -\family typewriter -k_compare -\family default - operation to use -\family typewriter -strcmp -\family default -. - In the flag's absence, direct value comparison will be used if the key - size is specified as zero (e. -\begin_inset space \thinspace{} -\end_inset - -g. -\begin_inset space \space{} -\end_inset - -with the -\family typewriter -HXhashmap_\SpecialChar softhyphen -init4 -\family default - function call), or -\family typewriter -memcmp -\family default - if the key size is non-zero. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_CKEY -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_CKEY -\end_layout - -\end_inset - - Instructs the map to make copies of keys when they are added to the map. - This is required when the buffer holding the key changes or goes out of - scope. - The flag presets the -\family typewriter -k_clone -\family default - and -\family typewriter -k_free -\family default - operations to -\family typewriter -HX_memdup -\family default - and -\family typewriter -free -\family default -, and as such, the -\family typewriter -key_size -\family default - parameter must not be zero. - If however, -\family typewriter -HXMAP_SKEY -\family default - is also specified, -\family typewriter -HX_strdup -\family default - and -\family typewriter -free -\family default - will be used and -\family typewriter -key_size -\family default - must be zero. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_SDATA -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_SDATA -\end_layout - -\end_inset - - Notifies the constructor that data will be C-style strings. - This sets up the -\family typewriter -d_clone -\family default - and -\family typewriter -d_free -\family default - operations. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_CDATA -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_CDATA -\end_layout - -\end_inset - - Instructs the map to make copies of the data when new entries are added - to the map. - This is required when the buffer holding the data either goes out of scope, - or you want to keep the original contents instead of just a pointer. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_SCKEY -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_SCKEY -\end_layout - -\end_inset - - Mnemonic for the combination of -\family typewriter -HXMAP_\SpecialChar softhyphen -SKEY -\family default - OR'ed with -\family typewriter -HXMAP_\SpecialChar softhyphen -CKEY -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_SCDATA -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_SCDATA -\end_layout - -\end_inset - - Mnemonic for the combination of -\family typewriter -HXMAP_\SpecialChar softhyphen -SDATA -\family default - OR'ed with -\family typewriter -HXMAP_\SpecialChar softhyphen -SDATA -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_SINGULAR -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_SINGULAR -\end_layout - -\end_inset - - Specifies that the -\begin_inset Quotes eld -\end_inset - -map -\begin_inset Quotes erd -\end_inset - - is only used as a set, i. -\begin_inset space \thinspace{} -\end_inset - -e. -\begin_inset space \space{} -\end_inset - -it does not store any values, only keys. - Henceforth, the -\family typewriter -value -\family default - argument to -\family typewriter -HXmap_add -\family default - must always be -\family typewriter -NULL -\family default -. -\end_layout - -\begin_layout Subsection -Flag combinations -\end_layout - -\begin_layout Standard -This subsection highlights the way -\family typewriter -HXMAP_SKEY -\family default - interacts with -\family typewriter -HXMAP_CKEY -\family default - and the key size. - The copy semantics are the same for -\family typewriter -HXMAP_SDATA -\family default - and -\family typewriter -HXMAP_CDATA -\family default -. -\end_layout - -\begin_layout Subsubsection* - -\family typewriter -HXMAP_SKEY -\family default - is unset, -\family typewriter -HXMAP_CKEY -\family default - is unset -\end_layout - -\begin_layout Standard -The -\family typewriter -key_size -\family default - parameter at the time of map construction is ignored. - The pointer value of the -\family typewriter -key -\family default - parameter for the -\family typewriter -HXmap_add -\family default - call is directly stored in the tree, and this is the key that uniquely - identifies the map entry and which is used for comparisons. - This may be used if you intend to directly map pointer values. -\end_layout - -\begin_layout LyX-Code -static struct something *x = ..., *y = ...; -\begin_inset Newline newline -\end_inset - -HXmap_add(map, &x[0], "foo"); -\begin_inset Newline newline -\end_inset - -HXmap_add(map, &x[1], "bar"); -\end_layout - -\begin_layout Subsubsection* - -\family typewriter -HXMAP_SKEY -\family default - is set, -\family typewriter -HXMAP_CKEY -\family default - is unset -\end_layout - -\begin_layout Standard -The -\family typewriter -key_size -\family default - parameter at the time of map construction is ignored. - The pointer value of the -\family typewriter -key -\family default - parameter for the -\family typewriter -HXmap_add -\family default - call is directly stored in the tree, but it is the C string -\shape italic -pointed to -\shape default - by the -\family typewriter -key -\family default - parameter that serves as the key. -\end_layout - -\begin_layout Subsubsection* - -\family typewriter -HXMAP_SKEY -\family default - is set, -\family typewriter -HXMAP_CKEY -\family default - is set -\end_layout - -\begin_layout Standard -The -\family typewriter -key_size -\family default - parameter at the time of map construction is ignored. - The string pointed to by the key parameter will be duplicated, and the - resulting pointer will be stored in the tree. - Again, it is the pointed-to string that is the key. -\end_layout - -\begin_layout Subsubsection* - -\family typewriter -HXMAP_SKEY -\family default - is unset, -\family typewriter -HXMAP_CKEY -\family default - is set -\end_layout - -\begin_layout Standard -The memory block pointed to by the key parameter will be duplicated. - The -\family typewriter -key_size -\family default - parameter must be non-zero for this to successfully work. -\end_layout - -\begin_layout Subsubsection* -With separate ops -\end_layout - -\begin_layout Standard -However, when a custom -\family typewriter -struct HXmap_ops -\family default - is provided in the call to -\family typewriter -HXmap_init5 -\family default -, any of these semantics can be overridden. - Particularly, since your own ops can practically ignore -\family typewriter -key_size -\family default -, it could be set to any value. -\end_layout - -\begin_layout Subsection -Key-data operations -\end_layout - -\begin_layout Standard -The -\family typewriter -HXMAP_SKEY -\family default -\SpecialChar breakableslash - -\family typewriter -CKEY -\family default -\SpecialChar breakableslash - -\family typewriter -SDATA -\family default -\SpecialChar breakableslash - -\family typewriter -CDATA -\family default - flags are generally sufficient to set up common maps where keys and/or - data are C strings or simple binary data where -\family typewriter -memdup -\family default -/ -\family typewriter -memcmp -\family default - is enough. - Where the provided mechanisms are not cutting it, an extra -\family typewriter -HXmap_ops -\family default - structure with functions specialized in handling the keys and/or data has - to be used as an argument to the initialization function call. -\end_layout - -\begin_layout LyX-Code - -\series bold -struct -\series default - HXmap_ops { -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -struct HXmap_ops -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -int (* -\series default -k_compare -\series bold -) -\series default -( -\series bold -const void * -\series default -, -\series bold -const void * -\series default -, -\series bold -size_t -\series default -); -\begin_inset Newline newline -\end_inset - - -\series bold -void *(* -\series default -k_clone -\series bold -) -\series default -( -\series bold -const void * -\series default -, -\series bold -size_t -\series default -); -\begin_inset Newline newline -\end_inset - - -\series bold -void (* -\series default -k_free -\series bold -) -\series default -( -\series bold -void * -\series default -); -\begin_inset Newline newline -\end_inset - - -\series bold -void *(* -\series default -d_clone -\series bold -) -\series default -( -\series bold -const void * -\series default -, -\series bold -size_t -\series default -); -\begin_inset Newline newline -\end_inset - - -\series bold -void (* -\series default -d_free -\series bold -) -\series default -( -\series bold -void * -\series default -); -\begin_inset Newline newline -\end_inset - - -\series bold -unsigned long (* -\series default -k_hash -\series bold -) -\series default -( -\series bold -const void * -\series default -, -\series bold -size_t -\series default -); -\begin_inset Newline newline -\end_inset - -}; -\end_layout - -\begin_layout Description - -\family typewriter -k_compare -\family default - Function to compare two keys. - The return value is the same as that of -\family typewriter -memcmp -\family default - or -\family typewriter -strcmp -\family default -: negative values indicate that the first key is -\begin_inset Quotes eld -\end_inset - -less than -\begin_inset Quotes erd -\end_inset - - the second, zero indicates that both keys are equal, and positive values - indicate that the first key is -\begin_inset Quotes eld -\end_inset - -greater than -\begin_inset Quotes erd -\end_inset - - the second. - The size argument in third position is provided so that -\family typewriter -memcmp -\family default -, which wants a size parameter, can directly be used without having to write - an own function. -\end_layout - -\begin_layout Description - -\family typewriter -k_clone -\family default - Function that will clone (duplicate) a key. - This is used for keys that will be added to the tree, and potentially also - for state-keeping during traversal of the map. - It is valid that this clone function simply returns the value of the pointer - it was actually passed; this is used by default for maps without -\family typewriter -HXMAP_CKEY -\family default - for example. -\end_layout - -\begin_layout Description - -\family typewriter -k_free -\family default - Function to free a key. - In most cases it defaults to -\family typewriter -free -\family default -(3), but in case you are using complex structs, more cleanup may be needed. -\end_layout - -\begin_layout Description - -\family typewriter -d_clone -\family default - Same as -\family typewriter -k_clone -\family default -, but for data. -\end_layout - -\begin_layout Description - -\family typewriter -d_free -\family default - Same as -\family typewriter -k_free -\family default -, but for data. -\end_layout - -\begin_layout Description - -\family typewriter -k_hash -\family default - Specifies an alternate hash function. - Only to be used with hash-based maps. - Hashmaps default to using the DJB2 string hash function when -\family typewriter -HXMAP_SKEY -\family default - is given, or otherwise the Jenkins' lookup3 hash function. -\end_layout - -\begin_layout Standard -libHX exports two hash functions that you can select for -\family typewriter -struct HXmap_ops -\family default -'s -\family typewriter -k_hash -\family default - if the default for a given flag combination is not to your liking. -\end_layout - -\begin_layout Description - -\family typewriter -HXhash_jlookup3 -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXhash_jlookup3 -\end_layout - -\end_inset - - Bob Jenkins's lookup3 hash. -\end_layout - -\begin_layout Description - -\family typewriter -HXhash_djb2 -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXhash_djb2 -\end_layout - -\end_inset - - DJB2 string hash. -\end_layout - -\begin_layout Subsection -Map operations -\end_layout - -\begin_layout LyX-Code - -\series bold -int -\series default - HXmap_add( -\series bold -struct -\series default - HXmap -\series bold -* -\series default -, -\series bold -const void * -\series default -key, -\series bold -const void * -\series default -value); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_add -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -const struct -\series default - HXmap_node -\series bold -* -\series default -HXmap_find( -\series bold -const struct -\series default - HXmap -\series bold -* -\series default -, -\series bold -const void * -\series default -key); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_find -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -void * -\series default -HXmap_get( -\series bold -const struct -\series default - HXmap -\series bold -* -\series default -, -\series bold -const void * -\series default -key); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_get -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -void * -\series default -HXmap_del( -\series bold -struct -\series default - HXmap -\series bold -* -\series default -, -\series bold -const void * -\series default -key); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_del -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -void -\series default - HXmap_free( -\series bold -struct -\series default - HXmap -\series bold -* -\series default -); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_free -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - HXmap_node -\series bold -* -\series default -HXmap_keysvalues( -\series bold -const struct -\series default - HXmap -\series bold -* -\series default -); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_keysvalues -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Description - -\family typewriter -HXmap_add -\family default - -\family typewriter -A -\family default -dds a new node to the tree using the given key and data. - When an element is in the map, the key may not be modified, as doing so - could possibly invalidate the internal location of the element, or its - ordering with respect to other elements. - If you need to change the key, you will have to delete the element from - the tree and re-insert it. - On error, -\family typewriter --errno -\family default - will be returned. -\begin_inset Newline newline -\end_inset - -When -\family typewriter -HXMAP_SINGULAR -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_SINGULAR -\end_layout - -\end_inset - - is in effect, -\family typewriter -value -\family default - must be -\family typewriter -NULL -\family default -, or -\family typewriter --EINVAL -\family default - is returned. -\end_layout - -\begin_layout Description - -\family typewriter -HXmap_find -\family default - Finds the node for the given key. - The key can be read from the node using -\family typewriter -node->key -\family default - or -\family typewriter -node->skey -\family default - (convenience alias for -\family typewriter -key -\family default -, but with a type of -\family typewriter -const char -\begin_inset space ~ -\end_inset - -* -\family default -), and the data by using -\family typewriter -node->data -\family default - or -\family typewriter -node->sdata -\family default -. - (see section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "subsec:maps-def" - -\end_inset - -). -\end_layout - -\begin_layout Description - -\family typewriter -HXmap_get -\family default - Get is a find operation directly returning -\family typewriter -node->data -\family default - instead of the node itself. - Since -\family typewriter -HXmap_get -\family default - may legitimately return -\family typewriter -NULL -\family default - if -\family typewriter -NULL -\family default - was stored in the tree as the data for a given key, only -\family typewriter -errno -\family default - will really tell whether the node was found or not; in the latter case, - -\family typewriter -errno -\family default - is set to -\family typewriter -ENOENT -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXmap_del -\family default - Removes an element from the map and returns the data value that was associated - with it. - When an error occurred, or the element was not found, -\family typewriter -NULL -\family default - is returned. - Because -\family typewriter -NULL -\family default - can be a valid data value, -\family typewriter -errno -\family default - can be checked for non-zero. - -\family typewriter -errno -\family default - will be -\family typewriter --ENOENT -\family default - if the element was not found, or zero when everything was ok. -\end_layout - -\begin_layout Description - -\family typewriter -HXmap_free -\family default - The function will delete all elements in the map and free memory it holds. -\end_layout - -\begin_layout Description - -\family typewriter -HXmap_keysvalues -\family default - Returns all key-value-pairs in an array of the size as many items were - in the map ( -\family typewriter -map->items -\family default -) at the time it was called. - The memory must be freed using -\family typewriter -free -\family default -(3) when it is no longer needed. - The order elements in the array follows the traverser notes (see below), - unless otherwise specified. -\end_layout - -\begin_layout Subsection -Map traversal -\end_layout - -\begin_layout LyX-Code - -\series bold -struct -\series default - HXmap_trav -\series bold -* -\series default -HXmap_travinit( -\series bold -const struct -\series default - HXmap -\series bold -* -\series default -); -\begin_inset Newline newline -\end_inset - - -\series bold -const struct -\series default - HXmap_node -\series bold -* -\series default -HXmap_traverse( -\series bold -struct -\series default - HXmap_trav -\series bold -* -\series default -iterator); -\begin_inset Newline newline -\end_inset - - -\series bold -void -\series default - HXmap_travfree( -\series bold -struct -\series default - HXmap_trav -\series bold -* -\series default -iterator); -\begin_inset Newline newline -\end_inset - - -\series bold -void -\series default - HXmap_qfe( -\series bold -const struct -\series default - HXmap -\series bold -* -\series default -, -\series bold -bool (* -\series default -fn -\series bold -) -\series default -( -\series bold -const struct -\series default - HXmap_node -\series bold -* -\series default -, -\begin_inset Newline newline -\end_inset - - -\series bold -void * -\series default -arg), -\series bold -void * -\series default -arg); -\end_layout - -\begin_layout Description - -\family typewriter -HXmap_travinit -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_travinit -\end_layout - -\end_inset - - Initializes a traverser (a. -\begin_inset space \thinspace{} -\end_inset - -k. -\begin_inset space \thinspace{} -\end_inset - -a. -\begin_inset space \space{} -\end_inset - -iterator) for the map, and returns a pointer to it. - -\family typewriter -NULL -\family default - will be returned in case of an error, such as memory allocation failure. - Traversers are returned even if the map has zero elements. -\end_layout - -\begin_layout Description - -\family typewriter -HXmap_traverse -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_traverse -\end_layout - -\end_inset - - Returns a pointer to a -\family typewriter -struct HXmap_node -\family default - for the next element -\begin_inset space ~ -\end_inset - -\SpecialChar breakableslash - key-value pair from the map, or -\family typewriter -NULL -\family default - if there are no more entries. -\end_layout - -\begin_layout Description - -\family typewriter -HXmap_travfree -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_travfree -\end_layout - -\end_inset - - Release the memory associated with a traverser. -\end_layout - -\begin_layout Description - -\family typewriter -HXmap_qfe -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXmap_qfe -\end_layout - -\end_inset - - The -\begin_inset Quotes eld -\end_inset - -quick foreach -\begin_inset Quotes erd -\end_inset - -. - Iterates over all map elements in the fastest possible manner, but has - the restriction that no modifications to the map are allowed. - Furthermore, a separate function to handle each visited node, is required. - (Hence this is also called -\begin_inset Quotes eld -\end_inset - -closed traversal -\begin_inset Quotes erd -\end_inset - -, because one cannot access the stack frame of the original function which - called -\family typewriter -HXmap_qfe -\family default -.) The user-defined function returns a bool which indicates whether traversal - shall continue or not. -\end_layout - -\begin_layout Standard -Flags for -\family typewriter -HXmap_travinit -\family default -: -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_NOFLAGS -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_NOFLAGS -\end_layout - -\end_inset - - A mnemonic for no flags, and is defined to be -\family typewriter -0 -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXMAP_DTRAV -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXMAP_DTRAV -\end_layout - -\end_inset - - Enable support for deletion during traversal. - As it can make traversal slower, it needs to be explicitly specified for - cases where it is needed, to not penalize cases where it is not. -\end_layout - -\begin_layout Standard -WARNING: Modifying the map while a traverser is active is implementation-specifi -c behavior! libHX generally ensures that there will be no undefined behavior - (e. -\begin_inset space \thinspace{} -\end_inset - -g. -\begin_inset space \space{} -\end_inset - -crashes), but there is no guarantee that elements will be returned exactly - once. - There are fundamental cases that one should be aware of: -\end_layout - -\begin_layout Itemize -An element is inserted before where the traverser is currently positioned - at. - The element may not be returned in subsequent calls to -\family typewriter -HXmap_traverse -\family default - on an already-active traverser. -\end_layout - -\begin_layout Itemize -Insertion or deletion may cause internal data structure to re-layout. -\begin_inset Separator latexpar -\end_inset - - -\end_layout - -\begin_deeper -\begin_layout Itemize -Traversers of ordered data structures may choose to rebuild their state. -\end_layout - -\begin_layout Itemize -Traversers of unordered data structures would run risk to return more than - once, or not at all. -\end_layout - -\end_deeper -\begin_layout Standard -Descriptions for different map types follow. -\end_layout - -\begin_layout Description -Hashmaps On -\family typewriter -HXmap_add -\family default -, an element may be inserted in a position that is before where the traverser - is currently positioned. - Such elements will not be returned in the remaining calls to -\family typewriter -HXmap_traverse -\family default -. - The insertion or deletion of an element may cause the internal data structure - to re-layout itself. - When this happens, the traverser will stop, so as to not return entries - twice. -\end_layout - -\begin_layout Description -Binary -\begin_inset space ~ -\end_inset - -trees Elements may be added before the traverser's position. - These elements will not be returned in subsequent traversion calls. - If the data structure changes as a result of an addition or deletion, the - traverser will rebuild its state and continue traversal transparently. - Because elements in a binary tree are ordered, that is, element positions - may not change with respect to another when the tree is rebalanced, there - is no risk of returning entries more than once. - Nor will elements that are sorted after the current traverser's position - not be returned (= -\begin_inset space ~ -\end_inset - -they will be returned, because they cannot get reordered to before the traverser - like in a hash map). - The HX rbtree implementation also has proper handling for when the node - which is currently visiting is deleted. -\end_layout - -\begin_layout Subsection -RB-tree Limitations -\end_layout - -\begin_layout Standard -The implementation has a theoretical minimum on the maximum number of nodes, - -\begin_inset Formula $2^{24}=16{,}777{,}216$ -\end_inset - -. - A worst-case tree with this many elements already has a height of 48 ( -\family typewriter -RBT_MAXDEP -\family default -), which is the maximum height currently supported. - The larger the height is that HXrbtree is supposed to handle, the more - memory (linear increase) it needs. - All functions that build or keep a path reserve memory for -\family typewriter -RBT_MAXDEP -\family default - nodes; on x86_64 this is 9 bytes per -\begin_inset Formula $\langle$ -\end_inset - -node, direction -\begin_inset Formula $\rangle$ -\end_inset - - pair, amounting to 432 bytes for path tracking alone. - It may not sound like a lot to many, but given that kernel people can limit - their stack usage to 4096 bytes is impressive alone -\end_layout - -\begin_layout Standard -\begin_inset Foot -status open - -\begin_layout Plain Layout -Not always of course. - Linux kernels are often configured to use an 8K stack because some components - still use a lot of stack space, but even 8K is still damn good. -\end_layout - -\end_inset - -. -\end_layout - -\begin_layout Subsection -Examples -\end_layout - -\begin_layout Subsubsection -Case-insensitive ordering -\end_layout - -\begin_layout Standard -The correct way: -\end_layout - -\begin_layout LyX-Code - -\series bold -static int -\series default - my_strcasecmp( -\series bold -const void * -\series default -a, -\series bold -const void * -\series default -b, -\series bold -size_t -\series default - z) -\begin_inset Newline newline -\end_inset - -{ -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - strcasecmp(a, b); -\begin_inset Newline newline -\end_inset - -} -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -static const struct -\series default - HXmap_ops icase = { -\begin_inset Newline newline -\end_inset - - .k_compare = my_strcasecmp, -\begin_inset Newline newline -\end_inset - -}; -\begin_inset Newline newline -\end_inset - -HXmap_init5(HXMAPT_RBTREE, HXMAP_SKEY, &icase, 0, -\shape italic -dsize -\shape default -); -\end_layout - -\begin_layout Standard -A hackish way (which wholly depends on the C implementation and use of extra - safeguards is a must): -\end_layout - -\begin_layout LyX-Code - -\series bold -static const struct -\series default - HXmap_ops icase = { -\begin_inset Newline newline -\end_inset - - .k_compare = ( -\series bold -void * -\series default -)strcasecmp, -\begin_inset Newline newline -\end_inset - -}; -\begin_inset Newline newline -\end_inset - -BUILD_BUG_ON( -\series bold -sizeof -\series default -(DEMOTE_TO_PTR(strcasecmp)) > -\series bold -sizeof -\series default -(void *)); -\begin_inset Newline newline -\end_inset - -BUILD_BUG_ON( -\series bold -sizeof -\series default -(DEMOTE_TO_PTR(strcasecmp)) > -\series bold -sizeof -\series default -(icase.k_compare)); -\begin_inset Newline newline -\end_inset - -HXmap_init5(HXMAPT_RBTREE, HXMAP_SKEY, &icase, 0, -\shape italic -dsize -\shape default -); -\end_layout - -\begin_layout Subsubsection -Reverse sorting order -\end_layout - -\begin_layout Standard -Any function that behaves like -\family typewriter -strcmp -\family default - can be used. - It merely has to return negative when -\begin_inset Formula $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 "subsec:maps-examples-bigkey" - -\end_inset - - -\end_layout - -\begin_layout Standard -Keys can actually store non-unique data, as long as this extra fields does - not actually contribute to the logical key -\begin_inset space ~ -\end_inset - -— the parts that do uniquely identify it. - In the following example, the -\family typewriter -notes -\family default - member may be part of struct package, which is the key as far as HXmap - is concerned, but still, only the name and versions are used to identify - it. -\end_layout - -\begin_layout LyX-Code - -\series bold -struct -\series default - package { -\begin_inset Newline newline -\end_inset - - -\series bold -char * -\series default -name; -\begin_inset Newline newline -\end_inset - - -\series bold -unsigned int -\series default - major_version; -\begin_inset Newline newline -\end_inset - - -\series bold -unsigned int -\series default - minor_version; -\begin_inset Newline newline -\end_inset - - -\series bold -char -\series default - notes -\series bold -[ -\series default -64 -\series bold -] -\series default -; -\begin_inset Newline newline -\end_inset - -}; -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -static int -\series default - package_cmp( -\series bold -const void * -\series default -a, -\series bold -const void * -\series default -b) -\begin_inset Newline newline -\end_inset - -{ -\begin_inset Newline newline -\end_inset - - -\series bold -const struct -\series default - package -\series bold -* -\series default -p = a, -\series bold -* -\series default -q = b; -\begin_inset Newline newline -\end_inset - - -\series bold -int -\series default - ret; -\begin_inset Newline newline -\end_inset - - ret = strcmp(p->name, q->name); -\begin_inset Newline newline -\end_inset - - -\series bold -if -\series default - (ret != 0) -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - ret; -\begin_inset Newline newline -\end_inset - - ret = p->major_version - q->major_version; -\begin_inset Newline newline -\end_inset - - -\series bold -if -\series default - (ret != 0) -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - ret; -\begin_inset Newline newline -\end_inset - - ret = p->minor_version - q->minor_version; -\begin_inset Newline newline -\end_inset - - -\series bold -if -\series default - (ret != 0) -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - ret; -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - 0; -\begin_inset Newline newline -\end_inset - -} -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -static const struct -\series default - HXmap_ops package_ops = { -\begin_inset Newline newline -\end_inset - - .k_compare = package_cmp, -\begin_inset Newline newline -\end_inset - -}; -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - -HXmap_init5(HXMAPT_RBTREE, -\shape italic -flags -\shape default -, &package_ops, -\begin_inset Newline newline -\end_inset - - -\series bold -sizeof -\series default -( -\series bold -struct -\series default - package), -\shape italic -dsize -\shape default -); -\end_layout - -\begin_layout Standard -\begin_inset Newpage clearpage -\end_inset - - -\end_layout - -\begin_layout Section -Doubly-linked list -\begin_inset CommandInset label -LatexCommand label -name "sec:deque" - -\end_inset - - -\end_layout - -\begin_layout Standard -HXdeque is a data structure for a doubly-linked non-circular -\family typewriter -NULL -\family default --sentineled list. - Despite being named a deque, which is short for double-ended queue, and - which may be implemented using an array, HXdeque is in fact using a linked - list to provide its deque functionality. - Furthermore, a dedicated root structure and decidated node structures with - indirect data referencing are used. -\end_layout - -\begin_layout Subsection -Structural definition -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 softhyphen -push -\family default - and -\family typewriter -HXdeque_\SpecialChar softhyphen -unshift -\family default - add the data item in a new node at the end ( -\begin_inset Quotes eld -\end_inset - -push -\begin_inset Quotes erd -\end_inset - -) or as the new first element ( -\begin_inset Quotes eld -\end_inset - -unshift -\begin_inset Quotes erd -\end_inset - - as Perl calls it), respectively. - The functions will return the new node on success, or -\family typewriter -NULL -\family default - on failure and -\family typewriter -errno -\family default - will be set. - The node is owned by the list. -\end_layout - -\begin_layout Standard - -\family typewriter -HXdeque_\SpecialChar softhyphen -pop -\family default - and -\family typewriter -HXdeque_\SpecialChar softhyphen -shift -\family default - remove the last ( -\begin_inset Quotes eld -\end_inset - -pop -\begin_inset Quotes erd -\end_inset - -) or first ( -\begin_inset Quotes eld -\end_inset - -shift -\begin_inset Quotes erd -\end_inset - -) node, respectively, and return the data pointer that was stored in the - data. -\end_layout - -\begin_layout Standard - -\family typewriter -HXdeque_\SpecialChar softhyphen -move -\family default - will unlink a node from its list, and reinsert it after the given target - node, which may be in a different list. -\end_layout - -\begin_layout Standard -Deleting a node is accomplished by calling -\family typewriter -HXdeque_del -\family default - on it. - The data pointer stored in the node is not freed, but returned. -\end_layout - -\begin_layout Subsection -Iteration -\end_layout - -\begin_layout Standard -Iterating over a HXdeque linked list is done manually and without additional - overhead of function calls: -\end_layout - -\begin_layout LyX-Code - -\series bold -const struct -\series default - HXdeque_node -\series bold -* -\series default -node; -\begin_inset Newline newline -\end_inset - - -\series bold -for -\series default - (node = dq->first; node != NULL; node = node->next) -\begin_inset Newline newline -\end_inset - - do_something(node->ptr); -\end_layout - -\begin_layout Subsection -Searching -\end_layout - -\begin_layout LyX-Code - -\series bold -struct -\series default - HXdeque_node -\series bold -* -\series default -HXdeque_find( -\series bold -struct -\series default - HXdeque -\series bold -* -\series default -dq, -\series bold -const void * -\series default -ptr); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXdeque_find -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -void * -\series default -HXdeque_get( -\series bold -struct -\series default - HXdeque -\series bold -* -\series default -dq, -\series bold -void * -\series default -ptr); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXdeque_get -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard - -\family typewriter -HXdeque_find -\family default - searches for the node which contains -\family typewriter -ptr -\family default -, and does so by beginning at the start of the list. - If no node is found, -\family typewriter -NULL -\family default - is returned. - If a pointer is more than once in the list, any node may be returned. -\end_layout - -\begin_layout Standard - -\family typewriter -HXdeque_get -\family default - will further return the data pointer stored in the node -\begin_inset space ~ -\end_inset - -— however, since that is just what the -\family typewriter -ptr -\family default - argument is, the function practically only checks for existence of -\family typewriter -ptr -\family default - in the list. -\end_layout - -\begin_layout Subsection -Examples -\end_layout - -\begin_layout Standard - -\series bold -\begin_inset Float figure -placement h -wide false -sideways false -status open - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 Standard - -\begin_layout Plain Layout -Example use of HXdeque to store and sort a list -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -In this example, all usernames are obtained from NSS, and put into a list. - -\family typewriter -HX_strdup -\family default - is used, because -\family typewriter -getpwent -\family default - will overwrite the buffer it uses to store its results. - The list is then converted to an array, and the list is freed (because - it is not need it anymore). - -\family typewriter -HXdeque_genocide -\family default - must not be used here, because it would free all the data pointers (strings - here) that were just inserted into the list. - Finally, the list is sorted using the well-known -\family typewriter -qsort -\family default - function. - Because -\family typewriter -strcmp -\family default - takes two -\family typewriter -const char -\begin_inset space ~ -\end_inset - -* -\family default - arguments, but -\family typewriter -qsort -\family default - mandates a function taking two -\family typewriter -const void -\begin_inset space ~ -\end_inset - -* -\family default -, a cast can be used to silence the compiler. - This only works because we know that the array consists of a bunch of -\family typewriter -char -\begin_inset space ~ -\end_inset - -* -\family default - pointers, so -\family typewriter -strcmp -\family default - will work. -\end_layout - -\begin_layout Standard -\begin_inset Newpage clearpage -\end_inset - - -\end_layout - -\begin_layout Section -Inline doubly-linked list -\begin_inset CommandInset label -LatexCommand label -name "sec:list" - -\end_inset - - -\end_layout - -\begin_layout Standard -Classical linked-list implementations, such as HXdeque, either store the - actual data within a node, or indirectly through a pointer, but the -\begin_inset Quotes eld -\end_inset - -inline doubly-linked list -\begin_inset Quotes erd -\end_inset - - instead does it reverse and has the list head within the data structure. -\end_layout - -\begin_layout Standard -\begin_inset Float figure -placement h -wide false -sideways false -status open - -\begin_layout LyX-Code - -\series bold -struct -\series default - package_desc { -\begin_inset Newline newline -\end_inset - - -\series bold -char * -\series default -package_name; -\begin_inset Newline newline -\end_inset - - -\series bold -int -\series default - version; -\end_layout - -\begin_layout LyX-Code -}; -\end_layout - -\begin_layout LyX-Code - -\series bold -struct -\series default - classic_direct_node { -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - classic_direct_node -\series bold -* -\series default -next, -\series bold -* -\series default -prev; -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - package_desc direct_data; -\begin_inset Newline newline -\end_inset - -}; -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - classic_indirect_node { -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - classic_indirect_node -\series bold -* -\series default -next, -\series bold -* -\series default -prev; -\begin_inset Newline newline -\end_inset - - -\series bold -void * -\series default -indirect_data; -\begin_inset Newline newline -\end_inset - -}; -\end_layout - -\begin_layout Plain Layout -\begin_inset Caption Standard - -\begin_layout Plain Layout -Classic linked-list implementations with direct/indirect data blocks. -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Float figure -placement H -wide false -sideways false -status open - -\begin_layout LyX-Code - -\series bold -struct -\series default - package_desc { -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - HXlist_head list; -\begin_inset Newline newline -\end_inset - - -\series bold -char * -\series default -package_name; -\begin_inset Newline newline -\end_inset - - -\series bold -int -\series default - version; -\begin_inset Newline newline -\end_inset - -}; -\end_layout - -\begin_layout Plain Layout -\begin_inset Caption Standard - -\begin_layout Plain Layout -List head (next,prev pointers) inlined into the data block -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -At first glance, an inline list does not look much different from -\family typewriter -struct classic_\SpecialChar softhyphen -direct_\SpecialChar softhyphen -data -\family default -, it is mostly a viewpoint decision which struct is in the foreground. -\end_layout - -\begin_layout Subsection -Synopsis -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 Standard - -\begin_layout Plain Layout -Storing strings in a HXdeque -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Float figure -placement H -wide false -sideways false -status open - -\begin_layout LyX-Code - -\series bold -struct -\series default - element { -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - HXlist_head list; -\begin_inset Newline newline -\end_inset - - -\series bold -char * -\family typewriter -\series default -data; -\begin_inset Newline newline -\end_inset - -}; -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -int -\series default - main( -\series bold -int -\series default - main, -\series bold -const char ** -\series default -argv) -\begin_inset Newline newline -\end_inset - -{ -\begin_inset Newline newline -\end_inset - - HXLIST_HEAD(lh); -\begin_inset Newline newline -\end_inset - - -\series bold -while -\series default - (--argc) { -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - element -\series bold -* -\series default -e = malloc( -\family default -\series bold -sizeof -\family typewriter -\series default -(*e)); -\begin_inset Newline newline -\end_inset - - e->data = *++argv; -\begin_inset Newline newline -\end_inset - - HXlist_init(&e->list); -\begin_inset Newline newline -\end_inset - - HXlist_add_tail(&e->list); -\begin_inset Newline newline -\end_inset - - } -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - 0; -\begin_inset Newline newline -\end_inset - -} -\end_layout - -\begin_layout Plain Layout -\begin_inset Caption Standard - -\begin_layout Plain Layout -Storing strings in a HXlist -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -These examples assume that -\family typewriter -argv -\family default - is persistent, which, for the sample, is true. -\end_layout - -\begin_layout Standard -With HXlist, one needs to have a struct with a HXlist_head in it, and if - one does not already have such a struct -\begin_inset space ~ -\end_inset - -—e. -\begin_inset space \thinspace{} -\end_inset - -g. -\begin_inset space \space{} -\end_inset - -by means of wanting to store more than just one value -\begin_inset space ~ -\end_inset - -— one will need to create it first, as shown, and this may lead to an expansion - of code. -\end_layout - -\begin_layout Standard -This however does not mean that HXlist is the better solution over HXdeque - for data already available in a struct. - As each struct has a list_head that is unique to the node, it is not possible - to share this data. - Trying to add a HXlist_head to another list is not going to end well, while - HXdeque has no problem with this as list heads are detached from the actual - data in HXdeque. -\end_layout - -\begin_layout Standard -\begin_inset Float figure -placement H -wide false -sideways false -status open - -\begin_layout LyX-Code - -\series bold -struct -\series default - point p = {15, 30}; -\begin_inset Newline newline -\end_inset - -HXdeque_push(dq, &p); -\begin_inset Newline newline -\end_inset - -HXdeque_push(dq, &p); -\end_layout - -\begin_layout Plain Layout -\begin_inset Caption Standard - -\begin_layout Plain Layout -Data can be added multiple times in a HXdeque without ill effects -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -To support this, an extra allocation is needed on the other hand. - In a HXlist, to store -\begin_inset Formula $n$ -\end_inset - - elements of compound data (e. -\begin_inset space \thinspace{} -\end_inset - -g. -\begin_inset space \space{} -\end_inset - - -\family typewriter -struct point -\family default -), -\begin_inset Formula $n$ -\end_inset - - allocations are needed, assuming the list head is a stack object, and the - points are not. - HXdeque will need at least -\begin_inset Formula $2n+1$ -\end_inset - - allocations, -\begin_inset Formula $n$ -\end_inset - - for the nodes, -\begin_inset Formula $n$ -\end_inset - - for the points and another for the head. -\end_layout - -\begin_layout Standard -\begin_inset Newpage clearpage -\end_inset - - -\end_layout - -\begin_layout Section -Counted inline doubly-linked list -\begin_inset CommandInset label -LatexCommand label -name "sec:clist" - -\end_inset - - -\end_layout - -\begin_layout Standard -clist is the inline doubly-linked list from chapter -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:list" - -\end_inset - -, extended by a counter to retrieve the number of elements in the list in - -\begin_inset Formula $\mathcal{O}\left(1\right)$ -\end_inset - - time. - This is also why all operations always require the list head. - For traversal of clists, use the corresponding HXlist macros. -\end_layout - -\begin_layout Subsection -Synopsis -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 -< -\family default -, -\family typewriter -> -\family default -, -\family typewriter -& -\family default - and -\family typewriter -" -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXQUOTE_LDAPFLT -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXQUOTE_LDAPFLT -\end_layout - -\end_inset - - Escape the string using backslash-plus-hexcode notation as described in - RFC 4515 -\begin_inset Foot -status open - -\begin_layout Plain Layout -\begin_inset Flex URL -status collapsed - -\begin_layout Plain Layout - -http://tools.ietf.org/html/rfc4515 -\end_layout - -\end_inset - - -\end_layout - -\end_inset - -, to make it suitable for use in an LDAP search filter. -\end_layout - -\begin_layout Description - -\family typewriter -HXQUOTE_LDAPRDN -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXQUOTE_LDAPRDN -\end_layout - -\end_inset - - Escape the string using backslash-plus-hexcode notation as described in - RFC 4514 -\begin_inset Foot -status open - -\begin_layout Plain Layout -\begin_inset Flex URL -status collapsed - -\begin_layout Plain Layout - -http://tools.ietf.org/html/rfc4514 -\end_layout - -\end_inset - - -\end_layout - -\end_inset - -, to make it suitable for use in an LDAP Relative Distinguished Name. -\end_layout - -\begin_layout Description - -\family typewriter -HXQUOTE_BASE64 -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXQUOTE_BASE64 -\end_layout - -\end_inset - - Transform the string to BASE64, as described in RFC 4648 -\begin_inset Foot -status open - -\begin_layout Plain Layout -\begin_inset Flex URL -status collapsed - -\begin_layout Plain Layout - -http://tools.ietf.org/html/rfc4648 -\end_layout - -\end_inset - - -\end_layout - -\end_inset - -. -\end_layout - -\begin_layout Description - -\family typewriter -HXQUOTE_URIENC -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXQUOTE_URIENC -\end_layout - -\end_inset - - Escape the string so that it becomes a valid part for an URI. -\end_layout - -\begin_layout Description - -\family typewriter -HXQUOTE_SQLSQUOTE -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXQUOTE_SQLSQUOTE -\end_layout - -\end_inset - - Escape all single quotes in the string by double single-quotes, as required - for using it in a single-quoted SQL string. - No surrounding quotes will be generated to facilitate concatenating of - -\family typewriter -HX_strquote -\family default - results. -\end_layout - -\begin_layout Description - -\family typewriter -HXQUOTE_SQLBQUOTE -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXQUOTE_SQLBQUOTE -\end_layout - -\end_inset - - Escape all backticks in the string by double backticks, as required for - using it in a backtick-quoted SQL string (used for table names and columns). - No surrounding ticks will be generated to facilitate concatenation. -\end_layout - -\begin_layout Standard -Specifying an unrecognized type will result in -\family typewriter -NULL -\family default - being returned and -\family typewriter -errno -\family default - be set to -\family typewriter -EINVAL -\family default -. -\end_layout - -\begin_layout Standard -If -\family typewriter -free_me -\family default - is -\family typewriter -NULL -\family default -, the function will always allocate memory, even if the string needs no - quoting. - The program then has to free the result: -\end_layout - -\begin_layout LyX-Code - -\series bold -char * -\series default -s = HX_strquote("<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_split_inplace( -\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_split_inplace -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -int -\series default - HX_split_fixed( -\series bold -char * -\series default -s, -\series bold -const char * -\series default -delimiters, -\series bold -int -\series default - max, -\series bold -char ** -\series default -arr); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\size normal -\color none -HX_split_fixed -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -char * -\series default -HX_strsep( -\series bold -char ** -\series default -sp, -\series bold -const char * -\series default -delimiters); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\size normal -\color none -HX_strsep -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -char * -\series default -HX_strsep2( -\series bold -char ** -\series default -sp, -\series bold -const char * -\series default -dstr); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\size normal -\color none -HX_strsep2 -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Description - -\family typewriter -HX_split -\family default - Split the string -\family typewriter -s -\family default - on any characters from the -\begin_inset Quotes eld -\end_inset - - -\family typewriter -delimiters -\family default - -\begin_inset Quotes erd -\end_inset - - string. - Both the substrings and the array holding the pointers to these substrings - will be allocated as required; the original string is not modified. - If -\family typewriter -max -\family default - is larger than zero, produces no more than -\family typewriter -max -\family default - fields. - If -\family typewriter -fields -\family default - is not -\family typewriter -NULL -\family default -, the number of elements produced will be stored in -\family typewriter -*fields -\family default -. - The result is a -\family typewriter -NULL -\family default --terminated array of -\family typewriter -char -\begin_inset space ~ -\end_inset - -* -\family default -, and the user needs to free it when done with it, using -\family typewriter -HX_zvecfree -\family default - or equivalent. - An empty string (zero-length string) for -\family typewriter -s -\family default - yields a single field. -\end_layout - -\begin_layout Description - -\family typewriter -HX_split_inplace -\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_split_fixed -\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 -arr -\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_split_fixed -\begin_inset CommandInset label -LatexCommand label -name "subsec:string-ex-HX_split_fixed" - -\end_inset - - -\end_layout - -\begin_layout Standard - -\family typewriter -HX_split_fixed -\family default - is often used just with scoped automatic-storage 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_split_fixed(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_split_inplace -\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_split_inplace -\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_split_inplace(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 Standard - -\begin_layout Plain Layout -Improvement of string safety over time -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -This makes it quite similar to the string operations (and append seems to - be the most commonly used one to me) supported in scripting languages that - also do without a size argument. - The essential part of such memory containers is that their internal (hidden) - metadata structure contains the length of the memory block in the container. - For binary data this may be the norm, but for C-style strings, the stored - and auto-updated length field serves as an accelerator cache. - For more details, see -\family typewriter -HXmc_length -\family default -. -\end_layout - -\begin_layout Standard -Of course, the automatic management of memory comes with a bit of overhead - as the string expands beyond its preallocated region. - Such may be mitigated by doing explicit (re)sizing. -\end_layout - -\begin_layout Subsection -Structural overview -\end_layout - -\begin_layout Standard -HXmc functions do not actually return a pointer to the memory container - (e. -\begin_inset space \thinspace{} -\end_inset - -g. -\begin_inset space \space{} -\end_inset - - -\family typewriter -struct -\family default -) itself, but a pointer to the data block. - Conversely, input parameters to HXmc functions will be the data block pointer. - It is of type -\family typewriter -hxmc_t -\begin_inset space ~ -\end_inset - -* -\family default -, which is typedef'ed to -\family typewriter -char -\begin_inset space ~ -\end_inset - -* -\family default - and inherits all properties and privileges of -\family typewriter -char -\begin_inset space ~ -\end_inset - -* -\family default -. - Pointer arithmetic is thus supported. - It also means you can just pass it to functions that take a -\family typewriter -char -\begin_inset space ~ -\end_inset - -* -\family default - without having to do a member access like -\family typewriter -s.c_str -\family default -. - The drawback is that many functions operating on the memory container need - a -\family typewriter -hxmc_t -\begin_inset space ~ -\end_inset - -** -\family default - (a level-two indirection), because not only does the memory block move, - but also the memory container itself. - This is due to the implementation of the container metadata which immediately - and always precedes the writable memory block. -\end_layout - -\begin_layout Standard -HXmc ensures that the data block is terminated by a NUL ( -\family typewriter -' -\backslash -0' -\family default -) byte (unless you trash it), so you do not have to, and of course, to be - on the safe side. - But, the automatic NUL byte is not part of the region allocated by the - user. - That is, when one uses the classic approach with -\family typewriter -malloc(4096) -\family default -, the user will have control of 4096 bytes and has to stuff the NUL byte - in there somehow on his own; for strings this means the maximum string - length is 4095. - Requesting space for a 4096-byte sized HXmc container gives you the possibility - to use all 4096 bytes for the string, because HXmc provides a NUL byte. -\end_layout - -\begin_layout Standard -By the way, -\family typewriter -hxmc_t -\family default - is the -\shape italic -only -\shape default - typedef in this entire library, to distinguish it from regular -\family typewriter -char -\begin_inset space ~ -\end_inset - -* -\family default - that does not have a backing memory cointainer. -\end_layout - -\begin_layout Subsection -Constructors, destructors -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 Standard - -\begin_layout Plain Layout - -\family typewriter -printf -\family default - positional parameters -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard - -\family typewriter -printf -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -printf -\end_layout - -\end_inset - -, at least from GNU libc, has something vaguely similar: positional parameters -\begin_inset Index idx -status open - -\begin_layout Plain Layout -positional parameters -\end_layout - -\end_inset - -. - They have inherent drawbacks, though. - One is of course the question of portability, but there is a bigger issue. - All parameters must be specified, otherwise there is no way to determine - the location of all following objects following the missing one on the - stack in a varargs-function like -\family typewriter -printf -\family default -., which makes it unsuitable to be used with templates where omitting some - placeholders is allowed. -\end_layout - -\begin_layout Subsection -Initialization, use and deallocation -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 "subsec:option-types" - -\end_inset - -) -\begin_inset space ~ -\end_inset - -— not all constants can be used, though, and their meaning also differs - from what -\family typewriter -HX_getopt -\family default - or -\family typewriter -HX_shconfig -\family default - use them for -\begin_inset space ~ -\end_inset - -— the two could be seen as -\begin_inset Quotes eld -\end_inset - -read -\begin_inset Quotes erd -\end_inset - - operations, while HXformat is a write operation. -\end_layout - -\begin_layout Subsubsection -Immediate types -\end_layout - -\begin_layout Standard -\begin_inset Quotes eld -\end_inset - -Immediate types -\begin_inset Quotes erd -\end_inset - - are resolved when -\family typewriter -HXformat_add -\family default - is called, that is, they are copied and inserted into the tree, and are - subsequently independent from any changes to variables in the program. - Because the HXopt-originating type name, that is, -\family typewriter -HXTYPE_* -\family default -, is also used for deferred types, the constant -\family typewriter -HXFORMAT_IMMED -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXFORMAT_IMMED -\end_layout - -\end_inset - - -\family default - needs to be specified on some types to denote an immediate value. -\end_layout - -\begin_layout Itemize - -\family typewriter -HXTYPE_STRING -\family default - -\begin_inset space ~ -\end_inset - -— -\family typewriter -ptr -\family default - is a -\family typewriter -const char * -\family default -. -\end_layout - -\begin_layout Itemize - -\family typewriter -HXTYPE_ -\family default -{ -\family typewriter -U -\family default -,}{ -\family typewriter -CHAR -\family default -, -\family typewriter -SHORT -\family default -, -\family typewriter -INT -\family default -, -\family typewriter -LONG -\family default -, -\family typewriter -LLONG -\family default -} -\family typewriter - | HXFORMAT_IMMED -\family default - -\begin_inset space ~ -\end_inset - -— mapping to the standard types -\end_layout - -\begin_layout Subsubsection -Deferred types -\end_layout - -\begin_layout Standard -\begin_inset Quotes eld -\end_inset - -Deferred types -\begin_inset Quotes erd -\end_inset - - are resolved on every invocation of a formatter function ( -\family typewriter -HXformat_*printf -\family default -). - The expansions may be changed by modifying the underlying variable pointed - to, but the pointer must remain valid and its pointee not go out of scope. - Figure -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "fig:hxformat-immediate-deferred" - -\end_inset - - shows the difference in a code sample. -\end_layout - -\begin_layout Itemize - -\family typewriter -HXTYPE_STRP -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_STRP -\end_layout - -\end_inset - - -\begin_inset space ~ -\end_inset - -— -\family typewriter -ptr -\family default - is a -\family typewriter -const char *const * -\family default -; the pointer resolution is deferred until the formatter is called with - one of the -\family typewriter -HXformat_*printf -\family default - functions. - Deferred in the sense it is always resolved anew. - -\end_layout - -\begin_layout Itemize - -\family typewriter -HXTYPE_BOOL -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_BOOL -\end_layout - -\end_inset - - -\begin_inset space ~ -\end_inset - -— -\family typewriter -ptr -\family default - is a -\family typewriter -const int -\begin_inset space ~ -\end_inset - -* -\family default -. -\end_layout - -\begin_layout Itemize - -\family typewriter -HXTYPE_ -\family default -{ -\family typewriter -U -\family default -,}{ -\family typewriter -CHAR -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_CHAR -\end_layout - -\end_inset - - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_UCHAR -\end_layout - -\end_inset - -, -\family typewriter -SHORT -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_SHORT -\end_layout - -\end_inset - - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_USHORT -\end_layout - -\end_inset - -, -\family typewriter -INT -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_INT -\end_layout - -\end_inset - - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_UINT -\end_layout - -\end_inset - -, -\family typewriter -LONG -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_LONG -\end_layout - -\end_inset - - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_ULONG -\end_layout - -\end_inset - -, -\family typewriter -LLONG -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_LLONG -\end_layout - -\end_inset - - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_ULLONG -\end_layout - -\end_inset - -} -\begin_inset space ~ -\end_inset - -— mapping to the standard types with one indirection (e. -\begin_inset space \thinspace{} -\end_inset - -g. -\begin_inset space \space{} -\end_inset - - -\family typewriter -int -\begin_inset space ~ -\end_inset - -* -\family default -) -\end_layout - -\begin_layout Itemize - -\family typewriter -HXTYPE_ -\family default -{ -\family typewriter -FLOAT -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_FLOAT -\end_layout - -\end_inset - -, -\family typewriter -DOUBLE -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_DOUBLE -\end_layout - -\end_inset - -} -\begin_inset space ~ -\end_inset - -— mapping to the two floating-point types with one indirection (e. -\begin_inset space \thinspace{} -\end_inset - -g. -\begin_inset space \space{} -\end_inset - - -\family typewriter -double -\begin_inset space ~ -\end_inset - -* -\family default -) -\end_layout - -\begin_layout Subsection -Invoking the formatter -\end_layout - -\begin_layout LyX-Code - -\series bold -int -\series default - HXformat_aprintf( -\series bold -struct -\series default - HXformat_map -\series bold -* -\series default -table, hxmc_t -\series bold -** -\series default -dest, -\series bold -const char * -\series default -template); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXformat_aprintf -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -int -\series default - HXformat_sprintf( -\series bold -struct -\series default - HXformat_map -\series bold -* -\series default -table, -\series bold -char * -\series default -dest, -\series bold -size_t -\series default - size, -\series bold -const char * -\series default -template); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\size normal -\color none -HXformat_sprintf -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -int -\series default - HXformat_fprintf( -\series bold -struct -\series default - HXformat_map -\series bold -* -\series default -table, FILE -\series bold -* -\series default -filp, -\series bold -const char * -\series default -template); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\size normal -\color none -HXformat_fprintf -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Description - -\family typewriter -HXformat_aprintf -\family default - Substitute placeholders in -\family typewriter -template -\family default - using the given table. - This will produce a string in a HX memory container ( -\family typewriter -hxmc_t -\family default -), and the pointer is put into -\family typewriter -*dest -\family default -. - The caller will be responsible for freeing it later when it is done using - the result. -\end_layout - -\begin_layout Description - -\family typewriter -HXformat_sprintf -\family default - Do substitution and store the expanded result in the buffer -\family typewriter -dest -\family default - which is of size -\family typewriter -size -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXformat_fprintf -\family default - Do substituion and directly output the expansion to the given stdio stream. -\end_layout - -\begin_layout Standard -On success, the length of the expanded string is returned, excluding the - trailing -\family typewriter -' -\backslash -0' -\family default -. - While -\family typewriter -HXformat_sprintf -\family default - will not write more than -\family typewriter -size -\family default - bytes (including the -\family typewriter -' -\backslash -0' -\family default -), the length it would have taken is returned, similar to what -\family typewriter -sprintf -\family default - does. - On error, negative errno is returned. -\end_layout - -\begin_layout Standard -The HXformat function family recognizes make-style like functions and recursive - expansion, described below. -\end_layout - -\begin_layout Subsection -Functions -\end_layout - -\begin_layout Standard -To expand a variable, one uses a syntax like -\begin_inset Quotes eld -\end_inset - - -\family typewriter -%(NAME) -\family default - -\begin_inset Quotes erd -\end_inset - - in the format string. - Recursive expansion like -\begin_inset Quotes eld -\end_inset - - -\family typewriter -%(%(USER)) -\family default - -\begin_inset Quotes erd -\end_inset - - is supported; assuming -\family typewriter -%(USER) -\family default - would expand to -\begin_inset Quotes eld -\end_inset - -linux -\begin_inset Quotes erd -\end_inset - -, HXformat would try to resolve -\begin_inset Quotes eld -\end_inset - - -\family typewriter -%(linux) -\family default - -\begin_inset Quotes erd -\end_inset - - next. - Besides these variable substitutions, HXformat also provides function calls - whose syntax is -\begin_inset Quotes eld -\end_inset - - -\family typewriter -%(nameOfFunction parameters[...]) -\family default - -\begin_inset Quotes erd -\end_inset - -. - Parameters can be any text, including variables. - Paramters are separated from another by a delimiter specific to each function. - See this list for details: -\end_layout - -\begin_layout Itemize - -\family typewriter -%(env -\family default - -\shape italic -variable -\family typewriter -\shape default -) -\begin_inset Newline newline -\end_inset - - -\family default -The -\family typewriter -env -\family default - function expands to the string that is stored in the environmental variable - by the given name. -\end_layout - -\begin_layout Itemize - -\family typewriter -%(exec -\family default -\shape italic -command -\family typewriter -\shape default - -\family default -[ -\shape italic -args -\shape default -...] -\family typewriter -) -\family default - -\begin_inset Newline newline -\end_inset - -The -\family typewriter -exec -\family default - function expands to the standard output of the command. - The command is directly run without shell invocation, so no special character - expansion (wildcards, etc.) takes place. - stdin is set to -\family typewriter -/dev\SpecialChar breakableslash -null -\family default -. - The parameter delimiter is the space character. - To be able to use this function -\begin_inset space ~ -\end_inset - -— as it is relevant to security -\begin_inset space ~ -\end_inset - -— the fmt table needs to have a key called -\begin_inset Quotes eld -\end_inset - - -\family typewriter -/libhx/exec -\family default - -\begin_inset Quotes erd -\end_inset - -. - See example -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "fig:hxformat-exec" - -\end_inset - - for details. -\end_layout - -\begin_layout Itemize - -\family typewriter -%(if -\family default -\shape italic -condition -\family typewriter -\shape default -, -\family default -[ -\shape italic -then -\shape default -][ -\family typewriter -, -\family default -[ -\shape italic -else -\shape default -]] -\family typewriter -) -\family default - -\begin_inset Newline newline -\end_inset - -If the condition parameter expands to a string of non-zero length, the function - expands to the -\begin_inset Quotes eld -\end_inset - -then -\begin_inset Quotes erd -\end_inset - - block, otherwise the -\begin_inset Quotes eld -\end_inset - -else -\begin_inset Quotes erd -\end_inset - - block. - The delimiter used is a comma. -\end_layout - -\begin_layout Itemize - -\family typewriter -%(lower -\family default -\shape italic -text -\family typewriter -\shape default -) -\family default -, -\family typewriter -%(upper -\family default -\shape italic -text -\family typewriter -\shape default -) -\family default - -\begin_inset Newline newline -\end_inset - -Lowercases or uppercases the supplied argument. - As these functions are meant to take only one argument, there is no delimiter - defined that would need escaping if multiple arguments were supposed to - be passed. - -\family typewriter -%(lower a,b) -\family default - is equivalent to -\family typewriter -%(lower "a,b") -\family default -. -\end_layout - -\begin_layout Itemize - -\family typewriter -%(shell -\family default -\shape italic -command -\family typewriter -\shape default - -\family default -[ -\shape italic -args -\shape default -...] -\family typewriter -) -\family default - -\begin_inset Newline newline -\end_inset - -Similar to -\family typewriter -%(exec) -\family default -, but invokes the shell inbetween (i. -\begin_inset space \thinspace{} -\end_inset - -e. -\begin_inset space \space{} -\end_inset - -` -\family typewriter -sh -c ' -\family default -\shape italic -command -\shape default -... -\family typewriter -' -\family default -`) such that special characters, redirection, and so on can be used. -\end_layout - -\begin_layout Itemize - -\family typewriter -%(substr -\family default -\shape italic -text -\family typewriter -\shape default -, -\family default -\shape italic -offset -\shape default -[ -\family typewriter -, -\family default -\shape italic -length -\shape default -] -\family typewriter -) -\family default - -\begin_inset Newline newline -\end_inset - -Extracts a substring out of the given text, starting at -\shape italic -offset -\shape default - and running for the given length. - If no length is given, will extract until the end of the string. - If -\shape italic -offset -\shape default - is negative, it specifies the offset from the end of the string. - If -\shape italic -length -\shape default - is negative, that many characters are left off the end. -\end_layout - -\begin_layout Itemize - -\family typewriter -%(snl -\family default -\shape italic -text -\family typewriter -\shape default -) -\family default - -\begin_inset Newline newline -\end_inset - -Strips trailing newlines from text and replaces any other newline by a space. - What happens implicity in Makefiles' -\family typewriter -$(shell -\family default -... -\family typewriter -) -\family default - statements usually is explicitly separate in libHX. -\end_layout - -\begin_layout Subsection -Examples -\end_layout - -\begin_layout Standard -\begin_inset Float figure -placement H -wide false -sideways false -status open - -\begin_layout LyX-Code - -\series bold -const char * -\series default -b = "Hello World"; -\begin_inset Newline newline -\end_inset - - -\family typewriter -\series bold -char -\series default - c -\family default -\series bold -[] -\family typewriter -\series default - = "Hello World"; -\family default - -\begin_inset Newline newline -\end_inset - - -\family typewriter -\series bold -struct -\series default - HXformat_map -\series bold -* -\series default -table = HXformat_init(); -\begin_inset Newline newline -\end_inset - -HXformat_add(table, "%(GREETING1)", b, HXTYPE_STRING); -\begin_inset Newline newline -\end_inset - -HXformat_add(table, "%(GREETING2)", &c, HXTYPE_STRP); -\begin_inset Newline newline -\end_inset - -b = NULL; -\begin_inset Newline newline -\end_inset - -snprintf(c, -\family default -\series bold -sizeof -\family typewriter -\series default -(c), "Hello Home"); -\begin_inset Newline newline -\end_inset - -HXformat_aprintf(...); -\end_layout - -\begin_layout Plain Layout -Upon calling -\family typewriter -HXformat_*printf -\family default -, -\family typewriter -%(GREETING1) -\family default - will expand to -\begin_inset Quotes eld -\end_inset - -Hello World -\begin_inset Quotes erd -\end_inset - - whereas -\family typewriter -%(GREETING2) -\family default - will expand to -\begin_inset Quotes eld -\end_inset - -Hello Home -\begin_inset Quotes erd -\end_inset - -. -\end_layout - -\begin_layout Plain Layout -\begin_inset Caption Standard - -\begin_layout Plain Layout -\begin_inset CommandInset label -LatexCommand label -name "fig:hxformat-immediate-deferred" - -\end_inset - -Immediate and deferred resolution -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Float figure -wide false -sideways false -status open - -\begin_layout LyX-Code - -\series bold -struct -\series default - HXformat_map -\series bold -* -\series default -table = HXformat_init(); -\begin_inset Newline newline -\end_inset - -HXformat_add(table, "/libhx/exec", NULL, HXTYPE_IMMED); -\begin_inset Newline newline -\end_inset - -HXformat_aprintf(table, &result, "%(exec uname -s)"); -\end_layout - -\begin_layout Plain Layout -\begin_inset Caption Standard - -\begin_layout Plain Layout -\begin_inset CommandInset label -LatexCommand label -name "fig:hxformat-exec" - -\end_inset - -Using the -\family typewriter -%(exec) -\family default - function -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Newpage clearpage -\end_inset - - -\end_layout - -\begin_layout Part -Filesystem operations -\end_layout - -\begin_layout Section -Dentry operations -\end_layout - -\begin_layout Subsection -Synopsis -\end_layout - -\begin_layout LyX-Code - -\series bold -#include <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 softhyphen -REALPATH_\SpecialChar softhyphen -SELF -\begin_inset space ~ -\end_inset - -| HX_\SpecialChar softhyphen -REALPATH_\SpecialChar softhyphen -PARENT -\family default -. - Note that -\family typewriter -HX_\SpecialChar softhyphen -REALPATH_\SpecialChar softhyphen -ABSOLUTE -\family default -, which would also be required to get libc's -\family typewriter -realpath -\family default -(3) behavior, is not included in the set. -\end_layout - -\begin_layout Description - -\family typewriter -HX_REALPATH_ABSOLUTE -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HX_REALPATH_ABSOLUTE -\end_layout - -\end_inset - - Requests that the output path shall be absolute. - In the absence of this flag, an absolute output path will only be produced - if the input path is also absolute. -\end_layout - -\begin_layout Description - -\family typewriter -HX_REALPATH_SELF -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HX_REALPATH_SELF -\end_layout - -\end_inset - - Request resolution of -\begin_inset Quotes eld -\end_inset - -. -\begin_inset Quotes erd -\end_inset - - path components. -\end_layout - -\begin_layout Description - -\family typewriter -HX_REALPATH_PARENT -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HX_REALPATH_PARENT -\end_layout - -\end_inset - - Request resolution of -\begin_inset Quotes eld -\end_inset - -.. -\begin_inset Quotes erd -\end_inset - - path components. -\end_layout - -\begin_layout Standard -The result is stored in a memory container whose pointer is returned through - -\family typewriter -*buf -\family default -. - The return value of the function will be negative to indicate a possible - system error, or be positive non-zero for success. -\end_layout - -\begin_layout Section -Directory traversal -\begin_inset CommandInset label -LatexCommand label -name "sec:dir-ops1" - -\end_inset - - -\end_layout - -\begin_layout Standard -libHX provides a minimal readdir-style wrapper for cross-platform directory - traversal. - This is needed because the Win32 platforms does not have readdir, and there - is some housekeeping to do on Unixish platforms, since the -\family typewriter -dirent -\family default - structure needs allocation of a path-specific size. -\end_layout - -\begin_layout Subsection -Synopsis -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 "subsec: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 "subsec:option-types" - -\end_inset - - -\end_layout - -\begin_layout Description - -\family typewriter -HXTYPE_NONE -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXTYPE_NONE -\end_layout - -\end_inset - - -\family default -\series default - The option does not take any argument, but the presence of the option may - be record by setting the -\family typewriter -*(int -\begin_inset space ~ -\end_inset - -*)ptr -\family default - to 1. - Other rules apply when -\family typewriter -HXOPT_\SpecialChar softhyphen -INC -\family default - or -\family typewriter -HXOPT_\SpecialChar softhyphen -DEC -\family default - are specified as flags (see section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "subsec:option-flags" - -\end_inset - -). -\end_layout - -\begin_layout Description - -\family typewriter -HXTYPE_VAL -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXTYPE_VAL -\end_layout - -\end_inset - - -\family default -\series default - Use the integer value specified by -\family typewriter -ival -\family default - and store it in -\family typewriter -*(int -\begin_inset space ~ -\end_inset - -*)ptr -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXTYPE_SVAL -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXTYPE_SVAL -\end_layout - -\end_inset - - -\family default -\series default - Use the memory location specified by -\family typewriter -sval -\family default - and store it in -\family typewriter -*(const char -\begin_inset space ~ -\end_inset - -**)ptr -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXTYPE_BOOL -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXTYPE_BOOL -\end_layout - -\end_inset - - -\family default -\series default - Interpret the supplied argument as a boolean descriptive (must be -\begin_inset Quotes eld -\end_inset - -yes -\begin_inset Quotes erd -\end_inset - -, -\begin_inset Quotes eld -\end_inset - -no -\begin_inset Quotes erd -\end_inset - -, -\begin_inset Quotes eld -\end_inset - -on -\begin_inset Quotes erd -\end_inset - -, -\begin_inset Quotes eld -\end_inset - -off -\begin_inset Quotes erd -\end_inset - -, -\begin_inset Quotes eld -\end_inset - -true -\begin_inset Quotes erd -\end_inset - -, -\begin_inset Quotes eld -\end_inset - -false -\begin_inset Quotes erd -\end_inset - -, -\begin_inset Quotes eld -\end_inset - -0 -\begin_inset Quotes erd -\end_inset - - or -\begin_inset Quotes eld -\end_inset - -1 -\begin_inset Quotes erd -\end_inset - -) and store the result in -\family typewriter -*(int -\begin_inset space ~ -\end_inset - -*)ptr -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXTYPE_STRING -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXTYPE_STRING -\end_layout - -\end_inset - - -\family default - The argument string is duplicated to a new memory region and the resulting - pointer stored into -\family typewriter -*(char -\begin_inset space ~ -\end_inset - -**)ptr -\family default -. - This incurs an allocation so that subsequently modifying the original argument - string in any way will not falsely propagate. -\end_layout - -\begin_layout Description - -\family typewriter -HXTYPE_STRDQ -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXTYPE_STRDQ -\end_layout - -\end_inset - - -\family default -\series default - The argument string is duplicated to a new memory region and the resulting - pointer is added to the given HXdeque. - Note that you often need to use deferred initialization of the options - table to avoid putting -\family typewriter -NULL -\family default - into the entry. - See section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "subsec:option-pitfalls-static" - -\end_inset - -. -\end_layout - -\begin_layout Standard -The following table lists the types that map to the common integral and - floating-point types. - Signed and unsigned integeral types are processed using -\family typewriter -strtol -\family default - and -\family typewriter -strtoul -\family default -, respectively. - -\family typewriter -strtol -\family default - and -\family typewriter -strtoul -\family default - will be called with automatic base detection. - This usually means that a leading -\begin_inset Quotes eld -\end_inset - -0 -\begin_inset Quotes erd -\end_inset - - indicates the string is given in octal (8) base, a leading -\begin_inset Quotes eld -\end_inset - -0x -\begin_inset Quotes erd -\end_inset - - indicates hexadecimal (16) base, and decimal (10) otherwise. - -\family typewriter -HXTYPE_\SpecialChar softhyphen -LLONG -\family default -, -\family typewriter - HXTYPE_\SpecialChar softhyphen -ULLONG -\family default -, -\family typewriter - HXTYPE_\SpecialChar softhyphen -INT64 -\family default - and -\family typewriter - HXTYPE_\SpecialChar softhyphen -UINT64 -\family default - use -\family typewriter - strtoll -\family default - and/or -\family typewriter - strtoull -\family default -, which may not be available on all platforms. -\begin_inset Separator latexpar -\end_inset - - -\end_layout - -\begin_layout Standard -\align center -\begin_inset Float table -placement H -wide false -sideways false -status open - -\begin_layout Plain Layout -\align center -\begin_inset Tabular -<lyxtabular version="3" rows="12" columns="4"> -<features tabularvalignment="middle"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="bottom"> -<column alignment="center" valignment="top"> -<column alignment="center" valignment="top"> -<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 Standard - -\begin_layout Plain Layout -Integral and floating-point types for the libHX option parser -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard - -\family typewriter -HXTYPE_\SpecialChar softhyphen -FLOAT -\family default - and -\family typewriter -HXTYPE_\SpecialChar softhyphen -DOUBLE -\family default - make use of -\family typewriter -strtod -\family default - ( -\family typewriter -strtof -\family default - is not used). - A corresponding -\family typewriter -type -\family default - for the -\begin_inset Quotes eld -\end_inset - -long double -\begin_inset Quotes erd -\end_inset - - format is not specified, but may be implemented on behalf of the user via - a callback (see section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "subsec:option-example-cb" - -\end_inset - -). -\end_layout - -\begin_layout Subsection -Flags -\begin_inset CommandInset label -LatexCommand label -name "subsec:option-flags" - -\end_inset - - -\end_layout - -\begin_layout Standard -Flags can be combined into the -\family typewriter -type -\family default - parameter by OR'ing them. - It is valid to not specify any flags at all, but most flags collide with - one another. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_INC -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_INC -\end_layout - -\end_inset - - -\family default -\series default - Perform an increment on the memory location specified by the -\family typewriter -*(int -\begin_inset space ~ -\end_inset - -*)ptr -\family default - pointer. - Make sure the referenced variable is initialized before! -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_DEC -\family default -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXOPT_DEC -\end_layout - -\end_inset - - -\series default - Perform a decrement on the pointee. -\end_layout - -\begin_layout Standard -Only one of -\family typewriter -HXOPT_\SpecialChar softhyphen -INC -\family default - and -\family typewriter -HXOPT_\SpecialChar softhyphen -DEC -\family default - may be specified at a time, and they require that the base type is -\family typewriter -HXTYPE_\SpecialChar softhyphen -NONE -\family default -, or they will have no effect. - An example may be found in section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "subsec:option-example-incdec" - -\end_inset - -. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_NOT -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_NOT -\end_layout - -\end_inset - - -\family default -\series default - Binary negation of the argument directly after reading it from the command - line into memory. - Any of the three following operations are executed with the already-negated - value. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_OR -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXOPT_OR -\end_layout - -\end_inset - - -\family default -\series default - Binary -\begin_inset Quotes eld -\end_inset - -OR -\begin_inset Quotes erd -\end_inset - -s the pointee with the specified\SpecialChar breakableslash -transformed value. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_AND -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_AND -\end_layout - -\end_inset - - -\family default -\series default - Binary -\begin_inset Quotes eld -\end_inset - -AND -\begin_inset Quotes erd -\end_inset - -s the pointee with the specified\SpecialChar breakableslash -transformed value. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_XOR -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_XOR -\end_layout - -\end_inset - - -\family default -\series default - Binary -\begin_inset Quotes eld -\end_inset - -XOR -\begin_inset Quotes erd -\end_inset - -s the pointee with the specified\SpecialChar breakableslash -transformed value. -\end_layout - -\begin_layout Standard -Only one of ( -\family typewriter -HXOPT_OR -\family default -, -\family typewriter -HXOPT_\SpecialChar softhyphen -AND -\family default -, -\family typewriter -HXOPT_\SpecialChar softhyphen -XOR -\family default -) may be specified at a time, but they can be used with any integral -\family typewriter -type -\family default - ( -\family typewriter -HXTYPE_\SpecialChar softhyphen -UINT -\family default -, -\family typewriter -HXTYPE_\SpecialChar softhyphen -ULONG -\family default -, etc.). - An example can be found in section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "subsec:option-example-mask" - -\end_inset - -. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_OPTIONAL -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_OPTIONAL -\end_layout - -\end_inset - - -\family default -\series default - This flag allows for an option to take zero or one argument. - Needless to say that this can be confusing to the user. - -\shape italic -iptables -\shape default -'s -\begin_inset Quotes eld -\end_inset - - -\family typewriter --L -\family default - -\begin_inset Quotes erd -\end_inset - - option for example is one of this kind (though it does not use the libHX - option parser). - When this flag is used, -\begin_inset Quotes eld -\end_inset - - -\family typewriter --f -b -\family default - -\begin_inset Quotes erd -\end_inset - - is interpreted as -\family typewriter --f -\family default - without an argument, as is -\begin_inset Quotes eld -\end_inset - - -\family typewriter --f --bar -\family default - -\begin_inset Quotes erd -\end_inset - - -\begin_inset space ~ -\end_inset - -— things that look like an option take precedence over an option with an - optional argument. - -\begin_inset Quotes eld -\end_inset - - -\family typewriter --f - -\family default - -\begin_inset Quotes erd -\end_inset - - of course denotes an option with an argument, as -\begin_inset Quotes eld -\end_inset - - -\family typewriter -- -\family default - -\begin_inset Quotes erd -\end_inset - - is used to indicate standard input/output. -\end_layout - -\begin_layout Subsection -Special entries -\end_layout - -\begin_layout Standard -HXopt provides two special entries via macros: -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_AUTOHELP -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_AUTOHELP -\end_layout - -\end_inset - - -\family default -\series default - Adds entries to recognize -\begin_inset Quotes eld -\end_inset - - -\family typewriter --? -\family default - -\begin_inset Quotes erd -\end_inset - - and -\begin_inset Quotes eld -\end_inset - - -\family typewriter ---help -\family default - -\begin_inset Quotes erd -\end_inset - - that will display the (long-format) help screen, and -\begin_inset Quotes eld -\end_inset - - -\family typewriter ---usage -\family default - -\begin_inset Quotes erd -\end_inset - - that will display the short option syntax overview. - All three options will exit the program afterwards. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_TABLEEND -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_TABLEEND -\end_layout - -\end_inset - - -\family default -\series default - This sentinel marks the end of the table and is required on all tables. - (See examples for details.) -\end_layout - -\begin_layout Subsection -Invoking the parser -\end_layout - -\begin_layout LyX-Code - -\series bold -int -\series default - HX_getopt( -\series bold -const struct -\series default - HXoption -\series bold -* -\series default -options_table, -\series bold -int * -\series default -argc, -\begin_inset Newline newline -\end_inset - - -\series bold -const char *** -\series default -argv, -\series bold -unsigned int -\series default - flags); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HX_getopt -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard - -\family typewriter -HX_getopt -\family default - is the actual parsing function. - It takes the option table, and a pointer to your -\family typewriter -argc -\family default - and -\family typewriter -argv -\family default - variables that you get from the -\family typewriter -main -\family default - function. - The parser will, unlike GNU getopt, literally -\begin_inset Quotes eld -\end_inset - -eat -\begin_inset Quotes erd -\end_inset - - all options and their arguments, leaving only non-options in -\family typewriter -argv -\family default -, and -\family typewriter -argc -\family default - updated, when finished. - This is similar to how Perl's -\begin_inset Quotes eld -\end_inset - -Getopt::Long -\begin_inset Quotes erd -\end_inset - - module works. - Additional flags can control the exact behavior of -\family typewriter -HX_getopt -\family default -: -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_PTHRU -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_PTHRU -\end_layout - -\end_inset - - -\family default -\series default - -\begin_inset Quotes eld -\end_inset - -Passthrough mode -\begin_inset Quotes erd -\end_inset - -. - Any unknown options are not -\begin_inset Quotes eld -\end_inset - -eaten -\begin_inset Quotes erd -\end_inset - - and are instead passed back into the resulting -\family typewriter -argv -\family default - array. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_QUIET -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_QUIET -\end_layout - -\end_inset - - -\family default -\series default - Do not print any diagnostics when encountering errors in the user's input. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_HELPONERR -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXOPT_HELPONERR -\end_layout - -\end_inset - - -\family default -\series default - Display the (long-format) help when an error, such as an unknown option - or a violation of syntax, is encountered. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_USAGEONERR -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXOPT_USAGEONERR -\end_layout - -\end_inset - - -\family default -\series default - Display the short-format usage syntax when an error is encountered. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_RQ_ORDER -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXOPT_RQ_ORDER -\end_layout - -\end_inset - - Specifying this option terminates option processing when the first non-option - argument in -\family typewriter -argv -\family default - is encountered. - This behavior is also implicit when the environment variable -\family typewriter -POSIXLY_CORRECT -\family default - is set. -\end_layout - -\begin_layout Standard -The return value can be one of the following: -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_ERR_SUCCESS -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXOPT_ERR_SUCCESS -\end_layout - -\end_inset - - Parsing was successful. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_ERR_UNKN -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_ERR_UNKN -\end_layout - -\end_inset - - -\family default -\series default - An unknown option was encountered. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_ERR_VOID -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_ERR_VOID -\end_layout - -\end_inset - - -\family default -\series default - An argument was given for an option which does not allow one. - In practice this only happens with -\begin_inset Quotes eld -\end_inset - - -\family typewriter ---foo=bar -\family default - -\begin_inset Quotes erd -\end_inset - - when -\family typewriter ---foo -\family default - is of type -\family typewriter -HXTYPE_\SpecialChar softhyphen -NONE -\family default -, -\family typewriter -HXTYPE_\SpecialChar softhyphen -VAL -\family default - or -\family typewriter -HXTYPE_\SpecialChar softhyphen -SVAL -\family default -. - This does not affect -\begin_inset Quotes eld -\end_inset - - -\family typewriter ---foo bar -\family default - -\begin_inset Quotes erd -\end_inset - -, because this can be unambiguously interpreted as -\begin_inset Quotes eld -\end_inset - - -\family typewriter -bar -\family default - -\begin_inset Quotes erd -\end_inset - - being a remaining argument to the program. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_ERR_MIS -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_ERR_MIS -\end_layout - -\end_inset - - -\family default -\series default - Missing argument for an option that requires one. -\end_layout - -\begin_layout Description - -\family typewriter -HXOPT_ERR_AMBIG -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXOPT_ERR_AMBIG -\end_layout - -\end_inset - - -\family default -\series default - An abbreviation of a long option was ambiguous. -\end_layout - -\begin_layout Description -negative -\begin_inset space ~ -\end_inset - -non-zero Failure on behalf of lower-level calls; errno. -\end_layout - -\begin_layout Subsection -Pitfalls -\end_layout - -\begin_layout Subsubsection -Staticness of tables -\begin_inset CommandInset label -LatexCommand label -name "subsec:option-pitfalls-static" - -\end_inset - - -\end_layout - -\begin_layout Standard -The following is an example of a possible pitfall regarding -\family typewriter -HXTYPE_\SpecialChar softhyphen -STRDQ -\family default -: -\end_layout - -\begin_layout LyX-Code - -\series bold -static struct -\series default - HXdeque -\series bold -* -\series default -dq; -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -static bool -\series default - get_options( -\series bold -int * -\series default -argc, -\series bold -const char *** -\series default -argv) -\begin_inset Newline newline -\end_inset - -{ -\begin_inset Newline newline -\end_inset - - -\series bold -static const struct -\series default - HXoption options_table -\series bold -[] -\series default - = { -\begin_inset Newline newline -\end_inset - - {.sh = 'N', .type = HXTYPE_STRDQ, .q_strdq = dq, -\begin_inset Newline newline -\end_inset - - .help = "Add name"}, -\begin_inset Newline newline -\end_inset - - HXOPT_TABLEEND, -\begin_inset Newline newline -\end_inset - - }; -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - HX_getopt(options_table, argc, argv, HXOPT_USAGEONERR) == -\begin_inset Newline newline -\end_inset - - HXOPT_ERR_SUCCESS; -\begin_inset Newline newline -\end_inset - -} -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -int -\series default - main( -\series bold -int -\series default - argc, -\series bold -const char ** -\series default -argv) -\begin_inset Newline newline -\end_inset - -{ -\begin_inset Newline newline -\end_inset - - dq = HXdeque_init(); -\begin_inset Newline newline -\end_inset - - get_options(&argc, &argv); -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - 0; -\begin_inset Newline newline -\end_inset - -} -\end_layout - -\begin_layout Standard -The problem here is that -\family typewriter -options_\SpecialChar softhyphen -table -\family default - is, due to the -\family typewriter -static -\family default - keyword, initialized at compile-time where -\family typewriter -dq -\family default - is still -\family typewriter -NULL -\family default -. - To counter this problem and have it doing the right thing, you must remove - the -\family typewriter -static -\family default - qualifier on the options table when used with -\family typewriter -HXTYPE_\SpecialChar softhyphen -STRDQ -\family default -, so that it will be evaluated when it is first executed. -\end_layout - -\begin_layout Standard -It was not deemed worthwhile to have -\family typewriter -HXTYPE_\SpecialChar softhyphen -STRDQ -\family default - take an indirect HXdeque ( -\family typewriter -struct HXdeque -\begin_inset space ~ -\end_inset - -** -\family default -) instead just to bypass this issue. - (Live with it.) -\end_layout - -\begin_layout Subsection -Limitations -\end_layout - -\begin_layout Standard -The HX option parser has been influenced by both popt and Getopt::Long, - but eventually, there are differences: -\end_layout - -\begin_layout Itemize -Long options with a single dash ( -\begin_inset Quotes eld -\end_inset - - -\family typewriter --foo bar -\family default - -\begin_inset Quotes erd -\end_inset - -). - This unsupported syntax clashes very easily with support for option bundling - or squashing. - In case of bundling, -\begin_inset Quotes eld -\end_inset - - -\family typewriter --foo -\family default - -\begin_inset Quotes erd -\end_inset - - might actually be -\begin_inset Quotes eld -\end_inset - - -\family typewriter --f -o -o -\family default - -\begin_inset Quotes erd -\end_inset - -, or -\begin_inset Quotes eld -\end_inset - - -\family typewriter --f oo -\family default - -\begin_inset Quotes erd -\end_inset - - in case of squashing. - It also introduces redundant ways to specify options, which is not in the - spirit of the author. -\end_layout - -\begin_layout Itemize -Options using a -\begin_inset Quotes eld -\end_inset - - -\family typewriter -+ -\family default - -\begin_inset Quotes erd -\end_inset - - as a prefix, as in -\begin_inset Quotes eld -\end_inset - - -\family typewriter -+foo -\family default - -\begin_inset Quotes erd -\end_inset - -. - Xterm for example uses it as a way to negate an option. - In the author's opinion, using one character to specify options is enough -\begin_inset space ~ -\end_inset - -— by GNU standards, a negator is named -\begin_inset Quotes eld -\end_inset - - -\family typewriter ---no-foo -\family default - -\begin_inset Quotes erd -\end_inset - -. - Even Microsoft stuck to a single option introducing character (that would - be -\begin_inset Quotes eld -\end_inset - - -\family typewriter -/ -\family default - -\begin_inset Quotes erd -\end_inset - -). -\end_layout - -\begin_layout Itemize -Table nesting like implemented in popt. - HXopt has no provision for nested tables, as the need has not come up yet. - It does however support chained processing (see section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "subsec:option-example-chained" - -\end_inset - -). - You cannot do nested tables even with callbacks, as the new -\family typewriter -argv -\family default - array is only put in place shortly before -\family typewriter -HX_getopt -\family default - returns. -\end_layout - -\begin_layout Subsection -Examples -\end_layout - -\begin_layout Subsubsection -Basic example -\end_layout - -\begin_layout Standard -The following code snippet should provide an equivalent of the GNU getopt - sample -\begin_inset Foot -status open - -\begin_layout Plain Layout -\begin_inset Flex URL -status open - -\begin_layout Plain Layout - -http://www.gnu.org/software/libtool/manual/libc/Example-of-Getopt.html -\backslash -#Example-of-Getopt -\end_layout - -\end_inset - - -\end_layout - -\end_inset - -. -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 "subsec:option-example-incdec" - -\end_inset - - -\end_layout - -\begin_layout LyX-Code - -\series bold -static int -\series default - verbosity = 1; -\series bold -/* -\family roman -\series default -\shape italic -somewhat silent by default -\family default -\series bold -\shape default - */ -\series default - -\begin_inset Newline newline -\end_inset - - -\series bold -static const struct -\series default - HXoption options_table -\series bold -[] -\series default - = { -\begin_inset Newline newline -\end_inset - - {.sh = 'q', .type = HXTYPE_NONE | HXOPT_DEC, .q_int = &verbosity, -\begin_inset Newline newline -\end_inset - - .help = "Reduce verbosity"}, -\begin_inset Newline newline -\end_inset - - {.sh = 'v', .type = HXTYPE_NONE | HXOPT_INC, .q_int = &verbosity, -\begin_inset Newline newline -\end_inset - - .help = "Increase verbosity"}, -\begin_inset Newline newline -\end_inset - - HXOPT_TABLEEND, -\begin_inset Newline newline -\end_inset - -}; -\end_layout - -\begin_layout Standard -This sample option table makes it possible to turn the verbosity of the - program up or down, depending on whether the user specified -\family typewriter --q -\family default - or -\family typewriter --v -\family default -. - By passing multiple -\family typewriter --v -\family default - flags, the verbosity can be turned up even more. - The range depends on the -\begin_inset Quotes eld -\end_inset - - -\family typewriter -int -\family default - -\begin_inset Quotes erd -\end_inset - - data type for your particular platform and compiler; if you want to have - the verbosity capped at a specific level, you will need to use an extra - callback: -\end_layout - -\begin_layout LyX-Code - -\series bold -static int -\series default - verbosity = 1; -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -static void -\series default - v_check( -\series bold -const struct -\series default - HXoptcb -\series bold -* -\series default -cbi) -\begin_inset Newline newline -\end_inset - -{ -\begin_inset Newline newline -\end_inset - - -\series bold -if -\series default - (verbosity < 0) -\begin_inset Newline newline -\end_inset - - verbosity = 0; -\begin_inset Newline newline -\end_inset - - -\series bold -else if -\series default - (verbosity > 4) -\begin_inset Newline newline -\end_inset - - verbosity = 4; -\begin_inset Newline newline -\end_inset - -} -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -static const struct -\series default - HXoption options_table -\series bold -[] -\series default - = { -\begin_inset Newline newline -\end_inset - - {.sh = 'q', .type = HXTYPE_NONE | HXOPT_DEC, .q_int = &verbosity, -\begin_inset Newline newline -\end_inset - - .cb = v_check, .help = "Lower verbosity"}, -\begin_inset Newline newline -\end_inset - - {.sh = 'v', .type = HXTYPE_NONE | HXOPT_INC, .q_int = &verbosity, -\begin_inset Newline newline -\end_inset - - .cb = v_check, .help = "Raise verbosity"}, -\begin_inset Newline newline -\end_inset - - HXOPT_TABLEEND, -\begin_inset Newline newline -\end_inset - -}; -\end_layout - -\begin_layout Subsubsection -Mask operations -\begin_inset CommandInset label -LatexCommand label -name "subsec:option-example-mask" - -\end_inset - - -\end_layout - -\begin_layout LyX-Code - -\series bold -/* -\family roman -\series default -\shape italic -run on all CPU cores by default -\family default -\series bold -\shape default - * -\series default -/ -\begin_inset Newline newline -\end_inset - - -\series bold -static unsigned int -\series default - cpu_mask = ~0U -\series bold -; -\begin_inset Newline newline -\end_inset - -/* -\family roman -\series default -\shape italic -use no network connections by default -\family default -\shape default - -\series bold -*/ -\begin_inset Newline newline -\end_inset - -static unsigned int -\series default - net_mask = 0; -\series bold - -\begin_inset Newline newline -\end_inset - -static struct -\series default - HXoption options_table -\series bold -[] -\series default - = { -\begin_inset Newline newline -\end_inset - - {.sh = 'c', .type = HXTYPE_UINT | HXOPT_NOT | HXOPT_AND, -\begin_inset Newline newline -\end_inset - - .q_uint = &cpu_mask, -\begin_inset Newline newline -\end_inset - - .help = "Mask of cores to exclude", .htyp = "cpu_mask"}, -\begin_inset Newline newline -\end_inset - - {.sh = 'n', .type = HXTYPE_UINT | HXOPT_OR, .q_uint = &net_mask, -\end_layout - -\begin_layout LyX-Code - .help = "Mask of network channels to additionally use", -\begin_inset Newline newline -\end_inset - - .htyp = "channel_mask"}, -\begin_inset Newline newline -\end_inset - - HXOPT_TABLEEND, -\begin_inset Newline newline -\end_inset - -}; -\end_layout - -\begin_layout Standard -What this options table does is -\family typewriter -cpu_mask &= ~x -\family default - and -\family typewriter -net_mask |= y -\family default -, the classic operations of clearing and setting bits. -\end_layout - -\begin_layout Subsubsection -Support for non-standard actions -\begin_inset CommandInset label -LatexCommand label -name "subsec:option-example-cb" - -\end_inset - - -\end_layout - -\begin_layout Standard -Supporting additional types or custom storage formats is easy, by simply - using -\family typewriter -HXTYPE_\SpecialChar softhyphen -STRING -\family default -, -\family typewriter -NULL -\family default - as the data pointer (usually by not specifying it at all), the pointer - to your data in the user-specified pointer -\family typewriter -uptr -\family default -, and the callback function in -\family typewriter -cb -\family default -. -\end_layout - -\begin_layout LyX-Code - -\series bold -struct -\series default - fixed_point { -\begin_inset Newline newline -\end_inset - - -\series bold -int -\series default - integral; -\begin_inset Newline newline -\end_inset - - -\series bold -unsigned int -\series default - fraction; -\begin_inset Newline newline -\end_inset - -}; -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -static struct -\series default - fixed_point number; -\end_layout - -\begin_layout LyX-Code -\begin_inset Newline newline -\end_inset - - -\series bold -static void -\series default - fixed_point_parse -\series bold -(const struct -\series default - HXoptcb -\series bold - -\series default -*cbi) -\begin_inset Newline newline -\end_inset - -{ -\begin_inset Newline newline -\end_inset - - -\series bold -char * -\series default -end; -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - number.integral = strtol(cbi->data, &end, 0); -\begin_inset Newline newline -\end_inset - - -\series bold -if -\series default - (*end == ' -\backslash -0') -\begin_inset Newline newline -\end_inset - - number.fraction = 0; -\begin_inset Newline newline -\end_inset - - -\series bold -else if -\series default - (*end == '.') -\begin_inset Newline newline -\end_inset - - number.fraction = strtoul(end + 1, NULL, 0); -\begin_inset Newline newline -\end_inset - - -\series bold -else -\series default - -\begin_inset Newline newline -\end_inset - - fprintf(stderr, "Illegal input. -\backslash -n"); -\begin_inset Newline newline -\end_inset - -} -\begin_inset Newline newline -\end_inset - - -\series bold - -\begin_inset Newline newline -\end_inset - -static const struct -\series default - HXoption options_table -\series bold -[] -\series default - = { -\begin_inset Newline newline -\end_inset - - {.sh = 'n', .type = HXTYPE_STRING, .cb = fixed_point_parse, -\begin_inset Newline newline -\end_inset - - .uptr = &number, .help = "Do this or that", -\begin_inset Newline newline -\end_inset - - HXOPT_TABLEEND, -\end_layout - -\begin_layout LyX-Code -}; -\end_layout - -\begin_layout Subsubsection -Chained argument processing -\begin_inset CommandInset label -LatexCommand label -name "subsec:option-example-chained" - -\end_inset - - -\end_layout - -\begin_layout Standard -On the first run, only -\family typewriter ---cake -\family default - and -\family typewriter ---fruit -\family default - is considered, which is then used to select the next set of accepted options. - Note that -\family typewriter -HXOPT_\SpecialChar softhyphen -DESTROY_\SpecialChar softhyphen -OLD -\family default - is used here, which causes the argv that is produced by the first invocation - of -\family typewriter -HX_getopt -\family default - in the -\family typewriter -get_options -\family default - function to be freed as it gets replaced by a new argv again by -\family typewriter -HX_getopt -\family default - in -\family typewriter -get_cakes -\family default -\SpecialChar breakableslash - -\family typewriter -get_fruit -\family default -. - -\family typewriter -HXOPT_\SpecialChar softhyphen -DESTROY_\SpecialChar softhyphen -OLD -\family default - is however -\shape italic -not -\shape default - specified in the first invocation, because the initial argv resides on - the stack and cannot be freed. -\end_layout - -\begin_layout LyX-Code - -\series bold -static bool -\series default - get_cakes( -\series bold -int * -\series default -argc, -\series bold -const char *** -\series default -argv) -\begin_inset Newline newline -\end_inset - -{ -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - HXoption option_table -\series bold -[] -\series default - = { -\begin_inset Newline newline -\end_inset - - ... -\begin_inset Newline newline -\end_inset - - }; -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - HX_getopt(cake_table, argc, argv, -\begin_inset Newline newline -\end_inset - - HXOPT_USAGEONERR | HXOPT_DESTROY_OLD) == HXOPT_ERR_SUCCESS; -\begin_inset Newline newline -\end_inset - -} -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -static bool -\series default - get_fruit( -\series bold -int * -\series default -argc, -\series bold -const char *** -\series default -argv) -\begin_inset Newline newline -\end_inset - -{ -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - HXoption fruit_table -\series bold -[] -\series default - = { -\begin_inset Newline newline -\end_inset - - ... -\begin_inset Newline newline -\end_inset - - }; -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - HX_getopt(fruit_table, argc, argv, -\begin_inset Newline newline -\end_inset - - HXOPT_USAGEONERR | HXOPT_DESTROY_OLD) == HXOPT_ERR_SUCCESS; -\begin_inset Newline newline -\end_inset - -} -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -static bool -\series default - get_options( -\series bold -int * -\series default -argc, -\series bold -const char *** -\series default -argv) -\begin_inset Newline newline -\end_inset - -{ -\begin_inset Newline newline -\end_inset - - -\series bold -int -\series default - cake = 0, fruit = 0; -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - HXoption option_table -\series bold -[] -\series default - = { -\begin_inset Newline newline -\end_inset - - {.ln = "cake", .type = HXTYPE_NONE, .ptr = &cake}, -\begin_inset Newline newline -\end_inset - - {.ln = "fruit", .type = HXTYPE_NONE, .ptr = &fruit}, -\begin_inset Newline newline -\end_inset - - HXOPT_TABLEEND, -\begin_inset Newline newline -\end_inset - - }; -\begin_inset Newline newline -\end_inset - - -\series bold -if -\series default - (HX_getopt(option_table, argc, argv, HXOPT_PTHRU) != -\begin_inset Newline newline -\end_inset - - HXOPT_ERR_SUCCESS) -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - false; -\begin_inset Newline newline -\end_inset - - -\series bold -if -\series default - (cake) -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - get_cakes(argc, argv); -\begin_inset Newline newline -\end_inset - - -\series bold -else if -\series default - (fruit) -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - get_fruit(argc, argv); -\begin_inset Newline newline -\end_inset - - -\series bold -return -\series default - false; -\begin_inset Newline newline -\end_inset - -} -\end_layout - -\begin_layout Standard -\begin_inset Newpage clearpage -\end_inset - - -\end_layout - -\begin_layout Section -Shell-style configuration file parser -\begin_inset CommandInset label -LatexCommand label -name "sec:shconf" - -\end_inset - - -\end_layout - -\begin_layout Standard -libHX provides functions to read shell-style configuration files. - Such files are common, for example, in -\family typewriter -/etc/sysconfig -\family default - on Linux systems. - The format is pretty basic; it only knows about -\begin_inset Quotes eld -\end_inset - - -\family typewriter -key=value -\family default - -\begin_inset Quotes erd -\end_inset - - pairs and does not even have sections like INI files. - Not relying on any features however makes them quite interchangable as - the syntax is accepted by Unix Shells. -\end_layout - -\begin_layout Standard -Lines beginning with a hash mark ( -\family typewriter -# -\family default -) are ignored, as are empty lines and unrecognized keys. -\end_layout - -\begin_layout LyX-Code - -\series bold -# Minimum / maximum values for automatic UID selection -\series default - -\begin_inset Newline newline -\end_inset - -UID_MIN=100 -\begin_inset Newline newline -\end_inset - -UID_MAX=65000 -\begin_inset Newline newline -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -# Home directory base -\series default - -\begin_inset Newline newline -\end_inset - -HOME="/home" -\begin_inset Newline newline -\end_inset - -#HOME="/export/home" -\end_layout - -\begin_layout Standard -Any form of variable or parameter substitution or expansion is highly implementa -tion specific, and is not supported in libHX's reader. - Even Shell users should not rely on it as you never know in which context - the configuration files are evaluated. - Still, you will have to escape specific sequences like you would need to - in Shell. - The use of single quotes is acceptable. - That means: -\end_layout - -\begin_layout LyX-Code -AMOUNT="US -\backslash -$5" -\begin_inset Newline newline -\end_inset - -AMOUNT='US$5' -\end_layout - -\begin_layout Subsection -Synopsis -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 "subsec:option-synopsis" - -\end_inset - -, only the -\begin_inset Quotes eld -\end_inset - - -\family typewriter -ln -\family default - -\begin_inset Quotes erd -\end_inset - -, -\begin_inset Quotes eld -\end_inset - - -\family typewriter -type -\family default - -\begin_inset Quotes erd -\end_inset - - and -\begin_inset Quotes eld -\end_inset - - -\family typewriter -ptr -\family default - -\begin_inset Quotes erd -\end_inset - - fields are used. - The list of accepted types is described in section -\begin_inset space ~ -\end_inset - - -\begin_inset CommandInset ref -LatexCommand ref -reference "subsec:option-types" - -\end_inset - -. -\end_layout - -\begin_layout Standard -To parse a file, call -\family typewriter -HX_shconfig -\family default - function with the corresponding parameters. - If you want to read configuration files from different paths, i. -\begin_inset space \thinspace{} -\end_inset - -e. -\begin_inset space \space{} -\end_inset - -to build up on default values, you can use -\family typewriter -HX_shconfig_pv -\family default - -\begin_inset Foot -status open - -\begin_layout Plain Layout -pv = path vector -\end_layout - -\end_inset - -, which is a variant for reading a file from multiple locations. - Its purpose is to facilitate reading system-wide settings which are then - overriden by a file in the users home directory, for example (per-setting-overr -ide). - It is also possible to do per-file-override, that is, a file in the home - directory has higher precedence than a system-wide one in such a way that - the system-wide configuration file is not even read. - This is accomplished by traversing the paths in the -\begin_inset Quotes eld -\end_inset - -other -\begin_inset Quotes erd -\end_inset - - direction (actually you have to turn the array around) and stopping at - the first existing file by use of the -\family typewriter -SHCONF_\SpecialChar softhyphen -ONE -\family default - flag. -\end_layout - -\begin_layout Standard - -\family typewriter -HX_shconfig_map -\family default - will return all entries from the file in a HXmap, usable for parsing arbitrary - keys without having to specify any static key table. -\end_layout - -\begin_layout Description - -\family typewriter -SHCONF_ONE -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -SHCONF_ONE -\end_layout - -\end_inset - - -\family default -\series default - Parsing files will stop after one file has been successfully parsed. - This allows for a -\begin_inset Quotes eld -\end_inset - -personal overrides system config -\begin_inset Quotes erd -\end_inset - - style. -\end_layout - -\begin_layout Standard -The call to -\family typewriter -HX_shconfig -\family default - will either return >0 for success, 0 for no success (actually, this is - never returned) and -\family typewriter --errno -\family default - for an error. -\end_layout - -\begin_layout Subsection -Example -\end_layout - -\begin_layout Subsubsection -Per-setting-override -\end_layout - -\begin_layout Standard -This example sources key-value pairs from a configuration file in a system - location ( -\family typewriter -/etc -\family default -) first, before overriding specific keys with new values from the file in - the home directory. -\end_layout - -\begin_layout LyX-Code - -\series bold -long -\series default - uid_min, uid_max; -\begin_inset Newline newline -\end_inset - - -\series bold -char * -\series default -passwd_file; -\begin_inset Newline newline -\end_inset - - -\series bold -struct -\series default - HXoption options_table -\series bold -[] -\series default - = { -\begin_inset Newline newline -\end_inset - - {.ln = "UID_MIN", .type = HXTYPE_LONG, .ptr = &uid_min}, -\begin_inset Newline newline -\end_inset - - {.ln = "UID_MAX", .type = HXTYPE_LONG, .ptr = &uid_max}, -\begin_inset Newline newline -\end_inset - - {.ln = "PWD_FILE", .type = HXTYPE_STRING, .ptr = &passwd_file}, -\begin_inset Newline newline -\end_inset - - HXOPT_TABLEEND, -\begin_inset Newline newline -\end_inset - -}; -\begin_inset Newline newline -\end_inset - - -\series bold -const char * -\series default -home = getenv("HOME"); -\begin_inset Newline newline -\end_inset - - -\series bold -const char * -\series default -paths -\series bold -[] -\series default - = {"/etc", home, NULL}; -\begin_inset Newline newline -\end_inset - -HX_shconfig(paths, "test.cf", options_table, 0); -\end_layout - -\begin_layout Subsubsection -Per-file-override -\end_layout - -\begin_layout Standard -This particular example reads from the file in the home directory first - (if it exists), but stops after it has been successfull, so any subsequent - locations listed in the -\family typewriter -paths -\family default - variable are not read. - This has the effect that the file from the home directory has the highest - priority too like in the previous example, but without any keys from the - system files. - Note the -\family typewriter -SHCONF_ONE -\family default - flag. -\end_layout - -\begin_layout LyX-Code - -\series bold -const char * -\series default -home = getenv("HOME"); -\begin_inset Newline newline -\end_inset - - -\series bold -const char * -\series default -paths -\series bold -[] -\series default - = {home, "/usr/local/etc", "/etc", NULL}; -\begin_inset Newline newline -\end_inset - -HX_shconfig_pv(paths, "test.cf", options_table, SHCONF_ONE); -\end_layout - -\begin_layout Standard -\begin_inset Newpage clearpage -\end_inset - - -\end_layout - -\begin_layout Part -Systems-related components -\end_layout - -\begin_layout Section -Random numbers -\begin_inset CommandInset label -LatexCommand label -name "sec:random" - -\end_inset - - -\end_layout - -\begin_layout Subsection -Function overview -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 softhyphen -run_\SpecialChar softhyphen -async -\family default -), the first three fields must be filled in by the user. -\end_layout - -\begin_layout Description - -\family typewriter -p_ops -\family default - A table of callbacks, generally used for setting and/or restoring signals - before/after execution. - This member may be -\family typewriter -NULL -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -p_data -\family default - Free pointer for the user to supply. - Will be passed to the callback functions when they are invoked. -\end_layout - -\begin_layout Description - -\family typewriter -p_flags -\family default - Process creation flags, see below. -\end_layout - -\begin_layout Standard -After the subprocess has been started, -\family typewriter -HXproc_run_async -\family default - will have filled in some fields: -\end_layout - -\begin_layout Description - -\family typewriter -p_stdin -\family default - If -\family typewriter -HXPROC_STDIN -\family default - was specified in -\family typewriter -p_flags -\family default -, -\family typewriter -p_stdin -\family default - will be assigned the write side file descriptor of the subprocess's to-be - stdin. - The subprocess will get the read side file descriptor in this member. - This is so that the correct fd is used in when -\family typewriter -p_ops->p_postfork -\family default - is called. -\end_layout - -\begin_layout Description - -\family typewriter -p_stdout -\family default - If -\family typewriter -HXPROC_STDOUT -\family default - is specified in -\family typewriter -p_flags -\family default -, -\family typewriter -p_stdout -\family default - will be assigned the read side file descriptor of the subprocess's to-be - stdout. - The subprocess will get the write side file descriptor in this member. -\end_layout - -\begin_layout Description - -\family typewriter -p_stderr -\family default - If -\family typewriter -HXPROC_STDERR -\family default - is specified in -\family typewriter -p_flags -\family default -, -\family typewriter -p_stderr -\family default - will be assigned the read side file descriptor of the subprocess's to-be - stderr, and the subprocess will get the write side fd. -\end_layout - -\begin_layout Description - -\family typewriter -p_pid -\family default - The process ID of the spawned process. -\end_layout - -\begin_layout Standard -Upon calling -\family typewriter -HXproc_wait -\family default -, further fields will have been filled when the function returns: -\end_layout - -\begin_layout Description - -\family typewriter -p_exited -\family default - Whether the process exited normally (cf. -\begin_inset space \space{} -\end_inset - -signalled\SpecialChar breakableslash -terminated). -\end_layout - -\begin_layout Description - -\family typewriter -p_terminated -\family default - Whether the process was terminated (signalled). -\end_layout - -\begin_layout Description - -\family typewriter -p_status -\family default - The exit status of the process or the termination signal. -\end_layout - -\begin_layout Subsubsection -Flags -\begin_inset CommandInset label -LatexCommand label -name "subsec:proc-pflags" - -\end_inset - - -\end_layout - -\begin_layout Standard -Possible values for the -\family typewriter -p_flags -\family default - member are: -\end_layout - -\begin_layout Description - -\family typewriter -HXPROC_STDIN -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXPROC_STDIN -\end_layout - -\end_inset - - -\family default -\series default - The subprocess's stdin file descriptor shall be connected to the master - program, that is, not inherit the stdin of the master. - Cannot be used for -\family typewriter -HXproc_\SpecialChar softhyphen -run_\SpecialChar softhyphen -sync -\family default - (because there would be no one to provide data in a sync operation). -\end_layout - -\begin_layout Description - -\family typewriter -HXPROC_STDOUT -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXPROC_STDOUT -\end_layout - -\end_inset - - -\family default -\series default - Connect the stdout file descriptor of the subprocess with the master. - Cannot be used for -\family typewriter -HXproc_run_sync -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXPROC_STDERR -\series medium - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -\series medium -HXPROC_STDERR -\end_layout - -\end_inset - - -\family default -\series default - Connect the stderr file descriptor of the subprocess with the master. - Cannot be used for -\family typewriter -HXproc_run_sync -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXPROC_NULL_STDIN -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXPROC_NULL_STDIN -\end_layout - -\end_inset - - The subprocess's stdin file descriptor shall be connected to -\family typewriter -/dev\SpecialChar breakableslash -null -\family default -. - -\family typewriter -HXPROC_\SpecialChar softhyphen -STDIN -\family default - and -\family typewriter -HXPROC_\SpecialChar softhyphen -NULL_\SpecialChar softhyphen -STDIN -\family default - are mutually exclusive. -\end_layout - -\begin_layout Description - -\family typewriter -HXPROC_NULL_STDOUT -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXPROC_NULL_STDOUT -\end_layout - -\end_inset - - Connect the stdout file descriptor of the subprocess to -\family typewriter -/dev\SpecialChar breakableslash -null -\family default -, thereby essentially discarding its output. - -\family typewriter -HXPROC_\SpecialChar softhyphen -STDOUT -\family default - and -\family typewriter -HXPROC_\SpecialChar softhyphen -NULL_\SpecialChar softhyphen -STDOUT -\family default - are mutuall exclusive. -\end_layout - -\begin_layout Description - -\family typewriter -HXPROC_NULL_STDERR -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXPROC_NULL_STDERR -\end_layout - -\end_inset - - Connect the stderr file descriptor of the subprocess to -\family typewriter -/dev\SpecialChar breakableslash -null -\family default -, thereby essentially discarding its output. - -\family typewriter -HXPROC_\SpecialChar softhyphen -STDERR -\family default - and -\family typewriter -HXPROC_\SpecialChar softhyphen -NULL_\SpecialChar softhyphen -STDERR -\family default - are mutually exclusive. -\end_layout - -\begin_layout Description - -\family typewriter -HXPROC_VERBOSE -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXPROC_VERBOSE -\end_layout - -\end_inset - - Have the subprocess print an error message to stderr if exec'ing returned - an error. -\end_layout - -\begin_layout Description - -\family typewriter -HXPROC_A0 -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXPROC_A0 -\end_layout - -\end_inset - - -\family typewriter -argv[0] -\family default - refers to program file, while -\family typewriter -argv[1] -\family default - to the program invocation name, with -\family typewriter -argv[2] -\family default - being the arguments. - Without this flag, -\family typewriter -argv[0] -\family default - will be both the program file and program invocation name, and arguments - begin at -\family typewriter -argv[1] -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -HXPROC_EXECV -\family default - -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -HXPROC_EXECV -\end_layout - -\end_inset - - Normally, -\family typewriter -execvp -\family default -(3) -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -execvp -\end_layout - -\end_inset - - will be used which scans -\family typewriter -$PATH -\family default - for the program. - Use this flag to use -\family typewriter -execv -\family default -(3) -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -execv -\end_layout - -\end_inset - - instead, which will not do such thing. -\end_layout - -\begin_layout Subsection -Callbacks -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 "subsec:proc-pflags" - -\end_inset - -. - -\family typewriter -HXPROC_STDIN -\family default -, -\family typewriter -HXPROC_STDOUT -\family default - and -\family typewriter -HXPROC_STDERR -\family default - are ignored because there would be no one in a synchronous execution that - could supply data to these file descriptors or read from them -\begin_inset Foot -status open - -\begin_layout Plain Layout -Even for threads, please just use the async model. -\end_layout - -\end_inset - -. -\end_layout - -\begin_layout Description - -\family typewriter -HXproc_wait -\family default - Wait for a subprocess to terminate, if it has not already. - It will also retrieve the exit status of the process and store it in the - -\family typewriter -struct HXproc -\family default -. -\end_layout - -\begin_layout Standard -Return value will be positive non-zero on success, or negative on error. - Underlying system function's errors are returned, plus: -\end_layout - -\begin_layout Description - -\family sans -EINVAL -\family default - Flags were not accepted. -\end_layout - -\begin_layout Section -Helper headers -\end_layout - -\begin_layout Subsection -ctype helpers -\end_layout - -\begin_layout Standard -Functions from the -\family typewriter -<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 softhyphen -New\SpecialChar softhyphen -Text\SpecialChar softhyphen -Node -\family default - and -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -xmlSetProp -\end_layout - -\end_inset - - -\family typewriter -xml\SpecialChar softhyphen -Set\SpecialChar softhyphen -Prop -\family default -, respectively. -\end_layout - -\begin_layout Standard - -\family typewriter -xml_getnsprop -\family default - works similar to -\family typewriter -xmlGetNsProp -\family default -, but instead of taking a namespace URI, it does a lookup by namespace prefix. - The argument order is also different compared to -\family typewriter -xmlGetNsProp -\family default -. -\end_layout - -\begin_layout Subsection -wxWidgets -\end_layout - -\begin_layout LyX-Code - -\series bold -#include -\series default - <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 softhyphen -FRAME_\SpecialChar softhyphen -STYLE -\family default - and a flag such that the dialog does not create a new window in the task - bar ( -\family typewriter -wxFRAME_\SpecialChar softhyphen -NO_\SpecialChar softhyphen -TASKBAR -\family default -). -\end_layout - -\begin_layout Description -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxDPOS -\end_layout - -\end_inset - - -\family typewriter -wxDPOS -\family default - Expands to -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxDefaultPosition -\end_layout - -\end_inset - - -\family typewriter -wxDefaultPosition -\family default -. -\end_layout - -\begin_layout Description -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxDSIZE -\end_layout - -\end_inset - - -\family typewriter -wxDSIZE -\family default - Expands to -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxDefaultSize -\end_layout - -\end_inset - - -\family typewriter -wxDefaultSize -\family default -. -\end_layout - -\begin_layout Description -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxDSPAN -\end_layout - -\end_inset - - -\family typewriter -wxDSPAN -\family default - Expands to -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxDefaultSpan -\end_layout - -\end_inset - - -\family typewriter -wxDefaultSpan -\family default -. -\end_layout - -\begin_layout Subsubsection -String conversion -\end_layout - -\begin_layout LyX-Code -wxString wxfu8( -\series bold -const char * -\series default -); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxfu8 -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - -wxString wxfv8( -\series bold -const char * -\series default -); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxfv8 -\end_layout - -\end_inset - - -\begin_inset Newline newline -\end_inset - - -\series bold -const char * -\series default -wxtu8( -\series bold -const -\series default - wxString -\series bold -& -\series default -); -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxtu8 -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Description - -\family typewriter -wxfu8 -\family default - Converts an UTF-8 string to a -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxString -\end_layout - -\end_inset - - -\family typewriter -wxString -\family default - object. -\end_layout - -\begin_layout Description - -\family typewriter -wxfv8 -\family default - Converts an UTF-8 string to an entity usable by -\begin_inset Index idx -status open - -\begin_layout Plain Layout - -\family typewriter -wxPrintf -\end_layout - -\end_inset - - -\family typewriter -wxPrintf -\family default -. -\end_layout - -\begin_layout Description - -\family typewriter -wxtu8 -\family default - Converts a wxString to a pointer to char usable by -\family typewriter -printf -\family default -. - Note that the validity of the pointer is very limited and usually does - not extend the statement in which it is used. - Hence storing the pointer in a variable ( -\begin_inset Quotes eld -\end_inset - - -\family typewriter -const char *p = wxtu8(s); -\family default - -\begin_inset Quotes erd -\end_inset - -) will make -\family typewriter -p -\family default - pointing to an invalid region as soon as the assignment is done. -\end_layout - -\begin_layout Part -\start_of_appendix -Appendix -\end_layout - -\begin_layout Standard -\begin_inset CommandInset index_print -LatexCommand printindex -type "idx" -name "Index" -literal "true" - -\end_inset - - -\end_layout - -\end_body -\end_document |