libutils(3)

NAME
Libutils is a library of useful routines

SYNOPSIS

#include <util.h>
#include <dstring.h>
#include <lists.h>

cc ... -lutils

INTRODUCTION
Libutils contains a set of commonly-used routines which fall into the following classes:

•   enhanced memory management

•   file operations: path search, loading, mapping

•   common lexical parsing

•   dynamic string manipulation

•   generic lists manipulation

util.c
This file contains various routines for file handling, string tokenizing, memory management etc

  Declarations in util.h

Macro CATCH

#define CATCH() (setjmp(*get_error_buf()))

a macro to set a checkpoint where control is transferred to for a registered error handler. register_error_handler Standard restrictions on use of setjmp(3) do apply.

Macro ALLOC, FREE

#define ALLOC(type) (alloc_chunk(sizeof(type)))
#define FREE(p)    (free_chunk((p), sizeof(*(p))))

Wrapper for alloc_chunk, free_chunk

Structure mapping

typedef struct mapping
{
    void *data;
    long len;
    int hfile;
    int really_mapped;
} mapping;

The structure for memory-mapped files. You can safely use its fields, but don’t ever try to modify them directly. See map_file

•   data: a pointer to mapped or loaded file contents.

•   len: the length of the file

•   hfile: file handle returned by open(2)

•   really_mapped: 1 if real mapping is used; 0 if emulated

Type ff_ioproc_t

typedef void *(*ff_ioproc_t)(const char *name);

The type of a function to open/create files found by find_filename

RETURNS:
    opaque data passed to the caller of find_filename

Structure table_t

typedef struct table_t
{
    char *key;
    void *data;
} table_t;

Generic sequential-access table type for lookup_table. Fields have obvious meaning.

Macro NUMOFITEMS

#define NUMOFITEMS(array) (sizeof(array) / sizeof(*(array)))

RETURNS:
    the number of items in a given array

Macro ENDOF

#define ENDOF(array) ((array) + NUMOFITEMS(array))

RETURNS:
    a pointer to the place right behind the next item of an array

  Miscellaneous functions

Function libutils_version

const char *libutils_version(void) ;

RETURNS:
    the version of libutils e. g. 0.7.15a

Function libutils_srcdate

const char *libutils_srcdate(void) ;

RETURNS:
    the modification date of original source tree as YYYY/MM/DD

Function set_line_no

int set_line_no(int newnl) ;

Sets the current line number for parsing routines to newl, if it is non-negative

RETURNS:
    the previous line number

Function strupr

void strupr(char *str);

Converts str to upper case in-place.

NOTE:
    Incompatible with common DOS strupr – the latter returns char *

Function setenv

int setenv(const char *name, const char *value, int overwrite);

Emulates setenv(3) if it is not found in the standard library. Not present otherwise.

Function filelength

off_t filelength(int fd);

RETURNS:
    the length of the file addressed by fh handle; -1 in case of an error

Function isnamesym

int isnamesym(int ch);

RETURNS:
    1 if ch is a valid XML name character (letter, digit, hyphen, underscore or colon); 0 otherwise

Function isplainnamesym

int isplainnamesym(int ch);

RETURNS:
    1 if isnamesym(ch) != 0 and ch is not a colon

Function versioncmp

int versioncmp(const char *ver1, const char *ver2);

Compares two strings as version designators. They should have the following structure: xx[.yy]*(-?suffix)?. Suffix may be a alphanumeric modifier or a special suffix. Special suffixes are the following (in the order they’re compared):

•   alpha

•   beta

•   pre[0-9]*

•   final

RETURNS:
    negative value if ver1 < ver2, 0 if they are equal, positive value otherwise

Function translate_cvs_date

const char *translate_cvs_date(const char *date);

