libfossil
fossil-util.h File Reference

This file declares a number of utility classes and routines used by libfossil. More...

#include "fossil-config.h"
#include <stdio.h>
#include <stdarg.h>
#include <time.h>

Go to the source code of this file.

Data Structures

struct  fsl_allocator
 Holds an allocator function and its related state. More...
 
struct  fsl_buffer
 A general-purpose buffer class, analog to Fossil v1's Blob class, but it is not called fsl_blob to avoid confusion with DB-side blobs. More...
 
struct  fsl_confirmer
 A helper type which wraps a fsl_confirmation_f() and its state into one object. More...
 
struct  fsl_error
 A container for storing generic error state. More...
 
struct  fsl_finalizer
 Generic interface for memory finalizers. More...
 
struct  fsl_fstat
 A simple wrapper around the stat(2) structure resp. More...
 
struct  fsl_id_bag
 A container type for lists of db record IDs. More...
 
struct  fsl_list
 Generic list container type. More...
 
struct  fsl_outputer
 An interface which encapsulates data for managing an output destination, primarily intended for use with fsl_output(). More...
 
struct  fsl_pathfinder
 The "Path Finder" class is a utility class for searching the filesystem for files matching a set of common prefixes and/or suffixes (i.e. More...
 
struct  fsl_state
 Generic state-with-finalizer holder. More...
 
struct  fsl_timer_state
 State for the fsl_timer_xxx() family of functions. More...
 
struct  fsl_zip_writer
 A utility class for creating ZIP-format archives. More...
 

Macros

#define fsl_allocator_empty_m   {NULL,NULL}
 Empty-initialized fsl_allocator instance. More...
 
#define fsl_buffer_empty_m   {NULL,0U,0U,0U}
 Empty-initialized fsl_buffer instance, intended for const-copy initialization. More...
 
#define fsl_confirmer_empty_m   {NULL,NULL}
 Initialized-with-defaults fsl_confirmer struct. More...
 
#define fsl_error_empty_m   {fsl_buffer_empty_m,0}
 Empty-initialized fsl_error instance, intended for const-copy initialization. More...
 
#define fsl_finalizer_empty_m   {NULL,NULL}
 Empty-initialized fsl_finalizer struct. More...
 
#define fsl_fstat_empty_m   {FSL_FSTAT_TYPE_UNKNOWN,0,0,0,0}
 Empty-initialized fsl_fstat structure, intended for const-copy construction. More...
 
#define fsl_id_bag_empty_m
 Initialized-with-defaults fsl_id_bag structure, intended for in-struct initialization. More...
 
#define fsl_list_empty_m   { NULL, 0, 0 }
 Empty-initialized fsl_list structure, intended for const-copy initialization. More...
 
#define fsl_outputer_empty_m   {NULL,NULL,fsl_state_empty_m}
 Empty-initialized fsl_outputer instance. More...
 
#define fsl_outputer_FILE_m
 fsl_outputer initializer which uses fsl_flush_f_FILE(), fsl_output_f_FILE(), and fsl_finalizer_f_FILE(). More...
 
#define fsl_pathfinder_empty_m   {fsl_list_empty_m/*ext*/,fsl_list_empty_m/*dirs*/,fsl_buffer_empty_m/*buf*/}
 Initialized-with-defaults fsl_pathfinder instance, intended for const copy initialization. More...
 
#define fsl_state_empty_m   {NULL,fsl_finalizer_empty_m}
 Empty-initialized fsl_state struct. More...
 
#define fsl_timer_state_empty_m   {0,0}
 Initialized-with-defaults fsl_timer_state_empty instance, intended for const copy initialization. More...
 
#define fsl_zip_writer_empty_m
 An initialized-with-defaults fsl_zip_writer instance, intended for in-struct or const-copy initialization. More...
 

Typedefs

typedef struct fsl_allocator fsl_allocator
 
typedef fsl_int_t(* fsl_appendf_f) (void *state, char const *data, fsl_int_t n)
 The fsl_appendf_f typedef is used to provide fsl_appendfv() with a flexible output routine, so that it can be easily send its output to arbitrary targets. More...
 
typedef struct fsl_buffer fsl_buffer
 
typedef int(* fsl_confirmation_f) (void *state, char const *msg, fsl_size_t msgLen)
 An interface for routines which answer a yes/no question, either via human interaction or programatic decisions. More...
 
typedef int fsl_confirmation_f_console_FILE(void *state, char const *msg, fsl_size_t msgLen)
 NOT YET IMPLEMENTED. More...
 
typedef struct fsl_confirmer fsl_confirmer
 
typedef struct fsl_error fsl_error
 
typedef struct fsl_finalizer fsl_finalizer
 
typedef void(* fsl_finalizer_f) (void *state, void *mem)
 Generic interface for finalizing/freeing memory. More...
 
typedef int(* fsl_flush_f) (void *state)
 Generic interface for flushing arbitrary output streams. More...
 
typedef struct fsl_fstat fsl_fstat
 
typedef enum fsl_fstat_perm_t fsl_fstat_perm_t
 
typedef enum fsl_fstat_type_t fsl_fstat_type_t
 
typedef int(* fsl_generic_cmp_f) (void const *lhs, void const *rhs)
 A typedef for comparison function used by standard C routines such as qsort(). More...
 
typedef struct fsl_id_bag fsl_id_bag
 
typedef int(* fsl_input_f) (void *state, void *dest, fsl_size_t *n)
 Generic interface for streaming in data. More...
 
typedef struct fsl_list fsl_list
 
typedef int(* fsl_list_visitor_f) (void *obj, void *visitorState)
 Generic visitor interface for fsl_list lists. More...
 
typedef int(* fsl_output_f) (void *state, void const *src, fsl_size_t n)
 Generic interface for streaming out data. More...
 
typedef struct fsl_outputer fsl_outputer
 
typedef struct fsl_pathfinder fsl_pathfinder
 
typedef void *(* fsl_realloc_f) (void *state, void *mem, fsl_size_t n)
 Generic stateful alloc/free/realloc() interface. More...
 
typedef struct fsl_state fsl_state
 
typedef struct fsl_timer_state fsl_timer_state
 
typedef char const * fsl_uuid_cstr
 The const counterpart of fsl_uuid_str. More...
 
typedef char * fsl_uuid_str
 fsl_uuid_str and fsl_uuid_cstr are "for documentation and readability purposes" typedefs used to denote strings which the API requires to be in the form of Fossil UUID strings. More...
 
typedef struct fsl_zip_writer fsl_zip_writer
 

Enumerations

enum  fsl_confirmation_t {
  FSL_CONFIRM_ERROR = -1,
  FSL_CONFIRM_YES = 0,
  FSL_CONFIRM_YES_ALL = 1,
  FSL_CONFIRM_NO = 2,
  FSL_CONFIRM_NO_ALL = 3
}
 Result codes for the fsl_confirmation_f() family of functions. More...
 
enum  fsl_diff_flag_t {
  FSL_DIFF_IGNORE_EOLWS = 0x01,
  FSL_DIFF_IGNORE_ALLWS = 0x03,
  FSL_DIFF_SIDEBYSIDE = 0x04,
  FSL_DIFF_VERBOSE = 0x08,
  FSL_DIFF_BRIEF = 0x10,
  FSL_DIFF_HTML = 0x20,
  FSL_DIFF_LINENO = 0x40,
  FSL_DIFF_NOOPT = 0x0100,
  FSL_DIFF_INVERT = 0x0200,
  FSL_DIFF_NOTTOOBIG = 0x0800,
  FSL_DIFF_STRIP_EOLCR = 0x1000,
  FSL_DIFF_ANSI_COLOR = 0x2000
}
 Flags for use with text-diff generation APIs, e.g. More...
 
enum  fsl_fstat_perm_t {
  FSL_FSTAT_PERM_UNKNOWN = 0,
  FSL_FSTAT_PERM_EXE = 0x01
}
 Bitmask values for use with the fsl_fstat::perms field. More...
 
enum  fsl_fstat_type_t {
  FSL_FSTAT_TYPE_UNKNOWN = 0,
  FSL_FSTAT_TYPE_DIR,
  FSL_FSTAT_TYPE_FILE,
  FSL_FSTAT_TYPE_LINK
}
 Values for use with the fsl_fstat::type field. More...
 
enum  fsl_open_flags {
  FSL_OPEN_F_NONE = 0,
  FSL_OPEN_F_RO = 0x01,
  FSL_OPEN_F_RW = 0x02,
  FSL_OPEN_F_CREATE = 0x04,
  FSL_OPEN_F_RWC = FSL_OPEN_F_RW | FSL_OPEN_F_CREATE,
  FSL_OPEN_F_SCHEMA_VALIDATE = 0x20
}
 Flags for use with fsl_db_open() and friends. More...
 

Functions

FSL_EXPORT fsl_int_t fsl_appendf (fsl_appendf_f pfAppend, void *pfAppendArg, const char *fmt,...)
 Identical to fsl_appendfv() but takes an ellipses list (...) instead of a va_list. More...
 
FSL_EXPORT fsl_int_t fsl_appendf_f_FILE (void *state, char const *s, fsl_int_t n)
 A fsl_appendf_f() impl which requires that state be an opened, writable (FILE*) handle. More...
 
FSL_EXPORT fsl_int_t fsl_appendfv (fsl_appendf_f pfAppend, void *pfAppendArg, const char *fmt, va_list ap)
 This function works similarly to classical printf implementations, but instead of outputing somewhere specific, it uses a callback function to push its output somewhere. More...
 
FSL_EXPORT int fsl_buffer_append (fsl_buffer *b, void const *src, fsl_int_t n)
 Appends the first n bytes of src, plus a NUL byte, to b, expanding b as necessary and incrementing b->used by n. More...
 
FSL_EXPORT int fsl_buffer_appendf (fsl_buffer *dest, char const *fmt,...)
 Uses fsl_appendf() to append formatted output to the given buffer. More...
 
FSL_EXPORT int fsl_buffer_appendfv (fsl_buffer *dest, char const *fmt, va_list args)
 va_list counterpart to fsl_buffer_appendfv(). More...
 
FSL_EXPORT fsl_size_t fsl_buffer_capacity (fsl_buffer const *b)
 Returns the current capacity of b, or 0 if !b. More...
 
FSL_EXPORT void fsl_buffer_clear (fsl_buffer *buf)
 Convenience equivalent of fsl_buffer_reserve(buf,0). More...
 
FSL_EXPORT int fsl_buffer_compare (fsl_buffer const *lhs, fsl_buffer const *rhs)
 Compares the contents of buffers lhs and rhs using memcmp(3) semantics. More...
 
FSL_EXPORT int fsl_buffer_compare_file (fsl_buffer const *b, char const *zFile)
 Bitwise-compares the contents of b against the file named by zFile. More...
 
FSL_EXPORT int fsl_buffer_compare_O1 (fsl_buffer const *lhs, fsl_buffer const *rhs)
 Compare two buffers in constant (a.k.a. More...
 
FSL_EXPORT int fsl_buffer_compress (fsl_buffer const *pIn, fsl_buffer *pOut)
 Compresses the first pIn->used bytes of pIn to pOut. More...
 
FSL_EXPORT int fsl_buffer_compress2 (fsl_buffer const *pIn1, fsl_buffer const *pIn2, fsl_buffer *pOut)
 Compress the concatenation of a blobs pIn1 and pIn2 into pOut. More...
 
FSL_EXPORT int fsl_buffer_copy (fsl_buffer const *src, fsl_buffer *dest)
 Overwrites dest's contents with a copy of those from src (reusing dest's memory if it has any). More...
 
FSL_EXPORT int fsl_buffer_copy_lines (fsl_buffer *pTo, fsl_buffer *pFrom, fsl_size_t N)
 Copy N lines of text from pFrom into pTo. More...
 
FSL_EXPORT char const * fsl_buffer_cstr (fsl_buffer const *b)
 Equivalent to ((char const *)b->mem), but returns NULL if !b. More...
 
FSL_EXPORT char const * fsl_buffer_cstr2 (fsl_buffer const *b, fsl_size_t *len)
 If buf is not NULL and has any memory allocated to it, that memory is returned. More...
 
FSL_EXPORT void fsl_buffer_defossilize (fsl_buffer *b)
 Defossilizes the contents of b. More...
 
FSL_EXPORT int fsl_buffer_delta_apply (fsl_buffer const *pOriginal, fsl_buffer const *pDelta, fsl_buffer *pTarget)
 Apply the delta in pDelta to the original content pOriginal to generate the target content pTarget. More...
 
FSL_EXPORT int fsl_buffer_delta_apply2 (fsl_buffer const *pOriginal, fsl_buffer const *pDelta, fsl_buffer *pTarget, fsl_error *pErr)
 Identical to fsl_buffer_delta_apply() except that if delta application fails then any error messages/codes are written to pErr if it is not NULL. More...
 
FSL_EXPORT int fsl_buffer_delta_create (fsl_buffer const *src, fsl_buffer const *newVers, fsl_buffer *delta)
 A fsl_delta_create() wrapper which uses the first two arguments as the original and "new" content versions to delta, and outputs the delta to the 3rd argument (overwriting any existing contents and re-using any memory it had allocated). More...
 
FSL_EXPORT int fsl_buffer_fill_from (fsl_buffer *dest, fsl_input_f src, void *state)
 Uses a fsl_input_f() function to buffer input into a fsl_buffer. More...
 
FSL_EXPORT int fsl_buffer_fill_from_FILE (fsl_buffer *dest, FILE *src)
 A fsl_buffer_fill_from() proxy which overwrite's dest->mem with the contents of the given FILE handler (which must be opened for read access). More...
 
FSL_EXPORT int fsl_buffer_fill_from_filename (fsl_buffer *dest, char const *filename)
 A wrapper for fsl_buffer_fill_from_FILE() which gets its input from the given file name. More...
 
FSL_EXPORT char fsl_buffer_is_compressed (fsl_buffer const *buf)
 Equivalent to fsl_data_is_compressed(buf->mem, buf->used). More...
 
FSL_EXPORT int fsl_buffer_reserve (fsl_buffer *buf, fsl_size_t n)
 Reserves at least n bytes of capacity in buf. More...
 
FSL_EXPORT int fsl_buffer_reset (fsl_buffer *buf)
 Resets buf->used to 0 and sets buf->mem[0] (if buf->mem is not NULL) to 0. More...
 
FSL_EXPORT int fsl_buffer_resize (fsl_buffer *buf, fsl_size_t n)
 Similar to fsl_buffer_reserve() except that... More...
 
FSL_EXPORT fsl_size_t fsl_buffer_size (fsl_buffer const *b)
 Returns the "used" size of b, or 0 if !b. More...
 
FSL_EXPORT char * fsl_buffer_str (fsl_buffer const *b)
 Equivalent to ((char *)b->mem), but returns NULL if !b. More...
 
FSL_EXPORT int fsl_buffer_stream_lines (fsl_buffer *pFrom, fsl_output_f fTo, void *toState, fsl_size_t N)
 Works identically to fsl_buffer_copy_lines() except that it sends its output. More...
 
FSL_EXPORT int fsl_buffer_strftime (fsl_buffer *b, char const *format, const struct tm *timeptr)
 A convenience form of fsl_strftime() which assumes that the formatted string is of "some reasonable size" and appends its formatted representation to b. More...
 
FSL_EXPORT void fsl_buffer_swap (fsl_buffer *left, fsl_buffer *right)
 Swaps the contents of the left and right arguments. More...
 
FSL_EXPORT void fsl_buffer_swap_free (fsl_buffer *left, fsl_buffer *right, int clearWhich)
 Similar fsl_buffer_swap() but it also optionally frees one of the buffer's memories after swapping them. More...
 
FSL_EXPORT int fsl_buffer_to_filename (fsl_buffer const *b, char const *fname)
 Writes the given buffer to the given filename. More...
 
FSL_EXPORT int fsl_buffer_uncompress (fsl_buffer const *pIn, fsl_buffer *pOut)
 Uncompress buffer pIn and store the result in pOut. More...
 
FSL_EXPORT fsl_int_t fsl_buffer_uncompressed_size (fsl_buffer const *b)
 The fsl_buffer counterpart of fsl_data_uncompressed_size(). More...
 
FSL_EXPORT void fsl_bytes_defossilize (unsigned char *inp, fsl_size_t *resultLen)
 "Defossilizes" bytes encoded by fsl_bytes_fossilize() in-place. More...
 
FSL_EXPORT int fsl_bytes_fossilize (unsigned char const *inp, fsl_int_t len, fsl_buffer *out)
 "Fossilizes" the first len bytes of the given input string. More...
 
FSL_EXPORT void fsl_canonical16 (char *z, fsl_size_t n)
 The input string is a base16 value. More...
 
FSL_EXPORT int fsl_chdir (const char *zChDir)
 Performs a chdir() to the directory named by zChDir. More...
 
FSL_EXPORT int fsl_confirm (fsl_confirmation_f f, void *state, char const *fmt,...)
 Creates a formatted message string using fsl_appendf(fmt,...) and passes that message to f(state,...). More...
 
FSL_EXPORT int fsl_confirmation_f_int (void *state, char const *msg, fsl_size_t msgLen)
 A fsl_confirmation_f() implementation which expects the state parameter to be a (int [const] *) which dereferences to one of the FSL_CONFIRM_xxx values, defaulting to FSL_CONFIRM_ERROR. More...
 
FSL_EXPORT int fsl_confirmv (fsl_confirmation_f f, void *state, char const *fmt, va_list)
 The va_list counterpart of fsl_confirm(). More...
 
FSL_EXPORT char fsl_data_is_compressed (unsigned char const *mem, fsl_size_t len)
 Returns true if this function believes that mem (which must be at least len bytes of valid memory long) appears to have been compressed by fsl_buffer_compress() or equivalent. More...
 
FSL_EXPORT fsl_int_t fsl_data_uncompressed_size (unsigned char const *mem, fsl_size_t len)
 If fsl_data_is_compressed(mem,len) returns true then this function returns the uncompressed size of the data, else it returns a negative value. More...
 
FSL_EXPORT int fsl_decode16 (const unsigned char *zIn, unsigned char *pOut, fsl_size_t N)
 Decode a N-character base-16 number into base-256. More...
 
FSL_EXPORT int fsl_delta_applied_size (unsigned char const *zDelta, fsl_size_t lenDelta, fsl_size_t *appliedSize)
 
FSL_EXPORT int fsl_delta_apply (unsigned char const *zSrc, fsl_size_t lenSrc, unsigned char const *zDelta, fsl_size_t lenDelta, unsigned char *zOut)
 Apply a delta created using fsl_delta_create(). More...
 
FSL_EXPORT int fsl_delta_apply2 (unsigned char const *zSrc, fsl_size_t lenSrc, unsigned char const *zDelta, fsl_size_t lenDelta, unsigned char *zOut, fsl_error *pErr)
 Functionally identical to fsl_delta_apply() but any errors generated during application of the delta are described in more detail in pErr. More...
 
FSL_EXPORT int fsl_delta_create (unsigned char const *zSrc, fsl_size_t lenSrc, unsigned char const *zOut, fsl_size_t lenOut, unsigned char *zDelta, fsl_size_t *deltaSize)
 Create a new delta between the memory zIn and zOut. More...
 
FSL_EXPORT int fsl_delta_create2 (unsigned char const *zSrc, fsl_size_t lenSrc, unsigned char const *zOut, fsl_size_t lenOut, fsl_output_f out, void *outState)
 Works identically to fsl_delta_create() but sends its output to the given output function. More...
 
FSL_EXPORT int fsl_diff_text (fsl_buffer const *pA, fsl_buffer const *pB, fsl_output_f out, void *outState, short contextLines, short sbsWidth, int diffFlags)
 Generates a textual diff from two text inputs and writes it to the given output function. More...
 
FSL_EXPORT int fsl_diff_text_to_buffer (fsl_buffer const *pA, fsl_buffer const *pB, fsl_buffer *pOut, short contextLines, short sbsWidth, int diffFlags)
 Functionally equivalent to: More...
 
FSL_EXPORT int fsl_dir_check (const char *zFilename)
 Returns a positive value if zFilename is a directory, 0 if zFilename does not exist, or a negative value if zFilename exists but is something other than a directory. More...
 
FSL_EXPORT int fsl_encode16 (const unsigned char *pIn, unsigned char *zOut, fsl_size_t N)
 Encode a N-digit base-256 in base-16. More...
 
FSL_EXPORT int fsl_errno_to_rc (int errNo, int dflt)
 Tries to convert the value of errNo, which is assumed to come from the global errno, to a fsl_rc_t code. More...
 
FSL_EXPORT void fsl_error_clear (fsl_error *err)
 Frees up any resources owned by err and sets its error code to 0, but does not free err. More...
 
FSL_EXPORT int fsl_error_copy (fsl_error const *src, fsl_error *dest)
 Copies the error state from src to dest. More...
 
FSL_EXPORT int fsl_error_get (fsl_error const *err, char const **str, fsl_size_t *len)
 Fetches the error state from err. More...
 
FSL_EXPORT void fsl_error_move (fsl_error *from, fsl_error *to)
 Moves the error state from one fsl_error object to another, intended as an allocation optimization when propagating error state up the API. More...
 
FSL_EXPORT void fsl_error_reset (fsl_error *err)
 Sets err->code to 0 and resets its buffer, but keeps any err->msg memory around for later re-use. More...
 
FSL_EXPORT int fsl_error_set (fsl_error *err, int code, char const *fmt,...)
 Populates err with the given code and formatted string, replacing any existing state. More...
 
FSL_EXPORT int fsl_error_setv (fsl_error *err, int code, char const *fmt, va_list args)
 va_list counterpart to fsl_error_set(). More...
 
FSL_EXPORT void fsl_fclose (FILE *f)
 Passes f to fclose(3) unless f is NULL or one of the C-standard (stdin, stdout, stderr) handles, in which cases it does nothing at all. More...
 
FSL_EXPORT int fsl_file_access (const char *zFilename, int flags)
 Returns 0 if the given file is readable. More...
 
FSL_EXPORT int fsl_file_canonical_name (const char *zOrigName, fsl_buffer *pOut, char slash)
 Equivalent to fsl_file_canonical_name2(NULL, zOrigName, pOut, slash). More...
 
FSL_EXPORT int fsl_file_canonical_name2 (const char *zRoot, const char *zOrigName, fsl_buffer *pOut, char slash)
 Computes a canonical pathname for a file or directory. More...
 
FSL_EXPORT int fsl_file_dirpart (char const *zFilename, fsl_int_t nLen, fsl_buffer *pOut, char leaveSlash)
 Calculates the "directory part" of zFilename and _appends_ it to pOut. More...
 
FSL_EXPORT fsl_time_t fsl_file_mtime (const char *zFilename)
 Return the modification time for a file. More...
 
FSL_EXPORT int fsl_file_mtime_set (const char *zFilename, fsl_time_t newMTime)
 Sets the mtime (Unix epoch) for a file. More...
 
FSL_EXPORT fsl_size_t fsl_file_simplify_name (char *z, fsl_int_t n_, char slash)
 Simplify a filename by: More...
 
FSL_EXPORT fsl_size_t fsl_file_size (const char *zFilename)
 Return the size of a file in bytes. More...
 
FSL_EXPORT int fsl_file_unlink (const char *zFilename)
 Deletes the given file from the filesystem. More...
 
FSL_EXPORT void fsl_filename_free (void *pOld)
 Deallocate pOld, which must have been allocated by fsl_filename_to_utf8(), fsl_utf8_to_filename(), fsl_getenv(), or another routine which explicitly documents this function as being the proper finalizer for its returned memory. More...
 
FSL_EXPORT char * fsl_filename_to_utf8 (const void *zFilename)
 Translate text from the OS's character set into UTF-8. More...
 
FSL_EXPORT int fsl_finalizer_f_buffer (void *state, void *mem)
 fsl_finalizer_f() impl which requires that mem be-a (fsl_buffer*). More...
 
FSL_EXPORT void fsl_finalizer_f_FILE (void *state, void *mem)
 A fsl_finalizer_f() impl which requires that mem be-a (FILE*). More...
 
FSL_EXPORT int fsl_find_home_dir (fsl_buffer *tgt, char requireWriteAccess)
 Tries to find the user's home directory. More...
 
FSL_EXPORT int fsl_flush_f_FILE (void *_FILE)
 A fsl_flush_f() impl which expects _FILE to be-a (FILE*) opened for writing, which this function passes the call on to fflush(). More...
 
FSL_EXPORT FILE * fsl_fopen (char const *name, char const *mode)
 _Almost_ equivalent to fopen(3) but: More...
 
FSL_EXPORT fsl_int_t fsl_fprintf (FILE *fp, char const *fmt,...)
 Emulates fprintf() using fsl_appendf(). More...
 
FSL_EXPORT fsl_int_t fsl_fprintfv (FILE *fp, char const *fmt, va_list args)
 The va_list counterpart of fsl_fprintf(). More...
 
FSL_EXPORT void fsl_free (void *mem)
 Semantically behaves like free(3), but may introduce instrumentation, error checking, or similar. More...
 
FSL_EXPORT int fsl_getcwd (char *zBuf, fsl_size_t nBuf, fsl_size_t *outLen)
 Writes the absolute path name of the current directory to zBuf, which must be at least nBuf bytes long (nBuf includes the space for a trailing NUL terminator). More...
 
FSL_EXPORT char * fsl_getenv (const char *zName)
 Returns a (possible) copy of the environment variable with the given key, or NULL if no entry is found. More...
 
FSL_EXPORT int fsl_glob_list_append (fsl_list *tgt, char const *zGlob)
 Appends a single blob pattern to tgt, in the form of a new (char *) owned by tgt. More...
 
FSL_EXPORT void fsl_glob_list_clear (fsl_list *globList)
 If globList is not NULL this is equivalent to fsl_list_visit_free(globList, 1), otherwise it is a no-op. More...
 
FSL_EXPORT char const * fsl_glob_list_matches (fsl_list const *globList, char const *zHaystack)
 Assumes globList is a list of (char [const] *) glob values and tries to match each one against zHaystack using fsl_str_glob(). More...
 
FSL_EXPORT int fsl_glob_list_parse (fsl_list *tgt, char const *zPatternList)
 Parses zPatternList as a comma-and/or-fsl_isspace()-delimited list of glob patterns (as supported by fsl_str_glob()). More...
 
FSL_EXPORT unsigned int fsl_gradient_color (unsigned int c1, unsigned int c2, unsigned int numberOfSteps, unsigned int stepNumber)
 For two color values encoded as RRGGBB values (see below for the structure), this function computes a gradient somewhere between those colors. More...
 
FSL_EXPORT char * fsl_guess_user_name ()
 Uses fsl_getenv() to look for the environment variables (FOSSIL_USER, (Windows: USERNAME), (Unix: USER, LOGNAME)). More...
 
FSL_EXPORT int fsl_htmlize (fsl_output_f out, void *oState, const char *zIn, fsl_int_t n)
 Make the given string safe for HTML by converting every "<" into "&lt;", every ">" into "&gt;", every "&" into "&amp;", and encode '"' as " so that it can appear as an argument to markup. More...
 
FSL_EXPORT char * fsl_htmlize_str (const char *zIn, fsl_int_t n)
 Equivalent to fsl_htmlize_to_buffer() but returns the result as a new string which must eventually be fsl_free()d by the caller. More...
 
FSL_EXPORT int fsl_htmlize_to_buffer (fsl_buffer *p, const char *zIn, fsl_int_t n)
 Functionally equivalent to fsl_htmlize() but optimized to perform only a single allocation. More...
 
FSL_EXPORT fsl_size_t fsl_htmlize_xlate (int c, char const **xlate)
 If c is a character Fossil likes to HTML-escape, assigns *xlate to its transformed form, else set it to NULL. More...
 
FSL_EXPORT void fsl_id_bag_clear (fsl_id_bag *p)
 Frees any memory owned by p, but does not free p. More...
 
FSL_EXPORT char fsl_id_bag_contains (fsl_id_bag *p, fsl_id_t e)
 Returns true (non-0) if e in the bag. More...
 
FSL_EXPORT fsl_size_t fsl_id_bag_count (fsl_id_bag *p)
 Return the number of elements in the bag. More...
 
FSL_EXPORT fsl_id_t fsl_id_bag_first (fsl_id_bag *p)
 Returns the ID of the first element in the bag. More...
 
FSL_EXPORT int fsl_id_bag_insert (fsl_id_bag *p, fsl_id_t e)
 Insert element e into the bag if it is not there already. More...
 
fsl_id_t fsl_id_bag_next (fsl_id_bag *p, fsl_id_t e)
 Returns the next element in the bag after e. More...
 
FSL_EXPORT void fsl_id_bag_remove (fsl_id_bag *p, fsl_id_t e)
 Remove element e from the bag if it exists in the bag. More...
 
FSL_EXPORT int fsl_input_f_buffer (void *state, void *dest, fsl_size_t *n)
 A fsl_input_f() implementation which requires that state be a readable (fsl_buffer*) handle. More...
 
FSL_EXPORT int fsl_input_f_FILE (void *state, void *dest, fsl_size_t *n)
 A fsl_input_f() implementation which requires that state be a readable (FILE*) handle. More...
 
FSL_EXPORT char fsl_is_absolute_path (const char *zPath)
 Returns true if the given path appears to be absolute, else false. More...
 
FSL_EXPORT char fsl_is_file (const char *zFilename)
 Return TRUE if the named file is an ordinary file. More...
 
FSL_EXPORT char fsl_is_simple_pathname (const char *z, char bStrictUtf8)
 Return true (non-0) if the filename given is a valid filename for a file in a repository. More...
 
FSL_EXPORT char fsl_is_uuid (char const *str)
 Returns true (non-0) if str is not NULL, is exactly FSL_UUID_STRLEN bytes long (meaning its final byte is a NUL), and contains only lower-case hexadecimal characters, else returns false (0). More...
 
FSL_EXPORT char fsl_isalnum (int c)
 Equivalent to fsl_isdigit(c) || fsl_isalpha(). More...
 
FSL_EXPORT char fsl_isalpha (int c)
 Returns true if the given letter is an ASCII alphabet character. More...
 
FSL_EXPORT char fsl_isatty (int fd)
 Returns the result of calling the platform's equivalent of isatty(fd). More...
 
FSL_EXPORT char fsl_isdigit (int c)
 Returns true if c is an ASCII digit in the range '0' to '9'. More...
 
FSL_EXPORT char fsl_islower (int c)
 Returns true if c is a lower-case ASCII alphabet character. More...
 
FSL_EXPORT char fsl_iso8601_to_julian (char const *zDate, fsl_double_t *pOut)
 If zDate is an ISO8601-format string, optionally with a .NNN fractional suffix, then this function returns true and sets pOut (if pOut is not NULL) to the corresponding Julian value. More...
 
FSL_EXPORT char fsl_isspace (int c)
 Returns true if c is ' ', '\r' (ASCII 13dec), or '\t' (ASCII 9 dec). More...
 
FSL_EXPORT char fsl_isupper (int c)
 Returns true if c is an upper-case ASCII alphabet character. More...
 
FSL_EXPORT fsl_double_t fsl_julian_now ()
 Returns the current Unix Epoch time converted to its approximate Julian form. More...
 
FSL_EXPORT char fsl_julian_to_iso8601 (fsl_double_t J, char *pOut, char addMs)
 Converts the Julian Day J to an ISO8601 time string. More...
 
FSL_EXPORT fsl_time_t fsl_julian_to_unix (fsl_double_t J)
 Returns the Julian Day time J value converted to a Unix Epoch timestamp. More...
 
FSL_EXPORT int fsl_list_append (fsl_list *self, void *cp)
 Appends a bitwise copy of cp to self->list, expanding the list as necessary and adjusting self->used. More...
 
FSL_EXPORT int fsl_list_clear (fsl_list *list, fsl_list_visitor_f childFinalizer, void *finalizerState)
 A list clean-up routine which takes a callback to clean up its contents. More...
 
FSL_EXPORT fsl_int_t fsl_list_index_of (fsl_list const *li, void const *value, fsl_generic_cmp_f cmpf)
 Searches for a value in the given list, using the given comparison function to determine equivalence. More...
 
FSL_EXPORT fsl_int_t fsl_list_index_of_cstr (fsl_list const *li, char const *key)
 Equivalent to fsl_list_index_of(li, key, fsl_strcmp_cmp). More...
 
FSL_EXPORT int fsl_list_reserve (fsl_list *self, fsl_size_t n)
 Possibly reallocates self->list, changing its size. More...
 
FSL_EXPORT void fsl_list_sort (fsl_list *li, fsl_generic_cmp_f cmp)
 Sorts the given list using the given comparison function. More...
 
FSL_EXPORT void fsl_list_swap (fsl_list *lhs, fsl_list *rhs)
 Swaps all contents of both lhs and rhs. More...
 
FSL_EXPORT int fsl_list_v_fsl_free (void *obj, void *visitorState)
 A fsl_list_visitor_f() implementation which requires that obj be arbitrary memory which can legally be passed to fsl_free() (which this function does). More...
 
FSL_EXPORT int fsl_list_visit (fsl_list const *self, int order, fsl_list_visitor_f visitor, void *visitorState)
 For each item in self->list, visitor(item,visitorState) is called. More...
 
FSL_EXPORT void fsl_list_visit_free (fsl_list *list, char freeListMem)
 Similar to fsl_list_clear(list, fsl_list_v_fsl_free, NULL), but only frees list->list if the second argument is true, otherwise it sets the list's length to 0 but keep the list->list memory intact for later use. More...
 
FSL_EXPORT int fsl_list_visit_p (fsl_list *self, int order, char shiftIfNulled, fsl_list_visitor_f visitor, void *visitorState)
 Works similarly to the visit operation without the _p suffix except that the pointer the visitor function gets is a (**) pointing back to the entry within this list. More...
 
void * fsl_malloc (fsl_size_t n)
 Semantically behaves like malloc(3), but may introduce instrumentation, error checking, or similar. More...
 
FSL_EXPORT int fsl_mkdir (const char *zName, char forceFlag)
 Create the directory with the given name if it does not already exist. More...
 
FSL_EXPORT int fsl_mkdir_for_file (char const *zName, char forceFlag)
 A convenience form of fsl_mkdir() which can recursively create directories. More...
 
FSL_EXPORT char * fsl_mprintf (char const *fmt,...)
 Works like fsl_appendfv(), but appends all output to a dynamically-allocated string, expanding the string as necessary to collect all formatted data. More...
 
FSL_EXPORT char * fsl_mprintfv (char const *fmt, va_list vargs)
 va_list counterpart to fsl_mprintf(). More...
 
FSL_EXPORT int fsl_output_f_buffer (void *state, void const *src, fsl_size_t n)
 A fsl_output_f() impl which requires state to be-a (fsl_buffer*), which this function passes to fsl_buffer_append(). More...
 
FSL_EXPORT int fsl_output_f_FILE (void *state, void const *src, fsl_size_t n)
 fsl_output_f() implementation which requires state to be a writeable (FILE*) handle. More...
 
FSL_EXPORT int fsl_output_f_fsl_cx (void *state, void const *src, fsl_size_t n)
 fsl_output_f() implementation which requires state to be a (fsl_cx*) to which this routine simply redirects the output via fsl_output(). More...
 
FSL_EXPORT void fsl_pathfinder_clear (fsl_pathfinder *pf)
 Frees all memory associated with pf, but does not free pf. More...
 
FSL_EXPORT int fsl_pathfinder_dir_add (fsl_pathfinder *pf, char const *dir)
 Adds the given directory to pf's search path. More...
 
FSL_EXPORT int fsl_pathfinder_ext_add (fsl_pathfinder *pf, char const *ext)
 Adds the given directory to pf's search extensions. More...
 
FSL_EXPORT int fsl_pathfinder_search (fsl_pathfinder *pf, char const *base, char const **pOut, fsl_size_t *outLen)
 Searches for a file whose name can be constructed by some combination of pf's directory/suffix list and the given base name. More...
 
FSL_EXPORT void * fsl_realloc (void *mem, fsl_size_t n)
 Behaves like realloc(3). More...
 
FSL_EXPORT void * fsl_realloc_f_stdalloc (void *state, void *mem, fsl_size_t n)
 A fsl_realloc_f() implementation which uses the standard malloc()/free()/realloc(). More...
 
FSL_EXPORT void fsl_rgb_decode (unsigned int src, int *r, int *g, int *b)
 Given an RGB-encoded source value, this function decodes the lower 24 bits into r, g, and b. More...
 
FSL_EXPORT unsigned int fsl_rgb_encode (int r, int g, int b)
 For the given red/green/blue values (all in the range of 0 to 255, or truncated to be so!) this function returns the RGB encoded in the lower 24 bits of a single number. More...
 
FSL_EXPORT fsl_size_t fsl_simplify_sql (char *sql, fsl_int_t len)
 "Simplifies" an SQL string by making the following modifications inline: More...
 
FSL_EXPORT fsl_size_t fsl_simplify_sql_buffer (fsl_buffer *b)
 Convenience form of fsl_simplify_sql() which assumes b holds an SQL string. More...
 
FSL_EXPORT fsl_int_t fsl_snprintf (char *dest, fsl_size_t n, char const *fmt,...)
 An sprintf(3) clone which uses fsl_appendf() for the formatting. More...
 
FSL_EXPORT fsl_int_t fsl_snprintfv (char *dest, fsl_size_t n, char const *fmt, va_list args)
 va_list counterpart to fsl_snprintf() More...
 
FSL_EXPORT int fsl_stat (const char *zFilename, fsl_fstat *fst, char derefSymlinks)
 Runs the OS's stat(2) equivalent to populate fst with information about the given file. More...
 
FSL_EXPORT char fsl_str_bool (char const *s)
 Returns false if s is NULL or starts with any of (0 (NUL), '0' (ASCII character zero), 'f', 'n', "off"), case-insensitively, else it returns true. More...
 
FSL_EXPORT char fsl_str_glob (const char *zGlob, const char *z)
 Return true (non-zero) if string z matches glob pattern zGlob and zero if the pattern does not match. More...
 
FSL_EXPORT char fsl_str_is_date (const char *z)
 Returns non-0 (true) if the first 10 digits of z _appear_ to form the start of an ISO date string (YYYY-MM-DD). More...
 
FSL_EXPORT int fsl_str_is_date2 (const char *z)
 Checks if z is syntactically a time-format string in the format: More...
 
FSL_EXPORT fsl_int_t fsl_str_to_int (char const *str, fsl_int_t dflt)
 Expects str to be a string containing a decimal value, optionally with a leading sign. More...
 
FSL_EXPORT fsl_size_t fsl_str_to_size (char const *str)
 Expects str to be a string containing an unsigned decimal value. More...
 
FSL_EXPORT int fsl_strcmp (char const *lhs, char const *rhs)
 Like strcmp(3) except that it accepts NULL pointers. More...
 
FSL_EXPORT int fsl_strcmp_cmp (void const *lhs, void const *rhs)
 Equivalent to fsl_strcmp(), but with a signature suitable for use as a generic comparison function (e.g. More...
 
FSL_EXPORT char * fsl_strdup (char const *src)
 Equivalent to fsl_strndup(src,-1). More...
 
FSL_EXPORT int fsl_stream (fsl_input_f inF, void *inState, fsl_output_f outF, void *outState)
 A generic streaming routine which copies data from an fsl_input_f() to an fsl_outpuf_f(). More...
 
FSL_EXPORT int fsl_stream_compare (fsl_input_f in1, void *in1State, fsl_input_f in2, void *in2State)
 Consumes two input streams looking for differences. More...
 
FSL_EXPORT fsl_size_t fsl_strftime (char *dest, fsl_size_t destLen, const char *format, const struct tm *timeptr)
 A strftime() implementation. More...
 
FSL_EXPORT fsl_size_t fsl_strftime_unix (char *dest, fsl_size_t destLen, char const *format, fsl_time_t epochTime, char convertToLocal)
 A convenience form of fsl_strftime() which takes its timestamp in the form of a Unix Epoch time. More...
 
FSL_EXPORT int fsl_stricmp (const char *zA, const char *zB)
 Case-insensitive form of fsl_strcmp(). More...
 
FSL_EXPORT int fsl_stricmp_cmp (void const *lhs, void const *rhs)
 Equivalent to fsl_stricmp(), but with a signature suitable for use as a generic comparison function (e.g. More...
 
FSL_EXPORT fsl_size_t fsl_strlen (char const *src)
 Equivalent to strlen(3) but returns 0 if src is NULL. More...
 
FSL_EXPORT int fsl_strncmp (const char *zA, const char *zB, fsl_size_t nByte)
 fsl_strcmp() variant which compares at most nByte bytes of the given strings, case-sensitively. More...
 
FSL_EXPORT char * fsl_strndup (char const *src, fsl_int_t len)
 Similar to strndup(3) but returns NULL if !src. More...
 
FSL_EXPORT int fsl_strnicmp (const char *zA, const char *zB, fsl_int_t nByte)
 fsl_strcmp() variant which compares at most nByte bytes of the given strings, case-insensitively. More...
 
FSL_EXPORT fsl_uint64_t fsl_timer_fetch (fsl_timer_state const *t)
 Returns the difference in _CPU_ times in microseconds since t was last passed to fsl_timer_start() or fsl_timer_reset(). More...
 
FSL_EXPORT fsl_uint64_t fsl_timer_reset (fsl_timer_state *t)
 Resets t to the current time and returns the number of microseconds since t was started or last reset. More...
 
FSL_EXPORT void fsl_timer_start (fsl_timer_state *t)
 Sets t's counter state to the current CPU timer usage, as determined by the OS. More...
 
FSL_EXPORT fsl_uint64_t fsl_timer_stop (fsl_timer_state *t)
 Clears t's state and returns the difference (in uSec) between the last time t was started or reset, as per fsl_timer_fetch(). More...
 
FSL_EXPORT int fsl_tolower (int c)
 Returns the upper-case form of c if c is an ASCII alphabet letter, else returns c. More...
 
FSL_EXPORT int fsl_toupper (int c)
 Returns the lower-case form of c if c is an ASCII alphabet letter, else returns c. More...
 
FSL_EXPORT void fsl_unicode_free (void *)
 Deallocates the given memory, which must have been allocated from fsl_unicode_to_utf8(), fsl_utf8_to_unicode(), or any function which explicitly documents this function as being the proper finalizer for its returned memory. More...
 
FSL_EXPORT char * fsl_unicode_to_utf8 (const void *zUnicode)
 Translates Unicode text into UTF-8. More...
 
FSL_EXPORT fsl_double_t fsl_unix_to_julian (fsl_time_t unixEpoch)
 Returns the given Unix Epoch timestamp value as its approximate Julian Day value. More...
 
FSL_EXPORT void * fsl_utf8_to_filename (const char *zUtf8)
 Translate text from UTF-8 to the OS's filename character set. More...
 
FSL_EXPORT void * fsl_utf8_to_unicode (const char *zUtf8)
 Translate UTF-8 to Unicode for use in system calls. More...
 
FSL_EXPORT int fsl_uuidcmp (fsl_uuid_cstr lhs, fsl_uuid_cstr rhs)
 Equivalent to fsl_strncmp(lhs, rhs, FSL_UUID_STRLEN). More...
 
FSL_EXPORT char fsl_validate16 (const char *zIn, fsl_size_t nIn)
 Return true (non-0) if the input string contains only valid base-16 digits. More...
 
FSL_EXPORT fsl_buffer const * fsl_zip_body (fsl_zip_writer const *z)
 Returns a pointer to z's ZIP content buffer. More...
 
FSL_EXPORT int fsl_zip_end (fsl_zip_writer *z)
 Ends the ZIP-creation process, padding all buffers, writing all final required values, and freeing up most of the memory owned by z. More...
 
FSL_EXPORT int fsl_zip_end_take (fsl_zip_writer *z, fsl_buffer *dest)
 This variant of fsl_zip_end() transfers the current contents of the zip's body to dest, replacing (freeing) any contents it may hold when this is called, then passes z to fsl_zip_finalize() to free any other resources (which are invalidated by the removal of the body). More...
 
FSL_EXPORT int fsl_zip_end_to_filename (fsl_zip_writer *z, char const *filename)
 This variant of fsl_zip_end_take() passes z to fsl_zip_end(), write's the ZIP body to the given filename, passes z to fsl_zip_finalize(), and returns the result of either end/save combination. More...
 
FSL_EXPORT int fsl_zip_file_add (fsl_zip_writer *z, char const *zFilename, fsl_buffer const *pContent, int permsFlag)
 Adds a file or directory to the ZIP writer z. More...
 
FSL_EXPORT void fsl_zip_finalize (fsl_zip_writer *z)
 Frees all memory owned by z and resets it to a clean state, but does not free z. More...
 
FSL_EXPORT int fsl_zip_root_set (fsl_zip_writer *z, char const *zRoot)
 Sets a virtual root directory in z, such that all files added with fsl_zip_file_add() will get this directory prefixed to it. More...
 
FSL_EXPORT void fsl_zip_timestamp_set_julian (fsl_zip_writer *z, fsl_double_t rDate)
 Set z's date and time from a Julian Day number. More...
 
FSL_EXPORT void fsl_zip_timestamp_set_unix (fsl_zip_writer *z, fsl_time_t epochTime)
 Set z's date and time from a Unix Epoch time. More...
 

Variables

FSL_EXPORT const fsl_buffer fsl_buffer_empty
 Empty-initialized fsl_buffer instance, intended for copy initialization. More...
 
FSL_EXPORT const fsl_confirmer fsl_confirmer_empty
 Initialized-with-defaults fsl_confirmer struct. More...
 
FSL_EXPORT const fsl_error fsl_error_empty
 Empty-initialized fsl_error instance, intended for copy initialization. More...
 
FSL_EXPORT const fsl_fstat fsl_fstat_empty
 Empty-initialized fsl_fstat instance, intended for copy construction. More...
 
FSL_EXPORT const fsl_id_bag fsl_id_bag_empty
 Initialized-with-defaults fsl_id_bag structure, intended for copy initialization. More...
 
FSL_EXPORT const fsl_list fsl_list_empty
 Empty-initialized fsl_list structure, intended for copy initialization. More...
 
FSL_EXPORT const fsl_outputer fsl_outputer_empty
 Empty-initialized fsl_outputer instance, intended for copy-initializing. More...
 
FSL_EXPORT const fsl_outputer fsl_outputer_FILE
 A fsl_outputer instance which is initialized to output to a (FILE*). More...
 
FSL_EXPORT const fsl_pathfinder fsl_pathfinder_empty
 Initialized-with-defaults fsl_pathfinder instance, intended for copy initialization. More...
 
FSL_EXPORT const fsl_state fsl_state_empty
 Empty-initialized fsl_state struct, intended for copy-initializing. More...
 
FSL_EXPORT const fsl_timer_state fsl_timer_state_empty
 Initialized-with-defaults fsl_timer_state_empty instance, intended for copy initialization. More...
 
FSL_EXPORT const fsl_zip_writer fsl_zip_writer_empty
 An initialized-with-defaults fsl_zip_writer instance, intended for copy-initialization. More...
 

Detailed Description

This file declares a number of utility classes and routines used by libfossil.

All of them considered "public", suitable for direct use by client code.

Definition in file fossil-util.h.

Macro Definition Documentation

#define fsl_allocator_empty_m   {NULL,NULL}

Empty-initialized fsl_allocator instance.

Definition at line 409 of file fossil-util.h.

#define fsl_buffer_empty_m   {NULL,0U,0U,0U}

Empty-initialized fsl_buffer instance, intended for const-copy initialization.

Definition at line 676 of file fossil-util.h.

#define fsl_confirmer_empty_m   {NULL,NULL}

Initialized-with-defaults fsl_confirmer struct.

Definition at line 3495 of file fossil-util.h.

#define fsl_error_empty_m   {fsl_buffer_empty_m,0}

Empty-initialized fsl_error instance, intended for const-copy initialization.

Definition at line 705 of file fossil-util.h.

#define fsl_finalizer_empty_m   {NULL,NULL}

Empty-initialized fsl_finalizer struct.

Definition at line 214 of file fossil-util.h.

#define fsl_fstat_empty_m   {FSL_FSTAT_TYPE_UNKNOWN,0,0,0,0}

Empty-initialized fsl_fstat structure, intended for const-copy construction.

Definition at line 2600 of file fossil-util.h.

#define fsl_id_bag_empty_m
Value:
{ \
0/*entryCount*/, 0/*capacity*/, \
0/*used*/, NULL/*list*/ }

Initialized-with-defaults fsl_id_bag structure, intended for in-struct initialization.

Definition at line 4019 of file fossil-util.h.

#define fsl_list_empty_m   { NULL, 0, 0 }

Empty-initialized fsl_list structure, intended for const-copy initialization.

Definition at line 172 of file fossil-util.h.

#define fsl_outputer_empty_m   {NULL,NULL,fsl_state_empty_m}

Empty-initialized fsl_outputer instance.

Definition at line 341 of file fossil-util.h.

#define fsl_outputer_FILE_m
Value:
{ \
{/*state*/ \
NULL, \
} \
}
FSL_EXPORT void fsl_finalizer_f_FILE(void *state, void *mem)
A fsl_finalizer_f() impl which requires that mem be-a (FILE*).
FSL_EXPORT int fsl_output_f_FILE(void *state, void const *src, fsl_size_t n)
fsl_output_f() implementation which requires state to be a writeable (FILE*) handle.
FSL_EXPORT int fsl_flush_f_FILE(void *_FILE)
A fsl_flush_f() impl which expects _FILE to be-a (FILE*) opened for writing, which this function pass...

fsl_outputer initializer which uses fsl_flush_f_FILE(), fsl_output_f_FILE(), and fsl_finalizer_f_FILE().

Definition at line 365 of file fossil-util.h.

#define fsl_pathfinder_empty_m   {fsl_list_empty_m/*ext*/,fsl_list_empty_m/*dirs*/,fsl_buffer_empty_m/*buf*/}

Initialized-with-defaults fsl_pathfinder instance, intended for const copy initialization.

Definition at line 3288 of file fossil-util.h.

#define fsl_state_empty_m   {NULL,fsl_finalizer_empty_m}

Empty-initialized fsl_state struct.

Definition at line 251 of file fossil-util.h.

#define fsl_timer_state_empty_m   {0,0}

Initialized-with-defaults fsl_timer_state_empty instance, intended for const copy initialization.

Definition at line 3824 of file fossil-util.h.

#define fsl_zip_writer_empty_m
Value:
{ \
0/*entryCount*/, \
0/*dosTime*/, \
0/*dosDate*/, \
0/*unixTime*/, \
NULL/*rootDir*/, \
}
#define fsl_buffer_empty_m
Empty-initialized fsl_buffer instance, intended for const-copy initialization.
Definition: fossil-util.h:676
#define fsl_list_empty_m
Empty-initialized fsl_list structure, intended for const-copy initialization.
Definition: fossil-util.h:172

An initialized-with-defaults fsl_zip_writer instance, intended for in-struct or const-copy initialization.

Definition at line 3577 of file fossil-util.h.

Typedef Documentation

typedef struct fsl_allocator fsl_allocator

Definition at line 38 of file fossil-util.h.

fsl_int_t(* fsl_appendf_f)(void *state, char const *data, fsl_int_t n)

The fsl_appendf_f typedef is used to provide fsl_appendfv() with a flexible output routine, so that it can be easily send its output to arbitrary targets.

The policies which implementations need to follow are:

  • state is an implementation-specific pointer (may be 0) which is passed to fsl_appendf(). fsl_appendfv() doesn't know what this argument is but passes it to its fsl_appendf_f argument. Typically this pointer will be an object or resource handle to which string data is pushed.
  • The 'data' parameter is the data to append. The API does not currently guaranty that data containing embeded NULs will survive the ride through fsl_appendf() and its delegates friends (but it "should work").
  • n is the number of bytes to read from data. The fact that n is of a signed type is historical. It can be treated as an unsigned type for purposes of fsl_appendf().
  • Returns, on success, the number of bytes appended (may be 0).
  • Returns, on error, an implementation-specified negative number. Returning a negative error code will cause fsl_appendfv() to stop processing and return. Note that 0 is a success value (some printf format specifiers do not add anything to the output).

Definition at line 1576 of file fossil-util.h.

typedef struct fsl_buffer fsl_buffer

Definition at line 39 of file fossil-util.h.

typedef int(* fsl_confirmation_f) (void *state, char const *msg, fsl_size_t msgLen)

An interface for routines which answer a yes/no question, either via human interaction or programatic decisions.

Conventions:

The state parameter is arbitrary state needed for the confirmation, and its type is implementation-specified.

msg is a message to present to the user (if any), and msgLen is its length in bytes.

Must return one of the fsl_confirmation_t values to indicate the result of the question.

Definition at line 3448 of file fossil-util.h.

typedef int fsl_confirmation_f_console_FILE(void *state, char const *msg, fsl_size_t msgLen)

NOT YET IMPLEMENTED.

A fsl_confirmation_f() implementation which reads from the opened FILE handle passed as the first argument.

Definition at line 3456 of file fossil-util.h.

typedef struct fsl_confirmer fsl_confirmer

Definition at line 3491 of file fossil-util.h.

typedef struct fsl_error fsl_error

Definition at line 40 of file fossil-util.h.

typedef struct fsl_finalizer fsl_finalizer

Definition at line 41 of file fossil-util.h.

typedef void(* fsl_finalizer_f) (void *state, void *mem)

Generic interface for finalizing/freeing memory.

Intended primarily for use as a destructor/finalizer for high-level structs. Implementations must semantically behave like free(mem), regardless of whether or not they actually free the memory. At the very least, they generally should clean up any memory owned by mem (e.g. db resources or buffers), even if they do not free() mem. some implementations assume that mem is stack-allocated and they only clean up resources owned by mem.

The state parameter is any state needed by the finalizer (e.g. a memory allocation context) and mem is the memory which is being finalized.

The exact interpretaion of the state and mem are of course implementation-specific.

Definition at line 197 of file fossil-util.h.

typedef int(* fsl_flush_f) (void *state)

Generic interface for flushing arbitrary output streams.

Must return 0 on success, non-0 on error, but the result code "should" (to avoid downstream confusion) be one of the fsl_rc_t values. When in doubt, return FSL_RC_IO on error. The interpretation of the state parameter is implementation-specific.

Definition at line 287 of file fossil-util.h.

typedef struct fsl_fstat fsl_fstat

Definition at line 42 of file fossil-util.h.

Definition at line 2561 of file fossil-util.h.

Definition at line 2545 of file fossil-util.h.

typedef int(* fsl_generic_cmp_f) (void const *lhs, void const *rhs)

A typedef for comparison function used by standard C routines such as qsort().

It is provided here primarily to simplify documentation of other APIs. Concrete implementations must compare lhs and rhs, returning negative, 0, or right depending on whether lhs is less than, equal to, or greater than rhs.

Implementations might need to be able to deal with NULL arguments. That depends on the routine which uses the comparison function.

Definition at line 60 of file fossil-util.h.

typedef struct fsl_id_bag fsl_id_bag

Definition at line 46 of file fossil-util.h.

typedef int(* fsl_input_f) (void *state, void *dest, fsl_size_t *n)

Generic interface for streaming in data.

Implementations must read (at most) *n bytes from their input, copy it to dest, assign n to the number of bytes actually read, return 0 on success, and return non-0 on error (assumed to be a value from the fsl_rc_t enum). When called, *n is the max length to read. On return, *n is the actual amount read. The state parameter is the implementation-specified input file/buffer/whatever channel.

Definition at line 298 of file fossil-util.h.

typedef struct fsl_list fsl_list

Definition at line 43 of file fossil-util.h.

typedef int(* fsl_list_visitor_f)(void *p, void *visitorState)

Generic visitor interface for fsl_list lists.

Used by fsl_list_visit(). p is the pointer held by that list entry and visitorState is the 4th argument passed to fsl_list_visit().

Implementations must return 0 on success. Any other value causes looping to stop and that value to be returned, but interpration of the value is up to the caller (it might or might not be an error, depending on the context). Note that client code may use custom values, and is not strictly required to use FSL_RC_xxx values. HOWEVER... all of the libfossil APIs which take these as arguments may respond differently to some codes (most notable FSL_RC_BREAK, which they tend to treat as a stop-iteration-without-error result), so clients are strongly encourage to return an FSL_RC_xxx value on error.

Definition at line 1813 of file fossil-util.h.

typedef int(* fsl_output_f) (void *state, void const *src, fsl_size_t n)

Generic interface for streaming out data.

Implementations must write n bytes from s to their destination channel and return 0 on success, non-0 on error (assumed to be a value from the fsl_rc_t enum). The state parameter is the implementation-specified output channel.

Potential TODO: change the final argument to a pointer, with semantics similar to fsl_input_f(): at call-time n is the number of bytes to output, and on returning n is the number of bytes actually written. This would allow, e.g. the fsl_zip_writer APIs to be able to stream a ZIP file (they have to know the real size of the output, and this interface doesn't support that operation).

Definition at line 275 of file fossil-util.h.

typedef struct fsl_outputer fsl_outputer

Definition at line 44 of file fossil-util.h.

Definition at line 3283 of file fossil-util.h.

typedef void*(* fsl_realloc_f) (void *state, void *mem, fsl_size_t n)

Generic stateful alloc/free/realloc() interface.

Implementations must behave as follows:

  • If 0==n then semantically behave like free(3) and return NULL.
  • If 0!=n and !mem then semantically behave like malloc(3), returning newly-allocated memory on success and NULL on error.
  • If 0!=n and NULL!=mem then semantically behave like realloc(3). Note that realloc specifies: "If n was equal to 0, either NULL or a pointer suitable to be passed to free() is returned." Which is kind of useless, and thus implementations MUST return NULL when n==0.

Definition at line 390 of file fossil-util.h.

typedef struct fsl_state fsl_state

Definition at line 45 of file fossil-util.h.

Definition at line 3818 of file fossil-util.h.

typedef char const* fsl_uuid_cstr

The const counterpart of fsl_uuid_str.

See also
fsl_is_uuid()

Definition at line 92 of file fossil-util.h.

typedef char* fsl_uuid_str

fsl_uuid_str and fsl_uuid_cstr are "for documentation and readability purposes" typedefs used to denote strings which the API requires to be in the form of Fossil UUID strings.

Such strings are exactly FSL_UUID_STRLEN bytes long plus a terminating NUL byte and contain only lower-case hexadecimal bytes. Where this typedef is used, the library requires, enforces, and/or assumes (at different times) that fsl_is_uuid() returns true for such strings (if they are not NULL, though not all contexts allow a NULL UUID). These typedef are _not_ used to denote arguments which may refer to partial UUIDs or symbolic names, only 100% bonafide Fossil UUIDs (which are different from RFC4122 UUIDs).

The API guarantees that this typedef will always be (char *) and that fsl_uuid_cstr will always ben (char const *), and thus it is safe/portable to use those type instead of thse. These typedefs serve only to improve the readability of certain APIs by implying (through the use of this typedef) the preconditions defined for UUID strings.

See also
fsl_is_uuid()

Definition at line 85 of file fossil-util.h.

Definition at line 3571 of file fossil-util.h.

Enumeration Type Documentation

Result codes for the fsl_confirmation_f() family of functions.

Enumerator
FSL_CONFIRM_ERROR 

Indicates there was some unrecoverable error during prompting.

Should be used with care.

FSL_CONFIRM_YES 

Indicates that the answer to the question at hand is "yes" or "okay.".

FSL_CONFIRM_YES_ALL 

Indicates that the answer to the question at hand is "yes" or "okay" and that the same answer should be assumed for any number of a series of similar questions.

This is intended to have semantics similar to answering questions like "replace this file, cancel, or replace this and all up-coming files?"

FSL_CONFIRM_NO 

This is the converse of FSL_CONFIRM_YES.

FSL_CONFIRM_NO_ALL 

This is the converse of FSL_CONFIRM_YES_ALL.

Definition at line 3405 of file fossil-util.h.

Flags for use with text-diff generation APIs, e.g.

fsl_diff_text().

Maintenance reminder: these values are holy and must not be changed without also changing the corresponding code in fsl_diff.c.

Enumerator
FSL_DIFF_IGNORE_EOLWS 

Ignore end-of-line whitespace.

FSL_DIFF_IGNORE_ALLWS 

Ignore end-of-line whitespace.

FSL_DIFF_SIDEBYSIDE 

Generate a side-by-side diff.

FSL_DIFF_VERBOSE 

Missing shown as empty files.

FSL_DIFF_BRIEF 

Show filenames only.

Not used in this impl!

FSL_DIFF_HTML 

Render HTML.

FSL_DIFF_LINENO 

Show line numbers.

FSL_DIFF_NOOPT 

Suppress optimizations (debug).

FSL_DIFF_INVERT 

Invert the diff (debug).

FSL_DIFF_NOTTOOBIG 

Only display if not "too big.".

FSL_DIFF_STRIP_EOLCR 

Strip trailing CR.

FSL_DIFF_ANSI_COLOR 

This flag tells text-mode diff generation to add ANSI color sequences to some output.

The colors are currently hard-coded and non-configurable. This has no effect for HTML output, and that flag trumps this one. It also currently only affects unified diffs, not side-by-side.

Maintenance reminder: this one currently has no counterpart in fossil(1), is not tracked in the same way, and need not map to an internal flag value. That's a good thing, because we'll be out of flags once Jan's done tinkering in fossil(1) ;).

Definition at line 3010 of file fossil-util.h.

Bitmask values for use with the fsl_fstat::perms field.

Enumerator
FSL_FSTAT_PERM_UNKNOWN 

Sentinel value.

FSL_FSTAT_PERM_EXE 

The executable bit, as understood by Fossil.

Fossil does not differentiate between different +x values for user/group/other.

Definition at line 2550 of file fossil-util.h.

Values for use with the fsl_fstat::type field.

Enumerator
FSL_FSTAT_TYPE_UNKNOWN 

Sentinel value for unknown/invalid filesystem entry types.

FSL_FSTAT_TYPE_DIR 

Indicates a directory filesystem entry.

FSL_FSTAT_TYPE_FILE 

Indicates a non-directory, non-symlink filesystem entry.

Because fossil's scope is limited to SCM work, it assumes that "special files" (sockets, etc.) are just files, and makes no special effort to handle them.

FSL_FSTAT_TYPE_LINK 

Indicates a symlink filesystem entry.

Definition at line 2531 of file fossil-util.h.

Flags for use with fsl_db_open() and friends.

Enumerator
FSL_OPEN_F_NONE 

The "no flags" value.

FSL_OPEN_F_RO 

Flag for fsl_db_open() specifying that the db should be opened in read-only mode.

FSL_OPEN_F_RW 

Flag for fsl_db_open() specifying that the db should be opened in read-write mode, but should not create the db if it does not already exist.

FSL_OPEN_F_CREATE 

Flag for fsl_db_open() specifying that the db should be opened in read-write mode, creating the db if it does not already exist.

FSL_OPEN_F_RWC 

Shorthand for RW+CREATE flags.

FSL_OPEN_F_SCHEMA_VALIDATE 

Tells fsl_repo_open_xxx() to confirm that the db is a repository.

Definition at line 1473 of file fossil-util.h.

Function Documentation

FSL_EXPORT fsl_int_t fsl_appendf ( fsl_appendf_f  pfAppend,
void *  pfAppendArg,
const char *  fmt,
  ... 
)

Identical to fsl_appendfv() but takes an ellipses list (...) instead of a va_list.

FSL_EXPORT fsl_int_t fsl_appendf_f_FILE ( void *  state,
char const *  s,
fsl_int_t  n 
)

A fsl_appendf_f() impl which requires that state be an opened, writable (FILE*) handle.

FSL_EXPORT fsl_int_t fsl_appendfv ( fsl_appendf_f  pfAppend,
void *  pfAppendArg,
const char *  fmt,
va_list  ap 
)

This function works similarly to classical printf implementations, but instead of outputing somewhere specific, it uses a callback function to push its output somewhere.

This allows it to be used for arbitrary external representations. It can be used, for example, to output to an external string, a UI widget, or file handle (it can also emulate printf by outputing to stdout this way).

INPUTS:

pfAppend: The is a fsl_appendf_f function which is responsible for accumulating the output. If pfAppend returns a negative value then processing stops immediately.

pfAppendArg: is ignored by this function but passed as the first argument to pfAppend. pfAppend will presumably use it as a data store for accumulating its string.

fmt: This is the format string, as in the usual printf(3), except that it supports more options (detailed below).

ap: This is a pointer to a list of arguments. Same as in vprintf() and friends.

OUTPUTS:

The return value is the total number of characters sent to the function "func", or a negative number on a pre-output error. If this function returns an integer greater than 1 it is in general impossible to know if all of the elements were output. As such failure can only happen if the callback function returns an error or if one of the formatting options needs to allocate memory and cannot. Both of those cases are very rare in a printf-like context, so this is not considered to be a significant problem. (The same is true for any classical printf implementations.) Clients may use their own state objects which can propagate errors from their own internals back to the caller, but generically speaking it is difficult to trace errors back through this routine. Then again, in practice that has never proven to be a problem.

Most printf-style specifiers work as they do in standard printf() implementations. There might be some very minor differences, but the more common format specifiers work as most developers expect them to. In addition...

Current (documented) printf extensions:

(If you are NOT reading this via doxygen-processed sources: the percent signs below are doubled for the sake of doxygen, and each pair refers to only a single percent sign in the format string.)

%z works like %s, but takes a non-const (char *) and deletes the string (using fsl_free()) after appending it to the output.

%h (HTML) works like %s but converts certain characters (namely '<' and '&') to their HTML escaped equivalents.

%t (URL encode) works like %s but converts certain characters into a representation suitable for use in an HTTP URL. (e.g. ' ' gets converted to %%20)

%T (URL decode) does the opposite of %t - it decodes URL-encoded strings and outputs their decoded form. ACHTUNG: fossil(1) interprets this the same as %t except that it leaves '/' characters unescaped (did that change at some point? This code originally derived from that one some years ago!). It is still to be determined whether we "really need" that behaviour (we don't really need either one, seeing as the library is not CGI-centric like fossil(1) is).

%r requires an int and renders it in "ordinal form". That is, the number 1 converts to "1st" and 398 converts to "398th".

%q quotes a string as required for SQL. That is, '\'' characters get doubled. It does NOT included the outer quotes and NULL values get replaced by the string "(NULL) (without quotes). See %Q...

%Q works like %q, but includes the outer '\'' characters and NULL pointers get output as the string literal "NULL" (without quotes), i.e. an SQL NULL.

%S works like %%.12s. It is intended for UUIDs.

%%/: works like %s but normalizes path-like strings by replacing backslashes with the One True Slash.

%b: works like %s but takes its input from a (fsl_buffer const*) argument.

%B: works like %Q but takes its input from a (fsl_buffer const*) argument.

%F: works like %s but runs the output through fsl_bytes_fossilize(). This requires dynamic memory allocation, so is less efficient than re-using a client-provided buffer with fsl_bytes_fossilize() if the client needs to fossilize more than one element. A '#' between the percent and F works like %%.*s - it expects an int-type argument to give the maximum number of bytes from F to fossilize (not the maximum output length). Be very careful to pass (or cast to) an int, not a fsl_size_t or any other type which has a different sizeof() than int, or else variadic arg handling may Do The Wrong Thing.

These extensions may be disabled by setting certain macros when compiling fsl_appendf.c (see that file for details).

FIXME? fsl_appendf_f() is an artifact of older code from which this implementation derives. The first parameter should arguably be replaced with fsl_output_f(), which does the same thing _but_ has different return semantics (more reliable, because the current semantics report partial success as success in some cases). Doing this would require us to change the return semantics of this function, but that wouldn't necessarily be a bad thing (we don't rely on sprintf()-like return semantics all that much, if at all). Or we just add a proxy which forwards to a fsl_output_f(). (Oh, hey, that's what fsl_outputf() does.) But that doesn't catch certain types of errors (namely allocation failures) which can happen as side-effects of some formatting operations.

Potential TODO: add fsl_bytes_fossilize_out() which works like fsl_bytes_fossilize() but sends its output to an fsl_output_f() and fsl_appendf_f(), so that this routine doesn't need to alloc for that case.

FSL_EXPORT int fsl_buffer_append ( fsl_buffer b,
void const *  src,
fsl_int_t  n 
)

Appends the first n bytes of src, plus a NUL byte, to b, expanding b as necessary and incrementing b->used by n.

If n is less than 0 then the equivalent of fsl_strlen((char const*)src) is used to calculate the length.

If n is 0 (or negative and !*src), this function ensures that b->mem is not NULL and is NUL-terminated, so it may allocate to have space for that NUL byte.

src may only be NULL if n==0. If passed (src==NULL, n!=0) then FSL_RC_RANGE is returned.

Returns 0 on success, FSL_RC_MISUSE if !f, !b, or !src, FSL_RC_OOM if allocation of memory fails.

If this function succeeds, it guarantees that it NUL-terminates the buffer (but that the NUL terminator is not counted in b->used).

See also
fsl_buffer_appendf()
fsl_buffer_reserve()

Referenced by fsl::operator<<().

FSL_EXPORT int fsl_buffer_appendf ( fsl_buffer dest,
char const *  fmt,
  ... 
)

Uses fsl_appendf() to append formatted output to the given buffer.

Returns 0 on success, FSL_RC_MISUSE if !f or !dest, and FSL_RC_OOM if an allocation fails while expanding dest.

See also
fsl_buffer_append()
fsl_buffer_reserve()
FSL_EXPORT int fsl_buffer_appendfv ( fsl_buffer dest,
char const *  fmt,
va_list  args 
)

va_list counterpart to fsl_buffer_appendfv().

FSL_EXPORT fsl_size_t fsl_buffer_capacity ( fsl_buffer const *  b)

Returns the current capacity of b, or 0 if !b.

FSL_EXPORT void fsl_buffer_clear ( fsl_buffer buf)

Convenience equivalent of fsl_buffer_reserve(buf,0).

This a no-op if buf==NULL.

FSL_EXPORT int fsl_buffer_compare ( fsl_buffer const *  lhs,
fsl_buffer const *  rhs 
)

Compares the contents of buffers lhs and rhs using memcmp(3) semantics.

Return negative, zero, or positive if the first buffer is less then, equal to, or greater than the second. Results are undefined if either argument is NULL.

When buffers of different length match on the first N bytes, where N is the shorter of the two buffers' lengths, it treats the shorter buffer as being "less than" the longer one.

FSL_EXPORT int fsl_buffer_compare_file ( fsl_buffer const *  b,
char const *  zFile 
)

Bitwise-compares the contents of b against the file named by zFile.

Returns 0 if they have the same size and contents, else non-zero. This function has no way to report if zFile cannot be opened, and any error results in a non-0 return value. No interpretation/canonicalization of zFile is performed - it is used as-is.

This resolves symlinks and returns non-0 if zFile refers (after symlink resolution) to a non-file.

If zFile does not exist, is not readable, or has a different size than b->used, non-0 is returned without opening/reading the file contents. If a content comparison is performed, it is streamed in chunks of an unspecified (but relatively small) size, so it does not need to read the whole file into memory (unless it is smaller than the chunk size).

FSL_EXPORT int fsl_buffer_compare_O1 ( fsl_buffer const *  lhs,
fsl_buffer const *  rhs 
)

Compare two buffers in constant (a.k.a.

O(1)) time and return zero if they are equal. Constant time comparison only applies for buffers of the same length. If lengths are different, immediately returns 1. This operation is provided for cases where the timing/duration of fsl_buffer_compare() (or an equivalent memcmp()) might inadvertently leak security-relevant information. Specifically, it address the concern that attackers can use timing differences to check for password misses, to narrow down an attack to passwords of a specific length or content properties.

FSL_EXPORT int fsl_buffer_compress ( fsl_buffer const *  pIn,
fsl_buffer pOut 
)

Compresses the first pIn->used bytes of pIn to pOut.

It is ok for pIn and pOut to be the same blob.

pOut must either be the same as pIn or else a properly initialized buffer. Any prior contents will be freed or their memory reused.

Results are undefined if any argument is NULL.

Returns 0 on success, FSL_RC_OOM on allocation error, and FSL_RC_ERROR if the lower-level compression routines fail.

Use fsl_buffer_uncompress() to uncompress the data. The data is encoded with a big-endian, unsigned 32-bit length as the first four bytes, and then the data as compressed by zlib.

TODO: if pOut!=pIn1 then re-use pOut's memory, if it has any.

See also
fsl_buffer_compress2()
fsl_buffer_uncompress()
fsl_buffer_is_compressed()
FSL_EXPORT int fsl_buffer_compress2 ( fsl_buffer const *  pIn1,
fsl_buffer const *  pIn2,
fsl_buffer pOut 
)

Compress the concatenation of a blobs pIn1 and pIn2 into pOut.

pOut must be either empty (cleanly initialized or newly recycled) or must be the same as either pIn1 or pIn2.

Results are undefined if any argument is NULL.

Returns 0 on success, FSL_RC_OOM on allocation error, and FSL_RC_ERROR if the lower-level compression routines fail.

TODO: if pOut!=(pIn1 or pIn2) then re-use its memory, if it has any.

See also
fsl_buffer_compress()
fsl_buffer_uncompress()
fsl_buffer_is_compressed()
FSL_EXPORT int fsl_buffer_copy ( fsl_buffer const *  src,
fsl_buffer dest 
)

Overwrites dest's contents with a copy of those from src (reusing dest's memory if it has any).

Results are undefined if either pointer is NULL or invalid. Returns 0 on success, FSL_RC_OOM on allocation error.

FSL_EXPORT int fsl_buffer_copy_lines ( fsl_buffer pTo,
fsl_buffer pFrom,
fsl_size_t  N 
)

Copy N lines of text from pFrom into pTo.

The copy begins at the current pFrom->cursor position. pFrom->cursor is left pointing at the first character past the last
copied.

If pTo==NULL then this routine simply skips over N lines.

Returns 0 if it copies lines or does nothing (because N is 0 or pFrom's contents have been exhausted. Copying fewer lines than requested (because of EOF) is not an error. Returns non-0 only on allocation error. Results are undefined if either of the first two arguments are NULL.

See also
fsl_buffer_stream_lines()
FSL_EXPORT char const* fsl_buffer_cstr ( fsl_buffer const *  b)

Equivalent to ((char const *)b->mem), but returns NULL if !b.

The returned string is effectively b->used bytes long unless the user decides to apply his own conventions. Note that the buffer APIs generally assure that buffers are NUL-terminated, meaning that strings returned from this function can (for the vast majority of cases) assume that the returned string is NUL-terminated (with a string length of b->used _bytes_).

See also
fsl_buffer_str()
fsl_buffer_cstr2()
FSL_EXPORT char const* fsl_buffer_cstr2 ( fsl_buffer const *  b,
fsl_size_t len 
)

If buf is not NULL and has any memory allocated to it, that memory is returned.

If both b and len are not NULL then *len is set to b->used. If b has no dynamic memory then NULL is returned and *len (if len is not NULL) is set to 0.

See also
fsl_buffer_str()
fsl_buffer_cstr()
FSL_EXPORT void fsl_buffer_defossilize ( fsl_buffer b)

Defossilizes the contents of b.

Equivalent to: fsl_bytes_defossilize( b->mem, &b->used );

FSL_EXPORT int fsl_buffer_delta_apply ( fsl_buffer const *  pOriginal,
fsl_buffer const *  pDelta,
fsl_buffer pTarget 
)

Apply the delta in pDelta to the original content pOriginal to generate the target content pTarget.

All three pointers must point to properly initialized memory.

If pTarget==pOriginal then this is a destructive operation, replacing the original's content with its new form.

Return 0 on success.

See also
fsl_buffer_delta_apply()
fsl_delta_apply()
fsl_delta_apply2()
FSL_EXPORT int fsl_buffer_delta_apply2 ( fsl_buffer const *  pOriginal,
fsl_buffer const *  pDelta,
fsl_buffer pTarget,
fsl_error pErr 
)

Identical to fsl_buffer_delta_apply() except that if delta application fails then any error messages/codes are written to pErr if it is not NULL.

It is rare that delta application fails (only if the inputs are invalid, e.g. do not belong together or are corrupt), but when it does, having error information can be useful.

See also
fsl_buffer_delta_apply()
fsl_delta_apply()
fsl_delta_apply2()
FSL_EXPORT int fsl_buffer_delta_create ( fsl_buffer const *  src,
fsl_buffer const *  newVers,
fsl_buffer delta 
)

A fsl_delta_create() wrapper which uses the first two arguments as the original and "new" content versions to delta, and outputs the delta to the 3rd argument (overwriting any existing contents and re-using any memory it had allocated).

If the output buffer (delta) is the same as src or newVers, FSL_RC_MISUSE is returned, and results are undefined if delta indirectly refers to the same buffer as either src or newVers.

Returns 0 on success.

FSL_EXPORT int fsl_buffer_fill_from ( fsl_buffer dest,
fsl_input_f  src,
void *  state 
)

Uses a fsl_input_f() function to buffer input into a fsl_buffer.

dest must be a non-NULL, initialized (though possibly empty) fsl_buffer object. Its contents, if any, will be overwritten by this function, and any memory it holds might be re-used.

The src function is called, and passed the state parameter, to fetch the input. If it returns non-0, this function returns that error code. src() is called, possibly repeatedly, until it reports that there is no more data.

Whether or not this function succeeds, dest still owns any memory pointed to by dest->mem, and the client must eventually free it by calling fsl_buffer_reserve(dest,0).

dest->mem might (and possibly will) be (re)allocated by this function, so any pointers to it held from before this call might be invalidated by this call.

On error non-0 is returned and dest may bge partially populated.

Errors include:

dest or src are NULL (FSL_RC_MISUSE)

Allocation error (FSL_RC_OOM)

src() returns an error code

Whether or not the state parameter may be NULL depends on the src implementation requirements.

On success dest will contain the contents read from the input source. dest->used will be the length of the read-in data, and dest->mem will point to the memory. dest->mem is automatically NUL-terminated if this function succeeds, but dest->used does not count that terminator. On error the state of dest->mem must be considered incomplete, and is not guaranteed to be NUL-terminated.

Example usage:

1 fsl_buffer buf = fsl_buffer_empty;
2 int rc = fsl_buffer_fill_from( &buf,
3 fsl_input_f_FILE,
4 stdin );
5 if( rc ){
6 fprintf(stderr,"Error %d (%s) while filling buffer.\n",
7 rc, fsl_rc_cstr(rc));
8 fsl_buffer_reserve( &buf, 0 );
9 return ...;
10 }
11 ... use the buf->mem ...
12 ... clean up the buffer ...
13 fsl_buffer_reserve( &buf, 0 );

To take over ownership of the buffer's memory, do:

1 void * mem = buf.mem;
2 buf = fsl_buffer_empty;

In which case the memory must eventually be passed to fsl_free() to free it.

FSL_EXPORT int fsl_buffer_fill_from_FILE ( fsl_buffer dest,
FILE *  src 
)

A fsl_buffer_fill_from() proxy which overwrite's dest->mem with the contents of the given FILE handler (which must be opened for read access).

Returns 0 on success, after which dest->mem contains dest->used bytes of content from the input source. On error dest may be partially filled.

FSL_EXPORT int fsl_buffer_fill_from_filename ( fsl_buffer dest,
char const *  filename 
)

A wrapper for fsl_buffer_fill_from_FILE() which gets its input from the given file name.

It uses fsl_fopen() to open the file, so it supports "-" as an alias for stdin.

Uses fsl_fopen() to open the file, so it supports the name '-' as an alias for stdin.

FSL_EXPORT char fsl_buffer_is_compressed ( fsl_buffer const *  buf)

Equivalent to fsl_data_is_compressed(buf->mem, buf->used).

FSL_EXPORT int fsl_buffer_reserve ( fsl_buffer buf,
fsl_size_t  n 
)

Reserves at least n bytes of capacity in buf.

Returns 0 on success, FSL_RC_OOM if allocation fails, FSL_RC_MISUSE if !buf.

This does not change buf->used, nor will it shrink the buffer (reduce buf->capacity) unless n is 0, in which case it immediately frees buf->mem and sets buf->capacity and buf->used to 0.

See also
fsl_buffer_resize()
fsl_buffer_clear()
FSL_EXPORT int fsl_buffer_reset ( fsl_buffer buf)

Resets buf->used to 0 and sets buf->mem[0] (if buf->mem is not NULL) to 0.

Does not (de)allocate memory, only changes the logical "used" size of the buffer. Returns 0 on success, FSL_RC_MISUSE if !buf.

Achtung for v1 porters: this function's semantics are much different from the v1 blob_reset(). To get those semantics, use fsl_buffer_reserve(buf, 0) or its convenience form fsl_buffer_clear().

FSL_EXPORT int fsl_buffer_resize ( fsl_buffer buf,
fsl_size_t  n 
)

Similar to fsl_buffer_reserve() except that...

  • It does not free all memory when n==0. Instead it essentially makes the memory a length-0, NUL-terminated string.
  • It will try to shrink (realloc) buf's memory if (n<buf->capacity).
  • It sets buf->capacity to (n+1) and buf->used to n. This routine allocates one extra byte to ensure that buf is always NUL-terminated.
  • On success it always NUL-terminates the buffer at offset buf->used.

Returns 0 on success, FSL_RC_MISUSE if !buf, FSL_RC_OOM if (re)allocation fails.

See also
fsl_buffer_reserve()
fsl_buffer_clear()
FSL_EXPORT fsl_size_t fsl_buffer_size ( fsl_buffer const *  b)

Returns the "used" size of b, or 0 if !b.

FSL_EXPORT char* fsl_buffer_str ( fsl_buffer const *  b)

Equivalent to ((char *)b->mem), but returns NULL if !b.

The returned memory is effectively b->used bytes long unless the user decides to apply his own conventions.

FSL_EXPORT int fsl_buffer_stream_lines ( fsl_buffer pFrom,
fsl_output_f  fTo,
void *  toState,
fsl_size_t  N 
)

Works identically to fsl_buffer_copy_lines() except that it sends its output.

See also
fsl_buffer_copy_lines()
FSL_EXPORT int fsl_buffer_strftime ( fsl_buffer b,
char const *  format,
const struct tm *  timeptr 
)

A convenience form of fsl_strftime() which assumes that the formatted string is of "some reasonable size" and appends its formatted representation to b.

Returns 0 on success, non-0 on error. If any argument is NULL or !*format then FSL_RC_MISUSE is returned. FSL_RC_RANGE is returned if the underlying call to fsl_strftime() fails (which it will if the format string resolves to something "unususually long"). It returns FSL_RC_OOM if appending to b fails due to an allocation error.

FSL_EXPORT void fsl_buffer_swap ( fsl_buffer left,
fsl_buffer right 
)

Swaps the contents of the left and right arguments.

Results are undefined if either argument is NULL or points to uninitialized memory.

FSL_EXPORT void fsl_buffer_swap_free ( fsl_buffer left,
fsl_buffer right,
int  clearWhich 
)

Similar fsl_buffer_swap() but it also optionally frees one of the buffer's memories after swapping them.

If clearWhich is negative then the left buffer (1st arg) is cleared _after_ swapping (i.e., the NEW left hand side gets cleared). If clearWhich is greater than 0 then the right buffer (2nd arg) is cleared _after_ swapping (i.e. the NEW right hand side gets cleared). If clearWhich is 0, this function behaves identically to fsl_buffer_swap().

A couple examples should clear this up:

1 fsl_buffer_swap_free( &b1, &b2, -1 );

Swaps the contents of b1 and b2, then frees the contents of the left-side buffer (b1).

1 fsl_buffer_swap_free( &b1, &b2, 1 );

Swaps the contents of b1 and b2, then frees the contents of the right-side buffer (b2).

FSL_EXPORT int fsl_buffer_to_filename ( fsl_buffer const *  b,
char const *  fname 
)

Writes the given buffer to the given filename.

Returns 0 on success, FSL_RC_MISUSE if !b or !fname, FSL_RC_IO if opening or writing fails.

Uses fsl_fopen() to open the file, so it supports the name '-' as an alias for stdout.

FSL_EXPORT int fsl_buffer_uncompress ( fsl_buffer const *  pIn,
fsl_buffer pOut 
)

Uncompress buffer pIn and store the result in pOut.

It is ok for pIn and pOut to be the same buffer. Returns 0 on success. On error pOut is not modified.

pOut must be either cleanly initialized/empty or the same as pIn.

Results are undefined if any argument is NULL.

Returns 0 on success, FSL_RC_OOM on allocation error, and FSL_RC_ERROR if the lower-level decompression routines fail.

TODO: if pOut!=(pIn1 or pIn2) then re-use its memory, if it has any.

See also
fsl_buffer_compress()
fsl_buffer_compress2()
fsl_buffer_is_compressed()
FSL_EXPORT fsl_int_t fsl_buffer_uncompressed_size ( fsl_buffer const *  b)
FSL_EXPORT void fsl_bytes_defossilize ( unsigned char *  inp,
fsl_size_t resultLen 
)

"Defossilizes" bytes encoded by fsl_bytes_fossilize() in-place.

inp must be a string encoded by fsl_bytes_fossilize(), and the decoding processes stops at the first unescaped NUL terminator. It has no error conditions except for !inp or if inp is not NUL-terminated, both of which invoke in undefined behaviour.

If resultLen is not NULL then *resultLen is set to the resulting string length.

FSL_EXPORT int fsl_bytes_fossilize ( unsigned char const *  inp,
fsl_int_t  len,
fsl_buffer out 
)

"Fossilizes" the first len bytes of the given input string.

If (len<0) then fsl_strlen(inp) is used to calculate its length. The output is appended to out, which is expanded as needed and out->used is updated accordingly. Returns 0 on success, FSL_RC_MISUSE if !inp or !out. Returns 0 without side-effects if 0==len or (!*inp && len<0). Returns FSL_RC_OOM if reservation of the output buffer fails (it is expanded, at most, one time by this function).

Fossilization replaces the following bytes/sequences with the listed replacements:

(Achtung: usage of doubled backslashes here it just to please doxygen - they will show up as single slashes in the processed output.)

  • Backslashes are doubled.
  • (\n, \r, \v, \t, \f) are replaced with \\X, where X is the conventional encoding letter for that escape sequence.
  • Spaces are replaced with \s.
  • Embedded NULs are replaced by \0 (numeric 0, not character '0').
FSL_EXPORT void fsl_canonical16 ( char *  z,
fsl_size_t  n 
)

The input string is a base16 value.

Convert it into its canonical form. This means that digits are all lower case and that conversions like "l"->"1" and "O"->"0" occur.

FSL_EXPORT int fsl_chdir ( const char *  zChDir)

Performs a chdir() to the directory named by zChDir.

Returns 0 on success. On error it tries to convert the underlying errno to one of the FSL_RC_xxx values, falling back to FSL_RC_IO if it cannot figure out anything more specific.

FSL_EXPORT int fsl_confirm ( fsl_confirmation_f  f,
void *  state,
char const *  fmt,
  ... 
)

Creates a formatted message string using fsl_appendf(fmt,...) and passes that message to f(state,...).

On success (message allocation succeeds) then the result of the call to f() is returned, otherwise

FSL_EXPORT int fsl_confirmation_f_int ( void *  state,
char const *  msg,
fsl_size_t  msgLen 
)

A fsl_confirmation_f() implementation which expects the state parameter to be a (int [const] *) which dereferences to one of the FSL_CONFIRM_xxx values, defaulting to FSL_CONFIRM_ERROR.

This function simply returns that value on each call, ignoring its msg and msgLen parameters. It does not modify the state.

Why? This can be used to feed a client-held status integer (not necessarily const) to the callback system. It was originally conceived for unit testing, but might find a client-side use or two. e.g. a simple progress dialog might implement its cancel operation via this callback, initially setting the state value (integer) to FSL_CONFIRM_YES, and changing it to FSL_CONFIRM_NO_ALL if the cancel button is clicked. The next time confirmation is called for, it would fail and the operation in question would be aborted.

FSL_EXPORT int fsl_confirmv ( fsl_confirmation_f  f,
void *  state,
char const *  fmt,
va_list   
)

The va_list counterpart of fsl_confirm().

FSL_EXPORT char fsl_data_is_compressed ( unsigned char const *  mem,
fsl_size_t  len 
)

Returns true if this function believes that mem (which must be at least len bytes of valid memory long) appears to have been compressed by fsl_buffer_compress() or equivalent.

This is not a 100% reliable check - it could potentially have false positives on certain inputs, but that is thought to be unlikely (at least for text data).

Returns 0 if mem is NULL.

FSL_EXPORT fsl_int_t fsl_data_uncompressed_size ( unsigned char const *  mem,
fsl_size_t  len 
)

If fsl_data_is_compressed(mem,len) returns true then this function returns the uncompressed size of the data, else it returns a negative value.

FSL_EXPORT int fsl_decode16 ( const unsigned char *  zIn,
unsigned char *  pOut,
fsl_size_t  N 
)

Decode a N-character base-16 number into base-256.

N must be a multiple of 2. The output buffer must be at least N/2 characters in length. Returns 0 on success.

FSL_EXPORT int fsl_delta_applied_size ( unsigned char const *  zDelta,
fsl_size_t  lenDelta,
fsl_size_t appliedSize 
)
FSL_EXPORT int fsl_delta_apply ( unsigned char const *  zSrc,
fsl_size_t  lenSrc,
unsigned char const *  zDelta,
fsl_size_t  lenDelta,
unsigned char *  zOut 
)

Apply a delta created using fsl_delta_create().

The output buffer must be big enough to hold the whole output file and a NUL terminator at the end. The fsl_delta_applied_size() routine can be used to determine that size.

zSrc represents the original sources to apply the delta to. It must be at least lenSrc bytes of valid memory.

zDelta holds the delta (created using fsl_delta_create()), and it must be lenDelta bytes long.

On success this function returns 0 and writes the applied delta to zOut.

Returns FSL_RC_MISUSE if any pointer argument is NULL. Returns FSL_RC_RANGE if lenSrc or lenDelta are "too big" (if they cause an overflow in the math). Invalid delta input can cause any of FSL_RC_RANGE, FSL_RC_DELTA_INVALID_TERMINATOR, FSL_RC_CHECKSUM_MISMATCH, FSL_RC_SIZE_MISMATCH, or FSL_RC_DELTA_INVALID_OPERATOR to be returned.

Refer to the fsl_delta_create() documentation above for a description of the delta file format.

See also
fsl_delta_applied_size()
fsl_delta_create()
fsl_delta_apply2()
FSL_EXPORT int fsl_delta_apply2 ( unsigned char const *  zSrc,
fsl_size_t  lenSrc,
unsigned char const *  zDelta,
fsl_size_t  lenDelta,
unsigned char *  zOut,
fsl_error pErr 
)

Functionally identical to fsl_delta_apply() but any errors generated during application of the delta are described in more detail in pErr.

If pErr is NULL this behaves exactly as documented for fsl_delta_apply().

FSL_EXPORT int fsl_delta_create ( unsigned char const *  zSrc,
fsl_size_t  lenSrc,
unsigned char const *  zOut,
fsl_size_t  lenOut,
unsigned char *  zDelta,
fsl_size_t deltaSize 
)

Create a new delta between the memory zIn and zOut.

The delta is written into a preallocated buffer, zDelta, which must be at least 60 bytes longer than the target memory, zOut. The delta string will be NUL-terminated, but it might also contain embedded NUL characters if either the zSrc or zOut files are binary.

On success this function returns 0 and the length of the delta string, in bytes, excluding the final NUL terminator character, is written to *deltaSize.

Returns FSL_RC_MISUSE if any of the pointer arguments are NULL and FSL_RC_OOM if memory allocation fails during generation of the delta. Returns FSL_RC_RANGE if lenSrc or lenOut are "too big" (if they cause an overflow in the math).

Output Format:

The delta begins with a base64 number followed by a newline. This number is the number of bytes in the TARGET file. Thus, given a delta file z, a program can compute the size of the output file simply by reading the first line and decoding the base-64 number found there. The fsl_delta_applied_size() routine does exactly this.

After the initial size number, the delta consists of a series of literal text segments and commands to copy from the SOURCE file. A copy command looks like this:

(Achtung: extra backslashes are for Doxygen's benefit - not visible in the processsed docs.)

NNN@MMM,

where NNN is the number of bytes to be copied and MMM is the offset into the source file of the first byte (both base-64). If NNN is 0 it means copy the rest of the input file. Literal text is like this:

NNN:TTTTT

where NNN is the number of bytes of text (base-64) and TTTTT is the text.

The last term is of the form

NNN;

In this case, NNN is a 32-bit bigendian checksum of the output file that can be used to verify that the delta applied correctly. All numbers are in base-64.

Pure text files generate a pure text delta. Binary files generate a delta that may contain some binary data.

Algorithm:

The encoder first builds a hash table to help it find matching patterns in the source file. 16-byte chunks of the source file sampled at evenly spaced intervals are used to populate the hash table.

Next we begin scanning the target file using a sliding 16-byte window. The hash of the 16-byte window in the target is used to search for a matching section in the source file. When a match is found, a copy command is added to the delta. An effort is made to extend the matching section to regions that come before and after the 16-byte hash window. A copy command is only issued if the result would use less space that just quoting the text literally. Literal text is added to the delta for sections that do not match or which can not be encoded efficiently using copy commands.

See also
fsl_delta_applied_size()
fsl_delta_apply()
FSL_EXPORT int fsl_delta_create2 ( unsigned char const *  zSrc,
fsl_size_t  lenSrc,
unsigned char const *  zOut,
fsl_size_t  lenOut,
fsl_output_f  out,
void *  outState 
)

Works identically to fsl_delta_create() but sends its output to the given output function.

out(outState,...) may be called any number of times to emit delta output. Each time it is called it should append the new bytes to its output channel.

The semantics of the return value and the first four arguments are identical to fsl_delta_create(), with these ammendments regarding the return value:

  • Returns FSL_RC_MISUSE if any of (zSrc, zOut, out) are NULL.
  • If out() returns non-0 at any time, delta generation is aborted and that code is returned.

Example usage:

1 int rc = fsl_delta_create( v1, v1len, v2, v2len,
2 fsl_output_f_FILE, stdout);
FSL_EXPORT int fsl_diff_text ( fsl_buffer const *  pA,
fsl_buffer const *  pB,
fsl_output_f  out,
void *  outState,
short  contextLines,
short  sbsWidth,
int  diffFlags 
)

Generates a textual diff from two text inputs and writes it to the given output function.

pA and pB are the buffers to diff.

contextLines is the number of lines of context to output. This parameter has a built-in limit of 2^16, and values larger than that get truncated. A value of 0 is legal, in which case no surrounding context is provided. A negative value translates to some unspecified default value.

sbsWidth specifies the width (in characters) of the side-by-side columns. If sbsWidth is not 0 then this function behaves as if diffFlags contains the FSL_DIFF_SIDEBYSIDE flag. If sbsWidth is negative, OR if diffFlags explicitly contains FSL_DIFF_SIDEBYSIDE and sbsWidth is 0, then some default width is used. This parameter has a built-in limit of 255, and values larger than that get truncated to 255.

diffFlags is a mask of fsl_diff_flag_t values. Not all of the fsl_diff_flag_t flags are yet [sup]ported.

The output is sent to out(outState,...). If out() returns non-0 during processing, processing stops and that result is returned to the caller of this function.

Returns 0 on success, FSL_RC_OOM on allocation error, FSL_RC_MISUSE if any arguments are invalid, FSL_RC_TYPE if any of the content appears to be binary (contains embedded NUL bytes), FSL_RC_RANGE if some range is exceeded (e.g. the maximum number of input lines).

None of (pA, pB, out) may be NULL.

TODOs:

  • Add a predicate function for outputing only matching differences, analog to fossil(1)'s regex support (but more flexible).
  • Expose the raw diff-generation bits via the internal API to facilitate/enable the creation of custom diff formats.
FSL_EXPORT int fsl_diff_text_to_buffer ( fsl_buffer const *  pA,
fsl_buffer const *  pB,
fsl_buffer pOut,
short  contextLines,
short  sbsWidth,
int  diffFlags 
)

Functionally equivalent to:

1  :
2 fsl_diff_text(pA, pB, fsl_output_f_buffer, pOut,
3 contextLines, sbsWidth, diffFlags);

Except that it returns FSL_RC_MISUSE if !pOut.

FSL_EXPORT int fsl_dir_check ( const char *  zFilename)

Returns a positive value if zFilename is a directory, 0 if zFilename does not exist, or a negative value if zFilename exists but is something other than a directory.

Results are undefined if zFilename is NULL.

This function expects zFilename to be a well-formed path - it performs no normalization on it.

FSL_EXPORT int fsl_encode16 ( const unsigned char *  pIn,
unsigned char *  zOut,
fsl_size_t  N 
)

Encode a N-digit base-256 in base-16.

N is the byte length of pIn and zOut must be at least (N*2+1) bytes long (the extra is for a terminating NUL). Returns zero on success, FSL_RC_MISUSE if !pIn or !zOut.

FSL_EXPORT int fsl_errno_to_rc ( int  errNo,
int  dflt 
)

Tries to convert the value of errNo, which is assumed to come from the global errno, to a fsl_rc_t code.

If it can, it returns something approximating the errno value, else it returns dflt.

Example usage:

1 FILE * f = fsl_fopen("...", "...");
2 int rc = f ? 0 : fsl_errno_to_rc(errno, FSL_RC_IO);
3 ...

Why require the caller to pass in errno, instead of accessing it directly from this function? To avoid the the off-chance that something changes errno between the call and the conversion (whether or not that's possible is as yet undetermined). It can also be used by clients to map to explicit errno values to fsl_rc_t values, e.g. fsl_errno_to_rc(EROFS,-1) returns FSL_RC_ACCESS.

A list of the errno-to-fossil conversions:

  • EINVAL: FSL_RC_MISUSE (could arguably be FSL_RC_RANGE, though)
  • ENOMEM: FSL_RC_OOM
  • EACCES, EBUSY, EPERM: FSL_RC_ACCESS
  • EISDIR, ENOTDIR: FSL_RC_TYPE
  • ENAMETOOLONG, ELOOP: FSL_RC_RANGE
  • ENOENT: FSL_RC_NOT_FOUND
  • EEXIST: FSL_RC_ALREADY_EXISTS
  • EIO: FSL_RC_IO

Any other value for errNo causes dflt to be returned.

FSL_EXPORT void fsl_error_clear ( fsl_error err)

Frees up any resources owned by err and sets its error code to 0, but does not free err.

This is harmless no-op if !err or if err holds no dynamically allocated no memory.

See also
fsl_error_set()
fsl_error_get()
fsl_error_move()
fsl_error_reset()
FSL_EXPORT int fsl_error_copy ( fsl_error const *  src,
fsl_error dest 
)

Copies the error state from src to dest.

If dest contains state, it is cleared/recycled by this operation.

Returns 0 on success, FSL_RC_MISUSE if either argument is NULL or if (src==dest), and FSL_RC_OOM if allocation of the message string fails.

As a special case, if src->code==FSL_RC_OOM, then the code is copied but the message bytes (if any) are not (under the assumption that we have no more memory).

FSL_EXPORT int fsl_error_get ( fsl_error const *  err,
char const **  str,
fsl_size_t len 
)

Fetches the error state from err.

If !err it returns FSL_RC_MISUSE without side-effects, else it returns err's current error code.

If str is not NULL then *str will be assigned to the raw (NUL-terminated) error string (which might be empty or even NULL). The memory for the string is owned by err and may be invalidated by any calls which take err as a non-const parameter OR which might modify it indirectly through a container object, so the client is required to copy it if it is needed for later on.

If len is not NULL then *len will be assigned to the length of the returned string (in bytes).

See also
fsl_error_set()
fsl_error_clear()
fsl_error_move()
FSL_EXPORT void fsl_error_move ( fsl_error from,
fsl_error to 
)

Moves the error state from one fsl_error object to another, intended as an allocation optimization when propagating error state up the API.

This "uplifts" an error from the 'from' object to the 'to' object. After this returns 'to' will contain the prior error state of 'from' and 'from' will contain the old error message memory of 'to'. 'from' will be re-set to the non-error state (its buffer memory is kept intact for later reuse, though).

Results are undefined if either parameter is NULL or either is not properly initialized. i.e. neither may refer to uninitialized memory. Copying fsl_error_empty at declaration-time is a simple way to ensure that instances are cleanly initialized.

FSL_EXPORT void fsl_error_reset ( fsl_error err)

Sets err->code to 0 and resets its buffer, but keeps any err->msg memory around for later re-use.

See also
fsl_error_clear()
FSL_EXPORT int fsl_error_set ( fsl_error err,
int  code,
char const *  fmt,
  ... 
)

Populates err with the given code and formatted string, replacing any existing state.

If fmt==NULL then fsl_rc_cstr(rc) is used to get the error string.

Returns code on success, some other non-0 code on error.

As a special case, if 0==code then fmt is ignored and the error state is cleared. This will not free any memory held by err but will re-set its string to start with a NUL byte, ready for re-use later on.

As a special case, if code==FSL_RC_OOM then fmt is ignored to avoid a memory allocation (which would presumably fail).

See also
fsl_error_get()
fsl_error_clear()
fsl_error_move()
FSL_EXPORT int fsl_error_setv ( fsl_error err,
int  code,
char const *  fmt,
va_list  args 
)

va_list counterpart to fsl_error_set().

FSL_EXPORT void fsl_fclose ( FILE *  f)

Passes f to fclose(3) unless f is NULL or one of the C-standard (stdin, stdout, stderr) handles, in which cases it does nothing at all.

FSL_EXPORT int fsl_file_access ( const char *  zFilename,
int  flags 
)

Returns 0 if the given file is readable.

Flags may be any values accepted by the access(2) resp. _waccess() system calls.

FSL_EXPORT int fsl_file_canonical_name ( const char *  zOrigName,
fsl_buffer pOut,
char  slash 
)

Equivalent to fsl_file_canonical_name2(NULL, zOrigName, pOut, slash).

See also
fsl_file_canonical_name2()
FSL_EXPORT int fsl_file_canonical_name2 ( const char *  zRoot,
const char *  zOrigName,
fsl_buffer pOut,
char  slash 
)

Computes a canonical pathname for a file or directory.

Makes the name absolute if it is relative. Removes redundant / characters. Removes all /./ path elements. Converts /A/../ to just /. If the slash parameter is non-zero, the trailing slash, if any, is retained.

If zRoot is not NULL then it is used for transforming a relative zOrigName into an absolute path. If zRoot is NULL fsl_getcwd() is used to determine the virtual root directory. If zRoot is empty (starts with a NUL byte) then this function effectively just sends zOrigName through fsl_file_simplify_name().

Returns 0 on success, FSL_RC_MISUSE if !zOrigName or !pOut, FSL_RC_OOM if an allocation fails.

pOut, if not NULL, is _appended_ to, so be sure to set pOut->used=0 (or pass it to fsl_buffer_reset()) before calling this if you want to start writing at the beginning of a re-used buffer. On error pOut might conceivably be partially populated, but that is highly unlikely. Nonetheless, be sure to fsl_buffer_clear() it at some point regardless of success or failure.

This function does no actual filesystem-level processing unless zRoot is NULL or empty (and then only to get the current directory). This does not confirm whether the resulting file exists, nor that it is strictly a valid filename for the current filesystem. It simply transforms a potentially relative path into an absolute one.

Example:

1 int rc;
2 char const * zRoot = "/a/b/c";
3 char const * zName = "../foo.bar";
4 fsl_buffer buf = fsl_buffer_empty;
5 rc = fsl_file_canonical_name2(zRoot, zName, &buf, 0);
6 if(!rc){
7 fsl_buffer_clear(&buf);
8 return rc;
9 }
10 assert(0 == fsl_strcmp( "/a/b/foo.bar, fsl_buffer_cstr(&buf)));
11 fsl_buffer_clear(&buf);
FSL_EXPORT int fsl_file_dirpart ( char const *  zFilename,
fsl_int_t  nLen,
fsl_buffer pOut,
char  leaveSlash 
)

Calculates the "directory part" of zFilename and _appends_ it to pOut.

The directory part is all parts up to the final path separator ('\' or '/'). If leaveSlash is true (non-0) then the separator part is appended to pOut, otherwise it is not. This function only examines the first nLen bytes of zFilename. If nLen is negative then fsl_strlen() is used to determine the number of bytes to examine.

If zFilename ends with a slash then it is considered to be its own directory part. i.e. the dirpart of "foo/" evaluates to "foo" (or "foo/" if leaveSlash is true), whereas the dirpart of "foo" resolves to nothing (empty - no output except a NUL terminator sent to pOut).

Returns 0 on success, FSL_RC_MISUSE if !zFilename or !pOut, FSL_RC_RANGE if 0==nLen or !*zFilename, and FSL_RC_OOM if appending to pOut fails. If zFilename contains only a path separator and leaveSlash is false then only a NUL terminator is appended to pOut if it is not already NUL-terminated.

This function does no filesystem-level validation of the the given path - only string evaluation.

FSL_EXPORT fsl_time_t fsl_file_mtime ( const char *  zFilename)

Return the modification time for a file.

Return -1 if the file does not exist or is not stat(2)able.

FSL_EXPORT int fsl_file_mtime_set ( const char *  zFilename,
fsl_time_t  newMTime 
)

Sets the mtime (Unix epoch) for a file.

Returns 0 on success, non-0 on error. If newMTime is less than 0 then the current time(2) is used. This routine does not create non-existent files (e.g. like a Unix "touch" command).

FSL_EXPORT fsl_size_t fsl_file_simplify_name ( char *  z,
fsl_int_t  n_,
char  slash 
)

Simplify a filename by:

converting all \ into / on windows and cygwin removing any trailing and duplicate / removing /./ removing /A/../

Changes are made in-place. Return the new name length. If the slash parameter is non-zero, the trailing slash, if any, is retained. If n is <0 then fsl_strlen() is used to calculate the length.

FSL_EXPORT fsl_size_t fsl_file_size ( const char *  zFilename)

Return the size of a file in bytes.

Returns -1 if the file does not exist or is not stat(2)able.

FSL_EXPORT int fsl_file_unlink ( const char *  zFilename)

Deletes the given file from the filesystem.

Returns 0 on success. If the component is a directory, this operation will fail unless the directory is empty. If zFilename refers to a symlink, the link (not its target) is removed.

Results are undefined if zFilename is NULL.

FSL_EXPORT void fsl_filename_free ( void *  pOld)

Deallocate pOld, which must have been allocated by fsl_filename_to_utf8(), fsl_utf8_to_filename(), fsl_getenv(), or another routine which explicitly documents this function as being the proper finalizer for its returned memory.

FSL_EXPORT char* fsl_filename_to_utf8 ( const void *  zFilename)

Translate text from the OS's character set into UTF-8.

Return a pointer to the translated text. Call fsl_filename_free() to deallocate any memory used to store the returned pointer when done.

This function must not convert '\' to '/' on Windows/Cygwin, as it is used in places where we are not sure it's really filenames we are handling, e.g. fsl_getenv() or handling the argv arguments from main().

On Windows, translate some characters in the in the range U+F001 - U+F07F (private use area) to ASCII. Cygwin sometimes generates such filenames. See: http://cygwin.com/cygwin-ug-net/using-specialnames.html

FSL_EXPORT int fsl_finalizer_f_buffer ( void *  state,
void *  mem 
)

fsl_finalizer_f() impl which requires that mem be-a (fsl_buffer*).

This function frees all memory associated with that buffer and zeroes out the structure, but does not free mem (because it is rare that fsl_buffers are created on the heap). The state parameter is ignored.

FSL_EXPORT void fsl_finalizer_f_FILE ( void *  state,
void *  mem 
)

A fsl_finalizer_f() impl which requires that mem be-a (FILE*).

This function passes that FILE to fsl_fclose(). The state parameter is ignored.

FSL_EXPORT int fsl_find_home_dir ( fsl_buffer tgt,
char  requireWriteAccess 
)

Tries to find the user's home directory.

If found, 0 is returned, tgt's memory is _overwritten_ (not appended) with the path, and tgt->used is set to the path's string length. (Design note: the overwrite behaviour is inconsistent with most of the API, but the implementation currently requires this.)

If requireWriteAccess is true then the directory is checked for write access, and FSL_RC_ACCESS is returned if that check fails. For historical (possibly techinical?) reasons, this check is only performed on Unix platforms. On others this argument is ignored. When writing code on Windows, it may be necessary to assume that write access is necessary on non-Windows platform, and to pass 1 for the second argument even though it is ignored on Windows.

On error non-0 is returned and tgt is updated with an error string OR (if the error was an allocation error while appending to the path or allocating MBCS strings for Windows), it returns FSL_RC_OOM and tgt "might" be updated with a partial path (up to the allocation error), and "might" be empty (if the allocation error happens early on).

This routine does not canonicalize/transform the home directory path provided by the environment, other than to convert the string byte encoding on some platforms. i.e. if the environment says that the home directory is "../" then this function will return that value, possibly to the eventual disappointment of the caller.

Result codes include:

  • FSL_RC_OK (0) means a home directory was found and tgt is populated with its path.
  • FSL_RC_NOT_FOUND means the home directory (platform-specific) could not be found.
  • FSL_RC_ACCESS if the home directory is not writable and requireWriteAccess is true. Unix platforms only - requireWriteAccess is ignored on others.
  • FSL_RC_TYPE if the home (as determined via inspection of the environment) is not a directory.
  • FSL_RC_OOM if a memory (re)allocation fails.
FSL_EXPORT int fsl_flush_f_FILE ( void *  _FILE)

A fsl_flush_f() impl which expects _FILE to be-a (FILE*) opened for writing, which this function passes the call on to fflush().

If fflush() returns 0, so does this function, else it returns non-0.

FSL_EXPORT FILE* fsl_fopen ( char const *  name,
char const *  mode 
)

_Almost_ equivalent to fopen(3) but:

  • expects name to be UTF8-encoded.
  • If name=="-", it returns one of stdin or stdout, depending on the mode string: stdout is returned if 'w' or '+' appear, otherwise stdin.

If it returns NULL, the errno "should" contain a description of the problem unless the problem was argument validation. Pass it to fsl_errno_to_rc() to convert that into an API-conventional error code.

If at all possible, use fsl_close() (as opposed to fclose()) to close these handles, as it has logic to skip closing the standard streams.

Potential TODOs:

  • extend mode string to support 'x', meaning "exclusive", analog to open(2)'s O_EXCL flag. Barring race conditions, we have enough infrastructure to implement that. (It turns out that glibc's fopen() supports an 'x' with exactly this meaning.)
  • extend mode to support a 't', meaning "temporary". The idea would be that we delete the file from the FS right after opening, except that Windows can't do that.
FSL_EXPORT fsl_int_t fsl_fprintf ( FILE *  fp,
char const *  fmt,
  ... 
)

Emulates fprintf() using fsl_appendf().

Returns the result of passing the data through fsl_appendf() to the given file handle.

FSL_EXPORT fsl_int_t fsl_fprintfv ( FILE *  fp,
char const *  fmt,
va_list  args 
)

The va_list counterpart of fsl_fprintf().

FSL_EXPORT void fsl_free ( void *  mem)

Semantically behaves like free(3), but may introduce instrumentation, error checking, or similar.

FSL_EXPORT int fsl_getcwd ( char *  zBuf,
fsl_size_t  nBuf,
fsl_size_t outLen 
)

Writes the absolute path name of the current directory to zBuf, which must be at least nBuf bytes long (nBuf includes the space for a trailing NUL terminator).

Returns FSL_RC_RANGE if the name would be too long for nBuf, FSL_RC_IO if it cannot determine the current directory (e.g. a side effect of having removed the directory at runtime or similar things), and 0 on success.

On success, if outLen is not NULL then the length of the string written to zBuf is assigned to *outLen. The output string is always NUL-terminated.

On Windows, the name is converted from unicode to UTF8 and all '\' characters are converted to '/'. No conversions are needed on Unix.

FSL_EXPORT char* fsl_getenv ( const char *  zName)

Returns a (possible) copy of the environment variable with the given key, or NULL if no entry is found.

The returned value must be passed to fsl_filename_free() to free it. ACHTUNG: DO NOT MODIFY the returned value - on Unix systems it is _not_ a copy. That interal API inconsistency "should" be resolved (==return a copy from here, but that means doing it everywhere) to avoid memory ownership problems later on.

Why return a copy? Because native strings from at least one of the more widespread OSes often have to be converted to something portable and this requires allocation on such platforms, but not on Unix. For API transparency, that means all platforms get the copy(-like) behaviour.

FSL_EXPORT int fsl_glob_list_append ( fsl_list tgt,
char const *  zGlob 
)

Appends a single blob pattern to tgt, in the form of a new (char *) owned by tgt.

This function copies zGlob and appends that copy to tgt.

Returns 0 on success, FSL_RC_MISUSE if !tgt or !zGlob or !*zGlob, FSL_RC_OOM if appending to the list fails.

See also
fsl_glob_list_parse()
fsl_glob_list_matches()
fsl_glob_list_clear()
FSL_EXPORT void fsl_glob_list_clear ( fsl_list globList)

If globList is not NULL this is equivalent to fsl_list_visit_free(globList, 1), otherwise it is a no-op.

Note that this does not free the globList object itself, just its underlying list entries and list memory. (In practice, lists are either allocated on the stack or as part of a higher-level structure, and not on the heap.)

See also
fsl_glob_list_parse()
fsl_glob_list_append()
fsl_glob_list_matches()
FSL_EXPORT char const* fsl_glob_list_matches ( fsl_list const *  globList,
char const *  zHaystack 
)

Assumes globList is a list of (char [const] *) glob values and tries to match each one against zHaystack using fsl_str_glob().

If any glob matches, it returns a pointer to the matched globList->list entry. If no matches are found, or if any argument is invalid, NULL is returned.

The returned bytes are owned by globList and may be invalidated at its leisure. It is primarily intended to be used as a boolean, for example:

1 if( fsl_glob_list_matches(myGlobs, someFilename) ) { ... }
See also
fsl_glob_list_parse()
fsl_glob_list_append()
fsl_glob_list_clear()
FSL_EXPORT int fsl_glob_list_parse ( fsl_list tgt,
char const *  zPatternList 
)

Parses zPatternList as a comma-and/or-fsl_isspace()-delimited list of glob patterns (as supported by fsl_str_glob()).

Each pattern in that list is copied and appended to tgt in the form of a new (char *) owned by that list.

Returns 0 on success, FSL_RC_OOM if copying a pattern to tgt fails, FSL_RC_MISUSE if !tgt or !zPatternList. An empty zPatternList is not considered an error (to simplify usage) and has no side-effects. On allocation error, tgt might be partially populated.

Elements of the glob list may be optionally enclosed in single our double-quotes. This allows a comma to be part of a glob pattern.

Leading and trailing spaces on unquoted glob patterns are ignored.

Note that there is no separate "glob list" class. A "glob list" is simply a fsl_list whose list entries are glob-pattern strings owned by that list.

Examples of a legal value for zPatternList:

1 "*.c *.h, *.sh, '*.in'"
See also
fsl_glob_list_append()
fsl_glob_list_matches()
fsl_glob_list_clear()
FSL_EXPORT unsigned int fsl_gradient_color ( unsigned int  c1,
unsigned int  c2,
unsigned int  numberOfSteps,
unsigned int  stepNumber 
)

For two color values encoded as RRGGBB values (see below for the structure), this function computes a gradient somewhere between those colors.

c1 and c2 are the edges of the gradient. numberOfSteps is the number of steps in the gradient. stepNumber is a number less than numberOfSteps which specifies the "degree" of the gradients. If either numberOfSteps or stepNumber is 0, c1 is returned. stepNumber of equal to or greater than c2 returns c2.

The returns value is an RGB-encoded value in the lower 24 bits, ordered in big-endian. In other words, assuming rc is the return value:

  • red = (rc&0xFF0000)>>16
  • green = (rc&0xFF00)>>8
  • blue = (rc&0xFF)

Or use fsl_rgb_decode() to break it into its component parts.

It can be passed directly to a printf-like function, using the hex-integer format specifier, e.g.:

1 fsl_buffer_appendf(&myBuf, "#%06x", rc);

Tip: for a given HTML RRGGBB value, its C representation is identical: HTML #F0D0A0 is 0xF0D0A0 in C.

See also
fsl_rgb_encode()
fsl_rgb_decode()
FSL_EXPORT char* fsl_guess_user_name ( )

Uses fsl_getenv() to look for the environment variables (FOSSIL_USER, (Windows: USERNAME), (Unix: USER, LOGNAME)).

If it finds one it returns a copy of that value, which must eventually be passed to fsl_free() to free it (NOT fsl_filename_free(), though fsl_getenv() requires that one). If it finds no match, or if copying the entry fails, it returns NULL.

See also
fsl_cx_user_set()
fsl_cx_user_get()
FSL_EXPORT int fsl_htmlize ( fsl_output_f  out,
void *  oState,
const char *  zIn,
fsl_int_t  n 
)

Make the given string safe for HTML by converting every "<" into "&lt;", every ">" into "&gt;", every "&" into "&amp;", and encode '"' as " so that it can appear as an argument to markup.

The escaped output is send to out(oState,...).

Returns 0 on success or if there is nothing to do (input has a length of 0, in which case out() is not called). Returns FSL_RC_MISUSE if !out or !zIn. If out() returns a non-0 code then that value is returned to the caller.

If n is negative, fsl_strlen() is used to calculate zIn's length.

FSL_EXPORT char* fsl_htmlize_str ( const char *  zIn,
fsl_int_t  n 
)

Equivalent to fsl_htmlize_to_buffer() but returns the result as a new string which must eventually be fsl_free()d by the caller.

Returns NULL for invalidate arguments or allocation error.

FSL_EXPORT int fsl_htmlize_to_buffer ( fsl_buffer p,
const char *  zIn,
fsl_int_t  n 
)

Functionally equivalent to fsl_htmlize() but optimized to perform only a single allocation.

Returns 0 on success or if there is nothing to do (input has a length of 0). Returns FSL_RC_MISUSE if !p or !zIn, and FSL_RC_OOM on allocation error.

If n is negative, fsl_strlen() is used to calculate zIn's length.

FSL_EXPORT fsl_size_t fsl_htmlize_xlate ( int  c,
char const **  xlate 
)

If c is a character Fossil likes to HTML-escape, assigns *xlate to its transformed form, else set it to NULL.

Returns 1 for untransformed characters and the strlen of *xlate for others. Bytes returned via xlate are static and immutable.

Results are undefined if xlate is NULL.

FSL_EXPORT void fsl_id_bag_clear ( fsl_id_bag p)

Frees any memory owned by p, but does not free p.

FSL_EXPORT char fsl_id_bag_contains ( fsl_id_bag p,
fsl_id_t  e 
)

Returns true (non-0) if e in the bag.

Returns false (0) if it is not. It is illegal to pass an e value of 0, and that will trigger an assertion in debug builds.

FSL_EXPORT fsl_size_t fsl_id_bag_count ( fsl_id_bag p)

Return the number of elements in the bag.

FSL_EXPORT fsl_id_t fsl_id_bag_first ( fsl_id_bag p)

Returns the ID of the first element in the bag.

Returns 0 if the bag is empty.

Example usage:

1 fsl_id_t nid;
2 for( nid = fsl_id_bag_first(&list);
3 nid > 0;
4 nid = fsl_id_bag_next(&list, nid)){
5 
6 ...do something...
7 }
FSL_EXPORT int fsl_id_bag_insert ( fsl_id_bag p,
fsl_id_t  e 
)

Insert element e into the bag if it is not there already.

Returns 0 if it actually inserts something or if it already contains such an entry, and some other value on error (e.g. FSL_RC_OOM).

e must be positive or an assertion is triggered in debug builds.

fsl_id_t fsl_id_bag_next ( fsl_id_bag p,
fsl_id_t  e 
)

Returns the next element in the bag after e.

Return 0 if e is the last element in the bag. Any insert or removal from the bag might reorder the bag. It is illegal to pass this 0 (and will trigger an assertion in debug builds). For the first call, pass it the non-0 return value from fsl_id_bag_first(). For subsequent calls, pass the previous return value from this function.

See also
fsl_id_bag_first() FSL_EXPORT
FSL_EXPORT void fsl_id_bag_remove ( fsl_id_bag p,
fsl_id_t  e 
)

Remove element e from the bag if it exists in the bag.

If e is not in the bag, this is a no-op.

FSL_EXPORT int fsl_input_f_buffer ( void *  state,
void *  dest,
fsl_size_t n 
)

A fsl_input_f() implementation which requires that state be a readable (fsl_buffer*) handle.

The buffer's cursor member is updated to track input postion, but that is the only modification made by this routine. Thus the user may need to reset the cursor to 0 if he wishes to start consuming the buffer at its starting point. Subsequent calls to this function will increment the cursor by the number of bytes returned via *n. The buffer's "used" member is used to determine the logical end of input.

Returns 0 on success and has no error conditions except for invalid arguments, which result in undefined beavhiour. Results are undefined if any argument is NULL.

Tip (and warning): sometimes a routine might have a const buffer handle which it would like to use in conjunction with this routine but cannot withou violating constness. Here's a crude workaround:

1 fsl_buffer kludge = *originalConstBuffer; // normally this is dangerous!
2 rc = some_func( fsl_input_f_buffer, &kludge, ... );
3 assert(kludge.mem==originalConstBuffer->mem); // See notes below.
4 // DO NOT clean up the kludge buffer. Memory belongs to the original!

That is ONLY (ONLY! ONLY!! ONLY!!!) legal because this routine modifies only fsl_buffer::cursor. Such a workaround is STRICLY ILLEGAL if there is ANY CHANCE WHATSOEVER that the buffer's memory will be modified, in particular if it will be resized, and such use will eventually leak and/or corrupt memory.

FSL_EXPORT int fsl_input_f_FILE ( void *  state,
void *  dest,
fsl_size_t n 
)

A fsl_input_f() implementation which requires that state be a readable (FILE*) handle.

FSL_EXPORT char fsl_is_absolute_path ( const char *  zPath)

Returns true if the given path appears to be absolute, else false.

On Unix a path is absolute if it starts with a '/'. On Windows a path is also absolute if it starts with a letter, a colon, and either a backslash or forward slash.

FSL_EXPORT char fsl_is_file ( const char *  zFilename)

Return TRUE if the named file is an ordinary file.

Return false for directories, devices, fifos, symlinks, etc.

FSL_EXPORT char fsl_is_simple_pathname ( const char *  z,
char  bStrictUtf8 
)

Return true (non-0) if the filename given is a valid filename for a file in a repository.

Valid filenames follow all of the following rules:

  • Does not begin with "/"
  • Does not contain any path element named "." or ".."
  • Does not contain "/..." (special case)
  • Does not contain any of these characters in the path: "\"
  • Does not end with "/".
  • Does not contain two or more "/" characters in a row.
  • Contains at least one character

Invalid UTF8 characters result in a false return if bStrictUtf8 is true. If bStrictUtf8 is false, invalid UTF8 characters are silently ignored. See http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences and http://en.wikipedia.org/wiki/Unicode (for the noncharacters).

Fossil compatibility note: the bStrictUtf8 flag must be true when parsing new manifests but is false when parsing legacy manifests, for backwards compatibility.

z must be NUL terminated. Results are undefined if !z.

Note that periods in and of themselves are valid filename components, with the special exceptions of "." and "..", one implication being that "...." is, for purposes of this function, a valid simple filename.

FSL_EXPORT char fsl_is_uuid ( char const *  str)

Returns true (non-0) if str is not NULL, is exactly FSL_UUID_STRLEN bytes long (meaning its final byte is a NUL), and contains only lower-case hexadecimal characters, else returns false (0).

Note that Fossil UUIDs are not RFC4122 UUIDs, but are SHA1 hash strings. Don't let that disturb you. As Tim Berners-Lee writes:

'The assertion that the space of URIs is a universal space sometimes encounters opposition from those who feel there should not be one universal space. These people need not oppose the concept because it is not of a single universal space: Indeed, the fact that URIs form universal space does not prevent anyone else from forming their own universal space, which of course by definition would be able to envelop within it as a subset the universal URI space. Therefore the web meets the "independent design" test, that if a similar system had been concurrently and independently invented elsewhere, in such a way that the arbitrary design decisions were made differently, when they met later, the two systems could be made to interoperate.'

Source: http://www.w3.org/DesignIssues/Axioms.html

(Just mentally translate URI as UUID.)

FSL_EXPORT char fsl_isalnum ( int  c)

Equivalent to fsl_isdigit(c) || fsl_isalpha().

FSL_EXPORT char fsl_isalpha ( int  c)

Returns true if the given letter is an ASCII alphabet character.

FSL_EXPORT char fsl_isatty ( int  fd)

Returns the result of calling the platform's equivalent of isatty(fd).

e.g. on Windows this is _isatty() and on Unix isatty(). i.e. it returns a true value (non-0) if it thinks that the given file descriptor value is attached to an interactive terminal, else it returns false.

FSL_EXPORT char fsl_isdigit ( int  c)

Returns true if c is an ASCII digit in the range '0' to '9'.

FSL_EXPORT char fsl_islower ( int  c)

Returns true if c is a lower-case ASCII alphabet character.

FSL_EXPORT char fsl_iso8601_to_julian ( char const *  zDate,
fsl_double_t pOut 
)

If zDate is an ISO8601-format string, optionally with a .NNN fractional suffix, then this function returns true and sets pOut (if pOut is not NULL) to the corresponding Julian value.

If zDate is not an ISO8601-format string then this returns false (0) and pOut is not modified.

This function does NOT confirm that zDate ends with a NUL byte. i.e. if passed a valid date string which has trailing bytes after it then those are simply ignored. This is so that it can be used to read subsets of larger strings.

Achtung: this calculation may, due to voodoo-level floating-point behaviours, differ by a small fraction of a point (at the millisecond level) for a given input compared to other implementations (e.g. sqlite's strftime() _might_ differ by a millisecond or two or _might_ not). Thus this routine should not be used when 100% round-trip fidelity is required, but is close enough for routines which do not require 100% millisecond-level fidelity in time conversions.

See also
fsl_julian_to_iso8601()
FSL_EXPORT char fsl_isspace ( int  c)

Returns true if c is ' ', '\r' (ASCII 13dec), or '\t' (ASCII 9 dec).

FSL_EXPORT char fsl_isupper ( int  c)

Returns true if c is an upper-case ASCII alphabet character.

FSL_EXPORT fsl_double_t fsl_julian_now ( )

Returns the current Unix Epoch time converted to its approximate Julian form.

Equivalent to fsl_unix_to_julian(time(0)). See fsl_unix_to_julian() for details. Note that the returned time has seconds, not milliseconds, precision.

FSL_EXPORT char fsl_julian_to_iso8601 ( fsl_double_t  J,
char *  pOut,
char  addMs 
)

Converts the Julian Day J to an ISO8601 time string.

If addMs is true then the string includes the '.NNN' fractional part, else it will not. This function writes (on success) either 20 or 24 bytes (including the terminating NUL byte) to pOut, depending on the value of addMs, and it is up to the caller to ensure that pOut is at least that long.

Returns true (non-0) on success and the only error conditions [it can catch] are if pOut is NULL, J is less than 0, or evaluates to a time value which does not fit in ISO8601 (e.g. only years 0-9999 are supported).

See also
fsl_iso8601_to_julian()
FSL_EXPORT fsl_time_t fsl_julian_to_unix ( fsl_double_t  J)

Returns the Julian Day time J value converted to a Unix Epoch timestamp.

It assumes 86400 seconds per day and does not account for any sort leap seconds, leap years, leap frogs, or any other kind of leap, up to and including a leap of faith.

FSL_EXPORT int fsl_list_append ( fsl_list self,
void *  cp 
)

Appends a bitwise copy of cp to self->list, expanding the list as necessary and adjusting self->used.

Ownership of cp is unchanged by this call. cp may not be NULL.

Returns 0 on success, FSL_RC_MISUSE if any argument is NULL, or FSL_RC_OOM on allocation error.

FSL_EXPORT int fsl_list_clear ( fsl_list list,
fsl_list_visitor_f  childFinalizer,
void *  finalizerState 
)

A list clean-up routine which takes a callback to clean up its contents.

Passes each element in the given list to childFinalizer(item,finalizerState). If that returns non-0, processing stops and that value is returned, otherwise fsl_list_reserve(list,0) is called and 0 is returned.

WARNING: if cleanup fails because childFinalizer() returns non-0, the returned object is effectively left in an undefined state and the client has no way (unless the finalizer somehow accounts for it) to know which entries in the list were cleaned up. Thus it is highly recommended that finalizer functions follow the conventional wisdom of "destructors do not throw."

See also
fsl_list_visit_free()
FSL_EXPORT fsl_int_t fsl_list_index_of ( fsl_list const *  li,
void const *  value,
fsl_generic_cmp_f  cmpf 
)

Searches for a value in the given list, using the given comparison function to determine equivalence.

The comparison function will never be passed a NULL value by this function - if value is NULL then only a NULL entry will compare equal to it. Results are undefined if li or cmpf are NULL.

Returns the index in li of the entry, or a negative value if no match is found.

FSL_EXPORT fsl_int_t fsl_list_index_of_cstr ( fsl_list const *  li,
char const *  key 
)

Equivalent to fsl_list_index_of(li, key, fsl_strcmp_cmp).

FSL_EXPORT int fsl_list_reserve ( fsl_list self,
fsl_size_t  n 
)

Possibly reallocates self->list, changing its size.

This function ensures that self->list has at least n entries. If n is 0 then the list is deallocated (but the self object is not), BUT THIS DOES NOT DO ANY TYPE-SPECIFIC CLEANUP of the items. If n is less than or equal to self->capacity then there are no side effects. If n is greater than self->capacity, self->list is reallocated and self->capacity is adjusted to be at least n (it might be bigger - this function may pre-allocate a larger value).

Passing an n of 0 when self->capacity is 0 is a no-op.

Newly-allocated slots will be initialized with NUL bytes.

Returns 0 on success, FSL_RC_MISUSE if !self, FSL_RC_OOM if reservation of new elements fails.

The return value should be used like this:

1 fsl_size_t const n = number of bytes to allocate;
2 int const rc = fsl_list_reserve( myList, n );
3 if( rc ) { ... error ... }
See also
fsl_list_clear()
fsl_list_visit_free()
FSL_EXPORT void fsl_list_sort ( fsl_list li,
fsl_generic_cmp_f  cmp 
)

Sorts the given list using the given comparison function.

Neither argument may be NULL. The arugments passed to the comparison function will be pointers to pointers to the original entries, and may (depending on how the list is used) point to NULL.

FSL_EXPORT void fsl_list_swap ( fsl_list lhs,
fsl_list rhs 
)

Swaps all contents of both lhs and rhs.

Results are undefined if lhs or rhs are NULL or not properly initialized (via initial copy initialization from fsl_list_empty resp. fsl_list_empty_m).

FSL_EXPORT int fsl_list_v_fsl_free ( void *  obj,
void *  visitorState 
)

A fsl_list_visitor_f() implementation which requires that obj be arbitrary memory which can legally be passed to fsl_free() (which this function does).

The visitorState parameter is ignored.

FSL_EXPORT int fsl_list_visit ( fsl_list const *  self,
int  order,
fsl_list_visitor_f  visitor,
void *  visitorState 
)

For each item in self->list, visitor(item,visitorState) is called.

The item is owned by self. The visitor function MUST NOT free the item (unless the visitor is a finalizer!), but may manipulate its contents if application rules do not specify otherwise.

If order is 0 or greater then the list is traversed from start to finish, else it is traverse from end to begin.

Returns 0 on success, non-0 on error.

If visitor() returns non-0 then looping stops and that code is returned.

FSL_EXPORT void fsl_list_visit_free ( fsl_list list,
char  freeListMem 
)

Similar to fsl_list_clear(list, fsl_list_v_fsl_free, NULL), but only frees list->list if the second argument is true, otherwise it sets the list's length to 0 but keep the list->list memory intact for later use.

Note that this function never frees the list argument, only its contents.

Be sure only to use this on lists of types for which fsl_free() is legal. i.e. don't use it on a list of fsl_deck objects or other types which have their own finalizers.

Results are undefined if list is NULL.

See also
fsl_list_clear()
FSL_EXPORT int fsl_list_visit_p ( fsl_list self,
int  order,
char  shiftIfNulled,
fsl_list_visitor_f  visitor,
void *  visitorState 
)

Works similarly to the visit operation without the _p suffix except that the pointer the visitor function gets is a (**) pointing back to the entry within this list.

That means that callers can assign the entry in the list to another value during the traversal process (e.g. set it to 0). If shiftIfNulled is true then if the callback sets the list's value to 0 then it is removed from the list and self->used is adjusted (self->capacity is not changed).

void* fsl_malloc ( fsl_size_t  n)

Semantically behaves like malloc(3), but may introduce instrumentation, error checking, or similar.

FSL_EXPORT int fsl_mkdir ( const char *  zName,
char  forceFlag 
)

Create the directory with the given name if it does not already exist.

If forceFlag is true, delete any prior non-directory object with the same name.

Return 0 on success, non-0 on error.

If the directory already exists then 0 is returned, not an error (FSL_RC_ALREADY_EXISTS), because that simplifies usage. If another filesystem entry with this name exists and forceFlag is true then that entry is deleted before creating the directory, and this operation fails if deletion fails. If forceFlag is false and a non-directory entry already exists, FSL_RC_TYPE is returned.

For recursively creating directories, use fsl_mkdir_for_file().

Bug/corner case: if zFilename refers to a symlink to a non-existent directory, this function gets slightly confused, tries to make a dir with the symlink's name, and returns FSL_RC_ALREADY_EXISTS. How best to resolve that is not yet clear. The problem is that stat(2)ing the symlink says "nothing is there" (because the link points to a non-existing thing), so we move on to the underlying mkdir(), which then fails because the link exists with that name.

FSL_EXPORT int fsl_mkdir_for_file ( char const *  zName,
char  forceFlag 
)

A convenience form of fsl_mkdir() which can recursively create directories.

If zName has a trailing slash then the last component is assumed to be a directory part, otherwise it is assumed to be a file part (and no directory is created for that part). zName may be either an absolute or relative path.

Returns 0 on success (including if all directories already exist). Returns FSL_RC_OOM if there is an allocation error. Returns FSL_RC_TYPE if one of the path components already exists and is not a directory. Returns FSL_RC_RANGE if zName is NULL or less than 2 bytes long.

On systems which support symlinks, a link to a directory is considered to be a directory for purposes of this function.

If forceFlag is true and a non-directory component is found in the filesystem where zName calls for a directory, that component is removed (and this function fails if removal fails).

Examples:

"/foo/bar" creates (if needed) /foo, but assumes "bar" is a file component. "/foo/bar/" creates /foo/bar. However "foo" will not create a directory - because the string has no path component, it is assumed to be a filename.

Both "/foo/bar/my.doc" and "/foo/bar/" result in the directories /foo/bar.

FSL_EXPORT char* fsl_mprintf ( char const *  fmt,
  ... 
)

Works like fsl_appendfv(), but appends all output to a dynamically-allocated string, expanding the string as necessary to collect all formatted data.

The returned NUL-terminated string is owned by the caller and it must be cleaned up using fsl_free(...). If !fmt, NULL is returned. It is conceivable that it returns NULL on a zero-length formatted string, e.g. (%.*s) with (0,"...") as arguments, but it will only do that if the whole format string resolves to empty.

FSL_EXPORT char* fsl_mprintfv ( char const *  fmt,
va_list  vargs 
)

va_list counterpart to fsl_mprintf().

FSL_EXPORT int fsl_output_f_buffer ( void *  state,
void const *  src,
fsl_size_t  n 
)

A fsl_output_f() impl which requires state to be-a (fsl_buffer*), which this function passes to fsl_buffer_append().

Returns 0 on success, FSL_RC_OOM (probably) on error.

FSL_EXPORT int fsl_output_f_FILE ( void *  state,
void const *  src,
fsl_size_t  n 
)

fsl_output_f() implementation which requires state to be a writeable (FILE*) handle.

A fsl_output_f() impl which requires state to be-a (FILE*), which this function passes the call on to fwrite().

Is a no-op (returning 0) if !n. Returns FSL_RC_MISUSE if !state or !src.

Returns 0 on success, FSL_RC_IO on error.

FSL_EXPORT int fsl_output_f_fsl_cx ( void *  state,
void const *  src,
fsl_size_t  n 
)

fsl_output_f() implementation which requires state to be a (fsl_cx*) to which this routine simply redirects the output via fsl_output().

Is a no-op (returning 0) if !n. Returns FSL_RC_MISUSE if !state or !src.

FSL_EXPORT void fsl_pathfinder_clear ( fsl_pathfinder pf)

Frees all memory associated with pf, but does not free pf.

Is a no-op if pf is NULL.

FSL_EXPORT int fsl_pathfinder_dir_add ( fsl_pathfinder pf,
char const *  dir 
)

Adds the given directory to pf's search path.

Returns 0 on success, FSL_RC_MISUSE if !pf or !dir (dir _may_ be an empty string), FSL_RC_OOM if copying the string or adding it to the list fails.

See also
fsl_pathfinder_ext_add()
fsl_pathfinder_search()
FSL_EXPORT int fsl_pathfinder_ext_add ( fsl_pathfinder pf,
char const *  ext 
)

Adds the given directory to pf's search extensions.

Returns 0 on success, FSL_RC_MISUSE if !pf or !dir (dir _may_ be an empty string), FSL_RC_OOM if copying the string or adding it to the list fails.

Note that the client is responsible for adding a "." to the extension, if needed, as this API does not apply any special meaning to any characters in a search extension. e.g. "-journal" and "~" are both perfectly valid extensions for this purpose.

See also
fsl_pathfinder_dir_add()
fsl_pathfinder_search()
FSL_EXPORT int fsl_pathfinder_search ( fsl_pathfinder pf,
char const *  base,
char const **  pOut,
fsl_size_t outLen 
)

Searches for a file whose name can be constructed by some combination of pf's directory/suffix list and the given base name.

It searches for files in the following manner:

If the 2nd parameter exists as-is in the filesystem, it is treated as a match, otherwise... Loop over all directories in pf->dirs. Create a path with DIR/base, or just base if the dir entry is empty (length of 0). Check for a match. If none is found, then... Loop over each extension in pf->ext, creating a path named DIR/baseEXT (note that it does not add any sort of separator between the base and the extensions, so "~" and "-foo" are legal extensions). Check for a match.

On success (a readable filesystem entry is found):

  • It returns 0.
  • If pOut is not NULL then *pOut is set to the path it found. The bytes of the returned string are only valid until the next search operation on pf, so copy them if you need them. Note that the returned path is _not_ normalized via fsl_file_canonical_name() or similar, and it may very well return a relative path (if base or one of pf->dirs contains a relative path part).
  • If outLen is not NULL, *outLen will be set to the length of the returned string.

On error:

  • Returns FSL_RC_MISUSE if !pf, !base, !*base.
  • Returns FSL_RC_OOM on allocation error (it uses a buffer to hold its path combinations and return value).
  • Returns FSL_RC_NOT_FOUND if it finds no entry.

The host platform's customary path separator is used to separate directory/file parts ('\' on Windows and '/' everywhere else).

Note that it _is_ legal for pOut and outLen to both be NULL, in which case a return of 0 signals that an entry was found, but the client has no way of knowing what path it might be (unless, of course, he relies on internal details of the fsl_pathfinder API, which he most certainly should not do).

Tip: if the client wants to be certain that this function will not allocate memory, simply use fsl_buffer_reserve() on pf->buf to reserve the desired amount of space in advance. As long as the search paths never extend that length, this function will not need to allocate. (Until/unless the following TODO is implemented...)

Potential TODO: use fsl_file_canonical_name() so that the search dirs themselves do not need to be entered using platform-specific separators. The main reason it's not done now is that it requires another allocation. The secondary reason is because it's sometimes useful to use relative paths in this context (based on usage in previous trees from which this code derives).

See also
fsl_pathfinder_dir_add()
fsl_pathfinder_ext_add()
fsl_pathfinder_clear()
FSL_EXPORT void* fsl_realloc ( void *  mem,
fsl_size_t  n 
)

Behaves like realloc(3).

Clarifications on the behaviour (because the standard has one case of unfortunate wording involving what it returns when n==0):

  • If passed (NULL, n>0) then it semantically behaves like fsl_malloc(f, n).
  • If 0==n then it semantically behaves like free(2) and returns NULL (clarifying the aforementioned wording problem).
  • If passed (non-NULL, n) then it semantically behaves like realloc(mem,n).
FSL_EXPORT void* fsl_realloc_f_stdalloc ( void *  state,
void *  mem,
fsl_size_t  n 
)

A fsl_realloc_f() implementation which uses the standard malloc()/free()/realloc().

The state parameter is ignored.

FSL_EXPORT void fsl_rgb_decode ( unsigned int  src,
int *  r,
int *  g,
int *  b 
)

Given an RGB-encoded source value, this function decodes the lower 24 bits into r, g, and b.

Any of r, g, and b may be NULL to skip over decoding of that part.

See also
fsl_rgb_encode()
fsl_gradient_color()
FSL_EXPORT unsigned int fsl_rgb_encode ( int  r,
int  g,
int  b 
)

For the given red/green/blue values (all in the range of 0 to 255, or truncated to be so!) this function returns the RGB encoded in the lower 24 bits of a single number.

See fsl_gradient_color() for an explanation and example.

For those asking themselves, "why does an SCM API have a function for encoding RGB colors?" the answer is: fossil(1) has a long history of using HTML color codes to set the color of branches, and this is provided in support of such features.

See also
fsl_rgb_decode()
fsl_gradient_color()
FSL_EXPORT fsl_size_t fsl_simplify_sql ( char *  sql,
fsl_int_t  len 
)

"Simplifies" an SQL string by making the following modifications inline:

  • Consecutive non-newline spaces outside of an SQL string are collapsed into one space.
  • Consecutive newlines outside of an SQL string are collapsed into one space.

Contents of SQL strings are not transformed in any way.

len must be the length of the sql string. If it is negative, fsl_strlen(sql) is used to calculate the length.

Returns the number of bytes in the modified string (its strlen) and NUL-terminates it at the new length. Thus the input string must be at least one byte longer than its virtual length (its NUL terminator byte suffices, provided it is NUL-terminated, as we can safely overwrite that byte).

If !sql or its length resolves to 0, this function returns 0 without side effects.

FSL_EXPORT fsl_size_t fsl_simplify_sql_buffer ( fsl_buffer b)

Convenience form of fsl_simplify_sql() which assumes b holds an SQL string.

It gets processed by fsl_simplify_sql() and its 'used' length potentially gets adjusted to match the adjusted SQL string.

FSL_EXPORT fsl_int_t fsl_snprintf ( char *  dest,
fsl_size_t  n,
char const *  fmt,
  ... 
)

An sprintf(3) clone which uses fsl_appendf() for the formatting.

Outputs at most n bytes to dest and returns the number of bytes output. Returns a negative value if !dest or !fmt. Returns 0 without side-effects if !n or !*fmt.

If the destination buffer is long enough (this function returns a non-negative value less than n), this function NUL-terminates it. If it returns n then there was no space for the terminator.

FSL_EXPORT fsl_int_t fsl_snprintfv ( char *  dest,
fsl_size_t  n,
char const *  fmt,
va_list  args 
)

va_list counterpart to fsl_snprintf()

FSL_EXPORT int fsl_stat ( const char *  zFilename,
fsl_fstat fst,
char  derefSymlinks 
)

Runs the OS's stat(2) equivalent to populate fst with information about the given file.

Returns 0 on success, FSL_RC_MISUSE if zFilename is NULL, and FSL_RC_RANGE if zFilename starts with a NUL byte. Returns FSL_RC_NOT_FOUND if no filesystem entry is found for the given name. Returns FSL_RC_IO if the underlying stat() (or equivalent) fails for undetermined reasons inside the underlying stat()/_wstati64() call. Note that the fst parameter may be NULL, in which case the return value will be 0 if the name is stat-able, but will return no other information about it.

The derefSymlinks argument is ignored on non-Unix platforms. On Unix platforms, if derefSymlinks is non-0 then stat(2) is used, else lstat(2) (if available on the platform) is used. For most cases clients should pass non-0. They should only pass 0 if they need to differentiate between symlinks and files.

The fsl_fstat_type_t family of flags can be used to determine the type of the filesystem object being stat()'d (file, directory, or symlink). It does apply any special logic for platform-specific oddities other than symlinks (e.g. character devices and such).

FSL_EXPORT char fsl_str_bool ( char const *  s)

Returns false if s is NULL or starts with any of (0 (NUL), '0' (ASCII character zero), 'f', 'n', "off"), case-insensitively, else it returns true.

FSL_EXPORT char fsl_str_glob ( const char *  zGlob,
const char *  z 
)

Return true (non-zero) if string z matches glob pattern zGlob and zero if the pattern does not match.

Always returns 0 if either argument is NULL. Supports all globbing rules supported by sqlite3_strglob().

FSL_EXPORT char fsl_str_is_date ( const char *  z)

Returns non-0 (true) if the first 10 digits of z _appear_ to form the start of an ISO date string (YYYY-MM-DD).

Whether or not the string is really a valid date is left for downstream code to determine. Returns 0 (false) in all other cases, including if z is NULL.

FSL_EXPORT int fsl_str_is_date2 ( const char *  z)

Checks if z is syntactically a time-format string in the format:

[Y]YYYY-MM-DD

(Yes, the year may be five-digits, left-padded with a zero for years less than 9999.)

Returns a positive value if the YYYYY part has five digits, a negative value if it has four. It returns 0 (false) if z does not match that pattern.

If it returns a negative value, the MM part of z starts at byte offset (z+5), and a positive value means the MM part starts at (z+6).

z need not be NUL terminated - this function does not read past the first invalid byte. Thus is can be used on, e.g., full ISO8601-format strings. If z is NULL, 0 is returned.

FSL_EXPORT fsl_int_t fsl_str_to_int ( char const *  str,
fsl_int_t  dflt 
)

Expects str to be a string containing a decimal value, optionally with a leading sign.

Returns its decoded value, or dflt if !str or on error.

FSL_EXPORT fsl_size_t fsl_str_to_size ( char const *  str)

Expects str to be a string containing an unsigned decimal value.

Returns its decoded value, or -1 on error.

FSL_EXPORT int fsl_strcmp ( char const *  lhs,
char const *  rhs 
)

Like strcmp(3) except that it accepts NULL pointers.

NULL sorts before all non-NULL string pointers. Also, this routine performs a binary comparison that does not consider locale.

FSL_EXPORT int fsl_strcmp_cmp ( void const *  lhs,
void const *  rhs 
)

Equivalent to fsl_strcmp(), but with a signature suitable for use as a generic comparison function (e.g.

for use with qsort() and search algorithms).

FSL_EXPORT char* fsl_strdup ( char const *  src)

Equivalent to fsl_strndup(src,-1).

FSL_EXPORT int fsl_stream ( fsl_input_f  inF,
void *  inState,
fsl_output_f  outF,
void *  outState 
)

A generic streaming routine which copies data from an fsl_input_f() to an fsl_outpuf_f().

Reads all data from inF() in chunks of an unspecified size and passes them on to outF(). It reads until inF() returns fewer bytes than requested. Returns the result of the last call to outF() or (only if reading fails) inF(). Returns FSL_RC_MISUSE if inF or ouF are NULL.

Here is an example which basically does the same thing as the cat(1) command on Unix systems:

1 fsl_stream( fsl_input_f_FILE, stdin, fsl_output_f_FILE, stdout );

Or copy a FILE to a buffer:

1 fsl_buffer myBuf = fsl_buffer_empty;
2 rc = fsl_stream( fsl_input_f_FILE, stdin, fsl_output_f_buffer, &myBuf );
3 // Note that on error myBuf might be partially populated.
4 // Eventually clean up the buffer:
5 fsl_buffer_clear(&myBuf);
FSL_EXPORT int fsl_stream_compare ( fsl_input_f  in1,
void *  in1State,
fsl_input_f  in2,
void *  in2State 
)

Consumes two input streams looking for differences.

It stops reading as soon as either or both streams run out of input or a byte-level difference is found. It consumes input in chunks of an unspecified size, and after this returns the input cursor of the streams is not well-defined. i.e. the cursor probably does not point to the exact position of the difference because this level of abstraction does not allow that unless we read byte by byte.

Returns 0 if both streams emit the same amount of output and that ouput is bitwise identical, otherwise it returns non-0.

FSL_EXPORT fsl_size_t fsl_strftime ( char *  dest,
fsl_size_t  destLen,
const char *  format,
const struct tm *  timeptr 
)

A strftime() implementation.

dest must be valid memory at least destLen bytes long. The result will be written there.

fmt must contain the format string. See the file fsl_strftime.c for the complete list of format specifiers and their descriptions.

timeptr must be the time the caller wants to format.

Returns 0 if any arguments are NULL.

On success it returns the number of bytes written to dest, not counting the terminating NUL byte (which it also writes). It returns 0 on any error, and the client may need to distinguish between real errors and (destLen==0 or !*fmt), both of which could also look like errors.

TODOs:

  • Refactor this to take a callback or a fsl_buffer, so that we can format arbitrarily long output.
  • Refactor it to return an integer error code.

(This implementation is derived from public domain sources dating back to the early 1990's.)

FSL_EXPORT fsl_size_t fsl_strftime_unix ( char *  dest,
fsl_size_t  destLen,
char const *  format,
fsl_time_t  epochTime,
char  convertToLocal 
)

A convenience form of fsl_strftime() which takes its timestamp in the form of a Unix Epoch time.

See fsl_strftime() for the semantics of the first 3 arguments and the return value. If convertToLocal is true then epochTime gets converted to local time (via, oddly enough, localtime(3)), otherwise gmtime(3) is used for the conversion.

BUG: this function uses static state and is not thread-safe.

FSL_EXPORT int fsl_stricmp ( const char *  zA,
const char *  zB 
)

Case-insensitive form of fsl_strcmp().

()

FSL_EXPORT int fsl_stricmp_cmp ( void const *  lhs,
void const *  rhs 
)

Equivalent to fsl_stricmp(), but with a signature suitable for use as a generic comparison function (e.g.

for use with qsort() and search algorithms).

()

FSL_EXPORT fsl_size_t fsl_strlen ( char const *  src)

Equivalent to strlen(3) but returns 0 if src is NULL.

Note that it counts bytes, not UTF characters.

FSL_EXPORT int fsl_strncmp ( const char *  zA,
const char *  zB,
fsl_size_t  nByte 
)

fsl_strcmp() variant which compares at most nByte bytes of the given strings, case-sensitively.

Returns 0 if nByte is 0.

FSL_EXPORT char* fsl_strndup ( char const *  src,
fsl_int_t  len 
)

Similar to strndup(3) but returns NULL if !src.

The returned memory must eventually be passed to fsl_free(). Returns NULL on allocation error. If len is less than 0 and src is not NULL then fsl_strlen() is used to calculate its length.

If src is not NULL but len is 0 then it will return an empty (length-0) string, as opposed to NULL.

FSL_EXPORT int fsl_strnicmp ( const char *  zA,
const char *  zB,
fsl_int_t  nByte 
)

fsl_strcmp() variant which compares at most nByte bytes of the given strings, case-insensitively.

If nByte is less than 0 then fsl_strlen(zB) is used to obtain the length for comparision purposes.

FSL_EXPORT fsl_uint64_t fsl_timer_fetch ( fsl_timer_state const *  t)

Returns the difference in _CPU_ times in microseconds since t was last passed to fsl_timer_start() or fsl_timer_reset().

It might return 0 due to system-level precision restrictions. Note that this is not useful for measuring wall times.

FSL_EXPORT fsl_uint64_t fsl_timer_reset ( fsl_timer_state t)

Resets t to the current time and returns the number of microseconds since t was started or last reset.

See also
fsl_timer_start()
fsl_timer_reset()
FSL_EXPORT void fsl_timer_start ( fsl_timer_state t)

Sets t's counter state to the current CPU timer usage, as determined by the OS.

Achtung: timer support is only enabled if the library is built with the FSL_CONFIG_ENABLE_TIMER macro set to a true value (it is on by default).

See also
fsl_timer_reset()
fsl_timer_stop()
FSL_EXPORT fsl_uint64_t fsl_timer_stop ( fsl_timer_state t)

Clears t's state and returns the difference (in uSec) between the last time t was started or reset, as per fsl_timer_fetch().

See also
fsl_timer_start()
fsl_timer_reset()
FSL_EXPORT int fsl_tolower ( int  c)

Returns the upper-case form of c if c is an ASCII alphabet letter, else returns c.

FSL_EXPORT int fsl_toupper ( int  c)

Returns the lower-case form of c if c is an ASCII alphabet letter, else returns c.

FSL_EXPORT void fsl_unicode_free ( void *  )

Deallocates the given memory, which must have been allocated from fsl_unicode_to_utf8(), fsl_utf8_to_unicode(), or any function which explicitly documents this function as being the proper finalizer for its returned memory.

FSL_EXPORT char* fsl_unicode_to_utf8 ( const void *  zUnicode)

Translates Unicode text into UTF-8.

Return a pointer to the translated text. Call fsl_unicode_free() to deallocate any memory used to store the returned pointer when done.

This function exists only for Windows. On other platforms it behaves like fsl_strdup().

FSL_EXPORT fsl_double_t fsl_unix_to_julian ( fsl_time_t  unixEpoch)

Returns the given Unix Epoch timestamp value as its approximate Julian Day value.

Note that the calculation does not account for leap seconds.

FSL_EXPORT void* fsl_utf8_to_filename ( const char *  zUtf8)

Translate text from UTF-8 to the OS's filename character set.

Return a pointer to the translated text. Call fsl_filename_free() to deallocate any memory used to store the returned pointer when done.

On Windows, characters in the range U+0001 to U+0031 and the characters '"', '*', ':', '<', '>', '?' and '|' are invalid in filenames. Therefore, translate those to characters in the in the range U+F001 - U+F07F (private use area), so those characters never arrive in any Windows API. The filenames might look strange in Windows explorer, but in the cygwin shell everything looks as expected.

See: http://cygwin.com/cygwin-ug-net/using-specialnames.html

The returned type is (wchar_t*) on Windows and (char*) everywhere else.

FSL_EXPORT void* fsl_utf8_to_unicode ( const char *  zUtf8)

Translate UTF-8 to Unicode for use in system calls.

Returns a pointer to the translated text. The returned value must eventually be passed to fsl_unicode_free() to deallocate any memory used to store the returned pointer when done.

This function exists only for Windows. On other platforms it behaves like fsl_strdup().

The returned type is (wchar_t*) on Windows and (char*) everywhere else.

FSL_EXPORT int fsl_uuidcmp ( fsl_uuid_cstr  lhs,
fsl_uuid_cstr  rhs 
)

Equivalent to fsl_strncmp(lhs, rhs, FSL_UUID_STRLEN).

FSL_EXPORT char fsl_validate16 ( const char *  zIn,
fsl_size_t  nIn 
)

Return true (non-0) if the input string contains only valid base-16 digits.

If any invalid characters appear in the string, return 0 (false).

FSL_EXPORT fsl_buffer const* fsl_zip_body ( fsl_zip_writer const *  z)

Returns a pointer to z's ZIP content buffer.

The contents are ONLY valid after fsl_zip_end() returns 0.

See also
fsl_zip_timestamp_set_julian()
fsl_zip_timestamp_set_unix()
fsl_zip_file_add()
fsl_zip_end()
fsl_zip_end_take()
fsl_zip_finalize()
FSL_EXPORT int fsl_zip_end ( fsl_zip_writer z)

Ends the ZIP-creation process, padding all buffers, writing all final required values, and freeing up most of the memory owned by z.

After calling this, z->body contains the full generated ZIP file.

Returns 0 on success. On error z's contents may still be partially intact (for debugging purposes) and z->body will not hold complete/valid ZIP file contents. Results are undefined if !z or z has not been properly initialized.

The caller must eventually pass z to fsl_zip_finalize() to free up any remaining resources.

See also
fsl_zip_timestamp_set_julian()
fsl_zip_timestamp_set_unix()
fsl_zip_file_add()
fsl_zip_body()
fsl_zip_finalize()
fsl_zip_end_take()
FSL_EXPORT int fsl_zip_end_take ( fsl_zip_writer z,
fsl_buffer dest 
)

This variant of fsl_zip_end() transfers the current contents of the zip's body to dest, replacing (freeing) any contents it may hold when this is called, then passes z to fsl_zip_finalize() to free any other resources (which are invalidated by the removal of the body).

Returns 0 on success, FSL_RC_MISUSE if either pointer is NULL, some non-0 code if the proxied fsl_zip_end() call fails. On error, the transfer of contents to dest does NOT take place, but z is finalized (if it is not NULL) regardless of success or failure (even if dest is NULL). i.e. on error z is still cleaned up.

FSL_EXPORT int fsl_zip_end_to_filename ( fsl_zip_writer z,
char const *  filename 
)

This variant of fsl_zip_end_take() passes z to fsl_zip_end(), write's the ZIP body to the given filename, passes z to fsl_zip_finalize(), and returns the result of either end/save combination.

Saving is not attempted if ending the ZIP fails.

On success 0 is returned and the contents of the ZIP are in the given file. On error z is STILL cleaned up, and the file might have been partially populated (only on I/O error after writing started). In either case, z is cleaned up and ready for re-use or (in the case of a heap-allocated instance) freed.

FSL_EXPORT int fsl_zip_file_add ( fsl_zip_writer z,
char const *  zFilename,
fsl_buffer const *  pContent,
int  permsFlag 
)

Adds a file or directory to the ZIP writer z.

zFilename is the virtual name of the file or directory. If pContent is NULL then it is assumed that we are creating one or more directories, otherwise the ZIP's entry is populated from pContent. The permsFlag argument specifies the fossil-specific permission flags from the fsl_file_perm_t enum, but currently ignores the permsFlag argument for directories. Not that this function creates directory entries for any files automatically, so there is rarely a need for client code to create them (unless they specifically want to ZIP an empty directory entry).

Notes of potential interest:

  • The ZIP is created in memory, and thus creating ZIPs with this API is exceedingly memory-hungry.
  • The timestamp of any given file must be set separately from this call using fsl_zip_timestamp_set_unix() or fsl_zip_timestamp_set_julian(). That value is then used for subsequent file-adds until a new time is set.
  • If a root directory has been set using fsl_zip_root_set() then that name, plus '/' (if the root does not end with one) gets prepended to all files added via this routine.

An example of the ZIP-generation process:

1 int rc;
2 fsl_zip_writer z = fsl_zip_writer_empty;
3 fsl_buffer buf = fsl_buffer_empty;
4 fsl_buffer const * zipBody;
5 
6 // ...fill the buf buffer (not shown here)...
7 
8 // Optionally set a virtual root dir for new files:
9 rc = fsl_zip_root_set( &z, "myRootDir" ); // trailing slash is optional
10 if(rc) { ... error ...; goto end; }
11 
12 // We must set a timestamp which will be used until we set another:
13 fsl_zip_timestamp_set_unix( &z, time(NULL) );
14 
15 // Add a file:
16 rc = fsl_zip_file_add( &z, "foo/bar.txt", &buf, FSL_FILE_PERM_REGULAR );
17 // Clean up our content:
18 fsl_buffer_reset(&buf); // only needed if we want to re-use the buffer's memory
19 if(rc) goto end;
20 
21 // ... add more files the same way (not shown) ...
22 
23 // Now "seal" the ZIP file:
24 rc = fsl_zip_end( &z );
25 if(rc) goto end;
26 
27 // Fetch the ZIP content:
28 zipBody = fsl_zip_body( &z );
29 // zipBody now points to zipBody->used bytes of ZIP file content
30 // which can be sent to an arbitrary destination, e.g.:
31 rc = fsl_buffer_to_filename( zipBody, "my.zip" );
32 
33 end:
34 fsl_buffer_clear(&buf);
35 // VERY important, once we're done with z:
36 fsl_zip_finalize( &z );
37 if(rc){...we had an error...}
See also
fsl_zip_timestamp_set_julian()
fsl_zip_timestamp_set_unix()
fsl_zip_end()
fsl_zip_body()
fsl_zip_finalize()
FSL_EXPORT void fsl_zip_finalize ( fsl_zip_writer z)

Frees all memory owned by z and resets it to a clean state, but does not free z.

Any fsl_zip_writer instance which has been modified via the fsl_zip_xxx() family of functions MUST eventually be passed to this function to clean up any contents it might have accumulated during its life. After this returns, z is legal for re-use in creating a new ZIP archive.

See also
fsl_zip_timestamp_set_julian()
fsl_zip_timestamp_set_unix()
fsl_zip_file_add()
fsl_zip_end()
fsl_zip_body()
FSL_EXPORT int fsl_zip_root_set ( fsl_zip_writer z,
char const *  zRoot 
)

Sets a virtual root directory in z, such that all files added with fsl_zip_file_add() will get this directory prefixed to it.

If zRoot is NULL or empty then this clears the virtual root, otherwise is injects any directory levels it needs to into the being-generated ZIP. Note that zRoot may contain multiple levels of directories, e.g. "foo/bar/baz", but it must be legal for use in a ZIP file.

This routine copies zRoot's bytes, so they may be transient.

Returns 0 on success, FSL_RC_ERROR if !z, FSL_RC_OOM on allocation error. Returns FSL_RC_RANGE if zRoot is an absolute path or if zRoot cannot be normalized to a "simplified name" (as per fsl_is_simple_pathname(), with the note that this routine will pass a copy of zRoot through fsl_file_simplify_name() first).

See also
fsl_zip_finalize()
FSL_EXPORT void fsl_zip_timestamp_set_julian ( fsl_zip_writer z,
fsl_double_t  rDate 
)

Set z's date and time from a Julian Day number.

Results are undefined if !z. Results will be invalid if rDate is negative. The timestamp is applied to all fsl_zip_file_add() operations until it is re-set.

See also
fsl_zip_timestamp_set_unix()
fsl_zip_file_add()
fsl_zip_end()
fsl_zip_body()
FSL_EXPORT void fsl_zip_timestamp_set_unix ( fsl_zip_writer z,
fsl_time_t  epochTime 
)

Set z's date and time from a Unix Epoch time.

Results are undefined if !z. Results will be invalid if rDate is negative. The timestamp is applied to all fsl_zip_file_add() operations until it is re-set.

Variable Documentation

FSL_EXPORT const fsl_buffer fsl_buffer_empty

Empty-initialized fsl_buffer instance, intended for copy initialization.

Definition at line 680 of file fossil-util.h.

FSL_EXPORT const fsl_confirmer fsl_confirmer_empty

Initialized-with-defaults fsl_confirmer struct.

Definition at line 3499 of file fossil-util.h.

FSL_EXPORT const fsl_error fsl_error_empty

Empty-initialized fsl_error instance, intended for copy initialization.

Definition at line 708 of file fossil-util.h.

FSL_EXPORT const fsl_fstat fsl_fstat_empty

Empty-initialized fsl_fstat instance, intended for copy construction.

Definition at line 2604 of file fossil-util.h.

FSL_EXPORT const fsl_id_bag fsl_id_bag_empty

Initialized-with-defaults fsl_id_bag structure, intended for copy initialization.

Definition at line 4013 of file fossil-util.h.

FSL_EXPORT const fsl_list fsl_list_empty

Empty-initialized fsl_list structure, intended for copy initialization.

Definition at line 177 of file fossil-util.h.

FSL_EXPORT const fsl_outputer fsl_outputer_empty

Empty-initialized fsl_outputer instance, intended for copy-initializing.

Definition at line 346 of file fossil-util.h.

FSL_EXPORT const fsl_outputer fsl_outputer_FILE

A fsl_outputer instance which is initialized to output to a (FILE*).

To use it, this value then set the copy's state.state member to an opened-for-write (FILE*) handle. By default it will use stdout. Its finalizer (if called!) will fclose(3) self.state.state if self.state.state is not one of (stdout, stderr). To disable the closing behaviour (and not close the file), set self.state.finalize.f to NULL (but then be sure that the file handle outlives this object and to fclose(3) it when finished with it).

Definition at line 359 of file fossil-util.h.

FSL_EXPORT const fsl_pathfinder fsl_pathfinder_empty

Initialized-with-defaults fsl_pathfinder instance, intended for copy initialization.

Definition at line 3294 of file fossil-util.h.

FSL_EXPORT const fsl_state fsl_state_empty

Empty-initialized fsl_state struct, intended for copy-initializing.

Definition at line 257 of file fossil-util.h.

FSL_EXPORT const fsl_timer_state fsl_timer_state_empty

Initialized-with-defaults fsl_timer_state_empty instance, intended for copy initialization.

Definition at line 3830 of file fossil-util.h.

FSL_EXPORT const fsl_zip_writer fsl_zip_writer_empty

An initialized-with-defaults fsl_zip_writer instance, intended for copy-initialization.

Definition at line 3593 of file fossil-util.h.