gallery/include/util.h

184 lines
5.9 KiB
C

#ifndef _UTIL_H
#define _UTIL_H
#include <sys/types.h>
#include <stdarg.h>
#include <stdlib.h>
/* Various utility functions for the gallery */
/* Memory management functions.
*
* These wrappers around malloc/calloc, realloc and free internally
* monitor the usage of memory chunks. It keeps track of all allocated
* pointers, allowing for garbage collection to occur at the end when
* all pointers should be unused.
*
* For performance, these can be disabled at compile time. Their prime focus is
* for development... to track where allocations are being made. It shouldn't
* be necessary in production -- if it is, there's a memory leakage bug.
*/
#ifdef MEMALLOC_TRACK
/* Memory allocation tracking enabled */
void* gcmalloc( size_t size );
void* gccalloc( size_t nmemb, size_t size );
void* gcrealloc( void* ptr, size_t size );
void gcfree( void* ptr );
void gcfreeall();
char* gcstrdup( const char* str );
char* gcreport();
/* The pointers are tracked in this linked list */
struct mem_chunk {
void* ptr;
size_t size;
struct mem_chunk* prev;
struct mem_chunk* next;
};
static struct mem_chunk* gc_head = NULL;
static struct mem_chunk* gc_tail = NULL;
static size_t gc_count = 0;
#else
/* Memory allocation tracking disabled */
#define gcmalloc( size ) malloc( size )
#define gccalloc( size, num ) calloc( size, num )
#define gcrealloc( ptr, size ) realloc( ptr, size )
#define gcfree( ptr ) free( ptr )
#define gcstrdup( size ) strdup( size )
#endif
/* Sanitise a given name. Names may only contain alpha-numeric
* characters, hyphens, underscores and full stop characters.
*
* This function sanitises in-place, invalid characters get replaced with
* underscores.
*/
void sanitise_name( char* name );
/* Cross-compatibility hack */
#ifndef PATHSEP
# ifdef WIN32
# define PATHSEP "\\"
# else
# define PATHSEP "/"
# endif
#endif
/* Concatenate one string onto the end of the other.
*
* This function does a realloc of the first string to make room for the second,
* returning the pointer to the concatenated string.
*
* This is different to strcat, which does not re-allocate memory or make room
* in any way.
*/
char* str_concat( char* dest, const char* src );
/* Like above, but add a single character */
char* str_concatc( char* dest, const char c );
/* Construct a path from given directory names.
* fmt is a list of types and sizes interpreted as follows:
* s Insert a string at this point.
* i Insert a signed integer at this point.
* u Insert an unsigned integer at this point.
* x Insert a hexadecimal integer at this point
* o Insert an octal integer at this point
* f Insert a floating-point/double at this point.
* / Insert the path separator string at this point.
* \ Insert the next character verbatim
*
* Whitespace is ignored, so you can add spaces for readability. Digits
* are interpreted as the width of the field in characters. Anything else
* is passed through verbatim.
*
* Whitespace can be passed through by escaping it however.
*
* For float/double fields, a decimal point followed by digits indicates
* the number of decimal digits to include.
*
* Example:
* "s/s ? s=6.2f & s=u & s=u" might yield
* "humour/funnypic.jpg?rotation=000.00&width=600&height=400"
*/
char* construct_path( const char* format, ...);
/* construct_path field widths are limited to the following number of
* characters...
*/
#define CONSTRUCT_PATH_FIELD_WIDTH 64
/* Obtain the CGI filesystem directory */
const char* get_cgidir();
/* Obtain the CGI directory URI */
const char* get_cgiuri();
/* Local versions of dirname and basename. These allocate and return copies of
* the strings passed to them.
*/
char* get_basename( const char* path );
char* get_dirname( const char* path );
/* Substitute the extension on a filename.
*
* This function does a string substitution on the filename given to it, and
* returns it. Returns NULL if it can't allocate a buffer.
*/
char* substitute_ext( const char* filename, const char* new_ext );
/* Parse a text file. The text files in this system have the format:
* "<some variable>\t<value>\n"
*
* Multiple lines with the same variable are concatenated together.
*
* The content of these files is stored in a chained struct like the one below.
*/
struct txtinfo_chain {
char* field_name;
char* field_val;
struct txtinfo_chain* next;
};
/* Create a txtinfo_chain object */
struct txtinfo_chain* create_txtinfo_chain( const char* name, const char* val );
/* Destroy a txtinfo_chain object. This destroys all linked objects! */
void destroy_txtinfo_chain( struct txtinfo_chain* chain );
/* Locate a field in a field chain. Return NULL if it isn't present. */
struct txtinfo_chain* find_txtinfo_chain( struct txtinfo_chain* chain, const char* name );
/* Return the value for a given field name. This returns a copy of the string. */
char* get_txtinfo_chain_val( struct txtinfo_chain* chain, const char *name );
/* Read a file into a txtinfo_chain object. Returns NULL on failure. */
struct txtinfo_chain* read_txtinfo_chain( const char* file );
/* Write out a txtinfo_chain object. Returns 0 on success, errno on failure. */
int write_txtinfo_chain( const char* file, struct txtinfo_chain* chain );
/* Duplicate a structure in memory.
* This calls malloc to allocate a region of the specified size,
* then does a memcpy from the supplied address.
*
* Returns the copy on success, or NULL on failure.
*/
void* memdup( void* ptr, size_t length );
/* Sort a generic array
*
* This does an in-place sort of the objects contained in the array.
* Since there's no way of knowing how to sort the objects, a function
* for doing this must be supplied as a pointer.
*
* str_sort_array does the above sort with strings, setting case_insensitive
* will cause the sorting algorithm to ignore the case.
*/
void sort_str_array( char** array, size_t length, int case_insensitive );
void sort_array( void** array, size_t length,
int (*compare)( const void*, const void* ) );
#endif