A very peculiar function used to translate CVS-supplied date ($Date: 2002/12/09 10:19:39 $ into YYYY/MM/DD. You’re unlikely to use this function.

NOTE:
    this function may cause buffer overflow

  Error handling functions

Function register_error_handler

void register_error_handler(void *arg);

Registers a new error handler associated with data pointed by arg

Function unwind_error

void unwind_error(void);

Deletes the most recently registered error handler. Makes the previous handler (if present) active.

Function get_error_buf

jmp_buf *get_error_buf(void);

RETURNS:
    the point to pass control to of the current error handler

ERROR:
    No error handlers registered

Function get_eh_data

void *get_eh_data(void);

RETURNS:
    the associated data of the current error handler

ERROR:
    No error handlers registered

Function get_error_desc

char *get_error_desc(void);

RETURNS:
    a pointer to static area holding the error description produced by recover_error.

Function set_current_filename

char *set_current_filename(char *fname);

If fname is not NULL, sets the current filename for error messages to fname

RETURNS:
    the previous filename

Function print_error_msg

void print_error_msg(const char *fmt, ...);

formats an error message a la printf(3) and prints it to stderr followed by a new line. If the current line number and filename are defined they are printed in front of a message.

NOTE:
    If vfprintf(3) is not present in the standard library, the format string itself is printed.

  If there are registered error handlers, passes control where the active handler
tells us. An error message is formatted according to fmt and put into a static area accessed by get_error_desc.

Otherwise error message is printed as if by print_error_msg, and the program terminates

NOTE:
    If the system has not vsnprintf(3) but has vsprintf(3), buffer overflow may occur. If none are present, the format string itself is copied.

Function fatal_error

void fatal_error(const char *fmt, ...);

Prints an error message as if by print_error_msg and terminates the program

Function warning

void warning(const char *fmt, ...);

Like print_error_msg but issues warning: between line number and the message itself

  Safe memory allocation functions
The functions below are equivalent to corresponding standard functions, but they call recover_error in case of memory lack and never return NULL

Function xmalloc

void *xmalloc(size_t size);

Function xcalloc

void *xcalloc(size_t n, size_t size);

Function xrealloc

void *xrealloc(void *addr, size_t news);

Function xstrdup

char *xstrdup(const char *src);

If strdup(3) is not in the standard library, implements it.

  Chunk-based memory allocation
These functions maintain lists of chunks of a given size. On request, a chunk from a list is reused. If there is no chunks left, new one is allocated and zeroed. When freed, a chunk is returned to a list. The maximal size of a chunk is 16385 * sizeof(void *) - 1 which is 65539 on 32-bit machines. Sizes of chunks less than 257 * sizeof(void *) (1028) are rounded up to sizeof(void *) boundary, others are rounded to 1K boundary

Function alloc_chunk

void *alloc_chunk(int size);

Function free_chunk

void free_chunk(void *chunk, int size);

NOTE:
    explicit size, since the function has no other means to detect it

Function reset_free_chunks

void reset_free_chunks(void);

Reclaims all the memory kept in chunks. You will rarely need to call this function

  Safe file management functions
They are equvalents of corresponding standard functions, but call recover_error and never return invalid values.

Function xfopen

FILE *xfopen(const char *name, const char *mode);

Function xopen

int xopen(const char *name, int mode, int rights);

  File loading functions

Function find_filename

void *find_filename(const char *name, const char *path, const char *defext,
    void *(*ioproc)(const char *name),    void *(crproc)(const char *name)    );

Tries to find name.

•   name: base filename

•   path: colon-separated list of directories where

•   name: is searched if it does not contain an explicit directory reference

•   defext: slash-separated list of extensions which are tried if name has no extension. Period is inserted if necessary.

•   ioproc: routine called when a file is found. Its value is returned. If it is NULL, the resulting filename is returned

•   crproc: routine called when a file is not found. Its value is returned, or NULL if it is NULL

Function load_file

char *load_file(const char *name, const char *path, const char *defext);

Finds a file via find_filename and loads it into memory.

ERROR:
    can’t locate name

RETURNS:
    a pointer to allocated buffer

Function imap_file

void *imap_file(const char *name);

Tries to map a file into memory for reading. If mapping fails or is not implemented on the system, loads the file

RETURNS:
    pointer to mapping

NOTE:
    In general, you’d better call map_file

Function map_file

mapping *map_file(const char *name, const char *path, const char *defext);

Like load_file, but first tries to map it, loads if mapping fails

Function delete_mapping

void delete_mapping(mapping *map);

Unmaps a file and frees all the resources allocated by imap_file

Function is_map_eof

int is_map_eof(mapping *map, const char *pos);

RETURNS:
    1 if pos points to the end of mapped area

  Common parsing functions

Function skip_spaces

void skip_spaces(const char *start, char **end);

Skips all the space characters and comments in an input string start. A comment starts with #, ends with a newline. A pointer to the first non-space character is stored into end. Line number is incremented as necessary.

NOTE:
    Comment-introducing character may be changed by assigning to util_comment_character variable

Function skip_spaces_nc

void skip_spaces_nc(const char *start, char **end);

Like skip_spaces, but doesn’t recognize comments

Function parse_single_char

int parse_single_char(const char *start, char **end);

Gets the first character of start recognizing C-style escape sequences. In addition, \e denotes ESC (code 27). A pointer to the next character is stored into end

RETURNS:
    a character code

NOTE:
    end may be NULL

Function parse_char

int parse_char(const char *start, char **end);

Parses a character constant like in C. The character pointed at by start is taken as a delimiter. Multicharacter constants are treated in a bigendian manner, i. e. the first character will occupy the most significant byte. A pointer to the character following the constant will be stored into end

RETURNS:
    the value of a constant

NOTE:
    end may be NULL

Function parse_string

char *parse_string(const char *start, char **end);

Parses a C-like string. The character pointed at by start is taken as a delimiter. A pointer to the character following the string is be stored into end

RETURNS:
    a parsed string

NOTE:
    The returned value is overwritten in a sequential call to parse_string and you shouldn’t try to free it

NOTE:
    end may be NULL

Function parse_id

char *parse_id(const char *start, char **end);

Parses an identifier – a token consisting of characters for which isnamesym is true. Starting point is at start, the first non-id character is stored into end.

RETURNS:
    a parsed identifier

NOTE:
    See the note of parse_string

NOTE:
    end may be NULL

Function parse_plain_id

char *parse_plain_id(const char *start, char **end);

Like parse_id, but parses a plain identifer, i. e. which doesn’t contain colons

Function parse_num_token

int parse_num_token(const char *start, char **end);

Parses a numerical token which is either a number in a form acceptable by strtoul(3) or a character constant acceptable by parse_char delimited by an apostrophe. Parsing starts at start, a pointer to the following character is stored into end

RETURNS:
    numerical value of a token

NOTE:
    end may be NULL

Function skip_ifs

void skip_ifs(const char *start, char **end, int else_flag);

Used to skip a block of text starting with start until a matching .endif. A pointer to the text following .endif is stored into end. Nested .if* are properly handled.

•   else_flag: if non-zero, .else behaves like .endif

NOTE:
    end must be non-NULL

NOTE:
    A directive may start with two dots as well

NOTE:
    A period may be replaced by another character by assigning to util_directive_character

  Generic table lookup

Function lookup_table

void *lookup_table(table_t *table, const char *key);

Looks up for a key in table (table_t)

NOTE:
    table must be a NULL-terminated array

RETURNS:
    table_t.data field if an item is found, NULL otherwise

Function lookup_name

int lookup_name(char **names, const char *key);

Looks up for a key in a table of names

NOTE:
    names must be a NULL-terminated array

RETURNS:
    zero-base index of key within names, a negative value if not found

  atexit enhancement

Function enh_atexit

int enh_atexit(void (*func)(void));

Registers a new atexit handler func. Unlike standard atexit(3), there is no limit on the number of handlers.

Registered handlers are executed in the order of registration.

RETURNS:
    0 if success, negative value if error

dstring.c
This file contains routines to maninpulate dynamic strings (dstrings)

  Definitions in dstring.h

Structure dstring

typedef struct dstring
{
    int curlen;
    int maxlen;
    int fixcnt;
    char *str;
    struct dstring *next;
    struct dstring *prev;
} dstring;

The handler type for dstrings. Fields of this structure should never be accessed directly. Moreover, dstring objects should only be created/destroyed with special functions (i.e. no over duration except dynamic)

Types ds_predicate_t, ds_iterator_t

typedef int (*ds_predicate_t)(int, int, void *);

typedef int (*ds_iterator_t)(int, void *);

Function types for search/comparison and string transformation resp.

Macro DS_BODY

#define DS_BODY(ds) ((ds)->str)

Gives direct access to the contents of a dstring

NOTE:
    Read-only access is recommended, though currently there is no formal restriction on modification

Enumeration dsmu_params

enum dsmu_params { dsmu_reserved, dsmu_unfixed, dsmu_unfixed_cnt,
                    dsmu_squeeze, dsmu_lastsqueeze_mem,
                    dsmu_lastsqueeze_cnt
                };

Various memory usage paramters. Undocumented until somebody really makes use of them :).

  Controlling variables

