.TH "libutils" "3" "(Fri May 23 19:29:21 2003)" .\" Artem V. Andreev .SH NAME Libutils is a library of useful routines .SH SYNOPSIS .P .br #include\ .br #include\ .br #include\ .br .P .BR cc .BR \&\.\&\.\&\. .BR \-lutils .SH INTRODUCTION Libutils contains a set of commonly\-used routines which fall into the following classes: .PD 0 .IP \(bu 4 .PD enhanced memory management .PD 0 .IP \(bu 4 .PD file operations: path search, loading, mapping .PD 0 .IP \(bu 4 .PD common lexical parsing .PD 0 .IP \(bu 4 .PD dynamic string manipulation .PD 0 .IP \(bu 4 .PD generic lists manipulation .IR "" .SH util\&\.c This file contains various routines for file handling, string tokenizing, memory management etc .P .SS Declarations in util\&\.h .P .TP .B Macro CATCH .P #define\ CATCH()\ (setjmp(*get_error_buf())) .br .P a macro to set a checkpoint where control is transferred to for a registered error handler\&\. .IR register_error_handler Standard restrictions on use of .IR setjmp(3) do apply\&\. .P .TP .B Macro ALLOC, FREE .P #define\ ALLOC(type)\ (alloc_chunk(sizeof(type))) .br #define\ FREE(p) (free_chunk((p),\ sizeof(*(p)))) .br .P Wrapper for .IR alloc_chunk , .IR free_chunk .P .TP .B Structure mapping .P typedef\ struct\ mapping .br { .br void\ *data; .br long\ len; .br int\ hfile; .br int\ really_mapped; .br }\ mapping; .P The structure for memory\-mapped files\&\. You can safely use its fields, but don\(cqt ever try to modify them directly\&\. See .IR map_file .PD 0 .IP \(bu 4 .PD .IR data : a pointer to mapped or loaded file contents\&\. .PD 0 .IP \(bu 4 .PD .IR len : the length of the file .PD 0 .IP \(bu 4 .PD .IR hfile : file handle returned by .IR open(2) .PD 0 .IP \(bu 4 .PD .IR really_mapped : 1 if real mapping is used; 0 if emulated .P .TP .B Type ff_ioproc_t .P typedef\ void\ *(*ff_ioproc_t)(const\ char\ *name); .P The type of a function to open/create files found by .IR find_filename Returns opaque data passed to the caller of .IR find_filename .P .TP .B Structure table_t .P typedef\ struct\ table_t .br { .br char\ *key; .br void\ *data; .br }\ table_t; .P Generic sequential\-access table type for .IR lookup_table \&\. Fields have obvious meaning\&\. .P .TP .B Macro NUMOFITEMS .P #define\ NUMOFITEMS(array)\ (sizeof(array)\ /\ sizeof(*(array))) .br .P Returns the number of items in a given array .P .TP .B Macro ENDOF .P #define\ ENDOF(array)\ ((array)\ +\ NUMOFITEMS(array)) .br .P Returns a pointer to the place right behind the next item of an array .SS Miscellaneous functions .P .TP .B Function libutils_version .P const\ char\ *libutils_version(void)\ ; .P Returns the version of .IR libutils e\&\. g\&\. .BR 0\&\.7\&\.15a .P .TP .B Function libutils_srcdate .P const\ char\ *libutils_srcdate(void)\ ; .P Returns the modification date of original source tree as .BR YYYY/MM/DD .P .TP .B Function set_line_no .P int\ set_line_no(int\ newnl)\ ; .P Sets the current line number for parsing routines to .IR newl , if it is non\-negative Returns the previous line number .P .TP .B Function strupr .P void\ strupr(char\ *str); .P Converts .IR str to upper case in\-place\&\. .IP "Note:" 10 Incompatible with common DOS strupr \(en the latter returns char * .P .TP .B Function setenv .P int\ setenv(const\ char\ *name,\ const\ char\ *value,\ int\ overwrite); .P Emulates .IR setenv(3) if it is not found in the standard library\&\. Not present otherwise\&\. .P .TP .B Function filelength .P off_t\ filelength(int\ fd); .P Returns the length of the file addressed by .IR fh handle; \-1 in case of an error .P .TP .B Function isnamesym .P int\ isnamesym(int\ ch); .P Returns 1 if .IR ch is a valid XML name character (letter, digit, hyphen, underscore or colon); 0 otherwise .P .TP .B Function isplainnamesym .P int\ isplainnamesym(int\ ch); .P Returns 1 if isnamesym(ch) != 0 and .IR ch is not a colon .P .TP .B Function versioncmp .P int\ versioncmp(const\ char\ *ver1,\ const\ char\ *ver2); .P Compares two strings as version designators\&\. They should have the following structure: .BR xx[\&\.yy]*(\-?suffix)? \&\. Suffix may be a alphanumeric modifier or a special suffix\&\. Special suffixes are the following (in the order they\(cqre compared): .PD 0 .IP \(bu 4 .PD alpha .PD 0 .IP \(bu 4 .PD beta .PD 0 .IP \(bu 4 .PD pre[0\-9]* .PD 0 .IP \(bu 4 .PD final Returns negative value if .IR ver1 < .IR ver2 , 0 if they are equal, positive value otherwise .P .TP .B Function translate_cvs_date .P const\ char\ *translate_cvs_date(const\ char\ *date); .P A very peculiar function used to translate CVS\-supplied date ($Date: 2003/05/18 21:58:26 $ into YYYY/MM/DD\&\. You\(cqre unlikely to use this function\&\. .IP "Note:" 10 this function may cause buffer overflow .SS Error handling functions .P .TP .B Function register_error_handler .P void\ register_error_handler(void\ *arg); .P Registers a new error handler associated with data pointed by .IR arg .P .TP .B Function unwind_error .P void\ unwind_error(void); .P Deletes the most recently registered error handler\&\. Makes the previous handler (if present) active\&\. .P .TP .B Function get_error_buf .P jmp_buf\ *get_error_buf(void); .P Returns the point to pass control to of the current error handler .IP "Error:" 10 .BR No .BR error .BR handlers .BR registered .P .P .TP .B Function get_eh_data .P void\ *get_eh_data(void); .P Returns the associated data of the current error handler .IP "Error:" 10 .BR No .BR error .BR handlers .BR registered .P .P .TP .B Function get_error_desc .P char\ *get_error_desc(void); .P Returns a pointer to static area holding the error description produced by .IR recover_error \&\. .P .TP .B Function set_current_filename .P char\ *set_current_filename(char\ *fname); .P If .IR fname is not NULL, sets the current filename for error messages to .IR fname Returns the previous filename .P .TP .B Function print_error_msg .P void\ print_error_msg(const\ char\ *fmt,\ \&\.\&\.\&\.); .P formats an error message a la .IR printf(3) and prints it to .IR stderr followed by a new line\&\. If the current line number and filename are defined they are printed in front of a message\&\. .IP "Note:" 10 If .IR vfprintf(3) is not present in the standard library, the format string itself is printed\&\. .P .TP .B Function recover_error .P void\ recover_error(const\ char\ *fmt,\ \&\.\&\.\&\.); .P If there are registered error handlers, passes control where the active handler tells us\&\. An error message is formatted according to .IR fmt and put into a static area accessed by .IR get_error_desc \&\. .P Otherwise error message is printed as if by .IR print_error_msg , and the program terminates .IP "Note:" 10 If the system has not .IR vsnprintf(3) but has .IR vsprintf(3) , buffer overflow may occur\&\. If none are present, the format string itself is copied\&\. .P .TP .B Function fatal_error .P void\ fatal_error(const\ char\ *fmt,\ \&\.\&\.\&\.); .P Prints an error message as if by .IR print_error_msg and terminates the program .P .TP .B Function warning .P void\ warning(const\ char\ *fmt,\ \&\.\&\.\&\.); .P Like .IR print_error_msg but issues .BR warning: between line number and the message itself .SS Safe memory allocation functions The functions below are equivalent to corresponding standard functions, but they call .IR recover_error in case of memory lack and never return NULL .P .TP .B Function xmalloc .P void\ *xmalloc(size_t\ size); .P .TP .B Function xcalloc .P void\ *xcalloc(size_t\ n,\ size_t\ size); .P .TP .B Function xrealloc .P void\ *xrealloc(void\ *addr,\ size_t\ news); .P .TP .B Function xstrdup .P char\ *xstrdup(const\ char\ *src); .P If .IR strdup(3) is not in the standard library, implements it\&\. .SS Chunk\-based memory allocation These functions maintain lists of .IR 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 .P .TP .B Function alloc_chunk .P void\ *alloc_chunk(int\ size); .P .TP .B Function free_chunk .P void\ free_chunk(void\ *chunk,\ int\ size); .IP "Note:" 10 explicit .IR size , since the function has no other means to detect it .P .TP .B Function reset_free_chunks .P void\ reset_free_chunks(void); .P Reclaims all the memory kept in chunks\&\. You will rarely need to call this function .SS Safe file management functions They are equvalents of corresponding standard functions, but call .IR recover_error and never return invalid values\&\. .P .TP .B Function xfopen .P FILE\ *xfopen(const\ char\ *name,\ const\ char\ *mode); .P .TP .B Function xopen .P int\ xopen(const\ char\ *name,\ int\ mode,\ int\ rights); .SS File loading functions .P .TP .B Function find_filename .P void\ *find_filename(const\ char\ *name,\ const\ char\ *path,\ const\ char\ *defext,\ .br void\ *(*ioproc)(const\ char\ *name), void\ *(crproc)(const\ char\ *name) ); .P Tries to find .IR name \&\. .PD 0 .IP \(bu 4 .PD .IR name : base filename .PD 0 .IP \(bu 4 .PD .IR path : colon\-separated list of directories where .PD 0 .IP \(bu 4 .PD .IR name : is searched if it does not contain an explicit directory reference .PD 0 .IP \(bu 4 .PD .IR defext : slash\-separated list of extensions which are tried if .IR name has no extension\&\. Period is inserted if necessary\&\. .PD 0 .IP \(bu 4 .PD .IR ioproc : routine called when a file is found\&\. Its value is returned\&\. If it is NULL, the resulting filename is returned .PD 0 .IP \(bu 4 .PD .IR crproc : routine called when a file is not found\&\. Its value is returned, or NULL if it is NULL .P .TP .B Function load_file .P char\ *load_file(const\ char\ *name,\ const\ char\ *path,\ const\ char\ *defext); .P Finds a file via .IR find_filename and loads it into memory\&\. .IP "Error:" 10 .BR can\(cqt .BR locate .BR name .P Returns a pointer to allocated buffer .P .TP .B Function imap_file .P void\ *imap_file(const\ char\ *name); .P Tries to map a file into memory .IR for .IR reading \&\. If mapping fails or is not implemented on the system, loads the file Returns pointer to .IR mapping .IP "Note:" 10 In general, you\(cqd better call .IR map_file .P .TP .B Function map_file .P mapping\ *map_file(const\ char\ *name,\ const\ char\ *path,\ const\ char\ *defext); .P Like .IR load_file , but first tries to map it, loads if mapping fails .P .TP .B Function delete_mapping .P void\ delete_mapping(mapping\ *map); .P Unmaps a file and frees all the resources allocated by .IR imap_file .P .TP .B Function is_map_eof .P int\ is_map_eof(mapping\ *map,\ const\ char\ *pos); .P Returns 1 if .IR pos points to the end of mapped area .SS Common parsing functions .P .TP .B Function skip_spaces .P void\ skip_spaces(const\ char\ *start,\ char\ **end); .P Skips all the space characters and comments in an input string .IR start \&\. A comment starts with .IR # , ends with a newline\&\. A pointer to the first non\-space character is stored into .IR end \&\. Line number is incremented as necessary\&\. .IP "Note:" 10 Comment\-introducing character may be changed by assigning to .IR util_comment_character variable .P .TP .B Function skip_spaces_nc .P void\ skip_spaces_nc(const\ char\ *start,\ char\ **end); .P Like .IR skip_spaces , but doesn\(cqt recognize comments .P .TP .B Function parse_single_char .P int\ parse_single_char(const\ char\ *start,\ char\ **end); .P Gets the first character of .IR start recognizing C\-style escape sequences\&\. In addition, .IR \(rse denotes ESC (code 27)\&\. A pointer to the next character is stored into .IR end Returns a character code .IP "Note:" 10 .IR end may be NULL .P .TP .B Function parse_char .P int\ parse_char(const\ char\ *start,\ char\ **end); .P Parses a character constant like in C\&\. The character pointed at by .IR 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 .IR end Returns the value of a constant .IP "Note:" 10 .IR end may be NULL .P .TP .B Function parse_string .P char\ *parse_string(const\ char\ *start,\ char\ **end); .P Parses a C\-like string\&\. The character pointed at by .IR start is taken as a delimiter\&\. A pointer to the character following the string is be stored into .IR end Returns a parsed string .IP "Note:" 10 The returned value is overwritten in a sequential call to parse_string and you shouldn\(cqt try to free it .IP "Note:" 10 .IR end may be NULL .P .TP .B Function parse_id .P char\ *parse_id(const\ char\ *start,\ char\ **end); .P Parses an .IR identifier \(en a token consisting of characters for which .IR isnamesym is true\&\. Starting point is at .IR start , the first non\-id character is stored into .IR end \&\. Returns a parsed identifier .IP "Note:" 10 See the note of .IR parse_string .IP "Note:" 10 .IR end may be NULL .P .TP .B Function parse_plain_id .P char\ *parse_plain_id(const\ char\ *start,\ char\ **end); .P Like .IR parse_id , but parses a .IR plain .IR identifer , i\&\. e\&\. which doesn\(cqt contain colons .P .TP .B Function parse_num_token .P int\ parse_num_token(const\ char\ *start,\ char\ **end); .P Parses a .IR numerical .IR token which is either a number in a form acceptable by .IR strtol(3) or a character constant acceptable by .IR parse_char delimited by an apostrophe\&\. Parsing starts at .IR start , a pointer to the following character is stored into .IR end Returns numerical value of a token .IP "Note:" 10 .IR end may be NULL .P .TP .B Function skip_ifs .P void\ skip_ifs(const\ char\ *start,\ char\ **end,\ int\ else_flag); .P Used to skip a block of text starting with .IR start until a matching .IR \&\.endif \&\. A pointer to the text following .IR \&\.endif is stored into .IR end \&\. Nested .IR \&\.if* are properly handled\&\. .PD 0 .IP \(bu 4 .PD .IR else_flag : if non\-zero, .IR \&\.else behaves like .IR \&\.endif .IP "Note:" 10 .IR end must be non\-NULL .IP "Note:" 10 A directive may start with two dots as well .IP "Note:" 10 A period may be replaced by another character by assigning to .IR util_directive_character .SS Generic table lookup .P .TP .B Function lookup_table .P void\ *lookup_table(table_t\ *table,\ const\ char\ *key); .P Looks up for a .IR key in .IR table .RI ( table_t ) .IP "Note:" 10 .IR table must be a NULL\-terminated array Returns .IR table_t\&\.data field if an item is found, NULL otherwise .P .TP .B Function lookup_name .P int\ lookup_name(char\ **names,\ const\ char\ *key); .P Looks up for a .IR key in a table of .IR names .IP "Note:" 10 .IR names must be a NULL\-terminated array Returns zero\-base index of .IR key within .IR names , a negative value if not found .SS atexit enhancement .P .TP .B Function enh_atexit .P int\ enh_atexit(void\ (*func)(void)); .P Registers a new atexit handler .IR func \&\. Unlike standard .IR atexit(3) , there is no limit on the number of handlers\&\. .P Registered handlers are executed in the order of registration\&\. Returns 0 if success, negative value if error .IR "" .SH dstring\&\.c This file contains routines to maninpulate dynamic strings .RI ( dstrings ) .P .SS Definitions in dstring\&\.h .P .TP .B Structure dstring .P typedef\ struct\ dstring .br { .br int\ curlen; .br int\ maxlen; .br int\ fixcnt; .br char\ *str; .br struct\ dstring\ *next; .br struct\ dstring\ *prev; .br }\ dstring; .P 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) .P .TP .B Types ds_predicate_t, ds_iterator_t .P typedef\ int\ (*ds_predicate_t)(int,\ int,\ void\ *); .P typedef\ int\ (*ds_iterator_t)(int,\ void\ *); .P Function types for search/comparison and string transformation resp\&\. .P .TP .B Macro DS_BODY .P #define\ DS_BODY(ds)\ ((ds)\->str) .br .P Gives direct access to the contents of a dstring .IP "Note:" 10 Read\-only access is recommended, though currently there is no formal restriction on modification .P .TP .B Enumeration dsmu_params .P enum\ dsmu_params\ {\ dsmu_reserved,\ dsmu_unfixed,\ dsmu_unfixed_cnt, .br dsmu_squeeze,\ dsmu_lastsqueeze_mem, .br dsmu_lastsqueeze_cnt .br }; .P Various memory usage paramters\&\. Undocumented until somebody really makes use of them :)\&\. .SS Controlling variables .P .TP .B Variable ds_reserved_mem_limit .P int\ ds_reserved_mem_limit\ =\ 1024\ *\ 1024; .P Contains the limit of memory occupied by free strings .P .TP .B Variable ds_unfix_mem_limit .P int\ ds_unfix_mem_limit\ =\ 256\ *\ 1024; .P Contains the limit of memory occupied by unfixed strings which triggers garbage collecting .P .TP .B Variable ds_unfix_max_cnt .P int\ ds_unfix_max_cnt\ =\ 8192; .P Contains the maximum number of unfixed strings which triggers garbage collecting\&\. .SS Functions ** .P .TP .B Function ds_expand .P void\ ds_expand(dstring\ *ds,\ int\ len); .P If a dstring .IR ds \(cqs buffer is smaller than .IR len , expands it adding yet .IR MAXLEN_DELTA \&\. Sets the current length to .IR len .P .TP .B Function ds_create .P dstring\ *ds_create(const\ char\ *src); .P Returns an unfixed dstring containing a copy of .IR src .P .TP .B Function ds_icreate .P dstring\ *ds_icreate(char\ *src,\ int\ len); .P Returns a dstring containing .IR src itself (no copy) .PD 0 .IP \(bu 4 .PD .IR len : is a length of a buffer\&\. It is caller\(cqs responsibility to ensure this is correct\&\. .IP "Note:" 10 .IR src should point to a malloc\(cqed memory\&\. .P .TP .B Function ds_createch .P dstring\ *ds_createch(int\ ch); .P Returns an unfixed dstring which contains a single .IR ch .P .TP .B Function ds_fromint .P dstring\ *ds_fromint(long\ val,\ int\ base,\ int\ len); .P Returns an unfixed dstring which contains a string representation of .IR val using .IR base as a conversion base (2 \(<= base \(<= 36)\&\. .PD 0 .IP \(bu 4 .PD .IR len : if .IR len > 0, the string is right\-padded by spaces to .IR len ; if .IR len < 0, the string is left\-padded to |len|\&\. .P .TP .B Function ds_fromuint .P dstring\ *ds_fromuint(unsigned\ long\ val,\ int\ base,\ int\ len); .P like .IR ds_fromint , but accepts an unsigned value .P .TP .B Function ds_fromllint .P dstring\ *ds_fromllint(long\ long\ val,\ int\ base,\ int\ len); .P Like .IR ds_fromint , but .IR val is of type long long .P .TP .B Function ds_fromullint .P dstring\ *ds_fromullint(unsigned\ long\ long\ val,\ int\ base,\ int\ len); .P Like .IR ds_fromint , but .IR val is of type unsigned long long .P .TP .B Function ds_fromptr .P dstring\ *ds_fromptr(void\ *ptr); .P Returns a (opaque) string representation of a pointer .P .TP .B Function ds_dbl_set_precision .P int\ ds_dbl_set_precision(int\ precision); .P sets the precision for floating\-point conversions; initial value is maximal possible precision\&\. If .IR precision is negative, the precision does not change\&\. Returns the old precision .P .TP .B Function ds_fromdouble .P dstring\ *ds_fromdouble(double\ d); .P Returns a string representation of a floating\-point value .P .TP .B Function ds_checkvalid .P dstring\ *ds_checkvalid(dstring\ *src); .P checks whether a dstring handler is valid; produces a fatal error if not Returns its arg .P .TP .B Function ds_fix .P dstring\ *ds_fix(dstring\ *src); .P fixes a given dstring so it cannot be squeezed Returns its arg .P .TP .B Function ds_unfix .P dstring\ *ds_unfix(dstring\ *src); .P unfixes a given dstring\&\. There may be many calls to .IR 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 .P .TP .B Function ds_destroy .P void\ ds_destroy(dstring\ *src); .P Unfixes a dstring and if it is really unfixed, schedules it for further reuse\&\. .P .TP .B Function ds_compact .P dstring\ *ds_compact(dstring\ *src); .P Compacts the space ocuupied by a dstring, removed any reserved bytes behind the last character Returns its arg .P .TP .B Function ds_squeeze .P void\ ds_squeeze(int\ unused); .P Performs squeezing by collecting all unfixed strings and scheduling them for reuse .IP "Note:" 10 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\&\. .IP "Note:" 10 The function should be called at the topmost level possible, so that there might not be unfixed, but really used dstrings .P .TP .B Function ds_memory_usage .P int\ ds_memory_usage(int\ param); .P Returns a given parameter for memory usage .P .TP .B Function ds_length .P int\ ds_length(dstring\ *src)\ ; .P Returns the length of a dstring .P .TP .B Function ds_isempty .P int\ ds_isempty(dstring\ *src)\ ; .P Returns 1 if a dstring is empty, 0 otherwise .P .TP .B Function ds_copy .P dstring\ *ds_copy(dstring\ *src); .P Returns an unfixed copy of a given dstring .P .TP .B Function ds_assign .P dstring\ *ds_assign(dstring\ *dest,\ dstring\ *src); .P Replaces the content of .IR dest with that of .IR src \&\. The latter is unaffected\&\. If .IR src is NULL, it is treated as an empty dstring Returns .IR dest .P .TP .B Function ds_concat .P dstring\ *ds_concat(dstring\ *arg1,\ dstring\ *arg2); .P Returns an unfixed concatenation of .IR arg1 and .IR arg2 .P .TP .B Function ds_append .P dstring\ *ds_append(dstring\ *dest,\ dstring\ *arg2); .P Appends .IR arg2 to .IR dest Returns .IR dest .P .TP .B Function ds_appendbin .P dstring\ *ds_appendbin(dstring\ *dest,\ dstring\ *arg2); .P Appends .IR arg2 to .IR dest in a way that allows binary zeros inside strings Returns .IR dest .P .TP .B Function ds_appendstr .P dstring\ *ds_appendstr(dstring\ *dest,\ const\ char\ *arg2); .P Same as .IR ds_append , but the last argument is a C string .P .TP .B Function ds_appendstr_bin .P dstring\ *ds_appendstr_bin(dstring\ *dest,\ const\ char\ *arg2,\ int\ len); .P Same as .IR ds_appendbin , but the last argument is a (not necessarily null\-terminated) C string .P .TP .B Function ds_appendch .P dstring\ *ds_appendch(dstring\ *dest,\ int\ ch); .P Same as .IR ds_append , but the last argument is a single character .P .TP .B Function ds_appendch_bin .P dstring\ *ds_appendch_bin(dstring\ *dest,\ int\ ch); .P Same as .IR ds_appendbin , but the last argument is a single character .P .TP .B Function ds_substr .P dstring\ *ds_substr(dstring\ *src,\ int\ start,\ int\ len); .P Returns an unfixed substring of .IR src starting with .IR start of the length .IR len .IP "Note:" 10 The function returns a copy, so changing it will not affect .IR src ; use .IR ds_setsubstr for that purpose .IP "Note:" 10 If .IR start and/or .IR len are too high, they are adjusted .P .TP .B Function ds_setsubstr .P dstring\ *ds_setsubstr(dstring\ *dest,\ int\ start,\ int\ len,\ dstring\ *arg); .P Replace a substring within .IR dest starting with .IR start of the length .IR len with .IR arg Returns .IR dest .IP "Note:" 10 If .IR start and/or .IR len are too high, they are adjusted .P .TP .B Function ds_isprefix .P int\ ds_isprefix(dstring\ *base,\ dstring\ *prefix); .P Returns 1 if .IR base starts with .IR prefix .P .TP .B Function ds_issuffix .P int\ ds_issuffix(dstring\ *base,\ dstring\ *suffix); .P Returns 1 if .IR base ends with .IR suffix .P .TP .B Function ds_commonprefix .P dstring\ *ds_commonprefix(dstring\ *str1,\ dstring\ *str2); .P Returns the longest common prefix of .IR str1 and .IR str2 (may be empty) .P .TP .B Function ds_std_predicate .P int\ ds_std_predicate(int\ ch,\ int\ ch1,\ void\ *extra); .P A standard byte\-to\-byte comparison predicate .P .TP .B Function ds_p_casefold .P int\ ds_p_casefold(int\ ch,\ int\ ch1,\ void\ *extra); .P A case\-folding comparison predicate .P .TP .B Function ds_find .P int\ ds_find(dstring\ *dest,\ int\ startpos,\ dstring\ *substr,\ ds_predicate_t\ userp,\ void\ *extra); .P Returns a position of the first occurrence of .IR substr within .IR dest starting with .IR startpos using .IR userp for comparison\&\. If .IR userp is NULL, .IR ds_std_predicate is assumed\&\. If .IR substr is not found, a negative value is returned .P .TP .B Function ds_rfind .P int\ ds_rfind(dstring\ *dest,\ dstring\ *substr,\ ds_predicate_t\ userp,\ void\ *extra); .P Like .IR ds_find , but finds the .IR last occurrence of .IR substr .IP "Note:" 10 This function has no .IR startpos .P .TP .B Function ds_compare .P int\ ds_compare(dstring\ *arg1,\ dstring\ *arg2,\ ds_predicate_t\ userp,\ void\ *extra); .P Analogous to .IR strcmp(3) for dstrings\&\. Uses .IR userp for comparison; if it is NULL, .IR ds_std_predicate is assumed\&\. .P .TP .B Function ds_comparestr .P int\ ds_comparestr(dstring\ *arg1,\ const\ char\ *arg2,\ ds_predicate_t\ userp,\ void\ *extra); .P Like the previous, but .IR arg2 is a C string .P .TP .B Function ds_collate .P int\ ds_collate(dstring\ *arg1,\ dstring\ *arg2); .P Compares two dstrings according to the current locale\&\. See .IR strcoll(3) .P .TP .B Function ds_tocollate .P dstring\ *ds_tocollate(dstring\ *arg1); .P Returns the result of .IR strxfrm(3) on a dstring .P .TP .B Function ds_reversip .P dstring\ *ds_reversip(dstring\ *src); .P Reverses its argument in\-place .P .TP .B Function ds_reverse .P dstring\ *ds_reverse(dstring\ *src); .P Like the previous, but operates on a copy of the argument .P .TP .B Functions ds_t_toupper, ds_t_tolower .P int\ ds_t_toupper(int\ ch,\ void\ *extra); .P .br int\ ds_t_tolower(int\ ch,\ void\ *extra); .P Standard transform functions to convert cases .P .TP .B Function ds_transform .P dstring\ *ds_transform(dstring\ *src,\ ds_iterator_t\ func,\ int\ inplace,\ void\ *extra); .P Applies a .IR func to each character in .IR src \&\. The result is stored in .IR src or in its copy depending of .IR inplace .P .TP .B Function ds_transform_bin .P dstring\ *ds_transform_bin(dstring\ *src,\ ds_iterator_t\ func,\ int\ inplace,\ void\ *extra); .P Like the previous but can handle binary strings .P .TP .B Function ds_xtransform .P dstring\ *ds_xtransform(dstring\ *src,\ ds_xtransform_t\ func,\ void\ *extra); .P Applies a .IR func to each character in .IR src creating a new string\&\. The way the string is created is completely determined by .IR func (unlike .IR ds_transform ) .P .TP .B Function ds_xtransform_bin .P dstring\ *ds_xtransform_bin(dstring\ *src,\ ds_xtransform_t\ func,\ void\ *extra); .P Like the previous, but can handle binary strings .P .TP .B Function ds_foreach .P void\ ds_foreach(dstring\ *src,\ ds_iterator_t\ func,\ void\ *extra); .P Applies a .IR func to each character of .IR src \&\. Unlike the previous, .IR src is never affected .P .TP .B Function ds_foreach_bin .P void\ ds_foreach_bin(dstring\ *src,\ ds_iterator_t\ func,\ void\ *extra); .P Like the previous, but can handle binary strings .IR "" .SH lists\&\.c This file contains routines for generic list maninpulation\&\. .SS Declarations in \(cqlists\&\.h\(cq .P .TP .B Types baselist_t, list_t .P typedef\ struct\ baselist_t .br { .br struct\ baselist_t\ *next; .br }\ baselist_t; .P .br typedef\ void\ *list_t; .P Basic types for list routines\&\. .P .TP .B Type list_predicate_t .P typedef\ int\ (*list_predicate_t)(void\ *base,\ void\ *key); .P The type for generic list testing function\&\. .IR base points to the current item\&\. The function should return 1 when .IR base is `equal\(cq to .IR key , 0 otherwise .P .TP .B Type list_iterator_t .P typedef\ void\ (*list_iterator_t)(void\ *base,\ void\ *extra); .P The type for generic list iteration function\&\. .IR base is the same as in the previous, .IR extra is a user\-supplied data .P .TP .B Type list_destroy_t .P typedef\ void\ (*list_destroy_t)(void\ *base); .P The type for list content destruction function\&\. .IR base is the same as in the previous\&\. .IP "Note:" 10 The function should .IR not deallocate memory for .IR base \&\. .P .TP .B Macro DEFLIST .P #define\ DEFLIST(name,\ body)\ typedef\ struct\ name\ {\ \(rs .br struct\ name\ *next;\ \(rs .br body\ \(rs .br }\ name .br .P A macro to declare structures compatible with .IR baselist_t .P .TP .B Macro list_next .P #define\ list_next(l)\ ((list_t)(((baselist_t\ *)(l))\->next)) .br .P A generic macro to get the tail of a list .SS Functions .P .TP .B Function list_free .P void\ list_free(list_t\ item,\ list_destroy_t\ destroy,\ int\ size); .P Destroys a single item of a list .PD 0 .IP \(bu 4 .PD .IR item : the pointer to a given item .PD 0 .IP \(bu 4 .PD .IR destroy : user\-supplied destruction function, may be NULL .PD 0 .IP \(bu 4 .PD .IR size : actual size of an item .P .TP .B Function list_add .P list_t\ list_add(list_t\ base,\ list_t\ new); .P Prepends an item .IR base to a list .IR new .IP "Note:" 10 both may be NULLs Returns a new list .P .TP .B Function list_find .P list_t\ list_find(list_t\ base,\ void\ *key,\ list_predicate_t\ predicate); .P Finds the first item in a list matching .IR key according to .IR predicate Returns the item found, or NULL if none .P .TP .B Function list_length .P int\ list_length(list_t\ l); .P Returns the length of a list .P .TP .B Function list_nth .P list_t\ list_nth(list_t\ l,\ int\ n); .P Returns .IR n th item of a list (starting with 0), NULL if the list contains less than n + 1 items .P .TP .B Function list_foreach .P void\ list_foreach(list_t\ base,\ list_iterator_t\ iterator,\ void\ *extra); .P Executes .IR iterator for each item in .IR base .P .TP .B Function list_insert .P list_t\ list_insert(list_t\ base,\ void\ *after,\ list_t\ new,\ list_predicate_t\ predicate); .P Inserts a .IR new item into .IR base list after an item matching .IR after \&\. If no such item is found, no insertion is performed\&\. If .IR after is NULL, the function is equivalent to .IR list_add Returns a new list .P .TP .B Function list_append .P list_t\ list_append(list_t\ base,\ list_t\ new); .P Appends a .IR new item to the list Returns .IR base .P .TP .B Function list_pop .P list_t\ list_pop(list_t\ base,\ list_destroy_t\ destroy,\ int\ elsize); .P Discards the head of the list, calling .IR list_free on it Returns the tail of the list .P .TP .B Function list_remove .P list_t\ list_remove(list_t\ base,\ void\ *key,\ list_predicate_t\ predicate,\ list_destroy_t\ destroy,\ int\ elsize); .P Removes the first item matching .IR key , calling .IR list_free on it\&\. If no such item is found, nothing happens Returns a new list .P .TP .B Function list_remove_all .P list_t\ list_remove_all(list_t\ base,\ void\ *key,\ list_predicate_t\ predicate,\ list_destroy_t\ destroy,\ int\ elsize); .P Like the previous, but removes all the items matching .IR key .P .TP .B Function list_delete .P void\ list_delete(list_t\ base,\ list_destroy_t\ destroy,\ int\ elsize); .P Destroys all the items of the list, calling .IR list_free on them\&\. .P .TP .B Function list_reversip .P list_t\ list_reversip(list_t\ src); .P Reverses the order of items in a list without producing a new list .\" Copyright \(co 2001, 2002, 2003 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\&\. .SH SEE ALSO .IR atexit(3) , .IR open(2) , .IR printf(3) , .IR setenv(3) , .IR setjmp(3) , .IR strcmp(3) , .IR strcoll(3) , .IR strdup(3) , .IR strtol(3) , .IR strxfrm(3) , .IR vfprintf(3) , .IR vsnprintf(3) , .IR vsprintf(3) .SH AUTHOR Artem V\&\. Andreev .SH COPYRIGHT Copyright \(co 2001, 2002, 2003 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\&\. .P 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\&\. .P 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\&\.