2005-09-20 23:26:39 +10:00
/** \file util.h
Generic utilities library .
2006-06-17 23:07:08 +10:00
All containers in this library except strinb_buffer_t are written
so that they don ' t allocate any memory until the first element is
inserted into them . That way it is known to be very cheap to
initialize various containers at startup , supporting the fish
notion of doing as much lazy initalization as possible .
2005-09-20 23:26:39 +10:00
*/
2005-10-05 01:11:39 +10:00
# ifndef FISH_UTIL_H
# define FISH_UTIL_H
# include <wchar.h>
2005-10-12 20:34:21 +10:00
# include <stdarg.h>
2006-01-26 22:21:34 +10:00
# include <unistd.h>
2005-10-05 01:11:39 +10:00
2006-08-01 02:16:41 +10:00
typedef void ( * func_ptr_t ) ( ) ;
typedef union
{
long long_val ;
void * ptr_val ;
func_ptr_t func_val ;
}
anything_t ;
2005-09-20 23:26:39 +10:00
/**
Data structure for an automatically resizing dynamically allocated queue ,
*/
2005-10-11 02:12:55 +10:00
typedef struct dyn_queue
2005-09-20 23:26:39 +10:00
{
/** Start of the array */
void * * start ;
/** End of the array*/
void * * stop ;
/** Where to insert elements */
void * * put_pos ;
/** Where to remove elements */
void * * get_pos ;
}
2006-08-01 02:16:41 +10:00
dyn_queue_t ;
2005-09-20 23:26:39 +10:00
/**
Internal struct used by hash_table_t .
*/
typedef struct
{
/** Hash key*/
2006-06-13 07:47:42 +10:00
void * key ;
2005-09-20 23:26:39 +10:00
/** Value */
2006-06-13 07:47:42 +10:00
void * data ;
2005-09-20 23:26:39 +10:00
}
2006-08-01 02:16:41 +10:00
hash_struct_t ;
2005-09-20 23:26:39 +10:00
/**
Data structure for the hash table implementaion . A hash table allows for
retrieval and removal of any element in O ( 1 ) , so long as a proper
hash function is supplied .
The hash table is implemented using a single hash function and
element storage directly in the array . When a collision occurs , the
hashtable iterates until a zero element is found . When the table is
75 % full , it will automatically reallocate itself . This
reallocation takes O ( n ) time . The table is guaranteed to never be
more than 75 % full or less than 30 % full ( Unless the table is
nearly empty ) . Its size is always a Mersenne number .
*/
typedef struct hash_table
{
/** The array containing the data */
hash_struct_t * arr ;
/** Number of elements */
int count ;
/** Length of array */
int size ;
/** Hash function */
2006-06-13 07:47:42 +10:00
int ( * hash_func ) ( void * key ) ;
2005-09-20 23:26:39 +10:00
/** Comparison function */
2006-06-13 07:47:42 +10:00
int ( * compare_func ) ( void * key1 , void * key2 ) ;
2005-09-20 23:26:39 +10:00
}
2006-08-01 02:16:41 +10:00
hash_table_t ;
2005-09-20 23:26:39 +10:00
/**
Data structure for an automatically resizing dynamically allocated
priority queue . A priority queue allows quick retrieval of the
smallest element of a set ( This implementation uses O ( log n ) time ) .
This implementation uses a heap for storing the queue .
*/
typedef struct priority_queue
{
/** Array contining the data */
void * * arr ;
/** Number of elements*/
int count ;
/** Length of array */
int size ;
/** Comparison function */
int ( * compare ) ( void * e1 , void * e2 ) ;
}
priority_queue_t ;
/**
Array list struct .
A dynamically growing list that supports stack operations .
*/
typedef struct array_list
{
/** Array containing the data */
2006-08-01 02:16:41 +10:00
anything_t * arr ;
2005-09-20 23:26:39 +10:00
/** Position to append elements at*/
int pos ;
/** Length of array */
int size ;
}
array_list_t ;
/**
Linked list node .
*/
typedef struct _ll_node
{
/** Next node */
struct _ll_node * next , /** Previous node */ * prev ;
/** Node data */
void * data ;
}
ll_node_t ;
/**
Buffer for concatenating arbitrary data .
*/
typedef struct buffer
{
char * buff ; /**<data buffer*/
size_t length ; /**< Size of buffer */
size_t used ; /**< Size of data in buffer */
}
buffer_t ;
/**
String buffer struct . An autoallocating buffer used for
concatenating strings . This is really just a buffer_t .
*/
typedef buffer_t string_buffer_t ;
/**
Returns the larger of two ints
*/
int maxi ( int a , int b ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Returns the smaller of two ints
*/
int mini ( int a , int b ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/*
All the datastuctures below autoresize . The queue , stack and
priority queue are all impemented using an array and are guaranteed
to never be less than 50 % full .
*/
/**
Initialize the queue . A queue is a FIFO buffer , i . e . the first
element to be inserted into the buffer is the first element to be
returned .
*/
2005-10-11 02:12:55 +10:00
void q_init ( dyn_queue_t * q ) ;
2005-10-27 00:48:23 +10:00
2006-01-24 09:33:47 +10:00
/**
Destroy the queue
*/
2005-10-11 02:12:55 +10:00
void q_destroy ( dyn_queue_t * q ) ;
2005-10-27 00:48:23 +10:00
2006-01-24 09:33:47 +10:00
/**
Insert element into queue
*/
2005-10-11 02:12:55 +10:00
int q_put ( dyn_queue_t * q , void * e ) ;
2005-10-27 00:48:23 +10:00
2006-01-24 09:33:47 +10:00
/**
Remove and return next element from queue
*/
2005-10-11 02:12:55 +10:00
void * q_get ( dyn_queue_t * q ) ;
2005-10-27 00:48:23 +10:00
2006-01-24 09:33:47 +10:00
/**
Return next element from queue without removing it
*/
2005-10-11 02:12:55 +10:00
void * q_peek ( dyn_queue_t * q ) ;
2005-10-27 00:48:23 +10:00
2006-01-24 09:33:47 +10:00
/**
Returns 1 if the queue is empty , 0 otherwise
*/
2005-10-11 02:12:55 +10:00
int q_empty ( dyn_queue_t * q ) ;
2005-09-20 23:26:39 +10:00
/**
Initialize a hash table . The hash function must never return the value 0.
*/
void hash_init ( hash_table_t * h ,
2006-06-13 07:47:42 +10:00
int ( * hash_func ) ( void * key ) ,
int ( * compare_func ) ( void * key1 , void * key2 ) ) ;
2005-09-20 23:26:39 +10:00
/**
Initialize a hash table . The hash function must never return the value 0.
*/
void hash_init2 ( hash_table_t * h ,
2006-06-13 07:47:42 +10:00
int ( * hash_func ) ( void * key ) ,
int ( * compare_func ) ( void * key1 , void * key2 ) ,
2005-09-20 23:26:39 +10:00
size_t capacity ) ;
/**
Destroy the hash table and free associated memory .
*/
void hash_destroy ( hash_table_t * h ) ;
/**
Set the key / value pair for the hashtable .
*/
int hash_put ( hash_table_t * h ,
const void * key ,
const void * data ) ;
/**
Returns the data with the associated key , or 0 if no such key is in the hashtable
*/
2006-06-13 07:47:42 +10:00
void * hash_get ( hash_table_t * h ,
const void * key ) ;
2005-09-20 23:26:39 +10:00
/**
Returns the hash tables version of the specified key
*/
2006-06-13 07:47:42 +10:00
void * hash_get_key ( hash_table_t * h ,
const void * key ) ;
2005-09-20 23:26:39 +10:00
/**
Returns the number of key / data pairs in the table .
*/
int hash_get_count ( hash_table_t * h ) ;
/**
2006-02-05 23:12:53 +10:00
Remove the specified key from the hash table if it exists . Do nothing if it does not exist .
2005-09-20 23:26:39 +10:00
\ param h The hashtable
\ param key The key
\ param old_key If not 0 , a pointer to the old key will be stored at the specified address
\ param old_data If not 0 , a pointer to the data will be stored at the specified address
*/
void hash_remove ( hash_table_t * h ,
const void * key ,
2006-06-13 07:47:42 +10:00
void * * old_key ,
void * * old_data ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Checks whether the specified key is in the hash table
*/
int hash_contains ( hash_table_t * h ,
const void * key ) ;
/**
Appends all keys in the table to the specified list
*/
void hash_get_keys ( hash_table_t * h ,
array_list_t * arr ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Appends all data elements in the table to the specified list
*/
void hash_get_data ( hash_table_t * h ,
array_list_t * arr ) ;
2005-10-27 00:48:23 +10:00
2006-01-24 09:33:47 +10:00
/**
Call the function func for each key / data pair in the table
2005-10-27 00:48:23 +10:00
*/
2005-09-20 23:26:39 +10:00
void hash_foreach ( hash_table_t * h ,
2006-06-13 07:47:42 +10:00
void ( * func ) ( void * , void * ) ) ;
2005-10-27 00:48:23 +10:00
2006-01-24 09:33:47 +10:00
/**
Same as hash_foreach , but the function func takes an additional
argument , which is provided by the caller in the variable aux
2005-10-27 00:48:23 +10:00
*/
2006-06-13 07:47:42 +10:00
void hash_foreach2 ( hash_table_t * h , void ( * func ) ( void * ,
void * ,
void * ) ,
2005-09-20 23:26:39 +10:00
void * aux ) ;
/**
Hash function suitable for character strings .
*/
2006-06-13 07:47:42 +10:00
int hash_str_func ( void * data ) ;
2005-09-20 23:26:39 +10:00
/**
Hash comparison function suitable for character strings
*/
2006-06-13 07:47:42 +10:00
int hash_str_cmp ( void * a ,
void * b ) ;
2005-09-20 23:26:39 +10:00
/**
Hash function suitable for wide character strings .
*/
2006-06-13 07:47:42 +10:00
int hash_wcs_func ( void * data ) ;
2005-09-20 23:26:39 +10:00
/**
Hash comparison function suitable for wide character strings
*/
2006-06-13 07:47:42 +10:00
int hash_wcs_cmp ( void * a ,
void * b ) ;
2005-09-20 23:26:39 +10:00
2006-02-04 23:09:14 +10:00
/**
Hash function suitable for direct pointer comparison
*/
2006-06-13 07:47:42 +10:00
int hash_ptr_func ( void * data ) ;
2006-02-04 23:09:14 +10:00
/**
Hash comparison function suitable for direct pointer comparison
*/
2006-06-13 07:47:42 +10:00
int hash_ptr_cmp ( void * a ,
void * b ) ;
2006-02-04 23:09:14 +10:00
2005-10-27 00:48:23 +10:00
/**
Initialize the priority queue
\ param q the queue to initialize
\ param compare a comparison function that can compare two entries in the queue
2005-09-20 23:26:39 +10:00
*/
void pq_init ( priority_queue_t * q ,
int ( * compare ) ( void * e1 , void * e2 ) ) ;
/**
Add element to the queue
2006-01-24 09:33:47 +10:00
\ param q the queue
\ param e the new element
2005-09-20 23:26:39 +10:00
*/
int pq_put ( priority_queue_t * q ,
2006-01-24 09:33:47 +10:00
void * e ) ;
2005-09-20 23:26:39 +10:00
/**
Removes and returns the last entry in the priority queue
*/
void * pq_get ( priority_queue_t * q ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Returns the last entry in the priority queue witout removing it .
*/
void * pq_peek ( priority_queue_t * q ) ;
/**
Returns 1 if the priority queue is empty , 0 otherwise .
*/
int pq_empty ( priority_queue_t * q ) ;
/**
Returns the number of elements in the priority queue .
*/
int pq_get_count ( priority_queue_t * q ) ;
/**
Destroy the priority queue and free memory used by it .
*/
void pq_destroy ( priority_queue_t * q ) ;
2005-10-04 23:43:26 +10:00
/**
2006-08-01 02:30:27 +10:00
Allocate heap memory for creating a new list and initialize
it . Equivalent to calling malloc and al_init .
2005-10-04 23:43:26 +10:00
*/
2005-10-04 23:53:21 +10:00
array_list_t * al_new ( ) ;
2005-10-04 23:43:26 +10:00
2005-10-27 00:48:23 +10:00
/**
Initialize the list .
*/
2005-09-20 23:26:39 +10:00
void al_init ( array_list_t * l ) ;
2005-10-27 00:48:23 +10:00
/**
Destroy the list and free memory used by it .
*/
2005-09-20 23:26:39 +10:00
void al_destroy ( array_list_t * l ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Append element to list
\ param l The list
\ param o The element
\ return
\ return 1 if succesfull , 0 otherwise
*/
int al_push ( array_list_t * l , const void * o ) ;
2006-08-01 02:16:41 +10:00
/**
Append element to list
\ param l The list
\ param o The element
\ return
\ return 1 if succesfull , 0 otherwise
*/
int al_push_long ( array_list_t * l , long o ) ;
/**
Append element to list
\ param l The list
\ param o The element
\ return
\ return 1 if succesfull , 0 otherwise
*/
int al_push_func ( array_list_t * l , void ( * f ) ( ) ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Append all elements of a list to another
\ param a The destination list
\ param b The source list
\ return 1 if succesfull , 0 otherwise
*/
int al_push_all ( array_list_t * a , array_list_t * b ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Sets the element at the specified index
\ param l The array_list_t
\ param pos The index
\ param o The element
*/
int al_set ( array_list_t * l , int pos , const void * o ) ;
2006-08-01 02:16:41 +10:00
/**
Sets the element at the specified index
\ param l The array_list_t
\ param pos The index
\ param o The element
*/
int al_set_long ( array_list_t * l , int pos , long v ) ;
/**
Sets the element at the specified index
\ param l The array_list_t
\ param pos The index
\ param o The element
*/
int al_set_func ( array_list_t * l , int pos , void ( * f ) ( ) ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Returns the element at the specified index
\ param l The array_list_t
\ param pos The index
\ return The element
*/
2006-06-13 07:47:42 +10:00
void * al_get ( array_list_t * l , int pos ) ;
2006-08-01 02:30:27 +10:00
/**
Returns the element at the specified index
\ param l The array_list_t
\ param pos The index
\ return The element
*/
2006-08-01 02:16:41 +10:00
long al_get_long ( array_list_t * l , int pos ) ;
2006-08-01 02:30:27 +10:00
/**
Returns the element at the specified index
\ param l The array_list_t
\ param pos The index
\ return The element
*/
2006-08-01 02:16:41 +10:00
func_ptr_t al_get_func ( array_list_t * l , int pos ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Truncates the list to new_sz items .
*/
void al_truncate ( array_list_t * l , int new_sz ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Removes and returns the last entry in the list
*/
2006-06-13 07:47:42 +10:00
void * al_pop ( array_list_t * l ) ;
2006-08-01 02:30:27 +10:00
/**
Removes and returns the last entry in the list
*/
2006-08-01 02:16:41 +10:00
long al_pop_long ( array_list_t * l ) ;
2006-08-01 02:30:27 +10:00
/**
Removes and returns the last entry in the list
*/
2006-08-01 02:16:41 +10:00
func_ptr_t al_pop_func ( array_list_t * l ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Returns the number of elements in the list
*/
int al_get_count ( array_list_t * l ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Returns the last entry in the list witout removing it .
*/
2006-06-13 07:47:42 +10:00
void * al_peek ( array_list_t * l ) ;
2006-08-01 02:30:27 +10:00
/**
Returns the last entry in the list witout removing it .
*/
2006-08-01 02:16:41 +10:00
long al_peek_long ( array_list_t * l ) ;
2006-08-01 02:30:27 +10:00
/**
Returns the last entry in the list witout removing it .
*/
2006-08-01 02:16:41 +10:00
func_ptr_t al_peek_func ( array_list_t * l ) ;
2005-10-27 00:48:23 +10:00
/**
Returns 1 if the list is empty , 0 otherwise
*/
2005-09-20 23:26:39 +10:00
int al_empty ( array_list_t * l ) ;
2005-10-27 00:48:23 +10:00
/**
Call the function func for each entry in the list
*/
2006-06-13 07:47:42 +10:00
void al_foreach ( array_list_t * l , void ( * func ) ( void * ) ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Same as al_foreach , but the function func takes an additional
argument , which is provided by the caller in the variable aux
*/
2006-06-13 07:47:42 +10:00
void al_foreach2 ( array_list_t * l , void ( * func ) ( void * , void * ) , void * aux ) ;
2005-09-20 23:26:39 +10:00
/**
Compares two wide character strings without case but with
a logical ordering for numbers .
This function tries to order strings in a way which is intuitive to
humans with regards to sorting strings containing numbers .
Most sorting functions would sort the strings ' file1 . txt '
' file5 . txt ' and ' file12 . txt ' as :
file1 . txt
file12 . txt
file5 . txt
This function regards any sequence of digits as a single entity
when performing comparisons , so the output is instead :
file1 . txt
file5 . txt
file12 . txt
Which most people would find more intuitive .
2005-10-27 00:48:23 +10:00
This won ' t return the optimum results for numbers in bases higher
than ten , such as hexadecimal , but at least a stable sort order
will result .
2005-09-20 23:26:39 +10:00
*/
int wcsfilecmp ( const wchar_t * a , const wchar_t * b ) ;
2006-01-24 09:33:47 +10:00
/*
String buffer functions
*/
2005-09-20 23:26:39 +10:00
/**
Initialize the specified string_buffer
*/
void sb_init ( string_buffer_t * ) ;
2006-01-24 06:40:14 +10:00
/**
Allocate memory for storing a stringbuffer and init it
*/
2005-10-06 08:37:08 +10:00
string_buffer_t * sb_new ( ) ;
2005-09-20 23:26:39 +10:00
/**
Append a string to the buffer
*/
void sb_append ( string_buffer_t * , const wchar_t * ) ;
/**
Append a part of a string to the buffer
*/
void sb_append_substring ( string_buffer_t * , const wchar_t * , size_t ) ;
/**
Append a character to the buffer
*/
void sb_append_char ( string_buffer_t * , wchar_t ) ;
/**
Append a null terminated list of strings to the buffer .
Example :
2005-10-27 00:48:23 +10:00
sb_append2 ( my_buff , L " foo " , L " bar " , ( void * ) 0 ) ;
Do not forget to cast the last 0 to ( void * ) , or you might encounter errors on 64 - bit platforms !
2005-09-20 23:26:39 +10:00
*/
void sb_append2 ( string_buffer_t * , . . . ) ;
/**
Append formated string data to the buffer . This function internally
relies on \ c vswprintf , so any filter options supported by that
2005-10-27 00:48:23 +10:00
function is also supported by this function .
2005-09-20 23:26:39 +10:00
*/
int sb_printf ( string_buffer_t * buffer , const wchar_t * format , . . . ) ;
2005-10-12 20:34:21 +10:00
/**
2005-10-27 00:48:23 +10:00
Vararg version of sb_printf .
2005-10-12 20:34:21 +10:00
*/
int sb_vprintf ( string_buffer_t * buffer , const wchar_t * format , va_list va_orig ) ;
2005-09-20 23:26:39 +10:00
/**
Destroy the buffer and free it ' s memory
*/
void sb_destroy ( string_buffer_t * ) ;
/**
2006-06-20 10:50:10 +10:00
Truncate the buffer . This will not deallocate the memory used , it will only set the contents of the string to L " \\ 0 " .
2005-09-20 23:26:39 +10:00
*/
void sb_clear ( string_buffer_t * ) ;
2006-01-24 09:33:47 +10:00
/*
Buffer functions
*/
2005-09-20 23:26:39 +10:00
/**
Initialize the specified buffer_t
2005-10-27 00:48:23 +10:00
*/
2005-09-20 23:26:39 +10:00
void b_init ( buffer_t * b ) ;
2005-10-27 00:48:23 +10:00
2005-09-20 23:26:39 +10:00
/**
Destroy the specified buffer_t
*/
void b_destroy ( buffer_t * b ) ;
/**
Add data of the specified length to the specified buffer_t
*/
void b_append ( buffer_t * b , const void * d , ssize_t len ) ;
/**
Get the current time in microseconds since Jan 1 , 1970
*/
long long get_time ( ) ;
2005-10-05 01:11:39 +10:00
# endif