Variable ds_reserved_mem_limit

int ds_reserved_mem_limit = 1024 * 1024;

Contains the limit of memory occupied by free strings

Variable ds_unfix_mem_limit

int ds_unfix_mem_limit = 256 * 1024;

Contains the limit of memory occupied by unfixed strings which triggers garbage collecting

Variable ds_unfix_max_cnt

int ds_unfix_max_cnt = 8192;

Contains the maximum number of unfixed strings which triggers garbage collecting.

Function ds_create

dstring *ds_create(const char *src);

RETURNS:
    an unfixed dstring containing a copy of src

Function ds_createch

dstring *ds_createch(int ch);

RETURNS:
    an unfixed dstring which contains a single ch

Function ds_fromint

dstring *ds_fromint(long val, int base, int len);

RETURNS:
    an unfixed dstring which contains a string representation of val using base as a conversion base (2 ≤ base ≤ 36).

•   len: if len > 0, the string is right-padded by spaces to len; if len < 0, the string is left-padded to |len|.

Function ds_fromuint

dstring *ds_fromuint(unsigned long val, int base, int len);

like ds_fromint, but accepts an unsigned value

Function ds_fromllint

dstring *ds_fromllint(long long val, int base, int len);

Like ds_fromint, but val is of type long long

Function ds_fromullint

dstring *ds_fromullint(unsigned long long val, int base, int len);

Like ds_fromint, but val is of type unsigned long long

Function ds_fromptr

dstring *ds_fromptr(void *ptr);

RETURNS:
    a (opaque) string representation of a pointer

Function ds_dbl_set_precision

int ds_dbl_set_precision(int precision);

sets the precision for floating-point conversions; initial value is maximal possible precision. If precision is negative, the precision does not change.

RETURNS:
    the old precision

Function ds_fromdouble

dstring *ds_fromdouble(double d);

RETURNS:
    a string representation of a floating-point value

Function ds_checkvalid

dstring *ds_checkvalid(dstring *src);

checks whether a dstring handler is valid; produces a fatal error if not

RETURNS:
    its arg

Function ds_fix

dstring *ds_fix(dstring *src);

fixes a given dstring so it cannot be squeezed

RETURNS:
    its arg

Function ds_unfix

dstring *ds_unfix(dstring *src);

unfixes a given dstring. There may be many calls to ds_fix for the same dstring; a counter is maintained internally, so only the last ds_unfix will actually do the job. If a dstring is not fixed, nothing happens

RETURNS:
    its arg

Function ds_destroy

void ds_destroy(dstring *src);

Unfixes a dstring and if it is really unfixed, schedules it for further reuse.

Function ds_compact

dstring *ds_compact(dstring *src);

Compacts the space ocuupied by a dstring, removed any reserved bytes behind the last character

RETURNS:
    its arg

Function ds_squeeze

void ds_squeeze(int unused);

Performs squeezing by collecting all unfixed strings and scheduling them for reuse

NOTE:
    Squeezing does not necessary take places, but only if some memory usage limits are reached. So it is performance-safe to call ds_squeeze several times.

NOTE:
    The function should be called at the topmost level possible, so that there might not be unfixed, but really used dstrings

Function ds_memory_usage

int ds_memory_usage(int param);

RETURNS:
    a given parameter for memory usage

Function ds_length

int ds_length(dstring *src) ;

RETURNS:
    the length of a dstring

Function ds_isempty

int ds_isempty(dstring *src) ;

RETURNS:
    1 if a dstring is empty, 0 otherwise

Function ds_copy

dstring *ds_copy(dstring *src);

RETURNS:
    an unfixed copy of a given dstring

Function ds_assign

dstring *ds_assign(dstring *dest, dstring *src);

Replaces the content of dest with that of src. The latter is unaffected. If src is NULL, it is treated as an empty dstring

RETURNS:
    dest

Function ds_concat

dstring *ds_concat(dstring *arg1, dstring *arg2);

RETURNS:
    an unfixed concatenation of arg1 and arg2

Function ds_append

dstring *ds_append(dstring *dest, dstring *arg2);

Appends arg2 to dest

RETURNS:
    dest

Function ds_appendstr

dstring *ds_appendstr(dstring *dest, const char *arg2);

Same as the previous, but the last argument is a C string

Function ds_appendch

dstring *ds_appendch(dstring *dest, int ch);

Same as the previous, but the last argument is a single character

Function ds_substr

dstring *ds_substr(dstring *src, int start, int len);

RETURNS:
    an unfixed substring of src starting with start of the length len

NOTE:
    The function returns a copy, so changing it will not affect src; use ds_setsubstr for that purpose

NOTE:
    If start and/or len are too high, they are adjusted

Function ds_setsubstr

dstring *ds_setsubstr(dstring *dest, int start, int len, dstring *arg);

Replace a substring within dest starting with start of the length len with arg

RETURNS:
    dest

NOTE:
    If start and/or len are too high, they are adjusted

Function ds_isprefix

int ds_isprefix(dstring *base, dstring *prefix);

RETURNS:
    1 if base starts with prefix

Function ds_issuffix

int ds_issuffix(dstring *base, dstring *suffix);

RETURNS:
    1 if base ends with suffix

Function ds_commonprefix

dstring *ds_commonprefix(dstring *str1, dstring *str2);

RETURNS:
    the longest common prefix of str1 and str2 (may be empty)

Function ds_std_predicate

int ds_std_predicate(int ch, int ch1, void *extra);

A standard byte-to-byte comparison predicate

Function ds_p_casefold

int ds_p_casefold(int ch, int ch1, void *extra);

A case-folding comparison predicate

Function ds_find

int ds_find(dstring *dest, int startpos, dstring *substr, ds_predicate_t userp, void *extra);

RETURNS:
    a position of the first occurrence of substr within dest starting with startpos using userp for comparison. If userp is NULL, ds_std_predicate is assumed. If substr is not found, a negative value is returned

Function ds_rfind

int ds_rfind(dstring *dest, dstring *substr, ds_predicate_t userp, void *extra);

Like ds_find, but finds the last occurrence of substr

NOTE:
    This function has no startpos

Function ds_compare

int ds_compare(dstring *arg1, dstring *arg2, ds_predicate_t userp, void *extra);

Analogous to strcmp(3) for dstrings. Uses userp for comparison; if it is NULL, ds_std_predicate is assumed.

Function ds_comparestr

int ds_comparestr(dstring *arg1, const char *arg2, ds_predicate_t userp, void *extra);

Like the previous, but arg2 is a C string

Function ds_collate

int ds_collate(dstring *arg1, dstring *arg2);

Compares two dstrings according to the current locale. See strcoll(3)

Function ds_tocollate

dstring *ds_tocollate(dstring *arg1);

RETURNS:
    the result of strxfrm(3) on a dstring

Function ds_reversip

dstring *ds_reversip(dstring *src);

Reverses its argument in-place

Function ds_reverse

dstring *ds_reverse(dstring *src);

Like the previous, but operates on a copy of the argument

Functions ds_t_toupper, ds_t_tolower

int ds_t_toupper(int ch, void *extra);

int ds_t_tolower(int ch, void *extra);

Standard transform functions to convert cases

Function ds_transform

dstring *ds_transform(dstring *src, ds_iterator_t func, int inplace, void *extra);

Applies a func to each character in src. The result is stored in src or in its copy depending of inplace

Function ds_foreach

void ds_foreach(dstring *src, ds_iterator_t func, void *extra);

Applies a func to each character of src. Unlike the previous, src is never affected

lists.c
This file contains routines for generic list maninpulation.

  Declarations in ’lists.h’

Types baselist_t, list_t

typedef struct baselist_t
{
    struct baselist_t *next;
} baselist_t;

typedef void *list_t;

Basic types for list routines.

Type list_predicate_t

typedef int (*list_predicate_t)(void *base, void *key);

The type for generic list testing function. base points to the current item. The function should return 1 when base is `equal’ to key, 0 otherwise

Type list_iterator_t

typedef void (*list_iterator_t)(void *base, void *extra);

The type for generic list iteration function. base is the same as in the previous, extra is a user-supplied data

Type list_destroy_t

typedef void (*list_destroy_t)(void *base);

The type for list content destruction function. base is the same as in the previous.

NOTE:
    The function should not deallocate memory for base.

Macro DEFLIST

#define DEFLIST(name, body) typedef struct name { \
                        struct name *next; \
                        body \
                        } name

A macro to declare structures compatible with baselist_t

Macro list_next

#define list_next(l) ((list_t)(((baselist_t *)(l))->next))

A generic macro to get the tail of a list

Function list_free

void list_free(list_t item, list_destroy_t destroy, int size);

Destroys a single item of a list

•   item: the pointer to a given item

•   destroy: user-supplied destruction function, may be NULL

•   size: actual size of an item

Function list_add

list_t list_add(list_t base, list_t new);

Prepends an item base to a list new

NOTE:
    both may be NULLs

RETURNS:
    a new list

Function list_find

list_t list_find(list_t base, void *key, list_predicate_t predicate);

Finds the first item in a list matching key according to predicate

RETURNS:
    the item found, or NULL if none

Function list_length

int list_length(list_t l);

RETURNS:
    the length of a list

Function list_nth

list_t list_nth(list_t l, int n);

RETURNS:
    nth item of a list (starting with 0), NULL if the list contains less than n + 1 items

Function list_foreach

void list_foreach(list_t base, list_iterator_t iterator, void *extra);

Executes iterator for each item in base

Function list_insert

list_t list_insert(list_t base, void *after, list_t new, list_predicate_t predicate);

Inserts a new item into base list after an item matching after. If no such item is found, no insertion is performed. If after is NULL, the function is equivalent to list_add

RETURNS:
    a new list

Function list_append

list_t list_append(list_t base, list_t new);

Appends a new item to the list

RETURNS:
    base

Function list_pop

list_t list_pop(list_t base, list_destroy_t destroy, int elsize);

Discards the head of the list, calling list_free on it

RETURNS:
    the tail of the list

Function list_remove

list_t list_remove(list_t base, void *key, list_predicate_t predicate, list_destroy_t destroy, int elsize);

Removes the first item matching key, calling list_free on it. If no such item is found, nothing happens

RETURNS:
    a new list

Function list_remove_all

list_t list_remove_all(list_t base, void *key, list_predicate_t predicate, list_destroy_t destroy, int elsize);

Like the previous, but removes all the items matching key

Function list_delete

void list_delete(list_t base, list_destroy_t destroy, int elsize);

Destroys all the items of the list, calling list_free on them.

Function list_reversip

list_t list_reversip(list_t src);

Reverses the order of items in a list without producing a new list

SEE ALSO
atexit(3), open(2), printf(3), setenv(3), setjmp(3), strcmp(3), strcoll(3), strdup(3), strtoul(3), strxfrm(3), vfprintf(3), vsnprintf(3), vsprintf(3)

AUTHOR
Artem V. Andreev

COPYRIGHT
Copyright © 2001-2002, Artem V. Andreev This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.