+ *
+ * EXAMPLE
+ *
+ * [category1]
+ * var1 => val1
+ * var2 => val2
+ * \# lines that begin with \# are comments
+ * \#var3 => val3
+ *
+ * @{
+ */
+
+#ifndef KS_CONFIG_H
+#define KS_CONFIG_H
+
+#include "ks.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+
+#define KS_URL_SEPARATOR "://"
+
+
+#ifdef WIN32
+#define KS_PATH_SEPARATOR "\\"
+#ifndef KS_CONFIG_DIR
+#define KS_CONFIG_DIR "c:\\openks"
+#endif
+#define ks_is_file_path(file) (*(file +1) == ':' || *file == '/' || strstr(file, SWITCH_URL_SEPARATOR))
+#else
+#define KS_PATH_SEPARATOR "/"
+#ifndef KS_CONFIG_DIR
+#define KS_CONFIG_DIR "/etc/openks"
+#endif
+#define ks_is_file_path(file) ((*file == '/') || strstr(file, SWITCH_URL_SEPARATOR))
+#endif
+
+/*!
+ \brief Evaluate the truthfullness of a string expression
+ \param expr a string expression
+ \return true or false
+*/
+#define ks_true(expr)\
+(expr && ( !strcasecmp(expr, "yes") ||\
+!strcasecmp(expr, "on") ||\
+!strcasecmp(expr, "true") ||\
+!strcasecmp(expr, "enabled") ||\
+!strcasecmp(expr, "active") ||\
+!strcasecmp(expr, "allow") ||\
+atoi(expr))) ? 1 : 0
+
+/*!
+ \brief Evaluate the falsefullness of a string expression
+ \param expr a string expression
+ \return true or false
+*/
+#define ks_false(expr)\
+(expr && ( !strcasecmp(expr, "no") ||\
+!strcasecmp(expr, "off") ||\
+!strcasecmp(expr, "false") ||\
+!strcasecmp(expr, "disabled") ||\
+!strcasecmp(expr, "inactive") ||\
+!strcasecmp(expr, "disallow") ||\
+!atoi(expr))) ? 1 : 0
+
+typedef struct ks_config ks_config_t;
+
+/*! \brief A simple file handle representing an open configuration file **/
+struct ks_config {
+ /*! FILE stream buffer to the opened file */
+ FILE *file;
+ /*! path to the file */
+ char path[512];
+ /*! current category */
+ char category[256];
+ /*! current section */
+ char section[256];
+ /*! buffer of current line being read */
+ char buf[1024];
+ /*! current line number in file */
+ int lineno;
+ /*! current category number in file */
+ int catno;
+ /*! current section number in file */
+ int sectno;
+
+ int lockto;
+};
+
+/*!
+ \brief Open a configuration file
+ \param cfg (ks_config_t *) config handle to use
+ \param file_path path to the file
+ \return 1 (true) on success 0 (false) on failure
+*/
+KS_DECLARE(int) ks_config_open_file(ks_config_t * cfg, const char *file_path);
+
+/*!
+ \brief Close a previously opened configuration file
+ \param cfg (ks_config_t *) config handle to use
+*/
+KS_DECLARE(void) ks_config_close_file(ks_config_t * cfg);
+
+/*!
+ \brief Retrieve next name/value pair from configuration file
+ \param cfg (ks_config_t *) config handle to use
+ \param var pointer to aim at the new variable name
+ \param val pointer to aim at the new value
+*/
+KS_DECLARE(int) ks_config_next_pair(ks_config_t * cfg, char **var, char **val);
+
+/*!
+ \brief Retrieve the CAS bits from a configuration string value
+ \param strvalue pointer to the configuration string value (expected to be in format whatever:xxxx)
+ \param outbits pointer to aim at the CAS bits
+*/
+KS_DECLARE(int) ks_config_get_cas_bits(char *strvalue, unsigned char *outbits);
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif /* defined(KS_CONFIG_H) */
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/libs/libks/src/include/ks_json.h b/libs/libks/src/include/ks_json.h
new file mode 100755
index 0000000000..1ad116e980
--- /dev/null
+++ b/libs/libks/src/include/ks_json.h
@@ -0,0 +1,127 @@
+/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+#include "ks.h"
+#ifndef cJSON__h
+#define cJSON__h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* cJSON Types: */
+#define cJSON_False 0
+#define cJSON_True 1
+#define cJSON_NULL 2
+#define cJSON_Number 3
+#define cJSON_String 4
+#define cJSON_Array 5
+#define cJSON_Object 6
+
+#define cJSON_IsReference 256
+
+/* The cJSON structure: */
+typedef struct cJSON {
+ struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
+ struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
+
+ int type; /* The type of the item, as above. */
+
+ char *valuestring; /* The item's string, if type==cJSON_String */
+ int valueint; /* The item's number, if type==cJSON_Number */
+ double valuedouble; /* The item's number, if type==cJSON_Number */
+
+ char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
+} cJSON;
+
+typedef struct cJSON_Hooks {
+ void *(*malloc_fn)(size_t sz);
+ void (*free_fn)(void *ptr);
+} cJSON_Hooks;
+
+/* Supply malloc, realloc and free functions to cJSON */
+KS_DECLARE(void) cJSON_InitHooks(cJSON_Hooks* hooks);
+
+
+/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
+KS_DECLARE(cJSON *)cJSON_Parse(const char *value);
+/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
+KS_DECLARE(char *)cJSON_Print(cJSON *item);
+/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
+KS_DECLARE(char *)cJSON_PrintUnformatted(cJSON *item);
+/* Delete a cJSON entity and all subentities. */
+KS_DECLARE(void) cJSON_Delete(cJSON *c);
+
+/* Returns the number of items in an array (or object). */
+KS_DECLARE(int) cJSON_GetArraySize(cJSON *array);
+/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
+KS_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item);
+/* Get item "string" from object. Case insensitive. */
+KS_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string);
+
+/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
+KS_DECLARE(const char *)cJSON_GetErrorPtr();
+
+/* These calls create a cJSON item of the appropriate type. */
+KS_DECLARE(cJSON *)cJSON_CreateNull();
+KS_DECLARE(cJSON *)cJSON_CreateTrue();
+KS_DECLARE(cJSON *)cJSON_CreateFalse();
+KS_DECLARE(cJSON *)cJSON_CreateBool(int b);
+KS_DECLARE(cJSON *)cJSON_CreateNumber(double num);
+KS_DECLARE(cJSON *)cJSON_CreateString(const char *string);
+KS_DECLARE(cJSON *)cJSON_CreateArray();
+KS_DECLARE(cJSON *)cJSON_CreateObject();
+
+/* These utilities create an Array of count items. */
+KS_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count);
+KS_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count);
+KS_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count);
+KS_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count);
+
+/* Append item to the specified array/object. */
+KS_DECLARE(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
+KS_DECLARE(void) cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
+/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
+KS_DECLARE(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
+KS_DECLARE(void) cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
+
+/* Remove/Detatch items from Arrays/Objects. */
+KS_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which);
+KS_DECLARE(void) cJSON_DeleteItemFromArray(cJSON *array,int which);
+KS_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string);
+KS_DECLARE(void) cJSON_DeleteItemFromObject(cJSON *object,const char *string);
+
+/* Update array items. */
+KS_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
+KS_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
+
+#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
+#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
+#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
+#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
+#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libks/src/include/ks_threadmutex.h b/libs/libks/src/include/ks_threadmutex.h
new file mode 100644
index 0000000000..2b12acaccd
--- /dev/null
+++ b/libs/libks/src/include/ks_threadmutex.h
@@ -0,0 +1,58 @@
+/*
+ * Cross Platform Thread/Mutex abstraction
+ * Copyright(C) 2007 Michael Jerris
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so.
+ *
+ * This work is provided under this license on an "as is" basis, without warranty of any kind,
+ * either expressed or implied, including, without limitation, warranties that the covered code
+ * is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire
+ * risk as to the quality and performance of the covered code is with you. Should any covered
+ * code prove defective in any respect, you (not the initial developer or any other contributor)
+ * assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty
+ * constitutes an essential part of this license. No use of any covered code is authorized hereunder
+ * except under this disclaimer.
+ *
+ */
+
+
+#ifndef _KS_THREADMUTEX_H
+#define _KS_THREADMUTEX_H
+
+#include "ks.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+typedef struct ks_mutex ks_mutex_t;
+typedef struct ks_thread ks_thread_t;
+typedef void *(*ks_thread_function_t) (ks_thread_t *, void *);
+
+KS_DECLARE(ks_status_t) ks_thread_create_detached(ks_thread_function_t func, void *data);
+ks_status_t ks_thread_create_detached_ex(ks_thread_function_t func, void *data, size_t stack_size);
+void ks_thread_override_default_stacksize(size_t size);
+KS_DECLARE(ks_status_t) ks_mutex_create(ks_mutex_t **mutex);
+KS_DECLARE(ks_status_t) ks_mutex_destroy(ks_mutex_t **mutex);
+KS_DECLARE(ks_status_t) ks_mutex_lock(ks_mutex_t *mutex);
+KS_DECLARE(ks_status_t) ks_mutex_trylock(ks_mutex_t *mutex);
+KS_DECLARE(ks_status_t) ks_mutex_unlock(ks_mutex_t *mutex);
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif /* defined(_KS_THREADMUTEX_H) */
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/libs/libks/src/include/mpool.h b/libs/libks/src/include/mpool.h
new file mode 100644
index 0000000000..23ac93fb91
--- /dev/null
+++ b/libs/libks/src/include/mpool.h
@@ -0,0 +1,463 @@
+/*
+ * Memory pool defines.
+ *
+ * Copyright 1996 by Gray Watson.
+ *
+ * This file is part of the mpool package.
+ *
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies, and that the name of Gray Watson not be used in advertising
+ * or publicity pertaining to distribution of the document or software
+ * without specific, written prior permission.
+ *
+ * Gray Watson makes no representations about the suitability of the
+ * software described herein for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * The author may be reached via http://256.com/gray/
+ *
+ * $Id: mpool.h,v 1.4 2006/05/31 20:26:11 gray Exp $
+ */
+
+#ifndef __MPOOL_H__
+#define __MPOOL_H__
+
+#include
+
+/*
+ * mpool flags to mpool_alloc or mpool_set_attr
+ */
+
+/*
+ * Choose a best fit algorithm not first fit. This takes more CPU
+ * time but will result in a tighter heap.
+ */
+#define MPOOL_FLAG_BEST_FIT (1<<0)
+
+/*
+ * By default the library adds 2 bytes onto all allocations to insert
+ * a magic number that it can look for to determine how large a freed
+ * memory chunk is. This flag indicates that few if any frees are
+ * going to be performed on the pool and to not waste memory on these
+ * bytes.
+ */
+#define MPOOL_FLAG_NO_FREE (1<<1)
+
+/*
+ * This enables very heavy packing at the possible expense of CPU.
+ * This affects a number of parts of the library.
+ *
+ * By default the 1st page of memory is reserved for the main mpool
+ * structure. This flag will cause the rest of the 1st block to be
+ * available for use as user memory.
+ *
+ * By default the library looks through the memory when freed looking
+ * for a magic value. There is an internal max size that it will look
+ * and then it will give up. This flag forces it to look until it
+ * finds it.
+ */
+#define MPOOL_FLAG_HEAVY_PACKING (1<<2)
+
+/*
+ * Use sbrk not mmap to allocate pages. This is not recommended for
+ * normal use.
+ */
+#define MPOOL_FLAG_USE_SBRK (1<<3)
+
+/*
+ * Mpool error codes
+ */
+#define MPOOL_ERROR_NONE 1 /* no error */
+#define MPOOL_ERROR_ARG_NULL 2 /* function argument is null */
+#define MPOOL_ERROR_ARG_INVALID 3 /* function argument is invalid */
+#define MPOOL_ERROR_PNT 4 /* invalid mpool pointer */
+#define MPOOL_ERROR_POOL_OVER 5 /* mpool structure was overwritten */
+#define MPOOL_ERROR_PAGE_SIZE 6 /* could not get system page-size */
+#define MPOOL_ERROR_OPEN_ZERO 7 /* could not open /dev/zero */
+#define MPOOL_ERROR_NO_MEM 8 /* no memory available */
+#define MPOOL_ERROR_MMAP 9 /* problems with mmap */
+#define MPOOL_ERROR_SIZE 10 /* error processing requested size */
+#define MPOOL_ERROR_TOO_BIG 11 /* allocation exceeded max size */
+#define MPOOL_ERROR_MEM 12 /* invalid memory address */
+#define MPOOL_ERROR_MEM_OVER 13 /* memory lower bounds overwritten */
+#define MPOOL_ERROR_NOT_FOUND 14 /* memory block not found in pool */
+#define MPOOL_ERROR_IS_FREE 15 /* memory block already free */
+#define MPOOL_ERROR_BLOCK_STAT 16 /* invalid internal block status */
+#define MPOOL_ERROR_FREE_ADDR 17 /* invalid internal free address */
+#define MPOOL_ERROR_SBRK_CONTIG 18 /* sbrk did not return contiguous mem*/
+#define MPOOL_ERROR_NO_PAGES 19 /* ran out of pages in pool */
+#define MPOOL_ERROR_ALLOC 20 /* calloc,malloc,free,realloc failed */
+#define MPOOL_ERROR_PNT_OVER 21 /* pointer structure was overwritten */
+
+/*
+ * Mpool function IDs for the mpool_log_func callback function.
+ */
+#define MPOOL_FUNC_CLOSE 1 /* mpool_close function called */
+#define MPOOL_FUNC_CLEAR 2 /* mpool_clear function called */
+#define MPOOL_FUNC_ALLOC 3 /* mpool_alloc function called */
+#define MPOOL_FUNC_CALLOC 4 /* mpool_calloc function called */
+#define MPOOL_FUNC_FREE 5 /* mpool_free function called */
+#define MPOOL_FUNC_RESIZE 6 /* mpool_resize function called */
+
+/*
+ * void mpool_log_func_t
+ *
+ * DESCRIPTION:
+ *
+ * Mpool transaction log function.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENT:
+ *
+ * mp_p -> Associated mpool address.
+ *
+ * func_id -> Integer function ID which identifies which mpool
+ * function is being called.
+ *
+ * byte_size -> Optionally specified byte size.
+ *
+ * ele_n -> Optionally specified element number. For mpool_calloc
+ * only.
+ *
+ * new_addr -> Optionally specified new address. For mpool_alloc,
+ * mpool_calloc, and mpool_resize only.
+ *
+ * old_addr -> Optionally specified old address. For mpool_resize and
+ * mpool_free only.
+ *
+ * old_byte_size -> Optionally specified old byte size. For
+ * mpool_resize only.
+ */
+typedef void (*mpool_log_func_t)(const void *mp_p,
+ const int func_id,
+ const unsigned long byte_size,
+ const unsigned long ele_n,
+ const void *old_addr, const void *new_addr,
+ const unsigned long old_byte_size);
+
+#ifdef MPOOL_MAIN
+
+#include "mpool_loc.h"
+
+#else
+
+/* generic mpool type */
+typedef void mpool_t;
+
+#endif
+
+/*<<<<<<<<<< The below prototypes are auto-generated by fillproto */
+
+/*
+ * mpool_t *mpool_open
+ *
+ * DESCRIPTION:
+ *
+ * Open/allocate a new memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - Pool pointer which must be passed to mpool_close to
+ * deallocate.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * flags -> Flags to set attributes of the memory pool. See the top
+ * of mpool.h.
+ *
+ * page_size -> Set the internal memory page-size. This must be a
+ * multiple of the getpagesize() value. Set to 0 for the default.
+ *
+ * start_addr -> Starting address to try and allocate memory pools.
+ * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+extern
+mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size,
+ void *start_addr, int *error_p);
+
+/*
+ * int mpool_close
+ *
+ * DESCRIPTION:
+ *
+ * Close/free a memory allocation pool previously opened with
+ * mpool_open.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to our memory pool.
+ */
+extern
+int mpool_close(mpool_t *mp_p);
+
+/*
+ * int mpool_clear
+ *
+ * DESCRIPTION:
+ *
+ * Wipe an opened memory pool clean so we can start again.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to our memory pool.
+ */
+extern
+int mpool_clear(mpool_t *mp_p);
+
+/*
+ * void *mpool_alloc
+ *
+ * DESCRIPTION:
+ *
+ * Allocate space for bytes inside of an already open memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - Pointer to the address to use.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool. If NULL then it will do a
+ * normal malloc.
+ *
+ * byte_size -> Number of bytes to allocate in the pool. Must be >0.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+extern
+void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size,
+ int *error_p);
+
+/*
+ * void *mpool_calloc
+ *
+ * DESCRIPTION:
+ *
+ * Allocate space for elements of bytes in the memory pool and zero
+ * the space afterwards.
+ *
+ * RETURNS:
+ *
+ * Success - Pointer to the address to use.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool. If NULL then it will do a
+ * normal calloc.
+ *
+ * ele_n -> Number of elements to allocate.
+ *
+ * ele_size -> Number of bytes per element being allocated.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+extern
+void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n,
+ const unsigned long ele_size, int *error_p);
+
+/*
+ * int mpool_free
+ *
+ * DESCRIPTION:
+ *
+ * Free an address from a memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool. If NULL then it will do a
+ * normal free.
+ *
+ * addr <-> Address to free.
+ *
+ * size -> Size of the address being freed.
+ */
+extern
+int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size);
+
+/*
+ * void *mpool_resize
+ *
+ * DESCRIPTION:
+ *
+ * Reallocate an address in a mmeory pool to a new size. This is
+ * different from realloc in that it needs the old address' size. If
+ * you don't have it then you need to allocate new space, copy the
+ * data, and free the old pointer yourself.
+ *
+ * RETURNS:
+ *
+ * Success - Pointer to the address to use.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool. If NULL then it will do a
+ * normal realloc.
+ *
+ * old_addr -> Previously allocated address.
+ *
+ * old_byte_size -> Size of the old address. Must be known, cannot be
+ * 0.
+ *
+ * new_byte_size -> New size of the allocation.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+extern
+void *mpool_resize(mpool_t *mp_p, void *old_addr,
+ const unsigned long old_byte_size,
+ const unsigned long new_byte_size,
+ int *error_p);
+
+/*
+ * int mpool_stats
+ *
+ * DESCRIPTION:
+ *
+ * Return stats from the memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p -> Pointer to the memory pool.
+ *
+ * page_size_p <- Pointer to an unsigned integer which, if not NULL,
+ * will be set to the page-size of the pool.
+ *
+ * num_alloced_p <- Pointer to an unsigned long which, if not NULL,
+ * will be set to the number of pointers currently allocated in pool.
+ *
+ * user_alloced_p <- Pointer to an unsigned long which, if not NULL,
+ * will be set to the number of user bytes allocated in this pool.
+ *
+ * max_alloced_p <- Pointer to an unsigned long which, if not NULL,
+ * will be set to the maximum number of user bytes that have been
+ * allocated in this pool.
+ *
+ * tot_alloced_p <- Pointer to an unsigned long which, if not NULL,
+ * will be set to the total amount of space (including administrative
+ * overhead) used by the pool.
+ */
+extern
+int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p,
+ unsigned long *num_alloced_p,
+ unsigned long *user_alloced_p,
+ unsigned long *max_alloced_p,
+ unsigned long *tot_alloced_p);
+
+/*
+ * int mpool_set_log_func
+ *
+ * DESCRIPTION:
+ *
+ * Set a logging callback function to be called whenever there was a
+ * memory transaction. See mpool_log_func_t.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool.
+ *
+ * log_func -> Log function (defined in mpool.h) which will be called
+ * with each mpool transaction.
+ */
+extern
+int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func);
+
+/*
+ * int mpool_set_max_pages
+ *
+ * DESCRIPTION:
+ *
+ * Set the maximum number of pages that the library will use. Once it
+ * hits the limit it will return MPOOL_ERROR_NO_PAGES.
+ *
+ * NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages
+ * value will include the page with the mpool header structure in it.
+ * If the flag is _not_ set then the max-pages will not include this
+ * first page.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool.
+ *
+ * max_pages -> Maximum number of pages used by the library.
+ */
+extern
+int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages);
+
+/*
+ * const char *mpool_strerror
+ *
+ * DESCRIPTION:
+ *
+ * Return the corresponding string for the error number.
+ *
+ * RETURNS:
+ *
+ * Success - String equivalient of the error.
+ *
+ * Failure - String "invalid error code"
+ *
+ * ARGUMENTS:
+ *
+ * error -> Error number that we are converting.
+ */
+extern
+const char *mpool_strerror(const int error);
+
+/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */
+
+#endif /* ! __MPOOL_H__ */
diff --git a/libs/libks/src/include/mpool_loc.h b/libs/libks/src/include/mpool_loc.h
new file mode 100644
index 0000000000..3d33f5d927
--- /dev/null
+++ b/libs/libks/src/include/mpool_loc.h
@@ -0,0 +1,116 @@
+/*
+ * Memory pool local defines.
+ *
+ * Copyright 1996 by Gray Watson.
+ *
+ * This file is part of the mpool package.
+ *
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies, and that the name of Gray Watson not be used in advertising
+ * or publicity pertaining to distribution of the document or software
+ * without specific, written prior permission.
+ *
+ * Gray Watson makes no representations about the suitability of the
+ * software described herein for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * The author may be reached via http://256.com/gray/
+ *
+ * $Id: mpool_loc.h,v 1.2 2005/05/20 20:08:54 gray Exp $
+ */
+
+#ifndef __MPOOL_LOC_H__
+#define __MPOOL_LOC_H__
+
+#define MPOOL_MAGIC 0xABACABA /* magic for struct */
+#define BLOCK_MAGIC 0xB1B1007 /* magic for blocks */
+#define FENCE_MAGIC0 (unsigned char)(0xFAU) /* 1st magic mem byte */
+#define FENCE_MAGIC1 (unsigned char)(0xD3U) /* 2nd magic mem byte */
+
+#define FENCE_SIZE 2 /* fence space */
+#define MIN_ALLOCATION (sizeof(mpool_free_t)) /* min alloc */
+#define MAX_FREE_SEARCH 10240 /* max size to search */
+#define MAX_FREE_LIST_SEARCH 100 /* max looking for free mem */
+
+/*
+ * bitflag tools for Variable and a Flag
+ */
+#define BIT_FLAG(x) (1 << (x))
+#define BIT_SET(v,f) (v) |= (f)
+#define BIT_CLEAR(v,f) (v) &= ~(f)
+#define BIT_IS_SET(v,f) ((v) & (f))
+#define BIT_TOGGLE(v,f) (v) ^= (f)
+
+#define SET_POINTER(pnt, val) \
+ do { \
+ if ((pnt) != NULL) { \
+ (*(pnt)) = (val); \
+ } \
+ } while(0)
+
+#define BLOCK_FLAG_USED BIT_FLAG(0) /* block is used */
+#define BLOCK_FLAG_FREE BIT_FLAG(1) /* block is free */
+
+#define DEFAULT_PAGE_MULT 16 /* pagesize = this * getpagesize*/
+
+/* How many pages SIZE bytes resides in. We add in the block header. */
+#define PAGES_IN_SIZE(mp_p, size) (((size) + sizeof(mpool_block_t) + \
+ (mp_p)->mp_page_size - 1) / \
+ (mp_p)->mp_page_size)
+#define SIZE_OF_PAGES(mp_p, page_n) ((page_n) * (mp_p)->mp_page_size)
+#define MAX_BITS 30 /* we only can allocate 1gb chunks */
+
+#define MAX_BLOCK_USER_MEMORY(mp_p) ((mp_p)->mp_page_size - \
+ sizeof(mpool_block_t))
+#define FIRST_ADDR_IN_BLOCK(block_p) (void *)((char *)(block_p) + \
+ sizeof(mpool_block_t))
+#define MEMORY_IN_BLOCK(block_p) ((char *)(block_p)->mb_bounds_p - \
+ ((char *)(block_p) + \
+ sizeof(mpool_block_t)))
+
+typedef struct {
+ unsigned int mp_magic; /* magic number for struct */
+ unsigned int mp_flags; /* flags for the struct */
+ unsigned long mp_alloc_c; /* number of allocations */
+ unsigned long mp_user_alloc; /* user bytes allocated */
+ unsigned long mp_max_alloc; /* maximum user bytes allocated */
+ unsigned int mp_page_c; /* number of pages allocated */
+ unsigned int mp_max_pages; /* maximum number of pages to use */
+ unsigned int mp_page_size; /* page-size of our system */
+ int mp_fd; /* fd for /dev/zero if mmap-ing */
+ off_t mp_top; /* top of our allocations in fd */
+ mpool_log_func_t mp_log_func; /* log callback function */
+ void *mp_addr; /* current address for mmaping */
+ void *mp_min_p; /* min address in pool for checks */
+ void *mp_bounds_p; /* max address in pool for checks */
+ struct mpool_block_st *mp_first_p; /* first memory block we are using */
+ struct mpool_block_st *mp_last_p; /* last memory block we are using */
+ struct mpool_block_st *mp_free[MAX_BITS + 1]; /* free lists based on size */
+ unsigned int mp_magic2; /* upper magic for overwrite sanity */
+} mpool_t;
+
+/* for debuggers to be able to interrogate the generic type in the .h file */
+typedef mpool_t mpool_ext_t;
+
+/*
+ * Block header structure. This structure *MUST* be long-word
+ * aligned.
+ */
+typedef struct mpool_block_st {
+ unsigned int mb_magic; /* magic number for block header */
+ void *mb_bounds_p; /* block boundary location */
+ struct mpool_block_st *mb_next_p; /* linked list next pointer */
+ unsigned int mb_magic2; /* upper magic for overwrite sanity */
+} mpool_block_t;
+
+/*
+ * Free list structure.
+ */
+typedef struct {
+ void *mf_next_p; /* pointer to the next free address */
+ unsigned long mf_size; /* size of the free block */
+} mpool_free_t;
+
+#endif /* ! __MPOOL_LOC_H__ */
diff --git a/libs/libks/src/include/simclist.h b/libs/libks/src/include/simclist.h
new file mode 100755
index 0000000000..2ce9d491ad
--- /dev/null
+++ b/libs/libks/src/include/simclist.h
@@ -0,0 +1,980 @@
+/*
+ * Copyright (c) 2007,2008 Mij
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+/*
+ * SimCList library. See http://mij.oltrelinux.com/devel/simclist
+ */
+
+
+#ifndef SIMCLIST_H
+#define SIMCLIST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+#include
+
+#ifndef SIMCLIST_NO_DUMPRESTORE
+# ifndef _WIN32
+# include /* list_dump_info_t's struct timeval */
+# else
+# include
+# endif
+#endif
+
+
+/* Be friend of both C90 and C99 compilers */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ /* "inline" and "restrict" are keywords */
+#else
+# define inline /* inline */
+# define restrict /* restrict */
+#endif
+
+
+/**
+ * Type representing list hashes.
+ *
+ * This is a signed integer value.
+ */
+typedef int32_t list_hash_t;
+
+#ifndef SIMCLIST_NO_DUMPRESTORE
+typedef struct {
+ uint16_t version; /* dump version */
+ struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */
+ uint32_t list_size;
+ uint32_t list_numels;
+ list_hash_t list_hash; /* hash of the list when dumped, or 0 if invalid */
+ uint32_t dumpsize;
+ int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */
+} list_dump_info_t;
+#endif
+
+/**
+ * a comparator of elements.
+ *
+ * A comparator of elements is a function that:
+ * -# receives two references to elements a and b
+ * -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively
+ *
+ * It is responsability of the function to handle possible NULL values.
+ */
+typedef int (*element_comparator)(const void *a, const void *b);
+
+/**
+ * a seeker of elements.
+ *
+ * An element seeker is a function that:
+ * -# receives a reference to an element el
+ * -# receives a reference to some indicator data
+ * -# returns non-0 if the element matches the indicator, 0 otherwise
+ *
+ * It is responsability of the function to handle possible NULL values in any
+ * argument.
+ */
+typedef int (*element_seeker)(const void *el, const void *indicator);
+
+/**
+ * an element lenght meter.
+ *
+ * An element meter is a function that:
+ * -# receives the reference to an element el
+ * -# returns its size in bytes
+ *
+ * It is responsability of the function to handle possible NULL values.
+ */
+typedef size_t (*element_meter)(const void *el);
+
+/**
+ * a function computing the hash of elements.
+ *
+ * An hash computing function is a function that:
+ * -# receives the reference to an element el
+ * -# returns a hash value for el
+ *
+ * It is responsability of the function to handle possible NULL values.
+ */
+typedef list_hash_t (*element_hash_computer)(const void *el);
+
+/**
+ * a function for serializing an element.
+ *
+ * A serializer function is one that gets a reference to an element,
+ * and returns a reference to a buffer that contains its serialization
+ * along with the length of this buffer.
+ * It is responsability of the function to handle possible NULL values,
+ * returning a NULL buffer and a 0 buffer length.
+ *
+ * These functions have 3 goals:
+ * -# "freeze" and "flatten" the memory representation of the element
+ * -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations
+ * -# possibly extract a compressed representation of the element
+ *
+ * @param el reference to the element data
+ * @param serialize_buffer reference to fill with the length of the buffer
+ * @return reference to the buffer with the serialized data
+ */
+typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len);
+
+/**
+ * a function for un-serializing an element.
+ *
+ * An unserializer function accomplishes the inverse operation of the
+ * serializer function. An unserializer function is one that gets a
+ * serialized representation of an element and turns it backe to the original
+ * element. The serialized representation is passed as a reference to a buffer
+ * with its data, and the function allocates and returns the buffer containing
+ * the original element, and it sets the length of this buffer into the
+ * integer passed by reference.
+ *
+ * @param data reference to the buffer with the serialized representation of the element
+ * @param data_len reference to the location where to store the length of the data in the buffer returned
+ * @return reference to a buffer with the original, unserialized representation of the element
+ */
+typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len);
+
+/* [private-use] list entry -- olds actual user datum */
+struct list_entry_s {
+ void *data;
+
+ /* doubly-linked list service references */
+ struct list_entry_s *next;
+ struct list_entry_s *prev;
+};
+
+/* [private-use] list attributes */
+struct list_attributes_s {
+ /* user-set routine for comparing list elements */
+ element_comparator comparator;
+ /* user-set routing for seeking elements */
+ element_seeker seeker;
+ /* user-set routine for determining the length of an element */
+ element_meter meter;
+ int copy_data;
+ /* user-set routine for computing the hash of an element */
+ element_hash_computer hasher;
+ /* user-set routine for serializing an element */
+ element_serializer serializer;
+ /* user-set routine for unserializing an element */
+ element_unserializer unserializer;
+};
+
+/** list object */
+typedef struct {
+ struct list_entry_s *head_sentinel;
+ struct list_entry_s *tail_sentinel;
+ struct list_entry_s *mid;
+
+ unsigned int numels;
+
+ /* array of spare elements */
+ struct list_entry_s **spareels;
+ unsigned int spareelsnum;
+
+#ifdef SIMCLIST_WITH_THREADS
+ /* how many threads are currently running */
+ unsigned int threadcount;
+#endif
+
+ /* service variables for list iteration */
+ int iter_active;
+ unsigned int iter_pos;
+ struct list_entry_s *iter_curentry;
+
+ /* list attributes */
+ struct list_attributes_s attrs;
+} list_t;
+
+/**
+ * initialize a list object for use.
+ *
+ * @param l must point to a user-provided memory location
+ * @return 0 for success. -1 for failure
+ */
+int list_init(list_t *restrict l);
+
+/**
+ * completely remove the list from memory.
+ *
+ * This function is the inverse of list_init(). It is meant to be called when
+ * the list is no longer going to be used. Elements and possible memory taken
+ * for internal use are freed.
+ *
+ * @param l list to destroy
+ */
+void list_destroy(list_t *restrict l);
+
+/**
+ * set the comparator function for list elements.
+ *
+ * Comparator functions are used for searching and sorting. If NULL is passed
+ * as reference to the function, the comparator is disabled.
+ *
+ * @param l list to operate
+ * @param comparator_fun pointer to the actual comparator function
+ * @return 0 if the attribute was successfully set; -1 otherwise
+ *
+ * @see element_comparator()
+ */
+int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun);
+
+/**
+ * set a seeker function for list elements.
+ *
+ * Seeker functions are used for finding elements. If NULL is passed as reference
+ * to the function, the seeker is disabled.
+ *
+ * @param l list to operate
+ * @param seeker_fun pointer to the actual seeker function
+ * @return 0 if the attribute was successfully set; -1 otherwise
+ *
+ * @see element_seeker()
+ */
+int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun);
+
+/**
+ * require to free element data when list entry is removed (default: don't free).
+ *
+ * [ advanced preference ]
+ *
+ * By default, when an element is removed from the list, it disappears from
+ * the list by its actual data is not free()d. With this option, every
+ * deletion causes element data to be freed.
+ *
+ * It is responsability of this function to correctly handle NULL values, if
+ * NULL elements are inserted into the list.
+ *
+ * @param l list to operate
+ * @param metric_fun pointer to the actual metric function
+ * @param copy_data 0: do not free element data (default); non-0: do free
+ * @return 0 if the attribute was successfully set; -1 otherwise
+ *
+ * @see element_meter()
+ * @see list_meter_int8_t()
+ * @see list_meter_int16_t()
+ * @see list_meter_int32_t()
+ * @see list_meter_int64_t()
+ * @see list_meter_uint8_t()
+ * @see list_meter_uint16_t()
+ * @see list_meter_uint32_t()
+ * @see list_meter_uint64_t()
+ * @see list_meter_float()
+ * @see list_meter_double()
+ * @see list_meter_string()
+ */
+int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data);
+
+/**
+ * set the element hash computing function for the list elements.
+ *
+ * [ advanced preference ]
+ *
+ * An hash can be requested depicting the list status at a given time. An hash
+ * only depends on the elements and their order. By default, the hash of an
+ * element is only computed on its reference. With this function, the user can
+ * set a custom function computing the hash of an element. If such function is
+ * provided, the list_hash() function automatically computes the list hash using
+ * the custom function instead of simply referring to element references.
+ *
+ * @param l list to operate
+ * @param hash_computer_fun pointer to the actual hash computing function
+ * @return 0 if the attribute was successfully set; -1 otherwise
+ *
+ * @see element_hash_computer()
+ */
+int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun);
+
+/**
+ * set the element serializer function for the list elements.
+ *
+ * [ advanced preference ]
+ *
+ * Serialize functions are used for dumping the list to some persistent
+ * storage. The serializer function is called for each element; it is passed
+ * a reference to the element and a reference to a size_t object. It will
+ * provide (and return) the buffer with the serialization of the element and
+ * fill the size_t object with the length of this serialization data.
+ *
+ * @param l list to operate
+ * @param serializer_fun pointer to the actual serializer function
+ * @return 0 if the attribute was successfully set; -1 otherwise
+ *
+ * @see element_serializer()
+ * @see list_dump_filedescriptor()
+ * @see list_restore_filedescriptor()
+ */
+int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun);
+
+/**
+ * set the element unserializer function for the list elements.
+ *
+ * [ advanced preference ]
+ *
+ * Unserialize functions are used for restoring the list from some persistent
+ * storage. The unserializer function is called for each element segment read
+ * from the storage; it is passed the segment and a reference to an integer.
+ * It shall allocate and return a buffer compiled with the resumed memory
+ * representation of the element, and set the integer value to the length of
+ * this buffer.
+ *
+ * @param l list to operate
+ * @param unserializer_fun pointer to the actual unserializer function
+ * @return 0 if the attribute was successfully set; -1 otherwise
+ *
+ * @see element_unserializer()
+ * @see list_dump_filedescriptor()
+ * @see list_restore_filedescriptor()
+ */
+int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun);
+
+/**
+ * append data at the end of the list.
+ *
+ * This function is useful for adding elements with a FIFO/queue policy.
+ *
+ * @param l list to operate
+ * @param data pointer to user data to append
+ *
+ * @return 1 for success. < 0 for failure
+ */
+int list_append(list_t *restrict l, const void *data);
+
+/**
+ * insert data in the head of the list.
+ *
+ * This function is useful for adding elements with a LIFO/Stack policy.
+ *
+ * @param l list to operate
+ * @param data pointer to user data to append
+ *
+ * @return 1 for success. < 0 for failure
+ */
+int list_prepend(list_t *restrict l, const void *restrict data);
+
+/**
+ * extract the element in the top of the list.
+ *
+ * This function is for using a list with a FIFO/queue policy.
+ *
+ * @param l list to operate
+ * @return reference to user datum, or NULL on errors
+ */
+void *list_fetch(list_t *restrict l);
+
+/**
+ * retrieve an element at a given position.
+ *
+ * @param l list to operate
+ * @param pos [0,size-1] position index of the element wanted
+ * @return reference to user datum, or NULL on errors
+ */
+void *list_get_at(const list_t *restrict l, unsigned int pos);
+
+/**
+ * return the maximum element of the list.
+ *
+ * @warning Requires a comparator function to be set for the list.
+ *
+ * Returns the maximum element with respect to the comparator function output.
+ *
+ * @see list_attributes_comparator()
+ *
+ * @param l list to operate
+ * @return the reference to the element, or NULL
+ */
+void *list_get_max(const list_t *restrict l);
+
+/**
+ * return the minimum element of the list.
+ *
+ * @warning Requires a comparator function to be set for the list.
+ *
+ * Returns the minimum element with respect to the comparator function output.
+ *
+ * @see list_attributes_comparator()
+ *
+ * @param l list to operate
+ * @return the reference to the element, or NULL
+ */
+void *list_get_min(const list_t *restrict l);
+
+/**
+ * retrieve and remove from list an element at a given position.
+ *
+ * @param l list to operate
+ * @param pos [0,size-1] position index of the element wanted
+ * @return reference to user datum, or NULL on errors
+ */
+void *list_extract_at(list_t *restrict l, unsigned int pos);
+
+/**
+ * insert an element at a given position.
+ *
+ * @param l list to operate
+ * @param data reference to data to be inserted
+ * @param pos [0,size-1] position index to insert the element at
+ * @return positive value on success. Negative on failure
+ */
+int list_insert_at(list_t *restrict l, const void *data, unsigned int pos);
+
+/**
+ * expunge the first found given element from the list.
+ *
+ * Inspects the given list looking for the given element; if the element
+ * is found, it is removed. Only the first occurence is removed.
+ * If a comparator function was not set, elements are compared by reference.
+ * Otherwise, the comparator is used to match the element.
+ *
+ * @param l list to operate
+ * @param data reference of the element to search for
+ * @return 0 on success. Negative value on failure
+ *
+ * @see list_attributes_comparator()
+ * @see list_delete_at()
+ */
+int list_delete(list_t *restrict l, const void *data);
+
+/**
+ * expunge an element at a given position from the list.
+ *
+ * @param l list to operate
+ * @param pos [0,size-1] position index of the element to be deleted
+ * @return 0 on success. Negative value on failure
+ */
+int list_delete_at(list_t *restrict l, unsigned int pos);
+
+/**
+ * expunge an array of elements from the list, given their position range.
+ *
+ * @param l list to operate
+ * @param posstart [0,size-1] position index of the first element to be deleted
+ * @param posend [posstart,size-1] position of the last element to be deleted
+ * @return the number of elements successfully removed on success, <0 on error
+ */
+int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend);
+
+/**
+ * clear all the elements off of the list.
+ *
+ * The element datums will not be freed.
+ *
+ * @see list_delete_range()
+ * @see list_size()
+ *
+ * @param l list to operate
+ * @return the number of elements removed on success, <0 on error
+ */
+int list_clear(list_t *restrict l);
+
+/**
+ * inspect the number of elements in the list.
+ *
+ * @param l list to operate
+ * @return number of elements currently held by the list
+ */
+unsigned int list_size(const list_t *restrict l);
+
+/**
+ * inspect whether the list is empty.
+ *
+ * @param l list to operate
+ * @return 0 iff the list is not empty
+ *
+ * @see list_size()
+ */
+int list_empty(const list_t *restrict l);
+
+/**
+ * find the position of an element in a list.
+ *
+ * @warning Requires a comparator function to be set for the list.
+ *
+ * Inspects the given list looking for the given element; if the element
+ * is found, its position into the list is returned.
+ * Elements are inspected comparing references if a comparator has not been
+ * set. Otherwise, the comparator is used to find the element.
+ *
+ * @param l list to operate
+ * @param data reference of the element to search for
+ * @return position of element in the list, or <0 if not found
+ *
+ * @see list_attributes_comparator()
+ * @see list_get_at()
+ */
+int list_locate(const list_t *restrict l, const void *data);
+
+/**
+ * returns an element given an indicator.
+ *
+ * @warning Requires a seeker function to be set for the list.
+ *
+ * Inspect the given list looking with the seeker if an element matches
+ * an indicator. If such element is found, the reference to the element
+ * is returned.
+ *
+ * @param l list to operate
+ * @param indicator indicator data to pass to the seeker along with elements
+ * @return reference to the element accepted by the seeker, or NULL if none found
+ */
+void *list_seek(list_t *restrict l, const void *indicator);
+
+/**
+ * inspect whether some data is member of the list.
+ *
+ * @warning Requires a comparator function to be set for the list.
+ *
+ * By default, a per-reference comparison is accomplished. That is,
+ * the data is in list if any element of the list points to the same
+ * location of data.
+ * A "semantic" comparison is accomplished, otherwise, if a comparator
+ * function has been set previously, with list_attributes_comparator();
+ * in which case, the given data reference is believed to be in list iff
+ * comparator_fun(elementdata, userdata) == 0 for any element in the list.
+ *
+ * @param l list to operate
+ * @param data reference to the data to search
+ * @return 0 iff the list does not contain data as an element
+ *
+ * @see list_attributes_comparator()
+ */
+int list_contains(const list_t *restrict l, const void *data);
+
+/**
+ * concatenate two lists
+ *
+ * Concatenates one list with another, and stores the result into a
+ * user-provided list object, which must be different from both the
+ * lists to concatenate. Attributes from the original lists are not
+ * cloned.
+ * The destination list referred is threated as virgin room: if it
+ * is an existing list containing elements, memory leaks will happen.
+ * It is OK to specify the same list twice as source, for "doubling"
+ * it in the destination.
+ *
+ * @param l1 base list
+ * @param l2 list to append to the base
+ * @param dest reference to the destination list
+ * @return 0 for success, -1 for errors
+ */
+int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest);
+
+/**
+ * sort list elements.
+ *
+ * @warning Requires a comparator function to be set for the list.
+ *
+ * Sorts the list in ascending or descending order as specified by the versus
+ * flag. The algorithm chooses autonomously what algorithm is best suited for
+ * sorting the list wrt its current status.
+ *
+ * @param l list to operate
+ * @param versus positive: order small to big; negative: order big to small
+ * @return 0 iff sorting was successful
+ *
+ * @see list_attributes_comparator()
+ */
+int list_sort(list_t *restrict l, int versus);
+
+/**
+ * start an iteration session.
+ *
+ * This function prepares the list to be iterated.
+ *
+ * @param l list to operate
+ * @return 0 if the list cannot be currently iterated. >0 otherwise
+ *
+ * @see list_iterator_stop()
+ */
+int list_iterator_start(list_t *restrict l);
+
+/**
+ * return the next element in the iteration session.
+ *
+ * @param l list to operate
+ * @return element datum, or NULL on errors
+ */
+void *list_iterator_next(list_t *restrict l);
+
+/**
+ * inspect whether more elements are available in the iteration session.
+ *
+ * @param l list to operate
+ * @return 0 iff no more elements are available.
+ */
+int list_iterator_hasnext(const list_t *restrict l);
+
+/**
+ * end an iteration session.
+ *
+ * @param l list to operate
+ * @return 0 iff the iteration session cannot be stopped
+ */
+int list_iterator_stop(list_t *restrict l);
+
+/**
+ * return the hash of the current status of the list.
+ *
+ * @param l list to operate
+ * @param hash where the resulting hash is put
+ *
+ * @return 0 for success; <0 for failure
+ */
+int list_hash(const list_t *restrict l, list_hash_t *restrict hash);
+
+#ifndef SIMCLIST_NO_DUMPRESTORE
+/**
+ * get meta informations on a list dump on filedescriptor.
+ *
+ * [ advanced function ]
+ *
+ * Extracts the meta information from a SimCList dump located in a file
+ * descriptor. The file descriptor must be open and positioned at the
+ * beginning of the SimCList dump block.
+ *
+ * @param fd file descriptor to get metadata from
+ * @param info reference to a dump metainformation structure to fill
+ * @return 0 for success; <0 for failure
+ *
+ * @see list_dump_filedescriptor()
+ */
+int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info);
+
+/**
+ * get meta informations on a list dump on file.
+ *
+ * [ advanced function ]
+ *
+ * Extracts the meta information from a SimCList dump located in a file.
+ *
+ * @param filename filename of the file to fetch from
+ * @param info reference to a dump metainformation structure to fill
+ * @return 0 for success; <0 for failure
+ *
+ * @see list_dump_filedescriptor()
+ */
+int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info);
+
+/**
+ * dump the list into an open, writable file descriptor.
+ *
+ * This function "dumps" the list to a persistent storage so it can be
+ * preserved across process terminations.
+ * When called, the file descriptor must be open for writing and positioned
+ * where the serialized data must begin. It writes its serialization of the
+ * list in a form which is portable across different architectures. Dump can
+ * be safely performed on stream-only (non seekable) descriptors. The file
+ * descriptor is not closed at the end of the operations.
+ *
+ * To use dump functions, either of these conditions must be satisfied:
+ * -# a metric function has been specified with list_attributes_copy()
+ * -# a serializer function has been specified with list_attributes_serializer()
+ *
+ * If a metric function has been specified, each element of the list is dumped
+ * as-is from memory, copying it from its pointer for its length down to the
+ * file descriptor. This might have impacts on portability of the dump to
+ * different architectures.
+ *
+ * If a serializer function has been specified, its result for each element is
+ * dumped to the file descriptor.
+ *
+ *
+ * @param l list to operate
+ * @param fd file descriptor to write to
+ * @param len location to store the resulting length of the dump (bytes), or NULL
+ *
+ * @return 0 if successful; -1 otherwise
+ *
+ * @see element_serializer()
+ * @see list_attributes_copy()
+ * @see list_attributes_serializer()
+ */
+int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len);
+
+/**
+ * dump the list to a file name.
+ *
+ * This function creates a filename and dumps the current content of the list
+ * to it. If the file exists it is overwritten. The number of bytes written to
+ * the file can be returned in a specified argument.
+ *
+ * @param l list to operate
+ * @param filename filename to write to
+ * @param len location to store the resulting length of the dump (bytes), or NULL
+ *
+ * @return 0 if successful; -1 otherwise
+ *
+ * @see list_attributes_copy()
+ * @see element_serializer()
+ * @see list_attributes_serializer()
+ * @see list_dump_filedescriptor()
+ * @see list_restore_file()
+ *
+ * This function stores a representation of the list
+ */
+int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len);
+
+/**
+ * restore the list from an open, readable file descriptor to memory.
+ *
+ * This function is the "inverse" of list_dump_filedescriptor(). It restores
+ * the list content from a (open, read-ready) file descriptor to memory. An
+ * unserializer might be needed to restore elements from the persistent
+ * representation back into memory-consistent format. List attributes can not
+ * be restored and must be set manually.
+ *
+ * @see list_dump_filedescriptor()
+ * @see list_attributes_serializer()
+ * @see list_attributes_unserializer()
+ *
+ * @param l list to restore to
+ * @param fd file descriptor to read from.
+ * @param len location to store the length of the dump read (bytes), or NULL
+ * @return 0 if successful; -1 otherwise
+ */
+int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len);
+
+/**
+ * restore the list from a file name.
+ *
+ * This function restores the content of a list from a file into memory. It is
+ * the inverse of list_dump_file().
+ *
+ * @see element_unserializer()
+ * @see list_attributes_unserializer()
+ * @see list_dump_file()
+ * @see list_restore_filedescriptor()
+ *
+ * @param l list to restore to
+ * @param filename filename to read data from
+ * @param len location to store the length of the dump read (bytes), or NULL
+ * @return 0 if successful; -1 otherwise
+ */
+int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len);
+#endif
+
+/* ready-made comparators, meters and hash computers */
+ /* comparator functions */
+/**
+ * ready-made comparator for int8_t elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_int8_t(const void *a, const void *b);
+
+/**
+ * ready-made comparator for int16_t elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_int16_t(const void *a, const void *b);
+
+/**
+ * ready-made comparator for int32_t elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_int32_t(const void *a, const void *b);
+
+/**
+ * ready-made comparator for int64_t elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_int64_t(const void *a, const void *b);
+
+/**
+ * ready-made comparator for uint8_t elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_uint8_t(const void *a, const void *b);
+
+/**
+ * ready-made comparator for uint16_t elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_uint16_t(const void *a, const void *b);
+
+/**
+ * ready-made comparator for uint32_t elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_uint32_t(const void *a, const void *b);
+
+/**
+ * ready-made comparator for uint64_t elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_uint64_t(const void *a, const void *b);
+
+/**
+ * ready-made comparator for float elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_float(const void *a, const void *b);
+
+/**
+ * ready-made comparator for double elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_double(const void *a, const void *b);
+
+/**
+ * ready-made comparator for string elements.
+ * @see list_attributes_comparator()
+ */
+int list_comparator_string(const void *a, const void *b);
+
+ /* metric functions */
+/**
+ * ready-made metric function for int8_t elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_int8_t(const void *el);
+
+/**
+ * ready-made metric function for int16_t elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_int16_t(const void *el);
+
+/**
+ * ready-made metric function for int32_t elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_int32_t(const void *el);
+
+/**
+ * ready-made metric function for int64_t elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_int64_t(const void *el);
+
+/**
+ * ready-made metric function for uint8_t elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_uint8_t(const void *el);
+
+/**
+ * ready-made metric function for uint16_t elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_uint16_t(const void *el);
+
+/**
+ * ready-made metric function for uint32_t elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_uint32_t(const void *el);
+
+/**
+ * ready-made metric function for uint64_t elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_uint64_t(const void *el);
+
+/**
+ * ready-made metric function for float elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_float(const void *el);
+
+/**
+ * ready-made metric function for double elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_double(const void *el);
+
+/**
+ * ready-made metric function for string elements.
+ * @see list_attributes_copy()
+ */
+size_t list_meter_string(const void *el);
+
+ /* hash functions */
+/**
+ * ready-made hash function for int8_t elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_int8_t(const void *el);
+
+/**
+ * ready-made hash function for int16_t elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_int16_t(const void *el);
+
+/**
+ * ready-made hash function for int32_t elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_int32_t(const void *el);
+
+/**
+ * ready-made hash function for int64_t elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_int64_t(const void *el);
+
+/**
+ * ready-made hash function for uint8_t elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_uint8_t(const void *el);
+
+/**
+ * ready-made hash function for uint16_t elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_uint16_t(const void *el);
+
+/**
+ * ready-made hash function for uint32_t elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_uint32_t(const void *el);
+
+/**
+ * ready-made hash function for uint64_t elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_uint64_t(const void *el);
+
+/**
+ * ready-made hash function for float elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_float(const void *el);
+
+/**
+ * ready-made hash function for double elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_double(const void *el);
+
+/**
+ * ready-made hash function for string elements.
+ * @see list_attributes_hash_computer()
+ */
+list_hash_t list_hashcomputer_string(const void *el);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/libs/libks/src/include/table.h b/libs/libks/src/include/table.h
new file mode 100644
index 0000000000..687358683d
--- /dev/null
+++ b/libs/libks/src/include/table.h
@@ -0,0 +1,1372 @@
+/*
+ * Generic table defines...
+ *
+ * Copyright 2000 by Gray Watson.
+ *
+ * This file is part of the table package.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies,
+ * and that the name of Gray Watson not be used in advertising or
+ * publicity pertaining to distribution of the document or software
+ * without specific, written prior permission.
+ *
+ * Gray Watson makes no representations about the suitability of the
+ * software described herein for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * The author may be reached via http://256.com/gray/
+ *
+ * $Id: table.h,v 1.11 2000/03/09 03:30:42 gray Exp $
+ */
+
+#ifndef __TABLE_H__
+#define __TABLE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * To build a "key" in any of the below routines, pass in a pointer to
+ * the key and its size [i.e. sizeof(int), etc]. With any of the
+ * "key" or "data" arguments, if their size is < 0, it will do an
+ * internal strlen of the item and add 1 for the \0.
+ *
+ * If you are using firstkey() and nextkey() functions, be careful if,
+ * after starting your firstkey loop, you use delete or insert, it
+ * will not crash but may produce interesting results. If you are
+ * deleting from firstkey to NULL it will work fine.
+ */
+
+/* return types for table functions */
+#define TABLE_ERROR_NONE 1 /* no error from function */
+#define TABLE_ERROR_PNT 2 /* bad table pointer */
+#define TABLE_ERROR_ARG_NULL 3 /* buffer args were null */
+#define TABLE_ERROR_SIZE 4 /* size of data was bad */
+#define TABLE_ERROR_OVERWRITE 5 /* key exists and we cant overwrite */
+#define TABLE_ERROR_NOT_FOUND 6 /* key does not exist */
+#define TABLE_ERROR_ALLOC 7 /* memory allocation error */
+#define TABLE_ERROR_LINEAR 8 /* no linear access started */
+#define TABLE_ERROR_OPEN 9 /* could not open file */
+#define TABLE_ERROR_SEEK 10 /* could not seek to pos in file */
+#define TABLE_ERROR_READ 11 /* could not read from file */
+#define TABLE_ERROR_WRITE 12 /* could not write to file */
+#define TABLE_ERROR_MMAP_NONE 13 /* no mmap support */
+#define TABLE_ERROR_MMAP 14 /* could not mmap file */
+#define TABLE_ERROR_MMAP_OP 15 /* can't perform operation on mmap */
+#define TABLE_ERROR_EMPTY 16 /* table is empty */
+#define TABLE_ERROR_NOT_EMPTY 17 /* table contains data */
+#define TABLE_ERROR_ALIGNMENT 18 /* invalid alignment value */
+#define TABLE_ERROR_COMPARE 19 /* problems with internal comparison */
+#define TABLE_ERROR_FREE 20 /* memory free error */
+
+/*
+ * Table flags set with table_attr.
+ */
+
+/*
+ * Automatically adjust the number of table buckets on the fly.
+ * Whenever the number of entries gets above some threshold, the
+ * number of buckets is realloced to a new size and each entry is
+ * re-hashed. Although this may take some time when it re-hashes, the
+ * table will perform better over time.
+ */
+#define TABLE_FLAG_AUTO_ADJUST (1<<0)
+
+/*
+ * If the above auto-adjust flag is set, also adjust the number of
+ * table buckets down as we delete entries.
+ */
+#define TABLE_FLAG_ADJUST_DOWN (1<<1)
+
+/* structure to walk through the fields in a linear order */
+typedef struct {
+ unsigned int tl_magic; /* magic structure to ensure correct init */
+ unsigned int tl_bucket_c; /* where in the table buck array we are */
+ unsigned int tl_entry_c; /* in the bucket, which entry we are on */
+} table_linear_t;
+
+/*
+ * int (*table_compare_t)
+ *
+ * DESCRIPTION
+ *
+ * Comparison function which compares two key/data pairs for table
+ * order.
+ *
+ * RETURNS:
+ *
+ * -1, 0, or 1 if key1 is <, ==, or > than key2.
+ *
+ * ARGUMENTS:
+ *
+ * key1 - Pointer to the first key entry.
+ *
+ * key1_size - Pointer to the size of the first key entry.
+ *
+ * data1 - Pointer to the first data entry.
+ *
+ * data1_size - Pointer to the size of the first data entry.
+ *
+ * key2 - Pointer to the second key entry.
+ *
+ * key2_size - Pointer to the size of the second key entry.
+ *
+ * data2 - Pointer to the second data entry.
+ *
+ * data2_size - Pointer to the size of the second data entry.
+ */
+typedef int (*table_compare_t)(const void *key1, const int key1_size,
+ const void *data1, const int data1_size,
+ const void *key2, const int key2_size,
+ const void *data2, const int data2_size);
+
+/*
+ * int (*table_mem_alloc_t)
+ *
+ * DESCRIPTION
+ *
+ * Function to override the table's allocation function.
+ *
+ * RETURNS:
+ *
+ * Success - Newly allocated pointer.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * pool_p <-> Pointer to our memory pool. If no pool is set then this
+ * will be NULL.
+ *
+ * size -> Number of bytes that needs to be allocated.
+ */
+typedef void *(*table_mem_alloc_t)(void *pool_p, const unsigned long size);
+
+/*
+ * int (*table_mem_resize_t)
+ *
+ * DESCRIPTION
+ *
+ * Function to override the table's memory resize function. The
+ * difference between this and realloc is that this provides the
+ * previous allocation size. You can specify NULL for this function
+ * in which cause the library will allocate, copy, and free itself.
+ *
+ * RETURNS:
+ *
+ * Success - Newly allocated pointer.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * pool_p <-> Pointer to our memory pool. If no pool is set then this
+ * will be NULL.
+ *
+ * old_addr -> Previously allocated address.
+ *
+ * old_size -> Size of the old address. Since the system is
+ * lightweight, it does not store size information on the pointer.
+ *
+ * new_size -> New size of the allocation.
+ */
+typedef void *(*table_mem_resize_t)(void *pool_p, void *old_addr,
+ const unsigned long old_size,
+ const unsigned long new_size);
+
+/*
+ * int (*table_mem_free_t)
+ *
+ * DESCRIPTION
+ *
+ * Function to override the table's free function.
+ *
+ * RETURNS:
+ *
+ * Success - 1
+ *
+ * Failure - 0
+ *
+ * ARGUMENTS:
+ *
+ * pool_p <-> Pointer to our memory pool. If no pool is set then this
+ * will be NULL.
+ *
+ * addr -> Address that we are freeing.
+ *
+ * min_size -> Minimum size of the address being freed or 0 if not
+ * known. This can also be the exact size if known.
+ */
+typedef int (*table_mem_free_t)(void *pool_p, void *addr,
+ const unsigned long min_size);
+
+#ifdef TABLE_MAIN
+
+#include "table_loc.h"
+
+#else
+
+/* generic table type */
+typedef void table_t;
+
+/* generic table entry type */
+typedef void table_entry_t;
+
+#endif
+
+/*<<<<<<<<<< The below prototypes are auto-generated by fillproto */
+
+/*
+ * table_t *table_alloc
+ *
+ * DESCRIPTION:
+ *
+ * Allocate a new table structure.
+ *
+ * RETURNS:
+ *
+ * A pointer to the new table structure which must be passed to
+ * table_free to be deallocated. On error a NULL is returned.
+ *
+ * ARGUMENTS:
+ *
+ * bucket_n - Number of buckets for the hash table. Our current hash
+ * value works best with base two numbers. Set to 0 to take the
+ * library default of 1024.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+extern
+table_t *table_alloc(const unsigned int bucket_n, int *error_p);
+
+/*
+ * table_t *table_alloc_in_pool
+ *
+ * DESCRIPTION:
+ *
+ * Allocate a new table structure in a memory pool or using
+ * alternative allocation and free functions.
+ *
+ * RETURNS:
+ *
+ * A pointer to the new table structure which must be passed to
+ * table_free to be deallocated. On error a NULL is returned.
+ *
+ * ARGUMENTS:
+ *
+ * bucket_n - Number of buckets for the hash table. Our current hash
+ * value works best with base two numbers. Set to 0 to take the
+ * library default of 1024.
+ *
+ * mem_pool <-> Memory pool to associate with the table. Can be NULL.
+ *
+ * alloc_func -> Allocate function we are overriding malloc() with.
+ *
+ * resize_func -> Resize function we are overriding the standard
+ * memory resize/realloc with. This can be NULL in which cause the
+ * library will allocate, copy, and free itself.
+ *
+ * free_func -> Free function we are overriding free() with.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+extern
+table_t *table_alloc_in_pool(const unsigned int bucket_n,
+ void *mem_pool,
+ table_mem_alloc_t alloc_func,
+ table_mem_resize_t resize_func,
+ table_mem_free_t free_func, int *error_p);
+
+/*
+ * int table_attr
+ *
+ * DESCRIPTION:
+ *
+ * Set the attributes for the table. The available attributes are
+ * specified at the top of table.h.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to a table structure which we will be altering.
+ *
+ * attr - Attribute(s) that we will be applying to the table.
+ */
+extern
+int table_attr(table_t *table_p, const int attr);
+
+/*
+ * int table_set_data_alignment
+ *
+ * DESCRIPTION:
+ *
+ * Set the alignment for the data in the table. This is used when you
+ * want to store binary data types and refer to them directly out of
+ * the table storage. For instance if you are storing integers as
+ * data in the table and want to be able to retrieve the location of
+ * the interger and then increment it as (*loc_p)++. Otherwise you
+ * would have to memcpy it out to an integer, increment it, and memcpy
+ * it back. If you are storing character data, no alignment is
+ * necessary.
+ *
+ * For most data elements, sizeof(long) is recommended unless you use
+ * smaller data types exclusively.
+ *
+ * WARNING: If necessary, you must set the data alignment before any
+ * data gets put into the table. Otherwise a TABLE_ERROR_NOT_EMPTY
+ * error will be returned.
+ *
+ * NOTE: there is no way to set the key data alignment although it
+ * should automatically be long aligned.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to a table structure which we will be altering.
+ *
+ * alignment - Alignment requested for the data. Must be a power of
+ * 2. Set to 0 for none.
+ */
+extern
+int table_set_data_alignment(table_t *table_p, const int alignment);
+
+/*
+ * int table_clear
+ *
+ * DESCRIPTION:
+ *
+ * Clear out and free all elements in a table structure.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer that we will be clearing.
+ */
+extern
+int table_clear(table_t *table_p);
+
+/*
+ * int table_free
+ *
+ * DESCRIPTION:
+ *
+ * Deallocates a table structure.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer that we will be freeing.
+ */
+extern
+int table_free(table_t *table_p);
+
+/*
+ * int table_insert_kd
+ *
+ * DESCRIPTION:
+ *
+ * Like table_insert except it passes back a pointer to the key and
+ * the data buffers after they have been inserted into the table
+ * structure.
+ *
+ * This routine adds a key/data pair both of which are made up of a
+ * buffer of bytes and an associated size. Both the key and the data
+ * will be copied into buffers allocated inside the table. If the key
+ * exists already, the associated data will be replaced if the
+ * overwrite flag is set, otherwise an error is returned.
+ *
+ * NOTE: be very careful changing the values since the table library
+ * provides the pointers to its memory. The key can _never_ be
+ * changed otherwise you will not find it again. The data can be
+ * changed but its length can never be altered unless you delete and
+ * re-insert it into the table.
+ *
+ * WARNING: The pointers to the key and data are not in any specific
+ * alignment. Accessing the key and/or data as an short, integer, or
+ * long pointer directly can cause problems.
+ *
+ * WARNING: Replacing a data cell (not inserting) will cause the table
+ * linked list to be temporarily invalid. Care must be taken with
+ * multiple threaded programs which are relying on the first/next
+ * linked list to be always valid.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer into which we will be inserting a
+ * new key/data pair.
+ *
+ * key_buf - Buffer of bytes of the key that we are inserting. If you
+ * are storing an (int) as the key (for example) then key_buf should
+ * be a (int *).
+ *
+ * key_size - Size of the key_buf buffer. If set to < 0 then the
+ * library will do a strlen of key_buf and add 1 for the '\0'. If you
+ * are storing an (int) as the key (for example) then key_size should
+ * be sizeof(int).
+ *
+ * data_buf - Buffer of bytes of the data that we are inserting. If
+ * it is NULL then the library will allocate space for the data in the
+ * table without copying in any information. If data_buf is NULL and
+ * data_size is 0 then the library will associate a NULL data pointer
+ * with the key. If you are storing a (long) as the data (for
+ * example) then data_buf should be a (long *).
+ *
+ * data_size - Size of the data_buf buffer. If set to < 0 then the
+ * library will do a strlen of data_buf and add 1 for the '\0'. If
+ * you are storing an (long) as the key (for example) then key_size
+ * should be sizeof(long).
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the key storage that was allocated in the table. If you are
+ * storing an (int) as the key (for example) then key_buf_p should be
+ * (int **) i.e. the address of a (int *).
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that was allocated in the table. If you are
+ * storing an (long) as the data (for example) then data_buf_p should
+ * be (long **) i.e. the address of a (long *).
+ *
+ * overwrite - Flag which, if set to 1, will allow the overwriting of
+ * the data in the table with the new data if the key already exists
+ * in the table.
+ */
+extern
+int table_insert_kd(table_t *table_p,
+ const void *key_buf, const int key_size,
+ const void *data_buf, const int data_size,
+ void **key_buf_p, void **data_buf_p,
+ const char overwrite_b);
+
+/*
+ * int table_insert
+ *
+ * DESCRIPTION:
+ *
+ * Exactly the same as table_insert_kd except it does not pass back a
+ * pointer to the key after they have been inserted into the table
+ * structure. This is still here for backwards compatibility.
+ *
+ * See table_insert_kd for more information.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer into which we will be inserting a
+ * new key/data pair.
+ *
+ * key_buf - Buffer of bytes of the key that we are inserting. If you
+ * are storing an (int) as the key (for example) then key_buf should
+ * be a (int *).
+ *
+ * key_size - Size of the key_buf buffer. If set to < 0 then the
+ * library will do a strlen of key_buf and add 1 for the '\0'. If you
+ * are storing an (int) as the key (for example) then key_size should
+ * be sizeof(int).
+ *
+ * data_buf - Buffer of bytes of the data that we are inserting. If
+ * it is NULL then the library will allocate space for the data in the
+ * table without copying in any information. If data_buf is NULL and
+ * data_size is 0 then the library will associate a NULL data pointer
+ * with the key. If you are storing a (long) as the data (for
+ * example) then data_buf should be a (long *).
+ *
+ * data_size - Size of the data_buf buffer. If set to < 0 then the
+ * library will do a strlen of data_buf and add 1 for the '\0'. If
+ * you are storing an (long) as the key (for example) then key_size
+ * should be sizeof(long).
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that was allocated in the table. If you are
+ * storing an (long) as the data (for example) then data_buf_p should
+ * be (long **) i.e. the address of a (long *).
+ *
+ * overwrite - Flag which, if set to 1, will allow the overwriting of
+ * the data in the table with the new data if the key already exists
+ * in the table.
+ */
+extern
+int table_insert(table_t *table_p,
+ const void *key_buf, const int key_size,
+ const void *data_buf, const int data_size,
+ void **data_buf_p, const char overwrite_b);
+
+/*
+ * int table_retrieve
+ *
+ * DESCRIPTION:
+ *
+ * This routine looks up a key made up of a buffer of bytes and an
+ * associated size in the table. If found then it returns the
+ * associated data information.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer into which we will be searching
+ * for the key.
+ *
+ * key_buf - Buffer of bytes of the key that we are searching for. If
+ * you are looking for an (int) as the key (for example) then key_buf
+ * should be a (int *).
+ *
+ * key_size - Size of the key_buf buffer. If set to < 0 then the
+ * library will do a strlen of key_buf and add 1 for the '\0'. If you
+ * are looking for an (int) as the key (for example) then key_size
+ * should be sizeof(int).
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that was allocated in the table and that is
+ * associated with the key. If a (long) was stored as the data (for
+ * example) then data_buf_p should be (long **) i.e. the address of a
+ * (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data stored in the table that is associated with
+ * the key.
+ */
+extern
+int table_retrieve(table_t *table_p,
+ const void *key_buf, const int key_size,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * int table_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine looks up a key made up of a buffer of bytes and an
+ * associated size in the table. If found then it will be removed
+ * from the table. The associated data can be passed back to the user
+ * if requested.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * NOTE: this could be an allocation error if the library is to return
+ * the data to the user.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we will be deleteing
+ * the key.
+ *
+ * key_buf - Buffer of bytes of the key that we are searching for to
+ * delete. If you are deleting an (int) key (for example) then
+ * key_buf should be a (int *).
+ *
+ * key_size - Size of the key_buf buffer. If set to < 0 then the
+ * library will do a strlen of key_buf and add 1 for the '\0'. If you
+ * are deleting an (int) key (for example) then key_size should be
+ * sizeof(int).
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that was allocated in the table and that was
+ * associated with the key. If a (long) was stored as the data (for
+ * example) then data_buf_p should be (long **) i.e. the address of a
+ * (long *). If a pointer is passed in, the caller is responsible for
+ * freeing it after use. If data_buf_p is NULL then the library will
+ * free up the data allocation itself.
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that was stored in the table and that was
+ * associated with the key.
+ */
+extern
+int table_delete(table_t *table_p,
+ const void *key_buf, const int key_size,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * int table_delete_first
+ *
+ * DESCRIPTION:
+ *
+ * This is like the table_delete routines except it deletes the first
+ * key/data pair in the table instead of an entry corresponding to a
+ * particular key. The associated key and data information can be
+ * passed back to the user if requested. This routines is handy to
+ * clear out a table.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * NOTE: this could be an allocation error if the library is to return
+ * the data to the user.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we will be deleteing
+ * the first key.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the first key that was allocated in the table.
+ * If an (int) was stored as the first key (for example) then
+ * key_buf_p should be (int **) i.e. the address of a (int *). If a
+ * pointer is passed in, the caller is responsible for freeing it
+ * after use. If key_buf_p is NULL then the library will free up the
+ * key allocation itself.
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that was stored in the table and that was
+ * associated with the key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that was allocated in the table and that was
+ * associated with the key. If a (long) was stored as the data (for
+ * example) then data_buf_p should be (long **) i.e. the address of a
+ * (long *). If a pointer is passed in, the caller is responsible for
+ * freeing it after use. If data_buf_p is NULL then the library will
+ * free up the data allocation itself.
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that was stored in the table and that was
+ * associated with the key.
+ */
+extern
+int table_delete_first(table_t *table_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * int table_info
+ *
+ * DESCRIPTION:
+ *
+ * Get some information about a table_p structure.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting
+ * information.
+ *
+ * num_buckets_p - Pointer to an integer which, if not NULL, will
+ * contain the number of buckets in the table.
+ *
+ * num_entries_p - Pointer to an integer which, if not NULL, will
+ * contain the number of entries stored in the table.
+ */
+extern
+int table_info(table_t *table_p, int *num_buckets_p, int *num_entries_p);
+
+/*
+ * int table_adjust
+ *
+ * DESCRIPTION:
+ *
+ * Set the number of buckets in a table to a certain value.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer of which we are adjusting.
+ *
+ * bucket_n - Number buckets to adjust the table to. Set to 0 to
+ * adjust the table to its number of entries.
+ */
+extern
+int table_adjust(table_t *table_p, const int bucket_n);
+
+/*
+ * int table_type_size
+ *
+ * DESCRIPTION:
+ *
+ * Return the size of the internal table type.
+ *
+ * RETURNS:
+ *
+ * The size of the table_t type.
+ *
+ * ARGUMENTS:
+ *
+ * None.
+ */
+extern
+int table_type_size(void);
+
+/*
+ * int table_first
+ *
+ * DESCRIPTION:
+ *
+ * Find first element in a table and pass back information about the
+ * key/data pair. If any of the key/data pointers are NULL then they
+ * are ignored.
+ *
+ * NOTE: This function is not reentrant. More than one thread cannot
+ * be doing a first and next on the same table at the same time. Use
+ * the table_first_r version below for this.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * first element.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the first key that is allocated in the table. If
+ * an (int) is stored as the first key (for example) then key_buf_p
+ * should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the first key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the first key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the first key.
+ */
+extern
+int table_first(table_t *table_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * int table_next
+ *
+ * DESCRIPTION:
+ *
+ * Find the next element in a table and pass back information about
+ * the key/data pair. If any of the key/data pointers are NULL then
+ * they are ignored.
+ *
+ * NOTE: This function is not reentrant. More than one thread cannot
+ * be doing a first and next on the same table at the same time. Use
+ * the table_next_r version below for this.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * next element.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the next key that is allocated in the table. If
+ * an (int) is stored as the next key (for example) then key_buf_p
+ * should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the next key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the next key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the next key.
+ */
+extern
+int table_next(table_t *table_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * int table_this
+ *
+ * DESCRIPTION:
+ *
+ * Find the current element in a table and pass back information about
+ * the key/data pair. If any of the key/data pointers are NULL then
+ * they are ignored.
+ *
+ * NOTE: This function is not reentrant. Use the table_current_r
+ * version below.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * current element.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the current key that is allocated in the table.
+ * If an (int) is stored as the current key (for example) then
+ * key_buf_p should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the current key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the current key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the current key.
+ */
+extern
+int table_this(table_t *table_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * int table_first_r
+ *
+ * DESCRIPTION:
+ *
+ * Reetrant version of the table_first routine above. Find first
+ * element in a table and pass back information about the key/data
+ * pair. If any of the key/data pointers are NULL then they are
+ * ignored.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * first element.
+ *
+ * linear_p - Pointer to a table linear structure which is initialized
+ * here. The same pointer should then be passed to table_next_r
+ * below.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the first key that is allocated in the table. If
+ * an (int) is stored as the first key (for example) then key_buf_p
+ * should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the first key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the first key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the first key.
+ */
+extern
+int table_first_r(table_t *table_p, table_linear_t *linear_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * int table_next_r
+ *
+ * DESCRIPTION:
+ *
+ * Reetrant version of the table_next routine above. Find next
+ * element in a table and pass back information about the key/data
+ * pair. If any of the key/data pointers are NULL then they are
+ * ignored.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * next element.
+ *
+ * linear_p - Pointer to a table linear structure which is incremented
+ * here. The same pointer must have been passed to table_first_r
+ * first so that it can be initialized.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the next key that is allocated in the table. If
+ * an (int) is stored as the next key (for example) then key_buf_p
+ * should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the next key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the next key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the next key.
+ */
+extern
+int table_next_r(table_t *table_p, table_linear_t *linear_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * int table_this_r
+ *
+ * DESCRIPTION:
+ *
+ * Reetrant version of the table_this routine above. Find current
+ * element in a table and pass back information about the key/data
+ * pair. If any of the key/data pointers are NULL then they are
+ * ignored.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * current element.
+ *
+ * linear_p - Pointer to a table linear structure which is accessed
+ * here. The same pointer must have been passed to table_first_r
+ * first so that it can be initialized.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the current key that is allocated in the table.
+ * If an (int) is stored as the current key (for example) then
+ * key_buf_p should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the current key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the current key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the current key.
+ */
+extern
+int table_this_r(table_t *table_p, table_linear_t *linear_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * table_t *table_mmap
+ *
+ * DESCRIPTION:
+ *
+ * Mmap a table from a file that had been written to disk earlier via
+ * table_write.
+ *
+ * RETURNS:
+ *
+ * A pointer to the new table structure which must be passed to
+ * table_munmap to be deallocated. On error a NULL is returned.
+ *
+ * ARGUMENTS:
+ *
+ * path - Table file to mmap in.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+extern
+table_t *table_mmap(const char *path, int *error_p);
+
+/*
+ * int table_munmap
+ *
+ * DESCRIPTION:
+ *
+ * Unmmap a table that was previously mmapped using table_mmap.
+ *
+ * RETURNS:
+ *
+ * Returns table error codes.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Mmaped table pointer to unmap.
+ */
+extern
+int table_munmap(table_t *table_p);
+
+/*
+ * int table_read
+ *
+ * DESCRIPTION:
+ *
+ * Read in a table from a file that had been written to disk earlier
+ * via table_write.
+ *
+ * RETURNS:
+ *
+ * Success - Pointer to the new table structure which must be passed
+ * to table_free to be deallocated.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * path - Table file to read in.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+extern
+table_t *table_read(const char *path, int *error_p);
+
+/*
+ * int table_write
+ *
+ * DESCRIPTION:
+ *
+ * Write a table from memory to file.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to the table that we are writing to the file.
+ *
+ * path - Table file to write out to.
+ *
+ * mode - Mode of the file. This argument is passed on to open when
+ * the file is created.
+ */
+extern
+int table_write(const table_t *table_p, const char *path, const int mode);
+
+/*
+ * table_entry_t *table_order
+ *
+ * DESCRIPTION:
+ *
+ * Order a table by building an array of table entry pointers and then
+ * sorting this array using the qsort function. To retrieve the
+ * sorted entries, you can then use the table_entry routine to access
+ * each entry in order.
+ *
+ * NOTE: This routine is thread safe and makes use of an internal
+ * status qsort function.
+ *
+ * RETURNS:
+ *
+ * Success - An allocated list of table-linear structures which must
+ * be freed by table_order_free later.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to the table that we are ordering.
+ *
+ * compare - Comparison function defined by the user. Its definition
+ * is at the top of the table.h file. If this is NULL then it will
+ * order the table my memcmp-ing the keys.
+ *
+ * num_entries_p - Pointer to an integer which, if not NULL, will
+ * contain the number of entries in the returned entry pointer array.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+extern
+table_entry_t **table_order(table_t *table_p, table_compare_t compare,
+ int *num_entries_p, int *error_p);
+
+/*
+ * int table_order_free
+ *
+ * DESCRIPTION:
+ *
+ * Free the pointer returned by the table_order or table_order_pos
+ * routines.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to the table.
+ *
+ * table_entries - Allocated list of entry pointers returned by
+ * table_order.
+ *
+ * entry_n - Number of entries in the array as passed back by
+ * table_order or table_order_pos in num_entries_p.
+ */
+extern
+int table_order_free(table_t *table_p, table_entry_t **table_entries,
+ const int entry_n);
+
+/*
+ * int table_entry
+ *
+ * DESCRIPTION:
+ *
+ * Get information about an element. The element is one from the
+ * array returned by the table_order function. If any of the key/data
+ * pointers are NULL then they are ignored.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * element.
+ *
+ * entry_p - Pointer to a table entry from the array returned by the
+ * table_order function.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of this entry that is allocated in the table. If an
+ * (int) is stored as this entry (for example) then key_buf_p should
+ * be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage of this entry that is allocated in the table.
+ * If a (long) is stored as this entry data (for example) then
+ * data_buf_p should be (long **) i.e. the address of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table.
+ */
+extern
+int table_entry(table_t *table_p, table_entry_t *entry_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * table_linear_t *table_order_pos
+ *
+ * DESCRIPTION:
+ *
+ * Order a table by building an array of table linear structures and
+ * then sorting this array using the qsort function. To retrieve the
+ * sorted entries, you can then use the table_entry_pos routine to
+ * access each entry in order.
+ *
+ * NOTE: This routine is thread safe and makes use of an internal
+ * status qsort function.
+ *
+ * RETURNS:
+ *
+ * Success - An allocated list of table-linear structures which must
+ * be freed by table_order_pos_free later.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to the table that we are ordering.
+ *
+ * compare - Comparison function defined by the user. Its definition
+ * is at the top of the table.h file. If this is NULL then it will
+ * order the table my memcmp-ing the keys.
+ *
+ * num_entries_p - Pointer to an integer which, if not NULL, will
+ * contain the number of entries in the returned entry pointer array.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+extern
+table_linear_t *table_order_pos(table_t *table_p, table_compare_t compare,
+ int *num_entries_p, int *error_p);
+
+/*
+ * int table_order_pos_free
+ *
+ * DESCRIPTION:
+ *
+ * Free the pointer returned by the table_order or table_order_pos
+ * routines.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to the table.
+ *
+ * table_entries - Allocated list of entry pointers returned by
+ * table_order_pos.
+ *
+ * entry_n - Number of entries in the array as passed back by
+ * table_order or table_order_pos in num_entries_p.
+ */
+extern
+int table_order_pos_free(table_t *table_p, table_linear_t *table_entries,
+ const int entry_n);
+
+/*
+ * int table_entry_pos
+ *
+ * DESCRIPTION:
+ *
+ * Get information about an element. The element is one from the
+ * array returned by the table_order function. If any of the key/data
+ * pointers are NULL then they are ignored.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * element.
+ *
+ * linear_p - Pointer to a table linear structure from the array
+ * returned by the table_order function.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of this entry that is allocated in the table. If an
+ * (int) is stored as this entry (for example) then key_buf_p should
+ * be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage of this entry that is allocated in the table.
+ * If a (long) is stored as this entry data (for example) then
+ * data_buf_p should be (long **) i.e. the address of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table.
+ */
+extern
+int table_entry_pos(table_t *table_p, table_linear_t *linear_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p);
+
+/*
+ * const char *table_strerror
+ *
+ * DESCRIPTION:
+ *
+ * Return the corresponding string for the error number.
+ *
+ * RETURNS:
+ *
+ * Success - String equivalient of the error.
+ *
+ * Failure - String "invalid error code"
+ *
+ * ARGUMENTS:
+ *
+ * error - Error number that we are converting.
+ */
+extern
+const char *table_strerror(const int error);
+
+/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ! __TABLE_H__ */
diff --git a/libs/libks/src/include/table_loc.h b/libs/libks/src/include/table_loc.h
new file mode 100644
index 0000000000..02514c8211
--- /dev/null
+++ b/libs/libks/src/include/table_loc.h
@@ -0,0 +1,229 @@
+/*
+ * local defines for the table module
+ *
+ * Copyright 2000 by Gray Watson.
+ *
+ * This file is part of the table package.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies,
+ * and that the name of Gray Watson not be used in advertising or
+ * publicity pertaining to distribution of the document or software
+ * without specific, written prior permission.
+ *
+ * Gray Watson makes no representations about the suitability of the
+ * software described herein for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * The author may be reached via http://256.com/gray/
+ *
+ * $Id: table_loc.h,v 1.11 2000/03/09 03:30:42 gray Exp $
+ */
+
+#ifndef __TABLE_LOC_H__
+#define __TABLE_LOC_H__
+
+#ifndef unix
+#define NO_MMAP
+#endif
+
+#ifndef BITSPERBYTE
+#define BITSPERBYTE 8
+#endif
+#ifndef BITS
+#define BITS(type) (BITSPERBYTE * (int)sizeof(type))
+#endif
+
+#define TABLE_MAGIC 0xBADF00D /* very magic magicness */
+#define LINEAR_MAGIC 0xAD00D00 /* magic value for linear struct */
+#define DEFAULT_SIZE 1024 /* default table size */
+#define MAX_ALIGNMENT 128 /* max alignment value */
+
+/*
+ * Maximum number of splits. This should mean that these routines can
+ * handle at least 2^128 different values (that's _quite_ a few). And
+ * then you can always increase the value.
+ */
+#define MAX_QSORT_SPLITS 128
+
+/*
+ * Maximum number of entries that must be in list for it to be
+ * partitioned. If there are fewer elements then just do our
+ * insertion sort.
+ */
+#define MAX_QSORT_MANY 8
+
+/*
+ * Macros.
+ */
+
+/* returns 1 when we should grow or shrink the table */
+#define SHOULD_TABLE_GROW(tab) ((tab)->ta_entry_n > (tab)->ta_bucket_n * 2)
+#define SHOULD_TABLE_SHRINK(tab) ((tab)->ta_entry_n < (tab)->ta_bucket_n / 2)
+
+/*
+ * void HASH_MIX
+ *
+ * DESCRIPTION:
+ *
+ * Mix 3 32-bit values reversibly. For every delta with one or two
+ * bits set, and the deltas of all three high bits or all three low
+ * bits, whether the original value of a,b,c is almost all zero or is
+ * uniformly distributed.
+ *
+ * If HASH_MIX() is run forward or backward, at least 32 bits in a,b,c
+ * have at least 1/4 probability of changing. If mix() is run
+ * forward, every bit of c will change between 1/3 and 2/3 of the
+ * time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
+ *
+ * HASH_MIX() takes 36 machine instructions, but only 18 cycles on a
+ * superscalar machine (like a Pentium or a Sparc). No faster mixer
+ * seems to work, that's the result of my brute-force search. There
+ * were about 2^68 hashes to choose from. I only tested about a
+ * billion of those.
+ */
+#define HASH_MIX(a, b, c) \
+ do { \
+ a -= b; a -= c; a ^= (c >> 13); \
+ b -= c; b -= a; b ^= (a << 8); \
+ c -= a; c -= b; c ^= (b >> 13); \
+ a -= b; a -= c; a ^= (c >> 12); \
+ b -= c; b -= a; b ^= (a << 16); \
+ c -= a; c -= b; c ^= (b >> 5); \
+ a -= b; a -= c; a ^= (c >> 3); \
+ b -= c; b -= a; b ^= (a << 10); \
+ c -= a; c -= b; c ^= (b >> 15); \
+ } while(0)
+
+#define SET_POINTER(pnt, val) \
+ do { \
+ if ((pnt) != NULL) { \
+ (*(pnt)) = (val); \
+ } \
+ } while(0)
+
+/*
+ * The following macros take care of the mmap case. When we are
+ * mmaping a table from a disk file, all of the pointers in the table
+ * structures are replaced with offsets into the file. The following
+ * macro, for each pointer, adds the starting address of the mmaped
+ * section onto each pointer/offset turning it back into a legitimate
+ * pointer.
+ */
+#ifdef NO_MMAP
+
+#define TABLE_POINTER(table, type, pnt) (pnt)
+
+#else
+
+#define TABLE_POINTER(tab_p, type, pnt) \
+ ((tab_p)->ta_mmap == NULL || (pnt) == NULL ? (pnt) : \
+ (type)((char *)((tab_p)->ta_mmap) + (long)(pnt)))
+
+#endif
+
+/*
+ * Macros to get at the key and the data pointers
+ */
+#define ENTRY_KEY_BUF(entry_p) ((entry_p)->te_key_buf)
+#define ENTRY_DATA_BUF(tab_p, entry_p) \
+ (ENTRY_KEY_BUF(entry_p) + (entry_p)->te_key_size)
+
+/*
+ * Table structures...
+ */
+
+/*
+ * HACK: this should be equiv as the table_entry_t without the key_buf
+ * char. We use this with the ENTRY_SIZE() macro above which solves
+ * the problem with the lack of the [0] GNU hack. We use the
+ * table_entry_t structure to better map the memory and make things
+ * faster.
+ */
+typedef struct table_shell_st {
+ unsigned int te_key_size; /* size of data */
+ unsigned int te_data_size; /* size of data */
+ struct table_shell_st *te_next_p; /* pointer to next in the list */
+ /* NOTE: this does not have the te_key_buf field here */
+} table_shell_t;
+
+/*
+ * Elements in the bucket linked-lists. The key[1] is the start of
+ * the key with the rest of the key and all of the data information
+ * packed in memory directly after the end of this structure.
+ *
+ * NOTE: if this structure is changed, the table_shell_t must be
+ * changed to match.
+ */
+typedef struct table_entry_st {
+ unsigned int te_key_size; /* size of data */
+ unsigned int te_data_size; /* size of data */
+ struct table_entry_st *te_next_p; /* pointer to next in the list */
+ unsigned char te_key_buf[1]; /* 1st byte of key buf */
+} table_entry_t;
+
+/* external structure for debuggers be able to see void */
+typedef table_entry_t table_entry_ext_t;
+
+/* main table structure */
+typedef struct table_st {
+ unsigned int ta_magic; /* magic number */
+ unsigned int ta_flags; /* table's flags defined in table.h */
+ unsigned int ta_bucket_n; /* num of buckets, should be 2^X */
+ unsigned int ta_entry_n; /* num of entries in all buckets */
+ unsigned int ta_data_align; /* data alignment value */
+ table_entry_t **ta_buckets; /* array of linked lists */
+ table_linear_t ta_linear; /* linear tracking */
+ struct table_st *ta_mmap; /* mmaped table */
+ unsigned long ta_file_size; /* size of on-disk space */
+
+ void *ta_mem_pool; /* pointer to some memory pool */
+ table_mem_alloc_t ta_alloc_func; /* memory allocation function */
+ table_mem_resize_t ta_resize_func; /* memory resize function */
+ table_mem_free_t ta_free_func; /* memory free function */
+} table_t;
+
+/* external table structure for debuggers */
+typedef table_t table_ext_t;
+
+/* local comparison functions */
+typedef int (*compare_t)(const void *element1_p, const void *element2_p,
+ table_compare_t user_compare,
+ const table_t *table_p, int *err_bp);
+
+/*
+ * to map error to string
+ */
+typedef struct {
+ int es_error; /* error number */
+ char *es_string; /* assocaited string */
+} error_str_t;
+
+static error_str_t errors[] = {
+ { TABLE_ERROR_NONE, "no error" },
+ { TABLE_ERROR_PNT, "invalid table pointer" },
+ { TABLE_ERROR_ARG_NULL, "buffer argument is null" },
+ { TABLE_ERROR_SIZE, "incorrect size argument" },
+ { TABLE_ERROR_OVERWRITE, "key exists and no overwrite" },
+ { TABLE_ERROR_NOT_FOUND, "key does not exist" },
+ { TABLE_ERROR_ALLOC, "error allocating memory" },
+ { TABLE_ERROR_LINEAR, "linear access not in progress" },
+ { TABLE_ERROR_OPEN, "could not open file" },
+ { TABLE_ERROR_SEEK, "could not seek to position in file" },
+ { TABLE_ERROR_READ, "could not read from file" },
+ { TABLE_ERROR_WRITE, "could not write to file" },
+ { TABLE_ERROR_MMAP_NONE, "no mmap support compiled in library" },
+ { TABLE_ERROR_MMAP, "could not mmap the file" },
+ { TABLE_ERROR_MMAP_OP, "operation not valid on mmap files" },
+ { TABLE_ERROR_EMPTY, "table is empty" },
+ { TABLE_ERROR_NOT_EMPTY, "table contains data" },
+ { TABLE_ERROR_ALIGNMENT, "invalid alignment value" },
+ { TABLE_ERROR_COMPARE, "problems with internal comparison" },
+ { TABLE_ERROR_FREE, "memory free error" },
+ { 0 }
+};
+
+#define INVALID_ERROR "invalid error code"
+
+#endif /* ! __TABLE_LOC_H__ */
diff --git a/libs/libks/src/ks.c b/libs/libks/src/ks.c
new file mode 100644
index 0000000000..b328f36798
--- /dev/null
+++ b/libs/libks/src/ks.c
@@ -0,0 +1,739 @@
+/*
+ * Copyright (c) 2007-2012, Anthony Minessale II
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/* Use select on windows and poll everywhere else.
+ Select is the devil. Especially if you are doing a lot of small socket connections.
+ If your FD number is bigger than 1024 you will silently create memory corruption.
+
+ If you have build errors on your platform because you don't have poll find a way to detect it and #define KS_USE_SELECT and #undef KS_USE_POLL
+ All of this will be upgraded to autoheadache eventually.
+*/
+
+/* TBD for win32 figure out how to tell if you have WSAPoll (vista or higher) and use it when available by #defining KS_USE_WSAPOLL (see below) */
+
+#ifdef _MSC_VER
+#define FD_SETSIZE 8192
+#define KS_USE_SELECT
+#else
+#define KS_USE_POLL
+#endif
+
+#include
+#ifndef WIN32
+#define closesocket(x) shutdown(x, 2); close(x)
+#include
+#include
+#else
+#pragma warning (disable:6386)
+/* These warnings need to be ignored warning in sdk header */
+#include
+#include
+#ifndef errno
+#define errno WSAGetLastError()
+#endif
+#ifndef EINTR
+#define EINTR WSAEINTR
+#endif
+#pragma warning (default:6386)
+#endif
+
+#ifdef KS_USE_POLL
+#include
+#endif
+
+#ifndef KS_MIN
+#define KS_MIN(x,y) ((x) < (y) ? (x) : (y))
+#endif
+#ifndef KS_MAX
+#define KS_MAX(x,y) ((x) > (y) ? (x) : (y))
+#endif
+#ifndef KS_CLAMP
+#define KS_CLAMP(min,max,val) (KS_MIN(max,KS_MAX(val,min)))
+#endif
+
+
+/* Written by Marc Espie, public domain */
+#define KS_CTYPE_NUM_CHARS 256
+
+const short _ks_C_toupper_[1 + KS_CTYPE_NUM_CHARS] = {
+ EOF,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+const short *_ks_toupper_tab_ = _ks_C_toupper_;
+
+KS_DECLARE(int) ks_toupper(int c)
+{
+ if ((unsigned int)c > 255)
+ return(c);
+ if (c < -1)
+ return EOF;
+ return((_ks_toupper_tab_ + 1)[c]);
+}
+
+const short _ks_C_tolower_[1 + KS_CTYPE_NUM_CHARS] = {
+ EOF,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+const short *_ks_tolower_tab_ = _ks_C_tolower_;
+
+KS_DECLARE(int) ks_tolower(int c)
+{
+ if ((unsigned int)c > 255)
+ return(c);
+ if (c < -1)
+ return EOF;
+ return((_ks_tolower_tab_ + 1)[c]);
+}
+
+KS_DECLARE(const char *)ks_stristr(const char *instr, const char *str)
+{
+/*
+** Rev History: 16/07/97 Greg Thayer Optimized
+** 07/04/95 Bob Stout ANSI-fy
+** 02/03/94 Fred Cole Original
+** 09/01/03 Bob Stout Bug fix (lines 40-41) per Fred Bulback
+**
+** Hereby donated to public domain.
+*/
+ const char *pptr, *sptr, *start;
+
+ if (!str || !instr)
+ return NULL;
+
+ for (start = str; *start; start++) {
+ /* find start of pattern in string */
+ for (; ((*start) && (ks_toupper(*start) != ks_toupper(*instr))); start++);
+
+ if (!*start)
+ return NULL;
+
+ pptr = instr;
+ sptr = start;
+
+ while (ks_toupper(*sptr) == ks_toupper(*pptr)) {
+ sptr++;
+ pptr++;
+
+ /* if end of pattern then pattern was found */
+ if (!*pptr)
+ return (start);
+
+ if (!*sptr)
+ return NULL;
+ }
+ }
+ return NULL;
+}
+
+#ifdef WIN32
+#ifndef vsnprintf
+#define vsnprintf _vsnprintf
+#endif
+#endif
+
+
+int vasprintf(char **ret, const char *format, va_list ap);
+
+KS_DECLARE(int) ks_vasprintf(char **ret, const char *fmt, va_list ap)
+{
+#if !defined(WIN32) && !defined(__sun)
+ return vasprintf(ret, fmt, ap);
+#else
+ char *buf;
+ int len;
+ size_t buflen;
+ va_list ap2;
+ char *tmp = NULL;
+
+#ifdef _MSC_VER
+#if _MSC_VER >= 1500
+ /* hack for incorrect assumption in msvc header files for code analysis */
+ __analysis_assume(tmp);
+#endif
+ ap2 = ap;
+#else
+ va_copy(ap2, ap);
+#endif
+
+ len = vsnprintf(tmp, 0, fmt, ap2);
+
+ if (len > 0 && (buf = malloc((buflen = (size_t) (len + 1)))) != NULL) {
+ len = vsnprintf(buf, buflen, fmt, ap);
+ *ret = buf;
+ } else {
+ *ret = NULL;
+ len = -1;
+ }
+
+ va_end(ap2);
+ return len;
+#endif
+}
+
+
+
+
+KS_DECLARE(int) ks_snprintf(char *buffer, size_t count, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = vsnprintf(buffer, count-1, fmt, ap);
+ if (ret < 0)
+ buffer[count-1] = '\0';
+ va_end(ap);
+ return ret;
+}
+
+static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
+{
+ if (file && func && line && level && fmt) {
+ return;
+ }
+ return;
+}
+
+
+static const char *LEVEL_NAMES[] = {
+ "EMERG",
+ "ALERT",
+ "CRIT",
+ "ERROR",
+ "WARNING",
+ "NOTICE",
+ "INFO",
+ "DEBUG",
+ NULL
+};
+
+static int ks_log_level = 7;
+
+static const char *cut_path(const char *in)
+{
+ const char *p, *ret = in;
+ char delims[] = "/\\";
+ char *i;
+
+ for (i = delims; *i; i++) {
+ p = in;
+ while ((p = strchr(p, *i)) != 0) {
+ ret = ++p;
+ }
+ }
+ return ret;
+}
+
+
+static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
+{
+ const char *fp;
+ char *data;
+ va_list ap;
+ int ret;
+
+ if (level < 0 || level > 7) {
+ level = 7;
+ }
+ if (level > ks_log_level) {
+ return;
+ }
+
+ fp = cut_path(file);
+
+ va_start(ap, fmt);
+
+ ret = ks_vasprintf(&data, fmt, ap);
+
+ if (ret != -1) {
+ fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data);
+ free(data);
+ }
+
+ va_end(ap);
+
+}
+
+ks_logger_t ks_log = null_logger;
+
+KS_DECLARE(void) ks_global_set_logger(ks_logger_t logger)
+{
+ if (logger) {
+ ks_log = logger;
+ } else {
+ ks_log = null_logger;
+ }
+}
+
+KS_DECLARE(void) ks_global_set_default_logger(int level)
+{
+ if (level < 0 || level > 7) {
+ level = 7;
+ }
+
+ ks_log = default_logger;
+ ks_log_level = level;
+}
+
+KS_DECLARE(size_t) ks_url_encode(const char *url, char *buf, size_t len)
+{
+ const char *p;
+ size_t x = 0;
+ const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}";
+ const char hex[] = "0123456789ABCDEF";
+
+ if (!buf) {
+ return 0;
+ }
+
+ if (!url) {
+ return 0;
+ }
+
+ len--;
+
+ for (p = url; *p; p++) {
+ if (x >= len) {
+ break;
+ }
+ if (*p < ' ' || *p > '~' || strchr(urlunsafe, *p)) {
+ if ((x + 3) >= len) {
+ break;
+ }
+ buf[x++] = '%';
+ buf[x++] = hex[*p >> 4];
+ buf[x++] = hex[*p & 0x0f];
+ } else {
+ buf[x++] = *p;
+ }
+ }
+ buf[x] = '\0';
+
+ return x;
+}
+
+KS_DECLARE(char *)ks_url_decode(char *s)
+{
+ char *o;
+ unsigned int tmp;
+
+ for (o = s; *s; s++, o++) {
+ if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
+ *o = (char) tmp;
+ s += 2;
+ } else {
+ *o = *s;
+ }
+ }
+ *o = '\0';
+ return s;
+}
+
+
+static int ks_socket_reuseaddr(ks_socket_t socket)
+{
+#ifdef WIN32
+ BOOL reuse_addr = TRUE;
+ return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse_addr, sizeof(reuse_addr));
+#else
+ int reuse_addr = 1;
+ return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
+#endif
+}
+
+
+struct thread_handler {
+ ks_listen_callback_t callback;
+ ks_socket_t server_sock;
+ ks_socket_t client_sock;
+ struct sockaddr_in addr;
+};
+
+static void *client_thread(ks_thread_t *me, void *obj)
+{
+ struct thread_handler *handler = (struct thread_handler *) obj;
+
+ handler->callback(handler->server_sock, handler->client_sock, &handler->addr);
+ free(handler);
+
+ return NULL;
+
+}
+
+KS_DECLARE(ks_status_t) ks_listen(const char *host, ks_port_t port, ks_listen_callback_t callback)
+{
+ ks_socket_t server_sock = KS_SOCK_INVALID;
+ struct sockaddr_in addr;
+ ks_status_t status = KS_SUCCESS;
+
+ if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ return KS_FAIL;
+ }
+
+ ks_socket_reuseaddr(server_sock);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(port);
+
+ if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ status = KS_FAIL;
+ goto end;
+ }
+
+ if (listen(server_sock, 10000) < 0) {
+ status = KS_FAIL;
+ goto end;
+ }
+
+ for (;;) {
+ int client_sock;
+ struct sockaddr_in echoClntAddr;
+#ifdef WIN32
+ int clntLen;
+#else
+ unsigned int clntLen;
+#endif
+
+ clntLen = sizeof(echoClntAddr);
+
+ if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == KS_SOCK_INVALID) {
+ status = KS_FAIL;
+ goto end;
+ }
+
+ callback(server_sock, client_sock, &echoClntAddr);
+ }
+
+ end:
+
+ if (server_sock != KS_SOCK_INVALID) {
+ closesocket(server_sock);
+ server_sock = KS_SOCK_INVALID;
+ }
+
+ return status;
+
+}
+
+KS_DECLARE(ks_status_t) ks_listen_threaded(const char *host, ks_port_t port, ks_listen_callback_t callback, int max)
+{
+ ks_socket_t server_sock = KS_SOCK_INVALID;
+ struct sockaddr_in addr;
+ ks_status_t status = KS_SUCCESS;
+ struct thread_handler *handler = NULL;
+
+ if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ return KS_FAIL;
+ }
+
+ ks_socket_reuseaddr(server_sock);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(port);
+
+ if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ status = KS_FAIL;
+ goto end;
+ }
+
+ if (listen(server_sock, max) < 0) {
+ status = KS_FAIL;
+ goto end;
+ }
+
+ for (;;) {
+ int client_sock;
+ struct sockaddr_in echoClntAddr;
+#ifdef WIN32
+ int clntLen;
+#else
+ unsigned int clntLen;
+#endif
+
+ clntLen = sizeof(echoClntAddr);
+
+ if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == KS_SOCK_INVALID) {
+ status = KS_FAIL;
+ goto end;
+ }
+
+ handler = malloc(sizeof(*handler));
+ ks_assert(handler);
+
+ memset(handler, 0, sizeof(*handler));
+ handler->callback = callback;
+ handler->server_sock = server_sock;
+ handler->client_sock = client_sock;
+ handler->addr = echoClntAddr;
+
+ ks_thread_create_detached(client_thread, handler);
+ }
+
+ end:
+
+ if (server_sock != KS_SOCK_INVALID) {
+ closesocket(server_sock);
+ server_sock = KS_SOCK_INVALID;
+ }
+
+ return status;
+
+}
+
+
+/* USE WSAPoll on vista or higher */
+#ifdef KS_USE_WSAPOLL
+KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags)
+{
+}
+#endif
+
+
+#ifdef KS_USE_SELECT
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 6262 ) /* warning C6262: Function uses '98348' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap */
+#endif
+KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags)
+{
+ int s = 0, r = 0;
+ fd_set rfds;
+ fd_set wfds;
+ fd_set efds;
+ struct timeval tv;
+
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ FD_ZERO(&efds);
+
+#ifndef WIN32
+ /* Wouldn't you rather know?? */
+ assert(sock <= FD_SETSIZE);
+#endif
+
+ if ((flags & KS_POLL_READ)) {
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4127 )
+ FD_SET(sock, &rfds);
+#pragma warning( pop )
+#else
+ FD_SET(sock, &rfds);
+#endif
+ }
+
+ if ((flags & KS_POLL_WRITE)) {
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4127 )
+ FD_SET(sock, &wfds);
+#pragma warning( pop )
+#else
+ FD_SET(sock, &wfds);
+#endif
+ }
+
+ if ((flags & KS_POLL_ERROR)) {
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4127 )
+ FD_SET(sock, &efds);
+#pragma warning( pop )
+#else
+ FD_SET(sock, &efds);
+#endif
+ }
+
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = (ms % 1000) * ms;
+
+ s = select(sock + 1, (flags & KS_POLL_READ) ? &rfds : NULL, (flags & KS_POLL_WRITE) ? &wfds : NULL, (flags & KS_POLL_ERROR) ? &efds : NULL, &tv);
+
+ if (s < 0) {
+ r = s;
+ } else if (s > 0) {
+ if ((flags & KS_POLL_READ) && FD_ISSET(sock, &rfds)) {
+ r |= KS_POLL_READ;
+ }
+
+ if ((flags & KS_POLL_WRITE) && FD_ISSET(sock, &wfds)) {
+ r |= KS_POLL_WRITE;
+ }
+
+ if ((flags & KS_POLL_ERROR) && FD_ISSET(sock, &efds)) {
+ r |= KS_POLL_ERROR;
+ }
+ }
+
+ return r;
+
+}
+#ifdef WIN32
+#pragma warning( pop )
+#endif
+#endif
+
+#ifdef KS_USE_POLL
+KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags)
+{
+ struct pollfd pfds[2] = { { 0 } };
+ int s = 0, r = 0;
+
+ pfds[0].fd = sock;
+
+ if ((flags & KS_POLL_READ)) {
+ pfds[0].events |= POLLIN;
+ }
+
+ if ((flags & KS_POLL_WRITE)) {
+ pfds[0].events |= POLLOUT;
+ }
+
+ if ((flags & KS_POLL_ERROR)) {
+ pfds[0].events |= POLLERR;
+ }
+
+ s = poll(pfds, 1, ms);
+
+ if (s < 0) {
+ r = s;
+ } else if (s > 0) {
+ if ((pfds[0].revents & POLLIN)) {
+ r |= KS_POLL_READ;
+ }
+ if ((pfds[0].revents & POLLOUT)) {
+ r |= KS_POLL_WRITE;
+ }
+ if ((pfds[0].revents & POLLERR)) {
+ r |= KS_POLL_ERROR;
+ }
+ }
+
+ return r;
+
+}
+#endif
+
+
+KS_DECLARE(unsigned int) ks_separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen)
+{
+ unsigned int count = 0;
+ char *d;
+ size_t dlen = strlen(delim);
+
+ array[count++] = buf;
+
+ while (count < arraylen && array[count - 1]) {
+ if ((d = strstr(array[count - 1], delim))) {
+ *d = '\0';
+ d += dlen;
+ array[count++] = d;
+ } else
+ break;
+ }
+
+ return count;
+}
+
diff --git a/libs/libks/src/ks_buffer.c b/libs/libks/src/ks_buffer.c
new file mode 100644
index 0000000000..469296a3a9
--- /dev/null
+++ b/libs/libks/src/ks_buffer.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2010-2012, Anthony Minessale II
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "ks_buffer.h"
+
+static unsigned buffer_id = 0;
+
+struct ks_buffer {
+ unsigned char *data;
+ unsigned char *head;
+ ks_size_t used;
+ ks_size_t actually_used;
+ ks_size_t datalen;
+ ks_size_t max_len;
+ ks_size_t blocksize;
+ unsigned id;
+ int loops;
+};
+
+
+KS_DECLARE(ks_status_t) ks_buffer_create(ks_buffer_t **buffer, ks_size_t blocksize, ks_size_t start_len, ks_size_t max_len)
+{
+ ks_buffer_t *new_buffer;
+
+ new_buffer = malloc(sizeof(*new_buffer));
+ if (new_buffer) {
+ memset(new_buffer, 0, sizeof(*new_buffer));
+
+ if (start_len) {
+ new_buffer->data = malloc(start_len);
+ if (!new_buffer->data) {
+ free(new_buffer);
+ return KS_FAIL;
+ }
+ memset(new_buffer->data, 0, start_len);
+ }
+
+ new_buffer->max_len = max_len;
+ new_buffer->datalen = start_len;
+ new_buffer->id = buffer_id++;
+ new_buffer->blocksize = blocksize;
+ new_buffer->head = new_buffer->data;
+
+ *buffer = new_buffer;
+ return KS_SUCCESS;
+ }
+
+ return KS_FAIL;
+}
+
+KS_DECLARE(ks_size_t) ks_buffer_len(ks_buffer_t *buffer)
+{
+
+ ks_assert(buffer != NULL);
+
+ return buffer->datalen;
+
+}
+
+
+KS_DECLARE(ks_size_t) ks_buffer_freespace(ks_buffer_t *buffer)
+{
+ ks_assert(buffer != NULL);
+
+ if (buffer->max_len) {
+ return (ks_size_t) (buffer->max_len - buffer->used);
+ }
+ return 1000000;
+
+}
+
+KS_DECLARE(ks_size_t) ks_buffer_inuse(ks_buffer_t *buffer)
+{
+ ks_assert(buffer != NULL);
+
+ return buffer->used;
+}
+
+KS_DECLARE(ks_size_t) ks_buffer_seek(ks_buffer_t *buffer, ks_size_t datalen)
+{
+ ks_size_t reading = 0;
+
+ ks_assert(buffer != NULL);
+
+ if (buffer->used < 1) {
+ buffer->used = 0;
+ return 0;
+ } else if (buffer->used >= datalen) {
+ reading = datalen;
+ } else {
+ reading = buffer->used;
+ }
+
+ buffer->used = buffer->actually_used - reading;
+ buffer->head = buffer->data + reading;
+
+ return reading;
+}
+
+KS_DECLARE(ks_size_t) ks_buffer_toss(ks_buffer_t *buffer, ks_size_t datalen)
+{
+ ks_size_t reading = 0;
+
+ ks_assert(buffer != NULL);
+
+ if (buffer->used < 1) {
+ buffer->used = 0;
+ return 0;
+ } else if (buffer->used >= datalen) {
+ reading = datalen;
+ } else {
+ reading = buffer->used;
+ }
+
+ buffer->used -= reading;
+ buffer->head += reading;
+
+ return buffer->used;
+}
+
+KS_DECLARE(void) ks_buffer_set_loops(ks_buffer_t *buffer, int loops)
+{
+ buffer->loops = loops;
+}
+
+KS_DECLARE(ks_size_t) ks_buffer_read_loop(ks_buffer_t *buffer, void *data, ks_size_t datalen)
+{
+ ks_size_t len;
+ if ((len = ks_buffer_read(buffer, data, datalen)) < datalen) {
+ if (buffer->loops == 0) {
+ return len;
+ }
+ buffer->head = buffer->data;
+ buffer->used = buffer->actually_used;
+ len = ks_buffer_read(buffer, (char*)data + len, datalen - len);
+ buffer->loops--;
+ }
+ return len;
+}
+
+KS_DECLARE(ks_size_t) ks_buffer_read(ks_buffer_t *buffer, void *data, ks_size_t datalen)
+{
+ ks_size_t reading = 0;
+
+ ks_assert(buffer != NULL);
+ ks_assert(data != NULL);
+
+
+ if (buffer->used < 1) {
+ buffer->used = 0;
+ return 0;
+ } else if (buffer->used >= datalen) {
+ reading = datalen;
+ } else {
+ reading = buffer->used;
+ }
+
+ memcpy(data, buffer->head, reading);
+ buffer->used -= reading;
+ buffer->head += reading;
+
+ /* if (buffer->id == 4) printf("%u o %d = %d\n", buffer->id, (unsigned)reading, (unsigned)buffer->used); */
+ return reading;
+}
+
+
+KS_DECLARE(ks_size_t) ks_buffer_packet_count(ks_buffer_t *buffer)
+{
+ char *pe, *p, *e, *head = (char *) buffer->head;
+ ks_size_t x = 0;
+
+ ks_assert(buffer != NULL);
+
+ e = (head + buffer->used);
+
+ for (p = head; p && *p && p < e; p++) {
+ if (*p == '\n') {
+ pe = p+1;
+ if (*pe == '\r') pe++;
+ if (pe <= e && *pe == '\n') {
+ p = pe++;
+ x++;
+ }
+ }
+ }
+
+ return x;
+}
+
+KS_DECLARE(ks_size_t) ks_buffer_read_packet(ks_buffer_t *buffer, void *data, ks_size_t maxlen)
+{
+ char *pe, *p, *e, *head = (char *) buffer->head;
+ ks_size_t datalen = 0;
+
+ ks_assert(buffer != NULL);
+ ks_assert(data != NULL);
+
+ e = (head + buffer->used);
+
+ for (p = head; p && *p && p < e; p++) {
+ if (*p == '\n') {
+ pe = p+1;
+ if (*pe == '\r') pe++;
+ if (pe <= e && *pe == '\n') {
+ pe++;
+ datalen = pe - head;
+ if (datalen > maxlen) {
+ datalen = maxlen;
+ }
+ break;
+ }
+ }
+ }
+
+ return ks_buffer_read(buffer, data, datalen);
+}
+
+KS_DECLARE(ks_size_t) ks_buffer_write(ks_buffer_t *buffer, const void *data, ks_size_t datalen)
+{
+ ks_size_t freespace, actual_freespace;
+
+ ks_assert(buffer != NULL);
+ ks_assert(data != NULL);
+ ks_assert(buffer->data != NULL);
+
+ if (!datalen) {
+ return buffer->used;
+ }
+
+ actual_freespace = buffer->datalen - buffer->actually_used;
+ if (actual_freespace < datalen && (!buffer->max_len || (buffer->used + datalen <= buffer->max_len))) {
+ memmove(buffer->data, buffer->head, buffer->used);
+ buffer->head = buffer->data;
+ buffer->actually_used = buffer->used;
+ }
+
+ freespace = buffer->datalen - buffer->used;
+
+ /*
+ if (buffer->data != buffer->head) {
+ memmove(buffer->data, buffer->head, buffer->used);
+ buffer->head = buffer->data;
+ }
+ */
+
+ if (freespace < datalen) {
+ ks_size_t new_size, new_block_size;
+ void *data1;
+
+ new_size = buffer->datalen + datalen;
+ new_block_size = buffer->datalen + buffer->blocksize;
+
+ if (new_block_size > new_size) {
+ new_size = new_block_size;
+ }
+ buffer->head = buffer->data;
+ data1 = realloc(buffer->data, new_size);
+ if (!data1) {
+ return 0;
+ }
+ buffer->data = data1;
+ buffer->head = buffer->data;
+ buffer->datalen = new_size;
+ }
+
+
+ freespace = buffer->datalen - buffer->used;
+
+ if (freespace < datalen) {
+ return 0;
+ } else {
+ memcpy(buffer->head + buffer->used, data, datalen);
+ buffer->used += datalen;
+ buffer->actually_used += datalen;
+ }
+ /* if (buffer->id == 4) printf("%u i %d = %d\n", buffer->id, (unsigned)datalen, (unsigned)buffer->used); */
+
+ return buffer->used;
+}
+
+KS_DECLARE(void) ks_buffer_zero(ks_buffer_t *buffer)
+{
+ ks_assert(buffer != NULL);
+ ks_assert(buffer->data != NULL);
+
+ buffer->used = 0;
+ buffer->actually_used = 0;
+ buffer->head = buffer->data;
+}
+
+KS_DECLARE(ks_size_t) ks_buffer_zwrite(ks_buffer_t *buffer, const void *data, ks_size_t datalen)
+{
+ ks_size_t w;
+
+ if (!(w = ks_buffer_write(buffer, data, datalen))) {
+ ks_buffer_zero(buffer);
+ return ks_buffer_write(buffer, data, datalen);
+ }
+
+ return w;
+}
+
+KS_DECLARE(void) ks_buffer_destroy(ks_buffer_t **buffer)
+{
+ if (*buffer) {
+ free((*buffer)->data);
+ free(*buffer);
+ }
+
+ *buffer = NULL;
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/libs/libks/src/ks_config.c b/libs/libks/src/ks_config.c
new file mode 100644
index 0000000000..efe410ce2c
--- /dev/null
+++ b/libs/libks/src/ks_config.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2007-2012, Anthony Minessale II
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ks.h"
+#include "ks_config.h"
+
+KS_DECLARE(int) ks_config_open_file(ks_config_t *cfg, const char *file_path)
+{
+ FILE *f;
+ const char *path = NULL;
+ char path_buf[1024];
+
+ if (file_path[0] == '/') {
+ path = file_path;
+ } else {
+ ks_snprintf(path_buf, sizeof(path_buf), "%s%s%s", KS_CONFIG_DIR, KS_PATH_SEPARATOR, file_path);
+ path = path_buf;
+ }
+
+ if (!path) {
+ return 0;
+ }
+
+ memset(cfg, 0, sizeof(*cfg));
+ cfg->lockto = -1;
+ ks_log(KS_LOG_DEBUG, "Configuration file is %s.\n", path);
+ f = fopen(path, "r");
+
+ if (!f) {
+ if (file_path[0] != '/') {
+ int last = -1;
+ char *var, *val;
+
+ ks_snprintf(path_buf, sizeof(path_buf), "%s%sopenks.conf", KS_CONFIG_DIR, KS_PATH_SEPARATOR);
+ path = path_buf;
+
+ if ((f = fopen(path, "r")) == 0) {
+ return 0;
+ }
+
+ cfg->file = f;
+ ks_set_string(cfg->path, path);
+
+ while (ks_config_next_pair(cfg, &var, &val)) {
+ if ((cfg->sectno != last) && !strcmp(cfg->section, file_path)) {
+ cfg->lockto = cfg->sectno;
+ return 1;
+ }
+ }
+
+ ks_config_close_file(cfg);
+ memset(cfg, 0, sizeof(*cfg));
+ return 0;
+ }
+
+ return 0;
+ } else {
+ cfg->file = f;
+ ks_set_string(cfg->path, path);
+ return 1;
+ }
+}
+
+KS_DECLARE(void) ks_config_close_file(ks_config_t *cfg)
+{
+
+ if (cfg->file) {
+ fclose(cfg->file);
+ }
+
+ memset(cfg, 0, sizeof(*cfg));
+}
+
+
+
+KS_DECLARE(int) ks_config_next_pair(ks_config_t *cfg, char **var, char **val)
+{
+ int ret = 0;
+ char *p, *end;
+
+ *var = *val = NULL;
+
+ if (!cfg || !cfg->file) {
+ return 0;
+ }
+
+ for (;;) {
+ cfg->lineno++;
+
+ if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) {
+ ret = 0;
+ break;
+ }
+ *var = cfg->buf;
+
+ if (**var == '[' && (end = strchr(*var, ']')) != 0) {
+ *end = '\0';
+ (*var)++;
+ if (**var == '+') {
+ (*var)++;
+ ks_copy_string(cfg->section, *var, sizeof(cfg->section));
+ cfg->sectno++;
+
+ if (cfg->lockto > -1 && cfg->sectno != cfg->lockto) {
+ break;
+ }
+ cfg->catno = 0;
+ cfg->lineno = 0;
+ *var = (char *) "";
+ *val = (char *) "";
+ return 1;
+ } else {
+ ks_copy_string(cfg->category, *var, sizeof(cfg->category));
+ cfg->catno++;
+ }
+ continue;
+ }
+
+
+
+ if (**var == '#' || **var == ';' || **var == '\n' || **var == '\r') {
+ continue;
+ }
+
+ if (!strncmp(*var, "__END__", 7)) {
+ break;
+ }
+
+
+ if ((end = strchr(*var, ';')) && *(end+1) == *end) {
+ *end = '\0';
+ end--;
+ } else if ((end = strchr(*var, '\n')) != 0) {
+ if (*(end - 1) == '\r') {
+ end--;
+ }
+ *end = '\0';
+ }
+
+ p = *var;
+ while ((*p == ' ' || *p == '\t') && p != end) {
+ *p = '\0';
+ p++;
+ }
+ *var = p;
+
+
+ if ((*val = strchr(*var, '=')) == 0) {
+ ret = -1;
+ /* log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); */
+ continue;
+ } else {
+ p = *val - 1;
+ *(*val) = '\0';
+ (*val)++;
+ if (*(*val) == '>') {
+ *(*val) = '\0';
+ (*val)++;
+ }
+
+ while ((*p == ' ' || *p == '\t') && p != *var) {
+ *p = '\0';
+ p--;
+ }
+
+ p = *val;
+ while ((*p == ' ' || *p == '\t') && p != end) {
+ *p = '\0';
+ p++;
+ }
+ *val = p;
+ ret = 1;
+ break;
+ }
+ }
+
+
+ return ret;
+
+}
+
+KS_DECLARE(int) ks_config_get_cas_bits(char *strvalue, unsigned char *outbits)
+{
+ char cas_bits[5];
+ unsigned char bit = 0x8;
+ char *double_colon = strchr(strvalue, ':');
+ int x = 0;
+
+ if (!double_colon) {
+ ks_log(KS_LOG_ERROR, "No CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", double_colon);
+ return -1;
+ }
+
+ double_colon++;
+ *outbits = 0;
+ cas_bits[4] = 0;
+
+ if (sscanf(double_colon, "%c%c%c%c", &cas_bits[0], &cas_bits[1], &cas_bits[2], &cas_bits[3]) != 4) {
+ ks_log(KS_LOG_ERROR, "Invalid CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", double_colon);
+ return -1;
+ }
+
+ ks_log(KS_LOG_DEBUG, "CAS bits specification found: %s\n", cas_bits);
+
+ for (; cas_bits[x]; x++) {
+ if ('1' == cas_bits[x]) {
+ *outbits |= bit;
+ } else if ('0' != cas_bits[x]) {
+ ks_log(KS_LOG_ERROR, "Invalid CAS pattern specified: %s, just 0 or 1 allowed for each bit\n");
+ return -1;
+ }
+ bit >>= 1;
+ }
+ return 0;
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/libs/libks/src/ks_json.c b/libs/libks/src/ks_json.c
new file mode 100644
index 0000000000..ffa965a609
--- /dev/null
+++ b/libs/libks/src/ks_json.c
@@ -0,0 +1,529 @@
+/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+/* cJSON */
+/* JSON parser in C. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "ks_json.h"
+#include "ks.h"
+
+static const char *ep;
+
+KS_DECLARE(const char *)cJSON_GetErrorPtr() {return ep;}
+
+static int cJSON_strcasecmp(const char *s1,const char *s2)
+{
+ if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
+ for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
+ return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
+}
+
+static void *glue_malloc(size_t theSize)
+{
+ return(malloc(theSize));
+}
+
+static void glue_free(void *thePtr)
+{
+ free(thePtr);
+}
+
+static void *(*cJSON_malloc)(size_t sz) = glue_malloc;
+static void (*cJSON_free)(void *ptr) = glue_free;
+
+static char* cJSON_strdup(const char* str)
+{
+ size_t len;
+ char* copy;
+ const char *s = str ? str : "";
+
+ len = strlen(s) + 1;
+ if (!(copy = (char*)cJSON_malloc(len))) return 0;
+ memcpy(copy,s,len);
+ return copy;
+}
+
+KS_DECLARE(void)cJSON_InitHooks(cJSON_Hooks* hooks)
+{
+ if (!hooks) { /* Reset hooks */
+ cJSON_malloc = malloc;
+ cJSON_free = free;
+ return;
+ }
+
+ cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
+ cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
+}
+
+/* Internal constructor. */
+static cJSON *cJSON_New_Item()
+{
+ cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
+ if (node) memset(node,0,sizeof(cJSON));
+ return node;
+}
+
+/* Delete a cJSON structure. */
+KS_DECLARE(void)cJSON_Delete(cJSON *c)
+{
+ cJSON *next;
+ while (c)
+ {
+ next=c->next;
+ if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
+ if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
+ if (c->string) cJSON_free(c->string);
+ cJSON_free(c);
+ c=next;
+ }
+}
+
+/* Parse the input text to generate a number, and populate the result into item. */
+static const char *parse_number(cJSON *item,const char *num)
+{
+ double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
+
+ /* Could use sscanf for this? */
+ if (*num=='-') sign=-1,num++; /* Has sign? */
+ if (*num=='0') num++; /* is zero */
+ if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
+ if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
+ if (*num=='e' || *num=='E') /* Exponent? */
+ { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
+ while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
+ }
+
+ n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
+
+ item->valuedouble=n;
+ item->valueint=(int)n;
+ item->type=cJSON_Number;
+ return num;
+}
+
+/* Render the number nicely from the given item into a string. */
+static char *print_number(cJSON *item)
+{
+ char *str;
+ double d=item->valuedouble;
+ if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
+ {
+ str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
+ if (str) sprintf(str,"%d",item->valueint);
+ }
+ else
+ {
+ str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
+ if (str)
+ {
+ if (fabs(floor(d)-d)<=DBL_EPSILON) sprintf(str,"%.0f",d);
+ else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
+ else sprintf(str,"%f",d);
+ }
+ }
+ return str;
+}
+
+/* Parse the input text into an unescaped cstring, and populate item. */
+static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+static const char *parse_string(cJSON *item,const char *str)
+{
+ const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
+ if (*str!='\"') {ep=str;return 0;} /* not a string! */
+
+ while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
+
+ out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
+ if (!out) return 0;
+
+ ptr=str+1;ptr2=out;
+ while (*ptr!='\"' && *ptr)
+ {
+ if (*ptr!='\\') *ptr2++=*ptr++;
+ else
+ {
+ ptr++;
+ switch (*ptr)
+ {
+ case 'b': *ptr2++='\b'; break;
+ case 'f': *ptr2++='\f'; break;
+ case 'n': *ptr2++='\n'; break;
+ case 'r': *ptr2++='\r'; break;
+ case 't': *ptr2++='\t'; break;
+ case 'u': /* transcode utf16 to utf8. */
+ if (sscanf(ptr+1,"%4x",&uc) < 1) break;
+
+ ptr+=4; /* get the unicode char. */
+
+ if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; // check for invalid.
+
+ if (uc>=0xD800 && uc<=0xDBFF) // UTF16 surrogate pairs.
+ {
+ if (ptr[1]!='\\' || ptr[2]!='u') break; // missing second-half of surrogate.
+ if (sscanf(ptr+3,"%4x",&uc2) < 1) break;
+ ptr+=6;
+ if (uc2<0xDC00 || uc2>0xDFFF) break; // invalid second-half of surrogate.
+ uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF);
+ }
+
+ len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
+
+ switch (len) {
+ case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 1: *--ptr2 =(char)(uc | firstByteMark[len]);
+ }
+ ptr2+=len;
+ break;
+ default: *ptr2++=*ptr; break;
+ }
+ ptr++;
+ }
+ }
+ *ptr2=0;
+ if (*ptr=='\"') ptr++;
+ item->valuestring=out;
+ item->type=cJSON_String;
+ return ptr;
+}
+
+/* Render the cstring provided to an escaped version that can be printed. */
+static char *print_string_ptr(const char *str)
+{
+ const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
+
+ if (!str) return cJSON_strdup("");
+ ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
+
+ out=(char*)cJSON_malloc(len+3);
+ if (!out) return 0;
+
+ ptr2=out;ptr=str;
+ *ptr2++='\"';
+ while (*ptr)
+ {
+ if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
+ else
+ {
+ *ptr2++='\\';
+ switch (token=*ptr++)
+ {
+ case '\\': *ptr2++='\\'; break;
+ case '\"': *ptr2++='\"'; break;
+ case '\b': *ptr2++='b'; break;
+ case '\f': *ptr2++='f'; break;
+ case '\n': *ptr2++='n'; break;
+ case '\r': *ptr2++='r'; break;
+ case '\t': *ptr2++='t'; break;
+ default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
+ }
+ }
+ }
+ *ptr2++='\"';*ptr2++=0;
+ return out;
+}
+/* Invote print_string_ptr (which is useful) on an item. */
+static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
+
+/* Predeclare these prototypes. */
+static const char *parse_value(cJSON *item,const char *value);
+static char *print_value(cJSON *item,int depth,int fmt);
+static const char *parse_array(cJSON *item,const char *value);
+static char *print_array(cJSON *item,int depth,int fmt);
+static const char *parse_object(cJSON *item,const char *value);
+static char *print_object(cJSON *item,int depth,int fmt);
+
+/* Utility to jump whitespace and cr/lf */
+static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
+
+/* Parse an object - create a new root, and populate. */
+KS_DECLARE(cJSON *)cJSON_Parse(const char *value)
+{
+ cJSON *c=cJSON_New_Item();
+ ep=0;
+ if (!c) return 0; /* memory fail */
+
+ if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;}
+ return c;
+}
+
+/* Render a cJSON item/entity/structure to text. */
+KS_DECLARE(char *) cJSON_Print(cJSON *item) {return print_value(item,0,1);}
+KS_DECLARE(char *) cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
+
+/* Parser core - when encountering text, process appropriately. */
+static const char *parse_value(cJSON *item,const char *value)
+{
+ if (!value) return 0; /* Fail on null. */
+ if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
+ if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
+ if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
+ if (*value=='\"') { return parse_string(item,value); }
+ if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
+ if (*value=='[') { return parse_array(item,value); }
+ if (*value=='{') { return parse_object(item,value); }
+
+ ep=value;return 0; /* failure. */
+}
+
+/* Render a value to text. */
+static char *print_value(cJSON *item,int depth,int fmt)
+{
+ char *out=0;
+ if (!item) return 0;
+ switch ((item->type)&255)
+ {
+ case cJSON_NULL: out=cJSON_strdup("null"); break;
+ case cJSON_False: out=cJSON_strdup("false");break;
+ case cJSON_True: out=cJSON_strdup("true"); break;
+ case cJSON_Number: out=print_number(item);break;
+ case cJSON_String: out=print_string(item);break;
+ case cJSON_Array: out=print_array(item,depth,fmt);break;
+ case cJSON_Object: out=print_object(item,depth,fmt);break;
+ }
+ return out;
+}
+
+/* Build an array from input text. */
+static const char *parse_array(cJSON *item,const char *value)
+{
+ cJSON *child;
+ if (*value!='[') {ep=value;return 0;} /* not an array! */
+
+ item->type=cJSON_Array;
+ value=skip(value+1);
+ if (*value==']') return value+1; /* empty array. */
+
+ item->child=child=cJSON_New_Item();
+ if (!item->child) return 0; /* memory fail */
+ value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+
+ while (*value==',')
+ {
+ cJSON *new_item;
+ if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
+ child->next=new_item;new_item->prev=child;child=new_item;
+ value=skip(parse_value(child,skip(value+1)));
+ if (!value) return 0; /* memory fail */
+ }
+
+ if (*value==']') return value+1; /* end of array */
+ ep=value;return 0; /* malformed. */
+}
+
+/* Render an array to text */
+static char *print_array(cJSON *item,int depth,int fmt)
+{
+ char **entries;
+ char *out=0,*ptr,*ret;int len=5;
+ cJSON *child=item->child;
+ int numentries=0,i=0,fail=0;
+
+ /* How many entries in the array? */
+ while (child) numentries++,child=child->next;
+ /* Allocate an array to hold the values for each */
+ entries=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!entries) return 0;
+ memset(entries,0,numentries*sizeof(char*));
+ /* Retrieve all the results: */
+ child=item->child;
+ while (child && !fail)
+ {
+ ret=print_value(child,depth+1,fmt);
+ entries[i++]=ret;
+ if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
+ child=child->next;
+ }
+
+ /* If we didn't fail, try to malloc the output string */
+ if (!fail) out=(char*)cJSON_malloc(len);
+ /* If that fails, we fail. */
+ if (!out) fail=1;
+
+ /* Handle failure. */
+ if (fail)
+ {
+ for (i=0;itype=cJSON_Object;
+ value=skip(value+1);
+ if (*value=='}') return value+1; /* empty array. */
+
+ item->child=child=cJSON_New_Item();
+ if (!item->child) return 0;
+ value=skip(parse_string(child,skip(value)));
+ if (!value) return 0;
+ child->string=child->valuestring;child->valuestring=0;
+ if (*value!=':') {ep=value;return 0;} /* fail! */
+ value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+
+ while (*value==',')
+ {
+ cJSON *new_item;
+ if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
+ child->next=new_item;new_item->prev=child;child=new_item;
+ value=skip(parse_string(child,skip(value+1)));
+ if (!value) return 0;
+ child->string=child->valuestring;child->valuestring=0;
+ if (*value!=':') {ep=value;return 0;} /* fail! */
+ value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+ }
+
+ if (*value=='}') return value+1; /* end of array */
+ ep=value;return 0; /* malformed. */
+}
+
+/* Render an object to text. */
+static char *print_object(cJSON *item,int depth,int fmt)
+{
+ char **entries=0,**names=0;
+ char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
+ cJSON *child=item->child;
+ int numentries=0,fail=0;
+ /* Count the number of entries. */
+ while (child) numentries++,child=child->next;
+ /* Allocate space for the names and the objects */
+ entries=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!entries) return 0;
+ names=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!names) {cJSON_free(entries);return 0;}
+ memset(entries,0,sizeof(char*)*numentries);
+ memset(names,0,sizeof(char*)*numentries);
+
+ /* Collect all the results into our arrays: */
+ child=item->child;depth++;if (fmt) len+=depth;
+ while (child)
+ {
+ names[i]=str=print_string_ptr(child->string);
+ entries[i++]=ret=print_value(child,depth,fmt);
+ if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
+ child=child->next;
+ }
+
+ /* Try to allocate the output string */
+ if (!fail) out=(char*)cJSON_malloc(len);
+ if (!out) fail=1;
+
+ /* Handle failure */
+ if (fail)
+ {
+ for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;}
+KS_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
+KS_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
+
+/* Utility for array list handling. */
+static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
+/* Utility for handling references. */
+static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
+
+/* Add item to array/object. */
+KS_DECLARE(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
+KS_DECLARE(void) cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
+KS_DECLARE(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
+KS_DECLARE(void) cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
+
+KS_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
+ if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
+KS_DECLARE(void) cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
+KS_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
+KS_DECLARE(void) cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
+
+/* Replace array/object items with new ones. */
+KS_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
+ newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
+ if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
+KS_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
+
+/* Create basic types: */
+KS_DECLARE(cJSON *)cJSON_CreateNull() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
+KS_DECLARE(cJSON *)cJSON_CreateTrue() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
+KS_DECLARE(cJSON *)cJSON_CreateFalse() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
+KS_DECLARE(cJSON *)cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
+KS_DECLARE(cJSON *)cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
+KS_DECLARE(cJSON *)cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
+KS_DECLARE(cJSON *)cJSON_CreateArray() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
+KS_DECLARE(cJSON *)cJSON_CreateObject() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
+
+/* Create Arrays: */
+KS_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && ichild=n;else suffix_object(p,n);p=n;}return a;}
+KS_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && ichild=n;else suffix_object(p,n);p=n;}return a;}
+KS_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && ichild=n;else suffix_object(p,n);p=n;}return a;}
+KS_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && ichild=n;else suffix_object(p,n);p=n;}return a;}
diff --git a/libs/libks/src/ks_threadmutex.c b/libs/libks/src/ks_threadmutex.c
new file mode 100644
index 0000000000..a23c02f762
--- /dev/null
+++ b/libs/libks/src/ks_threadmutex.c
@@ -0,0 +1,239 @@
+/*
+ * Cross Platform Thread/Mutex abstraction
+ * Copyright(C) 2007 Michael Jerris
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so.
+ *
+ * This work is provided under this license on an "as is" basis, without warranty of any kind,
+ * either expressed or implied, including, without limitation, warranties that the covered code
+ * is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire
+ * risk as to the quality and performance of the covered code is with you. Should any covered
+ * code prove defective in any respect, you (not the initial developer or any other contributor)
+ * assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty
+ * constitutes an essential part of this license. No use of any covered code is authorized hereunder
+ * except under this disclaimer.
+ *
+ */
+
+#ifdef WIN32
+/* required for TryEnterCriticalSection definition. Must be defined before windows.h include */
+#define _WIN32_WINNT 0x0400
+#endif
+
+#include "ks.h"
+#include "ks_threadmutex.h"
+
+#ifdef WIN32
+#include
+
+#define KS_THREAD_CALLING_CONVENTION __stdcall
+
+struct ks_mutex {
+ CRITICAL_SECTION mutex;
+};
+
+#else
+
+#include
+
+#define KS_THREAD_CALLING_CONVENTION
+
+struct ks_mutex {
+ pthread_mutex_t mutex;
+};
+
+#endif
+
+struct ks_thread {
+#ifdef WIN32
+ void *handle;
+#else
+ pthread_t handle;
+#endif
+ void *private_data;
+ ks_thread_function_t function;
+ size_t stack_size;
+#ifndef WIN32
+ pthread_attr_t attribute;
+#endif
+};
+
+size_t thread_default_stacksize = 240 * 1024;
+
+void ks_thread_override_default_stacksize(size_t size)
+{
+ thread_default_stacksize = size;
+}
+
+static void * KS_THREAD_CALLING_CONVENTION thread_launch(void *args)
+{
+ void *exit_val;
+ ks_thread_t *thread = (ks_thread_t *)args;
+ exit_val = thread->function(thread, thread->private_data);
+#ifndef WIN32
+ pthread_attr_destroy(&thread->attribute);
+#endif
+ free(thread);
+
+ return exit_val;
+}
+
+KS_DECLARE(ks_status_t) ks_thread_create_detached(ks_thread_function_t func, void *data)
+{
+ return ks_thread_create_detached_ex(func, data, thread_default_stacksize);
+}
+
+ks_status_t ks_thread_create_detached_ex(ks_thread_function_t func, void *data, size_t stack_size)
+{
+ ks_thread_t *thread = NULL;
+ ks_status_t status = KS_FAIL;
+
+ if (!func || !(thread = (ks_thread_t *)malloc(sizeof(ks_thread_t)))) {
+ goto done;
+ }
+
+ thread->private_data = data;
+ thread->function = func;
+ thread->stack_size = stack_size;
+
+#if defined(WIN32)
+ thread->handle = (void *)_beginthreadex(NULL, (unsigned)thread->stack_size, (unsigned int (__stdcall *)(void *))thread_launch, thread, 0, NULL);
+ if (!thread->handle) {
+ goto fail;
+ }
+ CloseHandle(thread->handle);
+
+ status = KS_SUCCESS;
+ goto done;
+#else
+
+ if (pthread_attr_init(&thread->attribute) != 0) goto fail;
+
+ if (pthread_attr_setdetachstate(&thread->attribute, PTHREAD_CREATE_DETACHED) != 0) goto failpthread;
+
+ if (thread->stack_size && pthread_attr_setstacksize(&thread->attribute, thread->stack_size) != 0) goto failpthread;
+
+ if (pthread_create(&thread->handle, &thread->attribute, thread_launch, thread) != 0) goto failpthread;
+
+ status = KS_SUCCESS;
+ goto done;
+
+ failpthread:
+
+ pthread_attr_destroy(&thread->attribute);
+#endif
+
+ fail:
+ if (thread) {
+ free(thread);
+ }
+ done:
+ return status;
+}
+
+
+KS_DECLARE(ks_status_t) ks_mutex_create(ks_mutex_t **mutex)
+{
+ ks_status_t status = KS_FAIL;
+#ifndef WIN32
+ pthread_mutexattr_t attr;
+#endif
+ ks_mutex_t *check = NULL;
+
+ check = (ks_mutex_t *)malloc(sizeof(**mutex));
+ if (!check)
+ goto done;
+#ifdef WIN32
+ InitializeCriticalSection(&check->mutex);
+#else
+ if (pthread_mutexattr_init(&attr))
+ goto done;
+
+ if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))
+ goto fail;
+
+ if (pthread_mutex_init(&check->mutex, &attr))
+ goto fail;
+
+ goto success;
+
+ fail:
+ pthread_mutexattr_destroy(&attr);
+ goto done;
+
+ success:
+#endif
+ *mutex = check;
+ status = KS_SUCCESS;
+
+ done:
+ return status;
+}
+
+KS_DECLARE(ks_status_t) ks_mutex_destroy(ks_mutex_t **mutex)
+{
+ ks_mutex_t *mp = *mutex;
+ *mutex = NULL;
+ if (!mp) {
+ return KS_FAIL;
+ }
+#ifdef WIN32
+ DeleteCriticalSection(&mp->mutex);
+#else
+ if (pthread_mutex_destroy(&mp->mutex))
+ return KS_FAIL;
+#endif
+ free(mp);
+ return KS_SUCCESS;
+}
+
+KS_DECLARE(ks_status_t) ks_mutex_lock(ks_mutex_t *mutex)
+{
+#ifdef WIN32
+ EnterCriticalSection(&mutex->mutex);
+#else
+ if (pthread_mutex_lock(&mutex->mutex))
+ return KS_FAIL;
+#endif
+ return KS_SUCCESS;
+}
+
+KS_DECLARE(ks_status_t) ks_mutex_trylock(ks_mutex_t *mutex)
+{
+#ifdef WIN32
+ if (!TryEnterCriticalSection(&mutex->mutex))
+ return KS_FAIL;
+#else
+ if (pthread_mutex_trylock(&mutex->mutex))
+ return KS_FAIL;
+#endif
+ return KS_SUCCESS;
+}
+
+KS_DECLARE(ks_status_t) ks_mutex_unlock(ks_mutex_t *mutex)
+{
+#ifdef WIN32
+ LeaveCriticalSection(&mutex->mutex);
+#else
+ if (pthread_mutex_unlock(&mutex->mutex))
+ return KS_FAIL;
+#endif
+ return KS_SUCCESS;
+}
+
+
+
+
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/libs/libks/src/mpool.c b/libs/libks/src/mpool.c
new file mode 100644
index 0000000000..72c5b6b108
--- /dev/null
+++ b/libs/libks/src/mpool.c
@@ -0,0 +1,1768 @@
+/*
+ * Memory pool routines.
+ *
+ * Copyright 1996 by Gray Watson.
+ *
+ * This file is part of the mpool package.
+ *
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies, and that the name of Gray Watson not be used in advertising
+ * or publicity pertaining to distribution of the document or software
+ * without specific, written prior permission.
+ *
+ * Gray Watson makes no representations about the suitability of the
+ * software described herein for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * The author may be reached via http://256.com/gray/
+ *
+ * $Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $
+ */
+
+/*
+ * Memory-pool allocation routines. I got sick of the GNU mmalloc
+ * library which was close to what we needed but did not exactly do
+ * what I wanted.
+ *
+ * The following uses mmap from /dev/zero. It allows a number of
+ * allocations to be made inside of a memory pool then with a clear or
+ * close the pool can be reset without any memory fragmentation and
+ * growth problems.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+#define MPOOL_MAIN
+
+#include "mpool.h"
+#include "mpool_loc.h"
+
+#ifdef __GNUC__
+#ident "$Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $"
+#else
+static char *rcs_id = "$Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $";
+#endif
+
+/* version */
+static char *version = "mpool library version 2.1.0";
+
+/* local variables */
+static int enabled_b = 0; /* lib initialized? */
+static unsigned int min_bit_free_next = 0; /* min size of next pnt */
+static unsigned int min_bit_free_size = 0; /* min size of next + size */
+static unsigned long bit_array[MAX_BITS + 1]; /* size -> bit */
+
+/****************************** local utilities ******************************/
+
+/*
+ * static void startup
+ *
+ * DESCRIPTION:
+ *
+ * Perform any library level initialization.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * None.
+ */
+static void startup(void)
+{
+ int bit_c;
+ unsigned long size = 1;
+
+ if (enabled_b) {
+ return;
+ }
+
+ /* allocate our free bit array list */
+ for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) {
+ bit_array[bit_c] = size;
+
+ /*
+ * Note our minimum number of bits that can store a pointer. This
+ * is smallest address that we can have a linked list for.
+ */
+ if (min_bit_free_next == 0 && size >= sizeof(void *)) {
+ min_bit_free_next = bit_c;
+ }
+ /*
+ * Note our minimum number of bits that can store a pointer and
+ * the size of the block.
+ */
+ if (min_bit_free_size == 0 && size >= sizeof(mpool_free_t)) {
+ min_bit_free_size = bit_c;
+ }
+
+ size *= 2;
+ }
+
+ enabled_b = 1;
+}
+
+/*
+ * static int size_to_bits
+ *
+ * DESCRIPTION:
+ *
+ * Calculate the number of bits in a size.
+ *
+ * RETURNS:
+ *
+ * Number of bits.
+ *
+ * ARGUMENTS:
+ *
+ * size -> Size of memory of which to calculate the number of bits.
+ */
+static int size_to_bits(const unsigned long size)
+{
+ int bit_c = 0;
+
+ for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) {
+ if (size <= bit_array[bit_c]) {
+ break;
+ }
+ }
+
+ return bit_c;
+}
+
+/*
+ * static int size_to_free_bits
+ *
+ * DESCRIPTION:
+ *
+ * Calculate the number of bits in a size going on the free list.
+ *
+ * RETURNS:
+ *
+ * Number of bits.
+ *
+ * ARGUMENTS:
+ *
+ * size -> Size of memory of which to calculate the number of bits.
+ */
+static int size_to_free_bits(const unsigned long size)
+{
+ int bit_c = 0;
+
+ if (size == 0) {
+ return 0;
+ }
+
+ for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) {
+ if (size < bit_array[bit_c]) {
+ break;
+ }
+ }
+
+ return bit_c - 1;
+}
+
+/*
+ * static int bits_to_size
+ *
+ * DESCRIPTION:
+ *
+ * Calculate the size represented by a number of bits.
+ *
+ * RETURNS:
+ *
+ * Number of bits.
+ *
+ * ARGUMENTS:
+ *
+ * bit_n -> Number of bits
+ */
+static unsigned long bits_to_size(const int bit_n)
+{
+ if (bit_n > MAX_BITS) {
+ return bit_array[MAX_BITS];
+ }
+ else {
+ return bit_array[bit_n];
+ }
+}
+
+/*
+ * static void *alloc_pages
+ *
+ * DESCRIPTION:
+ *
+ * Allocate space for a number of memory pages in the memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - New pages of memory
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to our memory pool.
+ *
+ * page_n -> Number of pages to alloc.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+static void *alloc_pages(mpool_t *mp_p, const unsigned int page_n,
+ int *error_p)
+{
+ void *mem, *fill_mem;
+ unsigned long size, fill;
+ int state;
+
+ /* are we over our max-pages? */
+ if (mp_p->mp_max_pages > 0 && mp_p->mp_page_c >= mp_p->mp_max_pages) {
+ SET_POINTER(error_p, MPOOL_ERROR_NO_PAGES);
+ return NULL;
+ }
+
+ size = SIZE_OF_PAGES(mp_p, page_n);
+
+#ifdef DEBUG
+ (void)printf("allocating %u pages or %lu bytes\n", page_n, size);
+#endif
+
+ if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) {
+ mem = sbrk(size);
+ if (mem == (void *)-1) {
+ SET_POINTER(error_p, MPOOL_ERROR_NO_MEM);
+ return NULL;
+ }
+ fill = (unsigned long)mem % mp_p->mp_page_size;
+
+ if (fill > 0) {
+ fill = mp_p->mp_page_size - fill;
+ fill_mem = sbrk(fill);
+ if (fill_mem == (void *)-1) {
+ SET_POINTER(error_p, MPOOL_ERROR_NO_MEM);
+ return NULL;
+ }
+ if ((char *)fill_mem != (char *)mem + size) {
+ SET_POINTER(error_p, MPOOL_ERROR_SBRK_CONTIG);
+ return NULL;
+ }
+ mem = (char *)mem + fill;
+ }
+ }
+ else {
+ state = MAP_PRIVATE;
+#ifdef MAP_FILE
+ state |= MAP_FILE;
+#endif
+#ifdef MAP_VARIABLE
+ state |= MAP_VARIABLE;
+#endif
+
+ /* mmap from /dev/zero */
+ mem = mmap((caddr_t)mp_p->mp_addr, size, PROT_READ | PROT_WRITE, state,
+ mp_p->mp_fd, mp_p->mp_top);
+ if (mem == (void *)MAP_FAILED) {
+ if (errno == ENOMEM) {
+ SET_POINTER(error_p, MPOOL_ERROR_NO_MEM);
+ }
+ else {
+ SET_POINTER(error_p, MPOOL_ERROR_MMAP);
+ }
+ return NULL;
+ }
+ mp_p->mp_top += size;
+ if (mp_p->mp_addr != NULL) {
+ mp_p->mp_addr = (char *)mp_p->mp_addr + size;
+ }
+ }
+
+ mp_p->mp_page_c += page_n;
+
+ SET_POINTER(error_p, MPOOL_ERROR_NONE);
+ return mem;
+}
+
+/*
+ * static int free_pages
+ *
+ * DESCRIPTION:
+ *
+ * Free previously allocated pages of memory.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * pages <-> Pointer to memory pages that we are freeing.
+ *
+ * size -> Size of the block that we are freeing.
+ *
+ * sbrk_b -> Set to one if the pages were allocated with sbrk else mmap.
+ */
+static int free_pages(void *pages, const unsigned long size,
+ const int sbrk_b)
+{
+ if (! sbrk_b) {
+ (void)munmap((caddr_t)pages, size);
+ }
+
+ return MPOOL_ERROR_NONE;
+}
+
+/*
+ * static int check_magic
+ *
+ * DESCRIPTION:
+ *
+ * Check for the existance of the magic ID in a memory pointer.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * addr -> Address inside of the block that we are tryign to locate.
+ *
+ * size -> Size of the block.
+ */
+static int check_magic(const void *addr, const unsigned long size)
+{
+ const unsigned char *mem_p;
+
+ /* set our starting point */
+ mem_p = (unsigned char *)addr + size;
+
+ if (*mem_p == FENCE_MAGIC0 && *(mem_p + 1) == FENCE_MAGIC1) {
+ return MPOOL_ERROR_NONE;
+ }
+ else {
+ return MPOOL_ERROR_PNT_OVER;
+ }
+}
+
+/*
+ * static void write_magic
+ *
+ * DESCRIPTION:
+ *
+ * Write the magic ID to the address.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * addr -> Address where to write the magic.
+ */
+static void write_magic(const void *addr)
+{
+ *(unsigned char *)addr = FENCE_MAGIC0;
+ *((unsigned char *)addr + 1) = FENCE_MAGIC1;
+}
+
+/*
+ * static void free_pointer
+ *
+ * DESCRIPTION:
+ *
+ * Moved a pointer into our free lists.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool.
+ *
+ * addr <-> Address where to write the magic. We may write a next
+ * pointer to it.
+ *
+ * size -> Size of the address space.
+ */
+static int free_pointer(mpool_t *mp_p, void *addr,
+ const unsigned long size)
+{
+ unsigned int bit_n;
+ unsigned long real_size;
+ mpool_free_t free_pnt;
+
+#ifdef DEBUG
+ (void)printf("freeing a block at %lx of %lu bytes\n", (long)addr, size);
+#endif
+
+ if (size == 0) {
+ return MPOOL_ERROR_NONE;
+ }
+
+ /*
+ * if the user size is larger then can fit in an entire block then
+ * we change the size
+ */
+ if (size > MAX_BLOCK_USER_MEMORY(mp_p)) {
+ real_size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, size)) -
+ sizeof(mpool_block_t);
+ }
+ else {
+ real_size = size;
+ }
+
+ /*
+ * We use a specific free bits calculation here because if we are
+ * freeing 10 bytes then we will be putting it into the 8-byte free
+ * list and not the 16 byte list. size_to_bits(10) will return 4
+ * instead of 3.
+ */
+ bit_n = size_to_free_bits(real_size);
+
+ /*
+ * Minimal error checking. We could go all the way through the
+ * list however this might be prohibitive.
+ */
+ if (mp_p->mp_free[bit_n] == addr) {
+ return MPOOL_ERROR_IS_FREE;
+ }
+
+ /* add the freed pointer to the free list */
+ if (bit_n < min_bit_free_next) {
+ /*
+ * Yes we know this will lose 99% of the allocations but what else
+ * can we do? No space for a next pointer.
+ */
+ if (mp_p->mp_free[bit_n] == NULL) {
+ mp_p->mp_free[bit_n] = addr;
+ }
+ }
+ else if (bit_n < min_bit_free_size) {
+ /* we copy, not assign, to maintain the free list */
+ memcpy(addr, mp_p->mp_free + bit_n, sizeof(void *));
+ mp_p->mp_free[bit_n] = addr;
+ }
+ else {
+
+ /* setup our free list structure */
+ free_pnt.mf_next_p = mp_p->mp_free[bit_n];
+ free_pnt.mf_size = real_size;
+
+ /* we copy the structure in since we don't know about alignment */
+ memcpy(addr, &free_pnt, sizeof(free_pnt));
+ mp_p->mp_free[bit_n] = addr;
+ }
+
+ return MPOOL_ERROR_NONE;
+}
+
+/*
+ * static int split_block
+ *
+ * DESCRIPTION:
+ *
+ * When freeing space in a multi-block chunk we have to create new
+ * blocks out of the upper areas being freed.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool.
+ *
+ * free_addr -> Address that we are freeing.
+ *
+ * size -> Size of the space that we are taking from address.
+ */
+static int split_block(mpool_t *mp_p, void *free_addr,
+ const unsigned long size)
+{
+ mpool_block_t *block_p, *new_block_p;
+ int ret, page_n;
+ void *end_p;
+
+ /*
+ * 1st we find the block pointer from our free addr. At this point
+ * the pointer must be the 1st one in the block if it is spans
+ * multiple blocks.
+ */
+ block_p = (mpool_block_t *)((char *)free_addr - sizeof(mpool_block_t));
+ if (block_p->mb_magic != BLOCK_MAGIC
+ || block_p->mb_magic2 != BLOCK_MAGIC) {
+ return MPOOL_ERROR_POOL_OVER;
+ }
+
+ page_n = PAGES_IN_SIZE(mp_p, size);
+
+ /* we are creating a new block structure for the 2nd ... */
+ new_block_p = (mpool_block_t *)((char *)block_p +
+ SIZE_OF_PAGES(mp_p, page_n));
+ new_block_p->mb_magic = BLOCK_MAGIC;
+ /* New bounds is 1st block bounds. The 1st block's is reset below. */
+ new_block_p->mb_bounds_p = block_p->mb_bounds_p;
+ /* Continue the linked list. The 1st block will point to us below. */
+ new_block_p->mb_next_p = block_p->mb_next_p;
+ new_block_p->mb_magic2 = BLOCK_MAGIC;
+
+ /* bounds for the 1st block are reset to the 1st page only */
+ block_p->mb_bounds_p = (char *)new_block_p;
+ /* the next block pointer for the 1st block is now the new one */
+ block_p->mb_next_p = new_block_p;
+
+ /* only free the space in the 1st block if it is only 1 block in size */
+ if (page_n == 1) {
+ /* now free the rest of the 1st block block */
+ end_p = (char *)free_addr + size;
+ ret = free_pointer(mp_p, end_p,
+ (char *)block_p->mb_bounds_p - (char *)end_p);
+ if (ret != MPOOL_ERROR_NONE) {
+ return ret;
+ }
+ }
+
+ /* now free the rest of the block */
+ ret = free_pointer(mp_p, FIRST_ADDR_IN_BLOCK(new_block_p),
+ MEMORY_IN_BLOCK(new_block_p));
+ if (ret != MPOOL_ERROR_NONE) {
+ return ret;
+ }
+
+ return MPOOL_ERROR_NONE;
+}
+
+/*
+ * static void *get_space
+ *
+ * DESCRIPTION:
+ *
+ * Moved a pointer into our free lists.
+ *
+ * RETURNS:
+ *
+ * Success - New address that we can use.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool.
+ *
+ * byte_size -> Size of the address space that we need.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+static void *get_space(mpool_t *mp_p, const unsigned long byte_size,
+ int *error_p)
+{
+ mpool_block_t *block_p;
+ mpool_free_t free_pnt;
+ int ret;
+ unsigned long size;
+ unsigned int bit_c, page_n, left;
+ void *free_addr = NULL, *free_end;
+
+ size = byte_size;
+ while ((size & (sizeof(void *) - 1)) > 0) {
+ size++;
+ }
+
+ /*
+ * First we check the free lists looking for something with enough
+ * pages. Maybe we should only look X bits higher in the list.
+ *
+ * XXX: this is where we'd do the best fit. We'd look for the
+ * closest match. We then could put the rest of the allocation that
+ * we did not use in a lower free list. Have a define which states
+ * how deep in the free list to go to find the closest match.
+ */
+ for (bit_c = size_to_bits(size); bit_c <= MAX_BITS; bit_c++) {
+ if (mp_p->mp_free[bit_c] != NULL) {
+ free_addr = mp_p->mp_free[bit_c];
+ break;
+ }
+ }
+
+ /*
+ * If we haven't allocated any blocks or if the last block doesn't
+ * have enough memory then we need a new block.
+ */
+ if (bit_c > MAX_BITS) {
+
+ /* we need to allocate more space */
+
+ page_n = PAGES_IN_SIZE(mp_p, size);
+
+ /* now we try and get the pages we need/want */
+ block_p = alloc_pages(mp_p, page_n, error_p);
+ if (block_p == NULL) {
+ /* error_p set in alloc_pages */
+ return NULL;
+ }
+
+ /* init the block header */
+ block_p->mb_magic = BLOCK_MAGIC;
+ block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(mp_p, page_n);
+ block_p->mb_next_p = mp_p->mp_first_p;
+ block_p->mb_magic2 = BLOCK_MAGIC;
+
+ /*
+ * We insert it into the front of the queue. We could add it to
+ * the end but there is not much use.
+ */
+ mp_p->mp_first_p = block_p;
+ if (mp_p->mp_last_p == NULL) {
+ mp_p->mp_last_p = block_p;
+ }
+
+ free_addr = FIRST_ADDR_IN_BLOCK(block_p);
+
+#ifdef DEBUG
+ (void)printf("had to allocate space for %lx of %lu bytes\n",
+ (long)free_addr, size);
+#endif
+
+ free_end = (char *)free_addr + size;
+ left = (char *)block_p->mb_bounds_p - (char *)free_end;
+ }
+ else {
+
+ if (bit_c < min_bit_free_next) {
+ mp_p->mp_free[bit_c] = NULL;
+ /* calculate the number of left over bytes */
+ left = bits_to_size(bit_c) - size;
+ }
+ else if (bit_c < min_bit_free_next) {
+ /* grab the next pointer from the freed address into our list */
+ memcpy(mp_p->mp_free + bit_c, free_addr, sizeof(void *));
+ /* calculate the number of left over bytes */
+ left = bits_to_size(bit_c) - size;
+ }
+ else {
+ /* grab the free structure from the address */
+ memcpy(&free_pnt, free_addr, sizeof(free_pnt));
+ mp_p->mp_free[bit_c] = free_pnt.mf_next_p;
+
+ /* are we are splitting up a multiblock chunk into fewer blocks? */
+ if (PAGES_IN_SIZE(mp_p, free_pnt.mf_size) > PAGES_IN_SIZE(mp_p, size)) {
+ ret = split_block(mp_p, free_addr, size);
+ if (ret != MPOOL_ERROR_NONE) {
+ SET_POINTER(error_p, ret);
+ return NULL;
+ }
+ /* left over memory was taken care of in split_block */
+ left = 0;
+ }
+ else {
+ /* calculate the number of left over bytes */
+ left = free_pnt.mf_size - size;
+ }
+ }
+
+#ifdef DEBUG
+ (void)printf("found a free block at %lx of %lu bytes\n",
+ (long)free_addr, left + size);
+#endif
+
+ free_end = (char *)free_addr + size;
+ }
+
+ /*
+ * If we have memory left over then we free it so someone else can
+ * use it. We do not free the space if we just allocated a
+ * multi-block chunk because we need to have every allocation easily
+ * find the start of the block. Every user address % page-size
+ * should take us to the start of the block.
+ */
+ if (left > 0 && size <= MAX_BLOCK_USER_MEMORY(mp_p)) {
+ /* free the rest of the block */
+ ret = free_pointer(mp_p, free_end, left);
+ if (ret != MPOOL_ERROR_NONE) {
+ SET_POINTER(error_p, ret);
+ return NULL;
+ }
+ }
+
+ /* update our bounds */
+ if (free_addr > mp_p->mp_bounds_p) {
+ mp_p->mp_bounds_p = free_addr;
+ }
+ else if (free_addr < mp_p->mp_min_p) {
+ mp_p->mp_min_p = free_addr;
+ }
+
+ return free_addr;
+}
+
+/*
+ * static void *alloc_mem
+ *
+ * DESCRIPTION:
+ *
+ * Allocate space for bytes inside of an already open memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - Pointer to the address to use.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool. If NULL then it will do a
+ * normal malloc.
+ *
+ * byte_size -> Number of bytes to allocate in the pool. Must be >0.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+static void *alloc_mem(mpool_t *mp_p, const unsigned long byte_size,
+ int *error_p)
+{
+ unsigned long size, fence;
+ void *addr;
+
+ /* make sure we have enough bytes */
+ if (byte_size < MIN_ALLOCATION) {
+ size = MIN_ALLOCATION;
+ }
+ else {
+ size = byte_size;
+ }
+
+ if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) {
+ fence = 0;
+ }
+ else {
+ fence = FENCE_SIZE;
+ }
+
+ /* get our free space + the space for the fence post */
+ addr = get_space(mp_p, size + fence, error_p);
+ if (addr == NULL) {
+ /* error_p set in get_space */
+ return NULL;
+ }
+
+ if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) {
+ write_magic((char *)addr + size);
+ }
+
+ /* maintain our stats */
+ mp_p->mp_alloc_c++;
+ mp_p->mp_user_alloc += size;
+ if (mp_p->mp_user_alloc > mp_p->mp_max_alloc) {
+ mp_p->mp_max_alloc = mp_p->mp_user_alloc;
+ }
+
+ SET_POINTER(error_p, MPOOL_ERROR_NONE);
+ return addr;
+}
+
+/*
+ * static int free_mem
+ *
+ * DESCRIPTION:
+ *
+ * Free an address from a memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool. If NULL then it will do a
+ * normal free.
+ *
+ * addr <-> Address to free.
+ *
+ * size -> Size of the address being freed.
+ */
+static int free_mem(mpool_t *mp_p, void *addr, const unsigned long size)
+{
+ unsigned long old_size, fence;
+ int ret;
+ mpool_block_t *block_p;
+
+ /*
+ * If the size is larger than a block then the allocation must be at
+ * the front of the block.
+ */
+ if (size > MAX_BLOCK_USER_MEMORY(mp_p)) {
+ block_p = (mpool_block_t *)((char *)addr - sizeof(mpool_block_t));
+ if (block_p->mb_magic != BLOCK_MAGIC
+ || block_p->mb_magic2 != BLOCK_MAGIC) {
+ return MPOOL_ERROR_POOL_OVER;
+ }
+ }
+
+ /* make sure we have enough bytes */
+ if (size < MIN_ALLOCATION) {
+ old_size = MIN_ALLOCATION;
+ }
+ else {
+ old_size = size;
+ }
+
+ /* if we are packing the pool smaller */
+ if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) {
+ fence = 0;
+ }
+ else {
+ /* find the user's magic numbers if they were written */
+ ret = check_magic(addr, old_size);
+ if (ret != MPOOL_ERROR_NONE) {
+ return ret;
+ }
+ fence = FENCE_SIZE;
+ }
+
+ /* now we free the pointer */
+ ret = free_pointer(mp_p, addr, old_size + fence);
+ if (ret != MPOOL_ERROR_NONE) {
+ return ret;
+ }
+ mp_p->mp_user_alloc -= old_size;
+
+ /* adjust our stats */
+ mp_p->mp_alloc_c--;
+
+ return MPOOL_ERROR_NONE;
+}
+
+/***************************** exported routines *****************************/
+
+/*
+ * mpool_t *mpool_open
+ *
+ * DESCRIPTION:
+ *
+ * Open/allocate a new memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - Pool pointer which must be passed to mpool_close to
+ * deallocate.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * flags -> Flags to set attributes of the memory pool. See the top
+ * of mpool.h.
+ *
+ * page_size -> Set the internal memory page-size. This must be a
+ * multiple of the getpagesize() value. Set to 0 for the default.
+ *
+ * start_addr -> Starting address to try and allocate memory pools.
+ * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size,
+ void *start_addr, int *error_p)
+{
+ mpool_block_t *block_p;
+ int page_n, ret;
+ mpool_t mp, *mp_p;
+ void *free_addr;
+
+ if (! enabled_b) {
+ startup();
+ }
+
+ /* zero our temp struct */
+ memset(&mp, 0, sizeof(mp));
+
+ mp.mp_magic = MPOOL_MAGIC;
+ mp.mp_flags = flags;
+ mp.mp_alloc_c = 0;
+ mp.mp_user_alloc = 0;
+ mp.mp_max_alloc = 0;
+ mp.mp_page_c = 0;
+ /* mp.mp_page_size set below */
+ /* mp.mp_blocks_bit_n set below */
+ /* mp.mp_fd set below */
+ /* mp.mp_top set below */
+ /* mp.mp_addr set below */
+ mp.mp_log_func = NULL;
+ mp.mp_min_p = NULL;
+ mp.mp_bounds_p = NULL;
+ mp.mp_first_p = NULL;
+ mp.mp_last_p = NULL;
+ mp.mp_magic2 = MPOOL_MAGIC;
+
+ /* get and sanity check our page size */
+ if (page_size > 0) {
+ mp.mp_page_size = page_size;
+ if (mp.mp_page_size % getpagesize() != 0) {
+ SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID);
+ return NULL;
+ }
+ }
+ else {
+ mp.mp_page_size = getpagesize() * DEFAULT_PAGE_MULT;
+ if (mp.mp_page_size % 1024 != 0) {
+ SET_POINTER(error_p, MPOOL_ERROR_PAGE_SIZE);
+ return NULL;
+ }
+ }
+
+ if (BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)) {
+ mp.mp_fd = -1;
+ mp.mp_addr = NULL;
+ mp.mp_top = 0;
+ }
+ else {
+ /* open dev-zero for our mmaping */
+ mp.mp_fd = open("/dev/zero", O_RDWR, 0);
+ if (mp.mp_fd < 0) {
+ SET_POINTER(error_p, MPOOL_ERROR_OPEN_ZERO);
+ return NULL;
+ }
+ mp.mp_addr = start_addr;
+ /* we start at the front of the file */
+ mp.mp_top = 0;
+ }
+
+ /*
+ * Find out how many pages we need for our mpool structure.
+ *
+ * NOTE: this adds possibly unneeded space for mpool_block_t which
+ * may not be in this block.
+ */
+ page_n = PAGES_IN_SIZE(&mp, sizeof(mpool_t));
+
+ /* now allocate us space for the actual struct */
+ mp_p = alloc_pages(&mp, page_n, error_p);
+ if (mp_p == NULL) {
+ if (mp.mp_fd >= 0) {
+ (void)close(mp.mp_fd);
+ mp.mp_fd = -1;
+ }
+ return NULL;
+ }
+
+ /*
+ * NOTE: we do not normally free the rest of the block here because
+ * we want to lesson the chance of an allocation overwriting the
+ * main structure.
+ */
+ if (BIT_IS_SET(flags, MPOOL_FLAG_HEAVY_PACKING)) {
+
+ /* we add a block header to the front of the block */
+ block_p = (mpool_block_t *)mp_p;
+
+ /* init the block header */
+ block_p->mb_magic = BLOCK_MAGIC;
+ block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(&mp, page_n);
+ block_p->mb_next_p = NULL;
+ block_p->mb_magic2 = BLOCK_MAGIC;
+
+ /* the mpool pointer is then the 2nd thing in the block */
+ mp_p = FIRST_ADDR_IN_BLOCK(block_p);
+ free_addr = (char *)mp_p + sizeof(mpool_t);
+
+ /* free the rest of the block */
+ ret = free_pointer(&mp, free_addr,
+ (char *)block_p->mb_bounds_p - (char *)free_addr);
+ if (ret != MPOOL_ERROR_NONE) {
+ if (mp.mp_fd >= 0) {
+ (void)close(mp.mp_fd);
+ mp.mp_fd = -1;
+ }
+ /* NOTE: after this line mp_p will be invalid */
+ (void)free_pages(block_p, SIZE_OF_PAGES(&mp, page_n),
+ BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK));
+ SET_POINTER(error_p, ret);
+ return NULL;
+ }
+
+ /*
+ * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool
+ * header is not on the block linked list.
+ */
+
+ /* now copy our tmp structure into our new memory area */
+ memcpy(mp_p, &mp, sizeof(mpool_t));
+
+ /* we setup min/max to our current address which is as good as any */
+ mp_p->mp_min_p = block_p;
+ mp_p->mp_bounds_p = block_p->mb_bounds_p;
+ }
+ else {
+ /* now copy our tmp structure into our new memory area */
+ memcpy(mp_p, &mp, sizeof(mpool_t));
+
+ /* we setup min/max to our current address which is as good as any */
+ mp_p->mp_min_p = mp_p;
+ mp_p->mp_bounds_p = (char *)mp_p + SIZE_OF_PAGES(mp_p, page_n);
+ }
+
+ SET_POINTER(error_p, MPOOL_ERROR_NONE);
+ return mp_p;
+}
+
+/*
+ * int mpool_close
+ *
+ * DESCRIPTION:
+ *
+ * Close/free a memory allocation pool previously opened with
+ * mpool_open.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to our memory pool.
+ */
+int mpool_close(mpool_t *mp_p)
+{
+ mpool_block_t *block_p, *next_p;
+ void *addr;
+ unsigned long size;
+ int ret, final = MPOOL_ERROR_NONE;
+
+ /* special case, just return no-error */
+ if (mp_p == NULL) {
+ return MPOOL_ERROR_ARG_NULL;
+ }
+ if (mp_p->mp_magic != MPOOL_MAGIC) {
+ return MPOOL_ERROR_PNT;
+ }
+ if (mp_p->mp_magic2 != MPOOL_MAGIC) {
+ return MPOOL_ERROR_POOL_OVER;
+ }
+
+ if (mp_p->mp_log_func != NULL) {
+ mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLOSE, 0, 0, NULL, NULL, 0);
+ }
+
+ /*
+ * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool
+ * header is not on the linked list.
+ */
+
+ /* free/invalidate the blocks */
+ for (block_p = mp_p->mp_first_p; block_p != NULL; block_p = next_p) {
+ if (block_p->mb_magic != BLOCK_MAGIC
+ || block_p->mb_magic2 != BLOCK_MAGIC) {
+ final = MPOOL_ERROR_POOL_OVER;
+ break;
+ }
+ block_p->mb_magic = 0;
+ block_p->mb_magic2 = 0;
+ /* record the next pointer because it might be invalidated below */
+ next_p = block_p->mb_next_p;
+ ret = free_pages(block_p, (char *)block_p->mb_bounds_p - (char *)block_p,
+ BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK));
+ if (ret != MPOOL_ERROR_NONE) {
+ final = ret;
+ }
+ }
+
+ /* close /dev/zero if necessary */
+ if (mp_p->mp_fd >= 0) {
+ (void)close(mp_p->mp_fd);
+ mp_p->mp_fd = -1;
+ }
+
+ /* invalidate the mpool before we ditch it */
+ mp_p->mp_magic = 0;
+ mp_p->mp_magic2 = 0;
+
+ /* last we munmap the mpool pointer itself */
+ if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) {
+
+ /* if we are heavy packing then we need to free the 1st block later */
+ if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) {
+ addr = (char *)mp_p - sizeof(mpool_block_t);
+ }
+ else {
+ addr = mp_p;
+ }
+ size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, sizeof(mpool_t)));
+
+ (void)munmap((caddr_t)addr, size);
+ }
+
+ return final;
+}
+
+/*
+ * int mpool_clear
+ *
+ * DESCRIPTION:
+ *
+ * Wipe an opened memory pool clean so we can start again.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to our memory pool.
+ */
+int mpool_clear(mpool_t *mp_p)
+{
+ mpool_block_t *block_p;
+ int final = MPOOL_ERROR_NONE, bit_n, ret;
+ void *first_p;
+
+ /* special case, just return no-error */
+ if (mp_p == NULL) {
+ return MPOOL_ERROR_ARG_NULL;
+ }
+ if (mp_p->mp_magic != MPOOL_MAGIC) {
+ return MPOOL_ERROR_PNT;
+ }
+ if (mp_p->mp_magic2 != MPOOL_MAGIC) {
+ return MPOOL_ERROR_POOL_OVER;
+ }
+
+ if (mp_p->mp_log_func != NULL) {
+ mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLEAR, 0, 0, NULL, NULL, 0);
+ }
+
+ /* reset all of our free lists */
+ for (bit_n = 0; bit_n <= MAX_BITS; bit_n++) {
+ mp_p->mp_free[bit_n] = NULL;
+ }
+
+ /* free the blocks */
+ for (block_p = mp_p->mp_first_p;
+ block_p != NULL;
+ block_p = block_p->mb_next_p) {
+ if (block_p->mb_magic != BLOCK_MAGIC
+ || block_p->mb_magic2 != BLOCK_MAGIC) {
+ final = MPOOL_ERROR_POOL_OVER;
+ break;
+ }
+
+ first_p = FIRST_ADDR_IN_BLOCK(block_p);
+
+ /* free the memory */
+ ret = free_pointer(mp_p, first_p, MEMORY_IN_BLOCK(block_p));
+ if (ret != MPOOL_ERROR_NONE) {
+ final = ret;
+ }
+ }
+
+ return final;
+}
+
+/*
+ * void *mpool_alloc
+ *
+ * DESCRIPTION:
+ *
+ * Allocate space for bytes inside of an already open memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - Pointer to the address to use.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool. If NULL then it will do a
+ * normal malloc.
+ *
+ * byte_size -> Number of bytes to allocate in the pool. Must be >0.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size,
+ int *error_p)
+{
+ void *addr;
+
+ if (mp_p == NULL) {
+ /* special case -- do a normal malloc */
+ addr = (void *)malloc(byte_size);
+ if (addr == NULL) {
+ SET_POINTER(error_p, MPOOL_ERROR_ALLOC);
+ return NULL;
+ }
+ else {
+ SET_POINTER(error_p, MPOOL_ERROR_NONE);
+ return addr;
+ }
+ }
+
+ if (mp_p->mp_magic != MPOOL_MAGIC) {
+ SET_POINTER(error_p, MPOOL_ERROR_PNT);
+ return NULL;
+ }
+ if (mp_p->mp_magic2 != MPOOL_MAGIC) {
+ SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER);
+ return NULL;
+ }
+
+ if (byte_size == 0) {
+ SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID);
+ return NULL;
+ }
+
+ addr = alloc_mem(mp_p, byte_size, error_p);
+
+ if (mp_p->mp_log_func != NULL) {
+ mp_p->mp_log_func(mp_p, MPOOL_FUNC_ALLOC, byte_size, 0, addr, NULL, 0);
+ }
+
+ return addr;
+}
+
+/*
+ * void *mpool_calloc
+ *
+ * DESCRIPTION:
+ *
+ * Allocate space for elements of bytes in the memory pool and zero
+ * the space afterwards.
+ *
+ * RETURNS:
+ *
+ * Success - Pointer to the address to use.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool. If NULL then it will do a
+ * normal calloc.
+ *
+ * ele_n -> Number of elements to allocate.
+ *
+ * ele_size -> Number of bytes per element being allocated.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n,
+ const unsigned long ele_size, int *error_p)
+{
+ void *addr;
+ unsigned long byte_size;
+
+ if (mp_p == NULL) {
+ /* special case -- do a normal calloc */
+ addr = (void *)calloc(ele_n, ele_size);
+ if (addr == NULL) {
+ SET_POINTER(error_p, MPOOL_ERROR_ALLOC);
+ return NULL;
+ }
+ else {
+ SET_POINTER(error_p, MPOOL_ERROR_NONE);
+ return addr;
+ }
+
+ }
+ if (mp_p->mp_magic != MPOOL_MAGIC) {
+ SET_POINTER(error_p, MPOOL_ERROR_PNT);
+ return NULL;
+ }
+ if (mp_p->mp_magic2 != MPOOL_MAGIC) {
+ SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER);
+ return NULL;
+ }
+
+ if (ele_n == 0 || ele_size == 0) {
+ SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID);
+ return NULL;
+ }
+
+ byte_size = ele_n * ele_size;
+ addr = alloc_mem(mp_p, byte_size, error_p);
+ if (addr != NULL) {
+ memset(addr, 0, byte_size);
+ }
+
+ if (mp_p->mp_log_func != NULL) {
+ mp_p->mp_log_func(mp_p, MPOOL_FUNC_CALLOC, ele_size, ele_n, addr, NULL, 0);
+ }
+
+ /* NOTE: error_p set above */
+ return addr;
+}
+
+/*
+ * int mpool_free
+ *
+ * DESCRIPTION:
+ *
+ * Free an address from a memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool. If NULL then it will do a
+ * normal free.
+ *
+ * addr <-> Address to free.
+ *
+ * size -> Size of the address being freed.
+ */
+int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size)
+{
+ if (mp_p == NULL) {
+ /* special case -- do a normal free */
+ free(addr);
+ return MPOOL_ERROR_NONE;
+ }
+ if (mp_p->mp_magic != MPOOL_MAGIC) {
+ return MPOOL_ERROR_PNT;
+ }
+ if (mp_p->mp_magic2 != MPOOL_MAGIC) {
+ return MPOOL_ERROR_POOL_OVER;
+ }
+
+ if (mp_p->mp_log_func != NULL) {
+ mp_p->mp_log_func(mp_p, MPOOL_FUNC_FREE, size, 0, NULL, addr, 0);
+ }
+
+ if (addr == NULL) {
+ return MPOOL_ERROR_ARG_NULL;
+ }
+ if (size == 0) {
+ return MPOOL_ERROR_ARG_INVALID;
+ }
+
+ return free_mem(mp_p, addr, size);
+}
+
+/*
+ * void *mpool_resize
+ *
+ * DESCRIPTION:
+ *
+ * Reallocate an address in a mmeory pool to a new size. This is
+ * different from realloc in that it needs the old address' size. If
+ * you don't have it then you need to allocate new space, copy the
+ * data, and free the old pointer yourself.
+ *
+ * RETURNS:
+ *
+ * Success - Pointer to the address to use.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool. If NULL then it will do a
+ * normal realloc.
+ *
+ * old_addr -> Previously allocated address.
+ *
+ * old_byte_size -> Size of the old address. Must be known, cannot be
+ * 0.
+ *
+ * new_byte_size -> New size of the allocation.
+ *
+ * error_p <- Pointer to integer which, if not NULL, will be set with
+ * a mpool error code.
+ */
+void *mpool_resize(mpool_t *mp_p, void *old_addr,
+ const unsigned long old_byte_size,
+ const unsigned long new_byte_size,
+ int *error_p)
+{
+ unsigned long copy_size, new_size, old_size, fence;
+ void *new_addr;
+ mpool_block_t *block_p;
+ int ret;
+
+ if (mp_p == NULL) {
+ /* special case -- do a normal realloc */
+ new_addr = (void *)realloc(old_addr, new_byte_size);
+ if (new_addr == NULL) {
+ SET_POINTER(error_p, MPOOL_ERROR_ALLOC);
+ return NULL;
+ }
+ else {
+ SET_POINTER(error_p, MPOOL_ERROR_NONE);
+ return new_addr;
+ }
+ }
+
+ if (mp_p->mp_magic != MPOOL_MAGIC) {
+ SET_POINTER(error_p, MPOOL_ERROR_PNT);
+ return NULL;
+ }
+ if (mp_p->mp_magic2 != MPOOL_MAGIC) {
+ SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER);
+ return NULL;
+ }
+
+ if (old_addr == NULL) {
+ SET_POINTER(error_p, MPOOL_ERROR_ARG_NULL);
+ return NULL;
+ }
+ if (old_byte_size == 0) {
+ SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID);
+ return NULL;
+ }
+
+ /*
+ * If the size is larger than a block then the allocation must be at
+ * the front of the block.
+ */
+ if (old_byte_size > MAX_BLOCK_USER_MEMORY(mp_p)) {
+ block_p = (mpool_block_t *)((char *)old_addr - sizeof(mpool_block_t));
+ if (block_p->mb_magic != BLOCK_MAGIC
+ || block_p->mb_magic2 != BLOCK_MAGIC) {
+ SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER);
+ return NULL;
+ }
+ }
+
+ /* make sure we have enough bytes */
+ if (old_byte_size < MIN_ALLOCATION) {
+ old_size = MIN_ALLOCATION;
+ }
+ else {
+ old_size = old_byte_size;
+ }
+
+ /* verify that the size matches exactly if we can */
+ if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) {
+ fence = 0;
+ }
+ else if (old_size > 0) {
+ ret = check_magic(old_addr, old_size);
+ if (ret != MPOOL_ERROR_NONE) {
+ SET_POINTER(error_p, ret);
+ return NULL;
+ }
+ fence = FENCE_SIZE;
+ }
+
+ /* make sure we have enough bytes */
+ if (new_byte_size < MIN_ALLOCATION) {
+ new_size = MIN_ALLOCATION;
+ }
+ else {
+ new_size = new_byte_size;
+ }
+
+ /*
+ * NOTE: we could here see if the size is the same or less and then
+ * use the current memory and free the space above. This is harder
+ * than it sounds if we are changing the block size of the
+ * allocation.
+ */
+
+ /* we need to get another address */
+ new_addr = alloc_mem(mp_p, new_byte_size, error_p);
+ if (new_addr == NULL) {
+ /* error_p set in mpool_alloc */
+ return NULL;
+ }
+
+ if (new_byte_size > old_byte_size) {
+ copy_size = old_byte_size;
+ }
+ else {
+ copy_size = new_byte_size;
+ }
+ memcpy(new_addr, old_addr, copy_size);
+
+ /* free the old address */
+ ret = free_mem(mp_p, old_addr, old_byte_size);
+ if (ret != MPOOL_ERROR_NONE) {
+ /* if the old free failed, try and free the new address */
+ (void)free_mem(mp_p, new_addr, new_byte_size);
+ SET_POINTER(error_p, ret);
+ return NULL;
+ }
+
+ if (mp_p->mp_log_func != NULL) {
+ mp_p->mp_log_func(mp_p, MPOOL_FUNC_RESIZE, new_byte_size,
+ 0, new_addr, old_addr, old_byte_size);
+ }
+
+ SET_POINTER(error_p, MPOOL_ERROR_NONE);
+ return new_addr;
+}
+
+/*
+ * int mpool_stats
+ *
+ * DESCRIPTION:
+ *
+ * Return stats from the memory pool.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p -> Pointer to the memory pool.
+ *
+ * page_size_p <- Pointer to an unsigned integer which, if not NULL,
+ * will be set to the page-size of the pool.
+ *
+ * num_alloced_p <- Pointer to an unsigned long which, if not NULL,
+ * will be set to the number of pointers currently allocated in pool.
+ *
+ * user_alloced_p <- Pointer to an unsigned long which, if not NULL,
+ * will be set to the number of user bytes allocated in this pool.
+ *
+ * max_alloced_p <- Pointer to an unsigned long which, if not NULL,
+ * will be set to the maximum number of user bytes that have been
+ * allocated in this pool.
+ *
+ * tot_alloced_p <- Pointer to an unsigned long which, if not NULL,
+ * will be set to the total amount of space (including administrative
+ * overhead) used by the pool.
+ */
+int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p,
+ unsigned long *num_alloced_p,
+ unsigned long *user_alloced_p,
+ unsigned long *max_alloced_p,
+ unsigned long *tot_alloced_p)
+{
+ if (mp_p == NULL) {
+ return MPOOL_ERROR_ARG_NULL;
+ }
+ if (mp_p->mp_magic != MPOOL_MAGIC) {
+ return MPOOL_ERROR_PNT;
+ }
+ if (mp_p->mp_magic2 != MPOOL_MAGIC) {
+ return MPOOL_ERROR_POOL_OVER;
+ }
+
+ SET_POINTER(page_size_p, mp_p->mp_page_size);
+ SET_POINTER(num_alloced_p, mp_p->mp_alloc_c);
+ SET_POINTER(user_alloced_p, mp_p->mp_user_alloc);
+ SET_POINTER(max_alloced_p, mp_p->mp_max_alloc);
+ SET_POINTER(tot_alloced_p, SIZE_OF_PAGES(mp_p, mp_p->mp_page_c));
+
+ return MPOOL_ERROR_NONE;
+}
+
+/*
+ * int mpool_set_log_func
+ *
+ * DESCRIPTION:
+ *
+ * Set a logging callback function to be called whenever there was a
+ * memory transaction. See mpool_log_func_t.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool.
+ *
+ * log_func -> Log function (defined in mpool.h) which will be called
+ * with each mpool transaction.
+ */
+int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func)
+{
+ if (mp_p == NULL) {
+ return MPOOL_ERROR_ARG_NULL;
+ }
+ if (mp_p->mp_magic != MPOOL_MAGIC) {
+ return MPOOL_ERROR_PNT;
+ }
+ if (mp_p->mp_magic2 != MPOOL_MAGIC) {
+ return MPOOL_ERROR_POOL_OVER;
+ }
+
+ mp_p->mp_log_func = log_func;
+
+ return MPOOL_ERROR_NONE;
+}
+
+/*
+ * int mpool_set_max_pages
+ *
+ * DESCRIPTION:
+ *
+ * Set the maximum number of pages that the library will use. Once it
+ * hits the limit it will return MPOOL_ERROR_NO_PAGES.
+ *
+ * NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages
+ * value will include the page with the mpool header structure in it.
+ * If the flag is _not_ set then the max-pages will not include this
+ * first page.
+ *
+ * RETURNS:
+ *
+ * Success - MPOOL_ERROR_NONE
+ *
+ * Failure - Mpool error code
+ *
+ * ARGUMENTS:
+ *
+ * mp_p <-> Pointer to the memory pool.
+ *
+ * max_pages -> Maximum number of pages used by the library.
+ */
+int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages)
+{
+ if (mp_p == NULL) {
+ return MPOOL_ERROR_ARG_NULL;
+ }
+ if (mp_p->mp_magic != MPOOL_MAGIC) {
+ return MPOOL_ERROR_PNT;
+ }
+ if (mp_p->mp_magic2 != MPOOL_MAGIC) {
+ return MPOOL_ERROR_POOL_OVER;
+ }
+
+ if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) {
+ mp_p->mp_max_pages = max_pages;
+ }
+ else {
+ /*
+ * If we are not heavy-packing the pool then we don't count the
+ * 1st page allocated which holds the mpool header structure.
+ */
+ mp_p->mp_max_pages = max_pages + 1;
+ }
+
+ return MPOOL_ERROR_NONE;
+}
+
+/*
+ * const char *mpool_strerror
+ *
+ * DESCRIPTION:
+ *
+ * Return the corresponding string for the error number.
+ *
+ * RETURNS:
+ *
+ * Success - String equivalient of the error.
+ *
+ * Failure - String "invalid error code"
+ *
+ * ARGUMENTS:
+ *
+ * error -> Error number that we are converting.
+ */
+const char *mpool_strerror(const int error)
+{
+ switch (error) {
+ case MPOOL_ERROR_NONE:
+ return "no error";
+ break;
+ case MPOOL_ERROR_ARG_NULL:
+ return "function argument is null";
+ break;
+ case MPOOL_ERROR_ARG_INVALID:
+ return "function argument is invalid";
+ break;
+ case MPOOL_ERROR_PNT:
+ return "invalid mpool pointer";
+ break;
+ case MPOOL_ERROR_POOL_OVER:
+ return "mpool structure was overwritten";
+ break;
+ case MPOOL_ERROR_PAGE_SIZE:
+ return "could not get system page-size";
+ break;
+ case MPOOL_ERROR_OPEN_ZERO:
+ return "could not open /dev/zero";
+ break;
+ case MPOOL_ERROR_NO_MEM:
+ return "no memory available";
+ break;
+ case MPOOL_ERROR_MMAP:
+ return "problems with mmap";
+ break;
+ case MPOOL_ERROR_SIZE:
+ return "error processing requested size";
+ break;
+ case MPOOL_ERROR_TOO_BIG:
+ return "allocation exceeds pool max size";
+ break;
+ case MPOOL_ERROR_MEM:
+ return "invalid memory address";
+ break;
+ case MPOOL_ERROR_MEM_OVER:
+ return "memory lower bounds overwritten";
+ break;
+ case MPOOL_ERROR_NOT_FOUND:
+ return "memory block not found in pool";
+ break;
+ case MPOOL_ERROR_IS_FREE:
+ return "memory address has already been freed";
+ break;
+ case MPOOL_ERROR_BLOCK_STAT:
+ return "invalid internal block status";
+ break;
+ case MPOOL_ERROR_FREE_ADDR:
+ return "invalid internal free address";
+ break;
+ case MPOOL_ERROR_SBRK_CONTIG:
+ return "sbrk did not return contiguous memory";
+ break;
+ case MPOOL_ERROR_NO_PAGES:
+ return "no available pages left in pool";
+ break;
+ case MPOOL_ERROR_ALLOC:
+ return "system alloc function failed";
+ break;
+ case MPOOL_ERROR_PNT_OVER:
+ return "user pointer admin space overwritten";
+ break;
+ default:
+ break;
+ }
+
+ return "invalid error code";
+}
diff --git a/libs/libks/src/simclist.c b/libs/libks/src/simclist.c
new file mode 100755
index 0000000000..c8d36f5ff4
--- /dev/null
+++ b/libs/libks/src/simclist.c
@@ -0,0 +1,1525 @@
+/*
+ * Copyright (c) 2007,2008,2009,2010,2011 Mij
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+/*
+ * SimCList library. See http://mij.oltrelinux.com/devel/simclist
+ */
+
+/* SimCList implementation, version 1.6 */
+
+#include
+#include
+#include /* for setting errno */
+#include
+#ifndef _WIN32
+ /* not in Windows! */
+# include
+# include
+#endif
+#ifndef SIMCLIST_NO_DUMPRESTORE
+ /* includes for dump/restore */
+# include
+# include /* for READ_ERRCHECK() and write() */
+# include /* for open() etc */
+# ifndef _WIN32
+# include /* for htons() on UNIX */
+# else
+# include /* for htons() on Windows */
+# endif
+#endif
+
+/* disable asserts */
+#ifndef SIMCLIST_DEBUG
+#define NDEBUG
+#endif
+
+#include
+
+
+#include /* for open()'s access modes S_IRUSR etc */
+#include
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+/* provide gettimeofday() missing in Windows */
+int gettimeofday(struct timeval *tp, void *tzp) {
+ DWORD t;
+
+ /* XSI says: "If tzp is not a null pointer, the behavior is unspecified" */
+ assert(tzp == NULL);
+
+ t = timeGetTime();
+ tp->tv_sec = t / 1000;
+ tp->tv_usec = t % 1000;
+ return 0;
+}
+#endif
+
+
+/* work around lack of inttypes.h support in broken Microsoft Visual Studio compilers */
+#if !defined(_WIN32) || !defined(_MSC_VER)
+# include /* (u)int*_t */
+#else
+# include
+typedef UINT8 uint8_t;
+typedef UINT16 uint16_t;
+typedef ULONG32 uint32_t;
+typedef UINT64 uint64_t;
+typedef INT8 int8_t;
+typedef INT16 int16_t;
+typedef LONG32 int32_t;
+typedef INT64 int64_t;
+#endif
+
+
+/* define some commodity macros for Dump/Restore functionality */
+#ifndef SIMCLIST_NO_DUMPRESTORE
+/* write() decorated with error checking logic */
+#define WRITE_ERRCHECK(fd, msgbuf, msglen) do { \
+ if (write(fd, msgbuf, msglen) < 0) return -1; \
+ } while (0);
+/* READ_ERRCHECK() decorated with error checking logic */
+#define READ_ERRCHECK(fd, msgbuf, msglen) do { \
+ if (read(fd, msgbuf, msglen) != msglen) { \
+ /*errno = EPROTO;*/ \
+ return -1; \
+ } \
+ } while (0);
+
+/* convert 64bit integers from host to network format */
+#define hton64(x) (\
+ htons(1) == 1 ? \
+ (uint64_t)x /* big endian */ \
+ : /* little endian */ \
+ ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
+ (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
+ (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
+ (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
+ (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
+ (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
+ (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
+ (((uint64_t)(x) & 0x00000000000000ffULL) << 56))) \
+ )
+
+/* convert 64bit integers from network to host format */
+#define ntoh64(x) (hton64(x))
+#endif
+
+/* some OSes don't have EPROTO (eg OpenBSD) */
+#ifndef EPROTO
+#define EPROTO EIO
+#endif
+
+#ifdef SIMCLIST_WITH_THREADS
+/* limit (approx) to the number of threads running
+ * for threaded operations. Only meant when
+ * SIMCLIST_WITH_THREADS is defined */
+#define SIMCLIST_MAXTHREADS 2
+#endif
+
+/*
+ * how many elems to keep as spare. During a deletion, an element
+ * can be saved in a "free-list", not free()d immediately. When
+ * latter insertions are performed, spare elems can be used instead
+ * of malloc()ing new elems.
+ *
+ * about this param, some values for appending
+ * 10 million elems into an empty list:
+ * (#, time[sec], gain[%], gain/no[%])
+ * 0 2,164 0,00 0,00 <-- feature disabled
+ * 1 1,815 34,9 34,9
+ * 2 1,446 71,8 35,9 <-- MAX gain/no
+ * 3 1,347 81,7 27,23
+ * 5 1,213 95,1 19,02
+ * 8 1,064 110,0 13,75
+ * 10 1,015 114,9 11,49 <-- MAX gain w/ likely sol
+ * 15 1,019 114,5 7,63
+ * 25 0,985 117,9 4,72
+ * 50 1,088 107,6 2,15
+ * 75 1,016 114,8 1,53
+ * 100 0,988 117,6 1,18
+ * 150 1,022 114,2 0,76
+ * 200 0,939 122,5 0,61 <-- MIN time
+ */
+#ifndef SIMCLIST_MAX_SPARE_ELEMS
+#define SIMCLIST_MAX_SPARE_ELEMS 5
+#endif
+
+
+#ifdef SIMCLIST_WITH_THREADS
+#include
+#endif
+
+#include "simclist.h"
+
+
+/* minumum number of elements for sorting with quicksort instead of insertion */
+#define SIMCLIST_MINQUICKSORTELS 24
+
+
+/* list dump declarations */
+#define SIMCLIST_DUMPFORMAT_VERSION 1 /* (short integer) version of fileformat managed by _dump* and _restore* functions */
+
+#define SIMCLIST_DUMPFORMAT_HEADERLEN 30 /* length of the header */
+
+/* header for a list dump */
+struct list_dump_header_s {
+ uint16_t ver; /* version */
+ int32_t timestamp_sec; /* dump timestamp, seconds since UNIX Epoch */
+ int32_t timestamp_usec; /* dump timestamp, microseconds since timestamp_sec */
+ int32_t rndterm; /* random value terminator -- terminates the data sequence */
+
+ uint32_t totlistlen; /* sum of every element' size, bytes */
+ uint32_t numels; /* number of elements */
+ uint32_t elemlen; /* bytes length of an element, for constant-size lists, <= 0 otherwise */
+ int32_t listhash; /* hash of the list at the time of dumping, or 0 if to be ignored */
+};
+
+
+
+/* deletes tmp from list, with care wrt its position (head, tail, middle) */
+static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned int pos);
+
+/* set default values for initialized lists */
+static int list_attributes_setdefaults(list_t *restrict l);
+
+#ifndef NDEBUG
+/* check whether the list internal REPresentation is valid -- Costs O(n) */
+static int list_repOk(const list_t *restrict l);
+
+/* check whether the list attribute set is valid -- Costs O(1) */
+static int list_attrOk(const list_t *restrict l);
+#endif
+
+/* do not inline, this is recursive */
+static void list_sort_quicksort(list_t *restrict l, int versus,
+ unsigned int first, struct list_entry_s *fel,
+ unsigned int last, struct list_entry_s *lel);
+
+static inline void list_sort_selectionsort(list_t *restrict l, int versus,
+ unsigned int first, struct list_entry_s *fel,
+ unsigned int last, struct list_entry_s *lel);
+
+static void *list_get_minmax(const list_t *restrict l, int versus);
+
+static inline struct list_entry_s *list_findpos(const list_t *restrict l, int posstart);
+
+/*
+ * Random Number Generator
+ *
+ * The user is expected to seed the RNG (ie call srand()) if
+ * SIMCLIST_SYSTEM_RNG is defined.
+ *
+ * Otherwise, a self-contained RNG based on LCG is used; see
+ * http://en.wikipedia.org/wiki/Linear_congruential_generator .
+ *
+ * Facts pro local RNG:
+ * 1. no need for the user to call srand() on his own
+ * 2. very fast, possibly faster than OS
+ * 3. avoid interference with user's RNG
+ *
+ * Facts pro system RNG:
+ * 1. may be more accurate (irrelevant for SimCList randno purposes)
+ * 2. why reinvent the wheel
+ *
+ * Default to local RNG for user's ease of use.
+ */
+
+#ifdef SIMCLIST_SYSTEM_RNG
+/* keep track whether we initialized already (non-0) or not (0) */
+static unsigned random_seed = 0;
+
+/* use local RNG */
+static inline void seed_random(void) {
+ if (random_seed == 0)
+ random_seed = (unsigned)getpid() ^ (unsigned)time(NULL);
+}
+
+static inline long get_random(void) {
+ random_seed = (1664525 * random_seed + 1013904223);
+ return random_seed;
+}
+
+#else
+/* use OS's random generator */
+# define seed_random()
+# define get_random() (rand())
+#endif
+
+
+/* list initialization */
+int list_init(list_t *restrict l) {
+ if (l == NULL) return -1;
+
+ seed_random();
+
+ l->numels = 0;
+
+ /* head/tail sentinels and mid pointer */
+ l->head_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
+ l->tail_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
+ l->head_sentinel->next = l->tail_sentinel;
+ l->tail_sentinel->prev = l->head_sentinel;
+ l->head_sentinel->prev = l->tail_sentinel->next = l->mid = NULL;
+ l->head_sentinel->data = l->tail_sentinel->data = NULL;
+
+ /* iteration attributes */
+ l->iter_active = 0;
+ l->iter_pos = 0;
+ l->iter_curentry = NULL;
+
+ /* free-list attributes */
+ l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS * sizeof(struct list_entry_s *));
+ l->spareelsnum = 0;
+
+#ifdef SIMCLIST_WITH_THREADS
+ l->threadcount = 0;
+#endif
+
+ list_attributes_setdefaults(l);
+
+ assert(list_repOk(l));
+ assert(list_attrOk(l));
+
+ return 0;
+}
+
+void list_destroy(list_t *restrict l) {
+ unsigned int i;
+
+ list_clear(l);
+ for (i = 0; i < l->spareelsnum; i++) {
+ free(l->spareels[i]);
+ }
+ free(l->spareels);
+ free(l->head_sentinel);
+ free(l->tail_sentinel);
+}
+
+int list_attributes_setdefaults(list_t *restrict l) {
+ l->attrs.comparator = NULL;
+ l->attrs.seeker = NULL;
+
+ /* also free() element data when removing and element from the list */
+ l->attrs.meter = NULL;
+ l->attrs.copy_data = 0;
+
+ l->attrs.hasher = NULL;
+
+ /* serializer/unserializer */
+ l->attrs.serializer = NULL;
+ l->attrs.unserializer = NULL;
+
+ assert(list_attrOk(l));
+
+ return 0;
+}
+
+/* setting list properties */
+int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun) {
+ if (l == NULL) return -1;
+
+ l->attrs.comparator = comparator_fun;
+
+ assert(list_attrOk(l));
+
+ return 0;
+}
+
+int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun) {
+ if (l == NULL) return -1;
+
+ l->attrs.seeker = seeker_fun;
+ assert(list_attrOk(l));
+
+ return 0;
+}
+
+int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data) {
+ if (l == NULL || (metric_fun == NULL && copy_data != 0)) return -1;
+
+ l->attrs.meter = metric_fun;
+ l->attrs.copy_data = copy_data;
+
+ assert(list_attrOk(l));
+
+ return 0;
+}
+
+int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun) {
+ if (l == NULL) return -1;
+
+ l->attrs.hasher = hash_computer_fun;
+ assert(list_attrOk(l));
+ return 0;
+}
+
+int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun) {
+ if (l == NULL) return -1;
+
+ l->attrs.serializer = serializer_fun;
+ assert(list_attrOk(l));
+ return 0;
+}
+
+int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun) {
+ if (l == NULL) return -1;
+
+ l->attrs.unserializer = unserializer_fun;
+ assert(list_attrOk(l));
+ return 0;
+}
+
+int list_append(list_t *restrict l, const void *data) {
+ return list_insert_at(l, data, l->numels);
+}
+
+int list_prepend(list_t *restrict l, const void *data) {
+ return list_insert_at(l, data, 0);
+}
+
+void *list_fetch(list_t *restrict l) {
+ return list_extract_at(l, 0);
+}
+
+void *list_get_at(const list_t *restrict l, unsigned int pos) {
+ struct list_entry_s *tmp;
+
+ tmp = list_findpos(l, pos);
+
+ return (tmp != NULL ? tmp->data : NULL);
+}
+
+void *list_get_max(const list_t *restrict l) {
+ return list_get_minmax(l, +1);
+}
+
+void *list_get_min(const list_t *restrict l) {
+ return list_get_minmax(l, -1);
+}
+
+/* REQUIRES {list->numels >= 1}
+ * return the min (versus < 0) or max value (v > 0) in l */
+static void *list_get_minmax(const list_t *restrict l, int versus) {
+ void *curminmax;
+ struct list_entry_s *s;
+
+ if (l->attrs.comparator == NULL || l->numels == 0)
+ return NULL;
+
+ curminmax = l->head_sentinel->next->data;
+ for (s = l->head_sentinel->next->next; s != l->tail_sentinel; s = s->next) {
+ if (l->attrs.comparator(curminmax, s->data) * versus > 0)
+ curminmax = s->data;
+ }
+
+ return curminmax;
+}
+
+/* set tmp to point to element at index posstart in l */
+static inline struct list_entry_s *list_findpos(const list_t *restrict l, int posstart) {
+ struct list_entry_s *ptr;
+ float x;
+ int i;
+
+ /* accept 1 slot overflow for fetching head and tail sentinels */
+ if (posstart < -1 || posstart > (int)l->numels) return NULL;
+
+ x = (float)(posstart+1) / l->numels;
+ if (x <= 0.25) {
+ /* first quarter: get to posstart from head */
+ for (i = -1, ptr = l->head_sentinel; i < posstart; ptr = ptr->next, i++);
+ } else if (x < 0.5) {
+ /* second quarter: get to posstart from mid */
+ for (i = (l->numels-1)/2, ptr = l->mid; i > posstart; ptr = ptr->prev, i--);
+ } else if (x <= 0.75) {
+ /* third quarter: get to posstart from mid */
+ for (i = (l->numels-1)/2, ptr = l->mid; i < posstart; ptr = ptr->next, i++);
+ } else {
+ /* fourth quarter: get to posstart from tail */
+ for (i = l->numels, ptr = l->tail_sentinel; i > posstart; ptr = ptr->prev, i--);
+ }
+
+ return ptr;
+}
+
+void *list_extract_at(list_t *restrict l, unsigned int pos) {
+ struct list_entry_s *tmp;
+ void *data;
+
+ if (l->iter_active || pos >= l->numels) return NULL;
+
+ tmp = list_findpos(l, pos);
+ data = tmp->data;
+
+ tmp->data = NULL; /* save data from list_drop_elem() free() */
+ list_drop_elem(l, tmp, pos);
+ l->numels--;
+
+ assert(list_repOk(l));
+
+ return data;
+}
+
+int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) {
+ struct list_entry_s *lent, *succ, *prec;
+
+ if (l->iter_active || pos > l->numels) return -1;
+
+ /* this code optimizes malloc() with a free-list */
+ if (l->spareelsnum > 0) {
+ lent = l->spareels[l->spareelsnum-1];
+ l->spareelsnum--;
+ } else {
+ lent = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
+ if (lent == NULL)
+ return -1;
+ }
+
+ if (l->attrs.copy_data) {
+ /* make room for user' data (has to be copied) */
+ size_t datalen = l->attrs.meter(data);
+ lent->data = (struct list_entry_s *)malloc(datalen);
+ memcpy(lent->data, data, datalen);
+ } else {
+ lent->data = (void*)data;
+ }
+
+ /* actually append element */
+ prec = list_findpos(l, pos-1);
+ succ = prec->next;
+
+ prec->next = lent;
+ lent->prev = prec;
+ lent->next = succ;
+ succ->prev = lent;
+
+ l->numels++;
+
+ /* fix mid pointer */
+ if (l->numels == 1) { /* first element, set pointer */
+ l->mid = lent;
+ } else if (l->numels % 2) { /* now odd */
+ if (pos >= (l->numels-1)/2) l->mid = l->mid->next;
+ } else { /* now even */
+ if (pos <= (l->numels-1)/2) l->mid = l->mid->prev;
+ }
+
+ assert(list_repOk(l));
+
+ return 1;
+}
+
+int list_delete(list_t *restrict l, const void *data) {
+ int pos, r;
+
+ pos = list_locate(l, data);
+ if (pos < 0)
+ return -1;
+
+ r = list_delete_at(l, pos);
+ if (r < 0)
+ return -1;
+
+ assert(list_repOk(l));
+
+ return 0;
+}
+
+int list_delete_at(list_t *restrict l, unsigned int pos) {
+ struct list_entry_s *delendo;
+
+
+ if (l->iter_active || pos >= l->numels) return -1;
+
+ delendo = list_findpos(l, pos);
+
+ list_drop_elem(l, delendo, pos);
+
+ l->numels--;
+
+
+ assert(list_repOk(l));
+
+ return 0;
+}
+
+int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend) {
+ struct list_entry_s *lastvalid, *tmp, *tmp2;
+ unsigned int numdel, midposafter, i;
+ int movedx;
+
+ if (l->iter_active || posend < posstart || posend >= l->numels) return -1;
+
+ numdel = posend - posstart + 1;
+ if (numdel == l->numels) return list_clear(l);
+
+ tmp = list_findpos(l, posstart); /* first el to be deleted */
+ lastvalid = tmp->prev; /* last valid element */
+
+ midposafter = (l->numels-1-numdel)/2;
+
+ midposafter = midposafter < posstart ? midposafter : midposafter+numdel;
+ movedx = midposafter - (l->numels-1)/2;
+
+ if (movedx > 0) { /* move right */
+ for (i = 0; i < (unsigned int)movedx; l->mid = l->mid->next, i++);
+ } else { /* move left */
+ movedx = -movedx;
+ for (i = 0; i < (unsigned int)movedx; l->mid = l->mid->prev, i++);
+ }
+
+ assert(posstart == 0 || lastvalid != l->head_sentinel);
+ i = posstart;
+ if (l->attrs.copy_data) {
+ /* also free element data */
+ for (; i <= posend; i++) {
+ tmp2 = tmp;
+ tmp = tmp->next;
+ if (tmp2->data != NULL) free(tmp2->data);
+ if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) {
+ l->spareels[l->spareelsnum++] = tmp2;
+ } else {
+ free(tmp2);
+ }
+ }
+ } else {
+ /* only free containers */
+ for (; i <= posend; i++) {
+ tmp2 = tmp;
+ tmp = tmp->next;
+ if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) {
+ l->spareels[l->spareelsnum++] = tmp2;
+ } else {
+ free(tmp2);
+ }
+ }
+ }
+ assert(i == posend+1 && (posend != l->numels || tmp == l->tail_sentinel));
+
+ lastvalid->next = tmp;
+ tmp->prev = lastvalid;
+
+ l->numels -= posend - posstart + 1;
+
+ assert(list_repOk(l));
+
+ return numdel;
+}
+
+int list_clear(list_t *restrict l) {
+ struct list_entry_s *s;
+ unsigned int numels;
+
+ /* will be returned */
+ numels = l->numels;
+
+ if (l->iter_active) return -1;
+
+ if (l->attrs.copy_data) { /* also free user data */
+ /* spare a loop conditional with two loops: spareing elems and freeing elems */
+ for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) {
+ /* move elements as spares as long as there is room */
+ if (s->data != NULL) free(s->data);
+ l->spareels[l->spareelsnum++] = s;
+ }
+ while (s != l->tail_sentinel) {
+ /* free the remaining elems */
+ if (s->data != NULL) free(s->data);
+ s = s->next;
+ free(s->prev);
+ }
+ l->head_sentinel->next = l->tail_sentinel;
+ l->tail_sentinel->prev = l->head_sentinel;
+ } else { /* only free element containers */
+ /* spare a loop conditional with two loops: spareing elems and freeing elems */
+ for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) {
+ /* move elements as spares as long as there is room */
+ l->spareels[l->spareelsnum++] = s;
+ }
+ while (s != l->tail_sentinel) {
+ /* free the remaining elems */
+ s = s->next;
+ free(s->prev);
+ }
+ l->head_sentinel->next = l->tail_sentinel;
+ l->tail_sentinel->prev = l->head_sentinel;
+ }
+ l->numels = 0;
+ l->mid = NULL;
+
+ assert(list_repOk(l));
+
+ return numels;
+}
+
+unsigned int list_size(const list_t *restrict l) {
+ return l->numels;
+}
+
+int list_empty(const list_t *restrict l) {
+ return (l->numels == 0);
+}
+
+int list_locate(const list_t *restrict l, const void *data) {
+ struct list_entry_s *el;
+ int pos = 0;
+
+ if (l->attrs.comparator != NULL) {
+ /* use comparator */
+ for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) {
+ if (l->attrs.comparator(data, el->data) == 0) break;
+ }
+ } else {
+ /* compare references */
+ for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) {
+ if (el->data == data) break;
+ }
+ }
+ if (el == l->tail_sentinel) return -1;
+
+ return pos;
+}
+
+void *list_seek(list_t *restrict l, const void *indicator) {
+ const struct list_entry_s *iter;
+
+ if (l->attrs.seeker == NULL) return NULL;
+
+ for (iter = l->head_sentinel->next; iter != l->tail_sentinel; iter = iter->next) {
+ if (l->attrs.seeker(iter->data, indicator) != 0) return iter->data;
+ }
+
+ return NULL;
+}
+
+int list_contains(const list_t *restrict l, const void *data) {
+ return (list_locate(l, data) >= 0);
+}
+
+int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) {
+ struct list_entry_s *el, *srcel;
+ unsigned int cnt;
+ int err;
+
+
+ if (l1 == NULL || l2 == NULL || dest == NULL || l1 == dest || l2 == dest)
+ return -1;
+
+ list_init(dest);
+
+ dest->numels = l1->numels + l2->numels;
+ if (dest->numels == 0)
+ return 0;
+
+ /* copy list1 */
+ srcel = l1->head_sentinel->next;
+ el = dest->head_sentinel;
+ while (srcel != l1->tail_sentinel) {
+ el->next = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
+ el->next->prev = el;
+ el = el->next;
+ el->data = srcel->data;
+ srcel = srcel->next;
+ }
+ dest->mid = el; /* approximate position (adjust later) */
+ /* copy list 2 */
+ srcel = l2->head_sentinel->next;
+ while (srcel != l2->tail_sentinel) {
+ el->next = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
+ el->next->prev = el;
+ el = el->next;
+ el->data = srcel->data;
+ srcel = srcel->next;
+ }
+ el->next = dest->tail_sentinel;
+ dest->tail_sentinel->prev = el;
+
+ /* fix mid pointer */
+ err = l2->numels - l1->numels;
+ if ((err+1)/2 > 0) { /* correct pos RIGHT (err-1)/2 moves */
+ err = (err+1)/2;
+ for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->next;
+ } else if (err/2 < 0) { /* correct pos LEFT (err/2)-1 moves */
+ err = -err/2;
+ for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->prev;
+ }
+
+ assert(!(list_repOk(l1) && list_repOk(l2)) || list_repOk(dest));
+
+ return 0;
+}
+
+int list_sort(list_t *restrict l, int versus) {
+ if (l->iter_active || l->attrs.comparator == NULL) /* cannot modify list in the middle of an iteration */
+ return -1;
+
+ if (l->numels <= 1)
+ return 0;
+ list_sort_quicksort(l, versus, 0, l->head_sentinel->next, l->numels-1, l->tail_sentinel->prev);
+ assert(list_repOk(l));
+ return 0;
+}
+
+#ifdef SIMCLIST_WITH_THREADS
+struct list_sort_wrappedparams {
+ list_t *restrict l;
+ int versus;
+ unsigned int first, last;
+ struct list_entry_s *fel, *lel;
+};
+
+static void *list_sort_quicksort_threadwrapper(void *wrapped_params) {
+ struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *)wrapped_params;
+ list_sort_quicksort(wp->l, wp->versus, wp->first, wp->fel, wp->last, wp->lel);
+ free(wp);
+ pthread_exit(NULL);
+ return NULL;
+}
+#endif
+
+static inline void list_sort_selectionsort(list_t *restrict l, int versus,
+ unsigned int first, struct list_entry_s *fel,
+ unsigned int last, struct list_entry_s *lel) {
+ struct list_entry_s *cursor, *toswap, *firstunsorted;
+ void *tmpdata;
+
+ if (last <= first) /* <= 1-element lists are always sorted */
+ return;
+
+ for (firstunsorted = fel; firstunsorted != lel; firstunsorted = firstunsorted->next) {
+ /* find min or max in the remainder of the list */
+ for (toswap = firstunsorted, cursor = firstunsorted->next; cursor != lel->next; cursor = cursor->next)
+ if (l->attrs.comparator(toswap->data, cursor->data) * -versus > 0) toswap = cursor;
+ if (toswap != firstunsorted) { /* swap firstunsorted with toswap */
+ tmpdata = firstunsorted->data;
+ firstunsorted->data = toswap->data;
+ toswap->data = tmpdata;
+ }
+ }
+}
+
+static void list_sort_quicksort(list_t *restrict l, int versus,
+ unsigned int first, struct list_entry_s *fel,
+ unsigned int last, struct list_entry_s *lel) {
+ unsigned int pivotid;
+ unsigned int i;
+ register struct list_entry_s *pivot;
+ struct list_entry_s *left, *right;
+ void *tmpdata;
+#ifdef SIMCLIST_WITH_THREADS
+ pthread_t tid;
+ int traised;
+#endif
+
+
+ if (last <= first) /* <= 1-element lists are always sorted */
+ return;
+
+ if (last - first+1 <= SIMCLIST_MINQUICKSORTELS) {
+ list_sort_selectionsort(l, versus, first, fel, last, lel);
+ return;
+ }
+
+ /* base of iteration: one element list */
+ if (! (last > first)) return;
+
+ pivotid = (get_random() % (last - first + 1));
+ /* pivotid = (last - first + 1) / 2; */
+
+ /* find pivot */
+ if (pivotid < (last - first + 1)/2) {
+ for (i = 0, pivot = fel; i < pivotid; pivot = pivot->next, i++);
+ } else {
+ for (i = last - first, pivot = lel; i > pivotid; pivot = pivot->prev, i--);
+ }
+
+ /* smaller PIVOT bigger */
+ left = fel;
+ right = lel;
+ /* iterate --- left ---> PIV <--- right --- */
+ while (left != pivot && right != pivot) {
+ for (; left != pivot && (l->attrs.comparator(left->data, pivot->data) * -versus <= 0); left = left->next);
+ /* left points to a smaller element, or to pivot */
+ for (; right != pivot && (l->attrs.comparator(right->data, pivot->data) * -versus >= 0); right = right->prev);
+ /* right points to a bigger element, or to pivot */
+ if (left != pivot && right != pivot) {
+ /* swap, then move iterators */
+ tmpdata = left->data;
+ left->data = right->data;
+ right->data = tmpdata;
+
+ left = left->next;
+ right = right->prev;
+ }
+ }
+
+ /* now either left points to pivot (end run), or right */
+ if (right == pivot) { /* left part longer */
+ while (left != pivot) {
+ if (l->attrs.comparator(left->data, pivot->data) * -versus > 0) {
+ tmpdata = left->data;
+ left->data = pivot->prev->data;
+ pivot->prev->data = pivot->data;
+ pivot->data = tmpdata;
+ pivot = pivot->prev;
+ pivotid--;
+ if (pivot == left) break;
+ } else {
+ left = left->next;
+ }
+ }
+ } else { /* right part longer */
+ while (right != pivot) {
+ if (l->attrs.comparator(right->data, pivot->data) * -versus < 0) {
+ /* move current right before pivot */
+ tmpdata = right->data;
+ right->data = pivot->next->data;
+ pivot->next->data = pivot->data;
+ pivot->data = tmpdata;
+ pivot = pivot->next;
+ pivotid++;
+ if (pivot == right) break;
+ } else {
+ right = right->prev;
+ }
+ }
+ }
+
+ /* sort sublists A and B : |---A---| pivot |---B---| */
+
+#ifdef SIMCLIST_WITH_THREADS
+ traised = 0;
+ if (pivotid > 0) {
+ /* prepare wrapped args, then start thread */
+ if (l->threadcount < SIMCLIST_MAXTHREADS-1) {
+ struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *)malloc(sizeof(struct list_sort_wrappedparams));
+ l->threadcount++;
+ traised = 1;
+ wp->l = l;
+ wp->versus = versus;
+ wp->first = first;
+ wp->fel = fel;
+ wp->last = first+pivotid-1;
+ wp->lel = pivot->prev;
+ if (pthread_create(&tid, NULL, list_sort_quicksort_threadwrapper, wp) != 0) {
+ free(wp);
+ traised = 0;
+ list_sort_quicksort(l, versus, first, fel, first+pivotid-1, pivot->prev);
+ }
+ } else {
+ list_sort_quicksort(l, versus, first, fel, first+pivotid-1, pivot->prev);
+ }
+ }
+ if (first + pivotid < last) list_sort_quicksort(l, versus, first+pivotid+1, pivot->next, last, lel);
+ if (traised) {
+ pthread_join(tid, (void **)NULL);
+ l->threadcount--;
+ }
+#else
+ if (pivotid > 0) list_sort_quicksort(l, versus, first, fel, first+pivotid-1, pivot->prev);
+ if (first + pivotid < last) list_sort_quicksort(l, versus, first+pivotid+1, pivot->next, last, lel);
+#endif
+}
+
+int list_iterator_start(list_t *restrict l) {
+ if (l->iter_active) return 0;
+ l->iter_pos = 0;
+ l->iter_active = 1;
+ l->iter_curentry = l->head_sentinel->next;
+ return 1;
+}
+
+void *list_iterator_next(list_t *restrict l) {
+ void *toret;
+
+ if (! l->iter_active) return NULL;
+
+ toret = l->iter_curentry->data;
+ l->iter_curentry = l->iter_curentry->next;
+ l->iter_pos++;
+
+ return toret;
+}
+
+int list_iterator_hasnext(const list_t *restrict l) {
+ if (! l->iter_active) return 0;
+ return (l->iter_pos < l->numels);
+}
+
+int list_iterator_stop(list_t *restrict l) {
+ if (! l->iter_active) return 0;
+ l->iter_pos = 0;
+ l->iter_active = 0;
+ return 1;
+}
+
+int list_hash(const list_t *restrict l, list_hash_t *restrict hash) {
+ struct list_entry_s *x;
+ list_hash_t tmphash;
+
+ assert(hash != NULL);
+
+ tmphash = l->numels * 2 + 100;
+ if (l->attrs.hasher == NULL) {
+#ifdef SIMCLIST_ALLOW_LOCATIONBASED_HASHES
+ /* ENABLE WITH CARE !! */
+#warning "Memlocation-based hash is consistent only for testing modification in the same program run."
+ int i;
+
+ /* only use element references */
+ for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) {
+ for (i = 0; i < sizeof(x->data); i++) {
+ tmphash += (tmphash ^ (uintptr_t)x->data);
+ }
+ tmphash += tmphash % l->numels;
+ }
+#else
+ return -1;
+#endif
+ } else {
+ /* hash each element with the user-given function */
+ for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) {
+ tmphash += tmphash ^ l->attrs.hasher(x->data);
+ tmphash += tmphash % l->numels;
+ }
+ }
+
+ *hash = tmphash;
+
+ return 0;
+}
+
+#ifndef SIMCLIST_NO_DUMPRESTORE
+int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info) {
+ int32_t terminator_head, terminator_tail;
+ uint32_t elemlen;
+ off_t hop;
+
+
+ /* version */
+ READ_ERRCHECK(fd, & info->version, sizeof(info->version));
+ info->version = ntohs(info->version);
+ if (info->version > SIMCLIST_DUMPFORMAT_VERSION) {
+ errno = EILSEQ;
+ return -1;
+ }
+
+ /* timestamp.tv_sec and timestamp.tv_usec */
+ READ_ERRCHECK(fd, & info->timestamp.tv_sec, sizeof(info->timestamp.tv_sec));
+ info->timestamp.tv_sec = ntohl(info->timestamp.tv_sec);
+ READ_ERRCHECK(fd, & info->timestamp.tv_usec, sizeof(info->timestamp.tv_usec));
+ info->timestamp.tv_usec = ntohl(info->timestamp.tv_usec);
+
+ /* list terminator (to check thereafter) */
+ READ_ERRCHECK(fd, & terminator_head, sizeof(terminator_head));
+ terminator_head = ntohl(terminator_head);
+
+ /* list size */
+ READ_ERRCHECK(fd, & info->list_size, sizeof(info->list_size));
+ info->list_size = ntohl(info->list_size);
+
+ /* number of elements */
+ READ_ERRCHECK(fd, & info->list_numels, sizeof(info->list_numels));
+ info->list_numels = ntohl(info->list_numels);
+
+ /* length of each element (for checking for consistency) */
+ READ_ERRCHECK(fd, & elemlen, sizeof(elemlen));
+ elemlen = ntohl(elemlen);
+
+ /* list hash */
+ READ_ERRCHECK(fd, & info->list_hash, sizeof(info->list_hash));
+ info->list_hash = ntohl(info->list_hash);
+
+ /* check consistency */
+ if (elemlen > 0) {
+ /* constant length, hop by size only */
+ hop = info->list_size;
+ } else {
+ /* non-constant length, hop by size + all element length blocks */
+ hop = info->list_size + elemlen*info->list_numels;
+ }
+ if (lseek(fd, hop, SEEK_CUR) == -1) {
+ return -1;
+ }
+
+ /* read the trailing value and compare with terminator_head */
+ READ_ERRCHECK(fd, & terminator_tail, sizeof(terminator_tail));
+ terminator_tail = ntohl(terminator_tail);
+
+ if (terminator_head == terminator_tail)
+ info->consistent = 1;
+ else
+ info->consistent = 0;
+
+ return 0;
+}
+
+int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info) {
+ int fd, ret;
+
+ fd = open(filename, O_RDONLY, 0);
+ if (fd < 0) return -1;
+
+ ret = list_dump_getinfo_filedescriptor(fd, info);
+ close(fd);
+
+ return ret;
+}
+
+int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len) {
+ struct list_entry_s *x;
+ void *ser_buf;
+ uint32_t bufsize;
+ struct timeval timeofday;
+ struct list_dump_header_s header;
+
+ if (l->attrs.meter == NULL && l->attrs.serializer == NULL) {
+ errno = ENOTTY;
+ return -1;
+ }
+
+ /**** DUMP FORMAT ****
+
+ [ ver timestamp | totlen numels elemlen hash | DATA ]
+
+ where DATA can be:
+ @ for constant-size list (element size is constant; elemlen > 0)
+ [ elem elem ... elem ]
+ @ for other lists (element size dictated by element_meter each time; elemlen <= 0)
+ [ size elem size elem ... size elem ]
+
+ all integers are encoded in NETWORK BYTE FORMAT
+ *****/
+
+
+ /* prepare HEADER */
+ /* version */
+ header.ver = htons( SIMCLIST_DUMPFORMAT_VERSION );
+
+ /* timestamp */
+ gettimeofday(&timeofday, NULL);
+ header.timestamp_sec = htonl(timeofday.tv_sec);
+ header.timestamp_usec = htonl(timeofday.tv_usec);
+
+ header.rndterm = htonl((int32_t)get_random());
+
+ /* total list size is postprocessed afterwards */
+
+ /* number of elements */
+ header.numels = htonl(l->numels);
+
+ /* include an hash, if possible */
+ if (l->attrs.hasher != NULL) {
+ if (htonl(list_hash(l, & header.listhash)) != 0) {
+ /* could not compute list hash! */
+ return -1;
+ }
+ } else {
+ header.listhash = htonl(0);
+ }
+
+ header.totlistlen = header.elemlen = 0;
+
+ /* leave room for the header at the beginning of the file */
+ if (lseek(fd, SIMCLIST_DUMPFORMAT_HEADERLEN, SEEK_SET) < 0) {
+ /* errno set by lseek() */
+ return -1;
+ }
+
+ /* write CONTENT */
+ if (l->numels > 0) {
+ /* SPECULATE that the list has constant element size */
+
+ if (l->attrs.serializer != NULL) { /* user user-specified serializer */
+ /* get preliminary length of serialized element in header.elemlen */
+ ser_buf = l->attrs.serializer(l->head_sentinel->next->data, & header.elemlen);
+ free(ser_buf);
+ /* request custom serialization of each element */
+ for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) {
+ ser_buf = l->attrs.serializer(x->data, &bufsize);
+ header.totlistlen += bufsize;
+ if (header.elemlen != 0) { /* continue on speculation */
+ if (header.elemlen != bufsize) {
+ free(ser_buf);
+ /* constant element length speculation broken! */
+ header.elemlen = 0;
+ header.totlistlen = 0;
+ x = l->head_sentinel;
+ if (lseek(fd, SIMCLIST_DUMPFORMAT_HEADERLEN, SEEK_SET) < 0) {
+ /* errno set by lseek() */
+ return -1;
+ }
+ /* restart from the beginning */
+ continue;
+ }
+ /* speculation confirmed */
+ WRITE_ERRCHECK(fd, ser_buf, bufsize);
+ } else { /* speculation found broken */
+ WRITE_ERRCHECK(fd, & bufsize, sizeof(size_t));
+ WRITE_ERRCHECK(fd, ser_buf, bufsize);
+ }
+ free(ser_buf);
+ }
+ } else if (l->attrs.meter != NULL) {
+ header.elemlen = (uint32_t)l->attrs.meter(l->head_sentinel->next->data);
+
+ /* serialize the element straight from its data */
+ for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) {
+ bufsize = l->attrs.meter(x->data);
+ header.totlistlen += bufsize;
+ if (header.elemlen != 0) {
+ if (header.elemlen != bufsize) {
+ /* constant element length speculation broken! */
+ header.elemlen = 0;
+ header.totlistlen = 0;
+ x = l->head_sentinel;
+ /* restart from the beginning */
+ continue;
+ }
+ WRITE_ERRCHECK(fd, x->data, bufsize);
+ } else {
+ WRITE_ERRCHECK(fd, &bufsize, sizeof(size_t));
+ WRITE_ERRCHECK(fd, x->data, bufsize);
+ }
+ }
+ }
+ /* adjust endianness */
+ header.elemlen = htonl(header.elemlen);
+ header.totlistlen = htonl(header.totlistlen);
+ }
+
+ /* write random terminator */
+ WRITE_ERRCHECK(fd, & header.rndterm, sizeof(header.rndterm)); /* list terminator */
+
+
+ /* write header */
+ lseek(fd, 0, SEEK_SET);
+
+ WRITE_ERRCHECK(fd, & header.ver, sizeof(header.ver)); /* version */
+ WRITE_ERRCHECK(fd, & header.timestamp_sec, sizeof(header.timestamp_sec)); /* timestamp seconds */
+ WRITE_ERRCHECK(fd, & header.timestamp_usec, sizeof(header.timestamp_usec)); /* timestamp microseconds */
+ WRITE_ERRCHECK(fd, & header.rndterm, sizeof(header.rndterm)); /* random terminator */
+
+ WRITE_ERRCHECK(fd, & header.totlistlen, sizeof(header.totlistlen)); /* total length of elements */
+ WRITE_ERRCHECK(fd, & header.numels, sizeof(header.numels)); /* number of elements */
+ WRITE_ERRCHECK(fd, & header.elemlen, sizeof(header.elemlen)); /* size of each element, or 0 for independent */
+ WRITE_ERRCHECK(fd, & header.listhash, sizeof(header.listhash)); /* list hash, or 0 for "ignore" */
+
+
+ /* possibly store total written length in "len" */
+ if (len != NULL) {
+ *len = sizeof(header) + ntohl(header.totlistlen);
+ }
+
+ return 0;
+}
+
+int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len) {
+ struct list_dump_header_s header;
+ unsigned long cnt;
+ void *buf;
+ uint32_t elsize, totreadlen, totmemorylen;
+
+ memset(& header, 0, sizeof(header));
+
+ /* read header */
+
+ /* version */
+ READ_ERRCHECK(fd, &header.ver, sizeof(header.ver));
+ header.ver = ntohs(header.ver);
+ if (header.ver != SIMCLIST_DUMPFORMAT_VERSION) {
+ errno = EILSEQ;
+ return -1;
+ }
+
+ /* timestamp */
+ READ_ERRCHECK(fd, & header.timestamp_sec, sizeof(header.timestamp_sec));
+ header.timestamp_sec = ntohl(header.timestamp_sec);
+ READ_ERRCHECK(fd, & header.timestamp_usec, sizeof(header.timestamp_usec));
+ header.timestamp_usec = ntohl(header.timestamp_usec);
+
+ /* list terminator */
+ READ_ERRCHECK(fd, & header.rndterm, sizeof(header.rndterm));
+
+ header.rndterm = ntohl(header.rndterm);
+
+ /* total list size */
+ READ_ERRCHECK(fd, & header.totlistlen, sizeof(header.totlistlen));
+ header.totlistlen = ntohl(header.totlistlen);
+
+ /* number of elements */
+ READ_ERRCHECK(fd, & header.numels, sizeof(header.numels));
+ header.numels = ntohl(header.numels);
+
+ /* length of every element, or '0' = variable */
+ READ_ERRCHECK(fd, & header.elemlen, sizeof(header.elemlen));
+ header.elemlen = ntohl(header.elemlen);
+
+ /* list hash, or 0 = 'ignore' */
+ READ_ERRCHECK(fd, & header.listhash, sizeof(header.listhash));
+ header.listhash = ntohl(header.listhash);
+
+
+ /* read content */
+ totreadlen = totmemorylen = 0;
+ if (header.elemlen > 0) {
+ /* elements have constant size = header.elemlen */
+ if (l->attrs.unserializer != NULL) {
+ /* use unserializer */
+ buf = malloc(header.elemlen);
+ for (cnt = 0; cnt < header.numels; cnt++) {
+ READ_ERRCHECK(fd, buf, header.elemlen);
+ list_append(l, l->attrs.unserializer(buf, & elsize));
+ totmemorylen += elsize;
+ }
+ } else {
+ /* copy verbatim into memory */
+ for (cnt = 0; cnt < header.numels; cnt++) {
+ buf = malloc(header.elemlen);
+ READ_ERRCHECK(fd, buf, header.elemlen);
+ list_append(l, buf);
+ }
+ totmemorylen = header.numels * header.elemlen;
+ }
+ totreadlen = header.numels * header.elemlen;
+ } else {
+ /* elements have variable size. Each element is preceded by its size */
+ if (l->attrs.unserializer != NULL) {
+ /* use unserializer */
+ for (cnt = 0; cnt < header.numels; cnt++) {
+ READ_ERRCHECK(fd, & elsize, sizeof(elsize));
+ buf = malloc((size_t)elsize);
+ READ_ERRCHECK(fd, buf, elsize);
+ totreadlen += elsize;
+ list_append(l, l->attrs.unserializer(buf, & elsize));
+ totmemorylen += elsize;
+ }
+ } else {
+ /* copy verbatim into memory */
+ for (cnt = 0; cnt < header.numels; cnt++) {
+ READ_ERRCHECK(fd, & elsize, sizeof(elsize));
+ buf = malloc(elsize);
+ READ_ERRCHECK(fd, buf, elsize);
+ totreadlen += elsize;
+ list_append(l, buf);
+ }
+ totmemorylen = totreadlen;
+ }
+ }
+
+ READ_ERRCHECK(fd, &elsize, sizeof(elsize)); /* read list terminator */
+ elsize = ntohl(elsize);
+
+ /* possibly verify the list consistency */
+ /* wrt hash */
+ /* don't do that
+ if (header.listhash != 0 && header.listhash != list_hash(l)) {
+ errno = ECANCELED;
+ return -1;
+ }
+ */
+
+ /* wrt header */
+ if (totreadlen != header.totlistlen && (int32_t)elsize == header.rndterm) {
+ errno = EPROTO;
+ return -1;
+ }
+
+ /* wrt file */
+ if (lseek(fd, 0, SEEK_CUR) != lseek(fd, 0, SEEK_END)) {
+ errno = EPROTO;
+ return -1;
+ }
+
+ if (len != NULL) {
+ *len = totmemorylen;
+ }
+
+ return 0;
+}
+
+int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len) {
+ int fd, oflag, mode;
+
+#ifndef _WIN32
+ oflag = O_RDWR | O_CREAT | O_TRUNC;
+ mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+#else
+ oflag = _O_RDWR | _O_CREAT | _O_TRUNC;
+ mode = _S_IRUSR | _S_IWUSR | _S_IRGRP | _S_IROTH;
+#endif
+ fd = open(filename, oflag, mode);
+ if (fd < 0) return -1;
+
+ list_dump_filedescriptor(l, fd, len);
+ close(fd);
+
+ return 0;
+}
+
+int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *restrict len) {
+ int fd;
+
+ fd = open(filename, O_RDONLY, 0);
+ if (fd < 0) return -1;
+
+ list_restore_filedescriptor(l, fd, len);
+ close(fd);
+
+ return 0;
+}
+#endif /* ifndef SIMCLIST_NO_DUMPRESTORE */
+
+
+static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned int pos) {
+ if (tmp == NULL) return -1;
+
+ /* fix mid pointer. This is wrt the PRE situation */
+ if (l->numels % 2) { /* now odd */
+ /* sort out the base case by hand */
+ if (l->numels == 1) l->mid = NULL;
+ else if (pos >= l->numels/2) l->mid = l->mid->prev;
+ } else { /* now even */
+ if (pos < l->numels/2) l->mid = l->mid->next;
+ }
+
+ tmp->prev->next = tmp->next;
+ tmp->next->prev = tmp->prev;
+
+ /* free what's to be freed */
+ if (l->attrs.copy_data && tmp->data != NULL)
+ free(tmp->data);
+
+ if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) {
+ l->spareels[l->spareelsnum++] = tmp;
+ } else {
+ free(tmp);
+ }
+
+ return 0;
+}
+
+/* ready-made comparators and meters */
+#define SIMCLIST_NUMBER_COMPARATOR(type) int list_comparator_##type(const void *a, const void *b) { return( *(type *)a < *(type *)b) - (*(type *)a > *(type *)b); }
+
+SIMCLIST_NUMBER_COMPARATOR(int8_t)
+SIMCLIST_NUMBER_COMPARATOR(int16_t)
+SIMCLIST_NUMBER_COMPARATOR(int32_t)
+SIMCLIST_NUMBER_COMPARATOR(int64_t)
+
+SIMCLIST_NUMBER_COMPARATOR(uint8_t)
+SIMCLIST_NUMBER_COMPARATOR(uint16_t)
+SIMCLIST_NUMBER_COMPARATOR(uint32_t)
+SIMCLIST_NUMBER_COMPARATOR(uint64_t)
+
+SIMCLIST_NUMBER_COMPARATOR(float)
+SIMCLIST_NUMBER_COMPARATOR(double)
+
+int list_comparator_string(const void *a, const void *b) { return strcmp((const char *)b, (const char *)a); }
+
+/* ready-made metric functions */
+#define SIMCLIST_METER(type) size_t list_meter_##type(const void *el) { if (el) { /* kill compiler whinge */ } return sizeof(type); }
+
+SIMCLIST_METER(int8_t)
+SIMCLIST_METER(int16_t)
+SIMCLIST_METER(int32_t)
+SIMCLIST_METER(int64_t)
+
+SIMCLIST_METER(uint8_t)
+SIMCLIST_METER(uint16_t)
+SIMCLIST_METER(uint32_t)
+SIMCLIST_METER(uint64_t)
+
+SIMCLIST_METER(float)
+SIMCLIST_METER(double)
+
+size_t list_meter_string(const void *el) { return strlen((const char *)el) + 1; }
+
+/* ready-made hashing functions */
+#define SIMCLIST_HASHCOMPUTER(type) list_hash_t list_hashcomputer_##type(const void *el) { return (list_hash_t)(*(type *)el); }
+
+SIMCLIST_HASHCOMPUTER(int8_t)
+SIMCLIST_HASHCOMPUTER(int16_t)
+SIMCLIST_HASHCOMPUTER(int32_t)
+SIMCLIST_HASHCOMPUTER(int64_t)
+
+SIMCLIST_HASHCOMPUTER(uint8_t)
+SIMCLIST_HASHCOMPUTER(uint16_t)
+SIMCLIST_HASHCOMPUTER(uint32_t)
+SIMCLIST_HASHCOMPUTER(uint64_t)
+
+SIMCLIST_HASHCOMPUTER(float)
+SIMCLIST_HASHCOMPUTER(double)
+
+list_hash_t list_hashcomputer_string(const void *el) {
+ size_t l;
+ list_hash_t hash = 123;
+ const char *str = (const char *)el;
+ char plus;
+
+ for (l = 0; str[l] != '\0'; l++) {
+ if (l) plus = hash ^ str[l];
+ else plus = hash ^ (str[l] - str[0]);
+ hash += (plus << (CHAR_BIT * (l % sizeof(list_hash_t))));
+ }
+
+ return hash;
+}
+
+
+#ifndef NDEBUG
+static int list_repOk(const list_t *restrict l) {
+ int ok, i;
+ struct list_entry_s *s;
+
+ ok = (l != NULL) && (
+ /* head/tail checks */
+ (l->head_sentinel != NULL && l->tail_sentinel != NULL) &&
+ (l->head_sentinel != l->tail_sentinel) && (l->head_sentinel->prev == NULL && l->tail_sentinel->next == NULL) &&
+ /* empty list */
+ (l->numels > 0 || (l->mid == NULL && l->head_sentinel->next == l->tail_sentinel && l->tail_sentinel->prev == l->head_sentinel)) &&
+ /* spare elements checks */
+ l->spareelsnum <= SIMCLIST_MAX_SPARE_ELEMS
+ );
+
+ if (!ok) return 0;
+
+ if (l->numels >= 1) {
+ /* correct referencing */
+ for (i = -1, s = l->head_sentinel; i < (int)(l->numels-1)/2 && s->next != NULL; i++, s = s->next) {
+ if (s->next->prev != s) break;
+ }
+ ok = (i == (int)(l->numels-1)/2 && l->mid == s);
+ if (!ok) return 0;
+ for (; s->next != NULL; i++, s = s->next) {
+ if (s->next->prev != s) break;
+ }
+ ok = (i == (int)l->numels && s == l->tail_sentinel);
+ }
+
+ return ok;
+}
+
+static int list_attrOk(const list_t *restrict l) {
+ int ok;
+
+ ok = (l->attrs.copy_data == 0 || l->attrs.meter != NULL);
+ return ok;
+}
+
+#endif
+
diff --git a/libs/libks/src/table.c b/libs/libks/src/table.c
new file mode 100644
index 0000000000..4e28556eb9
--- /dev/null
+++ b/libs/libks/src/table.c
@@ -0,0 +1,4079 @@
+/*
+ * Generic hash table handler...
+ *
+ * Copyright 2000 by Gray Watson.
+ *
+ * This file is part of the table package.
+ *
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies, and that the name of Gray Watson not be used in advertising
+ * or publicity pertaining to distribution of the document or software
+ * without specific, written prior permission.
+ *
+ * Gray Watson makes no representations about the suitability of the
+ * software described herein for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * The author may be reached via http://256.com/gray/
+ *
+ * $Id: table.c,v 1.19 2000/03/09 03:30:41 gray Exp $
+ */
+
+/*
+ * Handles basic hash-table manipulations. This is an implementation
+ * of open hashing with an array of buckets holding linked lists of
+ * elements. Each element has a key and a data. The user indexes on
+ * the key to find the data. See the typedefs in table_loc.h for more
+ * information.
+ */
+
+#include
+#include
+#include
+#include
+
+#ifdef unix
+
+#include
+
+#else
+
+#include
+#include
+#define NO_MMAP
+#define open _open
+
+#endif
+
+#ifndef NO_MMAP
+
+#include
+#include
+
+#ifndef MAP_FAILED
+#define MAP_FAILED (caddr_t)0L
+#endif
+
+#endif
+
+#define TABLE_MAIN
+
+#include "table.h"
+#include "table_loc.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+static char *rcs_id =
+ "$Id: table.c,v 1.19 2000/03/09 03:30:41 gray Exp $";
+
+/*
+ * Version id for the library. You also need to add an entry to the
+ * NEWS and ChangeLog files.
+ */
+static char *version_id = "$TableVersion: 4.3.0 March 8, 2000 $";
+
+/****************************** local functions ******************************/
+
+/*
+ * static table_entry_t *first_entry
+ *
+ * DESCRIPTION:
+ *
+ * Return the first entry in the table. It will set the linear
+ * structure counter to the position of the first entry.
+ *
+ * RETURNS:
+ *
+ * Success: A pointer to the first entry in the table.
+ *
+ * Failure: NULL if there is no first entry.
+ *
+ * ARGUMENTS:
+ *
+ * table_p -> Table whose next entry we are finding.
+ *
+ * linear_p <-> Pointer to a linear structure which we will advance
+ * and then find the corresponding entry.
+ */
+static table_entry_t *first_entry(const table_t *table_p,
+ table_linear_t *linear_p)
+{
+ table_entry_t *entry_p;
+ unsigned int bucket_c = 0;
+
+ /* look for the first non-empty bucket */
+ for (bucket_c = 0; bucket_c < table_p->ta_bucket_n; bucket_c++) {
+ entry_p = table_p->ta_buckets[bucket_c];
+ if (entry_p != NULL) {
+ if (linear_p != NULL) {
+ linear_p->tl_bucket_c = bucket_c;
+ linear_p->tl_entry_c = 0;
+ }
+ return TABLE_POINTER(table_p, table_entry_t *, entry_p);
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * static table_entry_t *next_entry
+ *
+ * DESCRIPTION:
+ *
+ * Return the next entry in the table which is past the position in
+ * our linear pointer. It will advance the linear structure counters.
+ *
+ * RETURNS:
+ *
+ * Success: A pointer to the next entry in the table.
+ *
+ * Failure: NULL.
+ *
+ * ARGUMENTS:
+ *
+ * table_p -> Table whose next entry we are finding.
+ *
+ * linear_p <-> Pointer to a linear structure which we will advance
+ * and then find the corresponding entry.
+ *
+ * error_p <- Pointer to an integer which when the routine returns
+ * will contain a table error code.
+ */
+static table_entry_t *next_entry(const table_t *table_p,
+ table_linear_t *linear_p, int *error_p)
+{
+ table_entry_t *entry_p;
+ int entry_c;
+
+ /* can't next if we haven't first-ed */
+ if (linear_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_LINEAR);
+ return NULL;
+ }
+
+ if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) {
+ /*
+ * NOTE: this might happen if we delete an item which shortens the
+ * table bucket numbers.
+ */
+ SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND);
+ return NULL;
+ }
+
+ linear_p->tl_entry_c++;
+
+ /* find the entry which is the nth in the list */
+ entry_p = table_p->ta_buckets[linear_p->tl_bucket_c];
+ /* NOTE: we swap the order here to be more efficient */
+ for (entry_c = linear_p->tl_entry_c; entry_c > 0; entry_c--) {
+ /* did we reach the end of the list? */
+ if (entry_p == NULL) {
+ break;
+ }
+ entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p;
+ }
+
+ /* did we find an entry in the current bucket? */
+ if (entry_p != NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_NONE);
+ return TABLE_POINTER(table_p, table_entry_t *, entry_p);
+ }
+
+ /* find the first entry in the next non-empty bucket */
+
+ linear_p->tl_entry_c = 0;
+ for (linear_p->tl_bucket_c++; linear_p->tl_bucket_c < table_p->ta_bucket_n;
+ linear_p->tl_bucket_c++) {
+ entry_p = table_p->ta_buckets[linear_p->tl_bucket_c];
+ if (entry_p != NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_NONE);
+ return TABLE_POINTER(table_p, table_entry_t *, entry_p);
+ }
+ }
+
+ SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND);
+ return NULL;
+}
+
+/*
+ * static table_entry_t *this_entry
+ *
+ * DESCRIPTION:
+ *
+ * Return the entry pointer in the table which is currently being
+ * indicated by our linear pointer.
+ *
+ * RETURNS:
+ *
+ * Success: A pointer to the next entry in the table.
+ *
+ * Failure: NULL.
+ *
+ * ARGUMENTS:
+ *
+ * table_p -> Table whose next entry we are finding.
+ *
+ * linear_p -> Pointer to a linear structure which we will find the
+ * corresponding entry.
+ *
+ * error_p <- Pointer to an integer which when the routine returns
+ * will contain a table error code.
+ */
+static table_entry_t *this_entry(const table_t *table_p,
+ const table_linear_t *linear_p,
+ int *error_p)
+{
+ table_entry_t *entry_p;
+ int entry_c;
+
+ /* can't next if we haven't first-ed */
+ if (linear_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_LINEAR);
+ return NULL;
+ }
+
+ if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) {
+ /*
+ * NOTE: this might happen if we delete an item which shortens the
+ * table bucket numbers.
+ */
+ SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND);
+ return NULL;
+ }
+
+ /* find the entry which is the nth in the list */
+ entry_p = table_p->ta_buckets[linear_p->tl_bucket_c];
+
+ /* NOTE: we swap the order here to be more efficient */
+ for (entry_c = linear_p->tl_entry_c; entry_c > 0; entry_c--) {
+ /* did we reach the end of the list? */
+ if (entry_p == NULL) {
+ break;
+ }
+ entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p;
+ }
+
+ /* did we find an entry in the current bucket? */
+ if (entry_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND);
+ return NULL;
+ }
+ else {
+ SET_POINTER(error_p, TABLE_ERROR_NONE);
+ return TABLE_POINTER(table_p, table_entry_t *, entry_p);
+ }
+}
+
+/*
+ * static unsigned int hash
+ *
+ * DESCRIPTION:
+ *
+ * Hash a variable-length key into a 32-bit value. Every bit of the
+ * key affects every bit of the return value. Every 1-bit and 2-bit
+ * delta achieves avalanche. About (6 * len + 35) instructions. The
+ * best hash table sizes are powers of 2. There is no need to use mod
+ * (sooo slow!). If you need less than 32 bits, use a bitmask. For
+ * example, if you need only 10 bits, do h = (h & hashmask(10)); In
+ * which case, the hash table should have hashsize(10) elements.
+ *
+ * By Bob Jenkins, 1996. bob_jenkins@compuserve.com. You may use
+ * this code any way you wish, private, educational, or commercial.
+ * It's free. See
+ * http://ourworld.compuserve.com/homepages/bob_jenkins/evahash.htm
+ * Use for hash table lookup, or anything where one collision in 2^^32
+ * is acceptable. Do NOT use for cryptographic purposes.
+ *
+ * RETURNS:
+ *
+ * Returns a 32-bit hash value.
+ *
+ * ARGUMENTS:
+ *
+ * key - Key (the unaligned variable-length array of bytes) that we
+ * are hashing.
+ *
+ * length - Length of the key in bytes.
+ *
+ * init_val - Initialization value of the hash if you need to hash a
+ * number of strings together. For instance, if you are hashing N
+ * strings (unsigned char **)keys, do it like this:
+ *
+ * for (i=0, h=0; i= 12; len -= 12) {
+ a += (key_p[0]
+ + ((unsigned int)key_p[1] << 8)
+ + ((unsigned int)key_p[2] << 16)
+ + ((unsigned int)key_p[3] << 24));
+ b += (key_p[4]
+ + ((unsigned int)key_p[5] << 8)
+ + ((unsigned int)key_p[6] << 16)
+ + ((unsigned int)key_p[7] << 24));
+ c += (key_p[8]
+ + ((unsigned int)key_p[9] << 8)
+ + ((unsigned int)key_p[10] << 16)
+ + ((unsigned int)key_p[11] << 24));
+ HASH_MIX(a,b,c);
+ key_p += 12;
+ }
+
+ c += length;
+
+ /* all the case statements fall through to the next */
+ switch(len) {
+ case 11:
+ c += ((unsigned int)key_p[10] << 24);
+ case 10:
+ c += ((unsigned int)key_p[9] << 16);
+ case 9:
+ c += ((unsigned int)key_p[8] << 8);
+ /* the first byte of c is reserved for the length */
+ case 8:
+ b += ((unsigned int)key_p[7] << 24);
+ case 7:
+ b += ((unsigned int)key_p[6] << 16);
+ case 6:
+ b += ((unsigned int)key_p[5] << 8);
+ case 5:
+ b += key_p[4];
+ case 4:
+ a += ((unsigned int)key_p[3] << 24);
+ case 3:
+ a += ((unsigned int)key_p[2] << 16);
+ case 2:
+ a += ((unsigned int)key_p[1] << 8);
+ case 1:
+ a += key_p[0];
+ /* case 0: nothing left to add */
+ }
+ HASH_MIX(a, b, c);
+
+ return c;
+}
+
+/*
+ * static int entry_size
+ *
+ * DESCRIPTION:
+ *
+ * Calculates the appropriate size of an entry to include the key and
+ * data sizes as well as any associated alignment to the data.
+ *
+ * RETURNS:
+ *
+ * The associated size of the entry.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table associated with the entries whose size we are
+ * determining.
+ *
+ * key_size - Size of the entry key.
+ *
+ * data - Size of the entry data.
+ */
+static int entry_size(const table_t *table_p, const unsigned int key_size,
+ const unsigned int data_size)
+{
+ int size, left;
+
+ /* initial size -- key is already aligned if right after struct */
+ size = sizeof(struct table_shell_st) + key_size;
+
+ /* if there is no alignment then it is easy */
+ if (table_p->ta_data_align == 0) {
+ return size + data_size;
+ }
+
+ /* add in our alignement */
+ left = size & (table_p->ta_data_align - 1);
+ if (left > 0) {
+ size += table_p->ta_data_align - left;
+ }
+
+ /* we add the data size here after the alignment */
+ size += data_size;
+
+ return size;
+}
+
+/*
+ * static unsigned char *entry_data_buf
+ *
+ * DESCRIPTION:
+ *
+ * Companion to the ENTRY_DATA_BUF macro but this handles any
+ * associated alignment to the data in the entry.
+ *
+ * NOTE: we assume here that the data-alignment is > 0.
+ *
+ * RETURNS:
+ *
+ * Pointer to the data segment of the entry.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table associated with the entry.
+ *
+ * entry_p - Entry whose data pointer we are determining.
+ */
+static unsigned char *entry_data_buf(const table_t *table_p,
+ const table_entry_t *entry_p)
+{
+ const unsigned char *buf_p;
+ unsigned int size, pad;
+
+ buf_p = entry_p->te_key_buf + entry_p->te_key_size;
+
+ /* we need the size of the space before the data */
+ size = sizeof(struct table_shell_st) + entry_p->te_key_size;
+
+ /* add in our alignment */
+ pad = size & (table_p->ta_data_align - 1);
+ if (pad > 0) {
+ pad = table_p->ta_data_align - pad;
+ }
+
+ return (unsigned char *)buf_p + pad;
+}
+
+/******************************* sort routines *******************************/
+
+/*
+ * static int local_compare
+ *
+ * DESCRIPTION:
+ *
+ * Compare two entries by calling user's compare program or by using
+ * memcmp.
+ *
+ * RETURNS:
+ *
+ * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2.
+ *
+ * ARGUMENTS:
+ *
+ * p1 - First entry pointer to compare.
+ *
+ * p2 - Second entry pointer to compare.
+ *
+ * compare - User comparison function. Ignored.
+ *
+ * table_p - Associated table being ordered. Ignored.
+ *
+ * err_bp - Pointer to an integer which will be set with 1 if an error
+ * has occurred. It cannot be NULL.
+ */
+static int local_compare(const void *p1, const void *p2,
+ table_compare_t compare, const table_t *table_p,
+ int *err_bp)
+{
+ const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2;
+ int cmp;
+ unsigned int size;
+
+ /* compare as many bytes as we can */
+ size = (*ent1_p)->te_key_size;
+ if ((*ent2_p)->te_key_size < size) {
+ size = (*ent2_p)->te_key_size;
+ }
+ cmp = memcmp(ENTRY_KEY_BUF(*ent1_p), ENTRY_KEY_BUF(*ent2_p), size);
+ /* if common-size equal, then if next more bytes, it is larger */
+ if (cmp == 0) {
+ cmp = (*ent1_p)->te_key_size - (*ent2_p)->te_key_size;
+ }
+
+ *err_bp = 0;
+ return cmp;
+}
+
+/*
+ * static int local_compare_pos
+ *
+ * DESCRIPTION:
+ *
+ * Compare two entries by calling user's compare program or by using
+ * memcmp.
+ *
+ * RETURNS:
+ *
+ * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2.
+ *
+ * ARGUMENTS:
+ *
+ * p1 - First entry pointer to compare.
+ *
+ * p2 - Second entry pointer to compare.
+ *
+ * compare - User comparison function. Ignored.
+ *
+ * table_p - Associated table being ordered.
+ *
+ * err_bp - Pointer to an integer which will be set with 1 if an error
+ * has occurred. It cannot be NULL.
+ */
+static int local_compare_pos(const void *p1, const void *p2,
+ table_compare_t compare,
+ const table_t *table_p, int *err_bp)
+{
+ const table_linear_t *lin1_p = p1, *lin2_p = p2;
+ const table_entry_t *ent1_p, *ent2_p;
+ int cmp, ret;
+ unsigned int size;
+
+ /* get entry pointers */
+ ent1_p = this_entry(table_p, lin1_p, &ret);
+ ent2_p = this_entry(table_p, lin2_p, &ret);
+ if (ent1_p == NULL || ent2_p == NULL) {
+ *err_bp = 1;
+ return 0;
+ }
+
+ /* compare as many bytes as we can */
+ size = ent1_p->te_key_size;
+ if (ent2_p->te_key_size < size) {
+ size = ent2_p->te_key_size;
+ }
+ cmp = memcmp(ENTRY_KEY_BUF(ent1_p), ENTRY_KEY_BUF(ent2_p), size);
+ /* if common-size equal, then if next more bytes, it is larger */
+ if (cmp == 0) {
+ cmp = ent1_p->te_key_size - ent2_p->te_key_size;
+ }
+
+ *err_bp = 0;
+ return cmp;
+}
+
+/*
+ * static int external_compare
+ *
+ * DESCRIPTION:
+ *
+ * Compare two entries by calling user's compare program or by using
+ * memcmp.
+ *
+ * RETURNS:
+ *
+ * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2.
+ *
+ * ARGUMENTS:
+ *
+ * p1 - First entry pointer to compare.
+ *
+ * p2 - Second entry pointer to compare.
+ *
+ * user_compare - User comparison function.
+ *
+ * table_p - Associated table being ordered.
+ *
+ * err_bp - Pointer to an integer which will be set with 1 if an error
+ * has occurred. It cannot be NULL.
+ */
+static int external_compare(const void *p1, const void *p2,
+ table_compare_t user_compare,
+ const table_t *table_p, int *err_bp)
+{
+ const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2;
+ /* since we know we are not aligned we can use the EXTRY_DATA_BUF macro */
+ *err_bp = 0;
+ return user_compare(ENTRY_KEY_BUF(*ent1_p), (*ent1_p)->te_key_size,
+ ENTRY_DATA_BUF(table_p, *ent1_p),
+ (*ent1_p)->te_data_size,
+ ENTRY_KEY_BUF(*ent2_p), (*ent2_p)->te_key_size,
+ ENTRY_DATA_BUF(table_p, *ent2_p),
+ (*ent2_p)->te_data_size);
+}
+
+/*
+ * static int external_compare_pos
+ *
+ * DESCRIPTION:
+ *
+ * Compare two entries by calling user's compare program or by using
+ * memcmp.
+ *
+ * RETURNS:
+ *
+ * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2.
+ *
+ * ARGUMENTS:
+ *
+ * p1 - First entry pointer to compare.
+ *
+ * p2 - Second entry pointer to compare.
+ *
+ * user_compare - User comparison function.
+ *
+ * table_p - Associated table being ordered.
+ *
+ * err_bp - Pointer to an integer which will be set with 1 if an error
+ * has occurred. It cannot be NULL.
+*/
+static int external_compare_pos(const void *p1, const void *p2,
+ table_compare_t user_compare,
+ const table_t *table_p, int *err_bp)
+{
+ const table_linear_t *lin1_p = p1, *lin2_p = p2;
+ const table_entry_t *ent1_p, *ent2_p;
+ int ret;
+
+ /* get entry pointers */
+ ent1_p = this_entry(table_p, lin1_p, &ret);
+ ent2_p = this_entry(table_p, lin2_p, &ret);
+ if (ent1_p == NULL || ent2_p == NULL) {
+ *err_bp = 1;
+ return 0;
+ }
+
+ /* since we know we are not aligned we can use the EXTRY_DATA_BUF macro */
+ *err_bp = 0;
+ return user_compare(ENTRY_KEY_BUF(ent1_p), (ent1_p)->te_key_size,
+ ENTRY_DATA_BUF(table_p, ent1_p), ent1_p->te_data_size,
+ ENTRY_KEY_BUF(ent2_p), ent2_p->te_key_size,
+ ENTRY_DATA_BUF(table_p, ent2_p), ent2_p->te_data_size);
+}
+
+/*
+ * static int external_compare_align
+ *
+ * DESCRIPTION:
+ *
+ * Compare two entries by calling user's compare program or by using
+ * memcmp. Alignment information is necessary.
+ *
+ * RETURNS:
+ *
+ * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2.
+ *
+ * ARGUMENTS:
+ *
+ * p1 - First entry pointer to compare.
+ *
+ * p2 - Second entry pointer to compare.
+ *
+ * user_compare - User comparison function.
+ *
+ * table_p - Associated table being ordered.
+ *
+ * err_bp - Pointer to an integer which will be set with 1 if an error
+ * has occurred. It cannot be NULL.
+ */
+static int external_compare_align(const void *p1, const void *p2,
+ table_compare_t user_compare,
+ const table_t *table_p, int *err_bp)
+{
+ const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2;
+ /* since we are aligned we have to use the entry_data_buf function */
+ *err_bp = 0;
+ return user_compare(ENTRY_KEY_BUF(*ent1_p), (*ent1_p)->te_key_size,
+ entry_data_buf(table_p, *ent1_p),
+ (*ent1_p)->te_data_size,
+ ENTRY_KEY_BUF(*ent2_p), (*ent2_p)->te_key_size,
+ entry_data_buf(table_p, *ent2_p),
+ (*ent2_p)->te_data_size);
+}
+
+/*
+ * static int external_compare_align_pos
+ *
+ * DESCRIPTION:
+ *
+ * Compare two entries by calling user's compare program or by using
+ * memcmp. Alignment information is necessary.
+ *
+ * RETURNS:
+ *
+ * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2.
+ *
+ * ARGUMENTS:
+ *
+ * p1 - First entry pointer to compare.
+ *
+ * p2 - Second entry pointer to compare.
+ *
+ * user_compare - User comparison function.
+ *
+ * table_p - Associated table being ordered.
+ *
+ * err_bp - Pointer to an integer which will be set with 1 if an error
+ * has occurred. It cannot be NULL.
+ */
+static int external_compare_align_pos(const void *p1, const void *p2,
+ table_compare_t user_compare,
+ const table_t *table_p, int *err_bp)
+{
+ const table_linear_t *lin1_p = p1, *lin2_p = p2;
+ const table_entry_t *ent1_p, *ent2_p;
+ int ret;
+
+ /* get entry pointers */
+ ent1_p = this_entry(table_p, lin1_p, &ret);
+ ent2_p = this_entry(table_p, lin2_p, &ret);
+ if (ent1_p == NULL || ent2_p == NULL) {
+ *err_bp = 1;
+ return 0;
+ }
+
+ /* since we are aligned we have to use the entry_data_buf function */
+ *err_bp = 0;
+ return user_compare(ENTRY_KEY_BUF(ent1_p), ent1_p->te_key_size,
+ entry_data_buf(table_p, ent1_p), ent1_p->te_data_size,
+ ENTRY_KEY_BUF(ent2_p), ent2_p->te_key_size,
+ entry_data_buf(table_p, ent2_p), ent2_p->te_data_size);
+}
+
+/*
+ * static void swap_bytes
+ *
+ * DESCRIPTION:
+ *
+ * Swap the values between two items of a specified size.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * item1_p -> Pointer to the first item.
+ *
+ * item2_p -> Pointer to the first item.
+ *
+ * ele_size -> Size of the two items.
+ */
+static void swap_bytes(unsigned char *item1_p, unsigned char *item2_p,
+ int ele_size)
+{
+ unsigned char char_temp;
+
+ for (; ele_size > 0; ele_size--) {
+ char_temp = *item1_p;
+ *item1_p = *item2_p;
+ *item2_p = char_temp;
+ item1_p++;
+ item2_p++;
+ }
+}
+
+/*
+ * static void insert_sort
+ *
+ * DESCRIPTION:
+ *
+ * Do an insertion sort which is faster for small numbers of items and
+ * better if the items are already sorted.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * first_p <-> Start of the list that we are splitting.
+ *
+ * last_p <-> Last entry in the list that we are splitting.
+ *
+ * holder_p <-> Location of hold area we can store an entry.
+ *
+ * ele_size -> Size of the each element in the list.
+ *
+ * compare -> Our comparison function.
+ *
+ * user_compare -> User comparison function. Could be NULL if we are
+ * just using a local comparison function.
+ *
+ * table_p -> Associated table being sorted.
+ */
+static int insert_sort(unsigned char *first_p, unsigned char *last_p,
+ unsigned char *holder_p,
+ const unsigned int ele_size, compare_t compare,
+ table_compare_t user_compare, table_t *table_p)
+{
+ unsigned char *inner_p, *outer_p;
+ int ret, err_b;
+
+ for (outer_p = first_p + ele_size; outer_p <= last_p; ) {
+
+ /* look for the place to insert the entry */
+ for (inner_p = outer_p - ele_size;
+ inner_p >= first_p;
+ inner_p -= ele_size) {
+ ret = compare(outer_p, inner_p, user_compare, table_p, &err_b);
+ if (err_b) {
+ return TABLE_ERROR_COMPARE;
+ }
+ if (ret >= 0) {
+ break;
+ }
+ }
+ inner_p += ele_size;
+
+ /* do we need to insert the entry in? */
+ if (outer_p != inner_p) {
+ /*
+ * Now we shift the entry down into its place in the already
+ * sorted list.
+ */
+ memcpy(holder_p, outer_p, ele_size);
+ memmove(inner_p + ele_size, inner_p, outer_p - inner_p);
+ memcpy(inner_p, holder_p, ele_size);
+ }
+
+ outer_p += ele_size;
+ }
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * static int split
+ *
+ * DESCRIPTION:
+ *
+ * This sorts an array of longs via the quick sort algorithm (it's
+ * pretty quick)
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * first_p -> Start of the list that we are splitting.
+ *
+ * last_p -> Last entry in the list that we are splitting.
+ *
+ * ele_size -> Size of the each element in the list.
+ *
+ * compare -> Our comparison function.
+ *
+ * user_compare -> User comparison function. Could be NULL if we are
+ * just using a local comparison function.
+ *
+ * table_p -> Associated table being sorted.
+ */
+static int split(unsigned char *first_p, unsigned char *last_p,
+ const unsigned int ele_size, compare_t compare,
+ table_compare_t user_compare, table_t *table_p)
+{
+ unsigned char *left_p, *right_p, *pivot_p, *left_last_p, *right_first_p;
+ unsigned char *firsts[MAX_QSORT_SPLITS], *lasts[MAX_QSORT_SPLITS], *pivot;
+ unsigned int width, split_c = 0;
+ int size1, size2, min_qsort_size;
+ int ret, err_b;
+
+ /*
+ * Allocate some space for our pivot value. We also use this as
+ * holder space for our insert sort.
+ */
+ pivot = alloca(ele_size);
+ if (pivot == NULL) {
+ /* what else can we do? */
+ abort();
+ }
+
+ min_qsort_size = MAX_QSORT_MANY * ele_size;
+
+ while (1) {
+
+ /* find the left, right, and mid point */
+ left_p = first_p;
+ right_p = last_p;
+ /* is there a faster way to find this? */
+ width = (last_p - first_p) / ele_size;
+ pivot_p = first_p + ele_size * (width >> 1);
+
+ /*
+ * Find which of the left, middle, and right elements is the
+ * median (Knuth vol3 p123).
+ */
+ ret = compare(first_p, pivot_p, user_compare, table_p, &err_b);
+ if (err_b) {
+ return TABLE_ERROR_COMPARE;
+ }
+ if (ret > 0) {
+ swap_bytes(first_p, pivot_p, ele_size);
+ }
+ ret = compare(pivot_p, last_p, user_compare, table_p, &err_b);
+ if (err_b) {
+ return TABLE_ERROR_COMPARE;
+ }
+ if (ret > 0) {
+ swap_bytes(pivot_p, last_p, ele_size);
+ ret = compare(first_p, pivot_p, user_compare, table_p, &err_b);
+ if (err_b) {
+ return TABLE_ERROR_COMPARE;
+ }
+ if (ret > 0) {
+ swap_bytes(first_p, pivot_p, ele_size);
+ }
+ }
+
+ /*
+ * save our pivot so we don't have to worry about hitting and
+ * swapping it elsewhere while we iterate across the list below.
+ */
+ memcpy(pivot, pivot_p, ele_size);
+
+ do {
+
+ /* shift the left side up until we reach the pivot value */
+ while (1) {
+ ret = compare(left_p, pivot, user_compare, table_p, &err_b);
+ if (err_b) {
+ return TABLE_ERROR_COMPARE;
+ }
+ if (ret >= 0) {
+ break;
+ }
+ left_p += ele_size;
+ }
+ /* shift the right side down until we reach the pivot value */
+ while (1) {
+ ret = compare(pivot, right_p, user_compare, table_p, &err_b);
+ if (err_b) {
+ return TABLE_ERROR_COMPARE;
+ }
+ if (ret >= 0) {
+ break;
+ }
+ right_p -= ele_size;
+ }
+
+ /* if we met in the middle then we are done */
+ if (left_p == right_p) {
+ left_p += ele_size;
+ right_p -= ele_size;
+ break;
+ }
+ else if (left_p < right_p) {
+ /*
+ * swap the left and right since they both were on the wrong
+ * size of the pivot and continue
+ */
+ swap_bytes(left_p, right_p, ele_size);
+ left_p += ele_size;
+ right_p -= ele_size;
+ }
+ } while (left_p <= right_p);
+
+ /* Rename variables to make more sense. This will get optimized out. */
+ right_first_p = left_p;
+ left_last_p = right_p;
+
+ /* determine the size of the left and right hand parts */
+ size1 = left_last_p - first_p;
+ size2 = last_p - right_first_p;
+
+ /* is the 1st half small enough to just insert-sort? */
+ if (size1 < min_qsort_size) {
+
+ /* use the pivot as our temporary space */
+ ret = insert_sort(first_p, left_last_p, pivot, ele_size, compare,
+ user_compare, table_p);
+ if (ret != TABLE_ERROR_NONE) {
+ return ret;
+ }
+
+ /* is the 2nd part small as well? */
+ if (size2 < min_qsort_size) {
+
+ /* use the pivot as our temporary space */
+ ret = insert_sort(right_first_p, last_p, pivot, ele_size, compare,
+ user_compare, table_p);
+ if (ret != TABLE_ERROR_NONE) {
+ return ret;
+ }
+
+ /* pop a partition off our stack */
+ if (split_c == 0) {
+ /* we are done */
+ return TABLE_ERROR_NONE;
+ }
+ split_c--;
+ first_p = firsts[split_c];
+ last_p = lasts[split_c];
+ }
+ else {
+ /* we can just handle the right side immediately */
+ first_p = right_first_p;
+ /* last_p = last_p */
+ }
+ }
+ else if (size2 < min_qsort_size) {
+
+ /* use the pivot as our temporary space */
+ ret = insert_sort(right_first_p, last_p, pivot, ele_size, compare,
+ user_compare, table_p);
+ if (ret != TABLE_ERROR_NONE) {
+ return ret;
+ }
+
+ /* we can just handle the left side immediately */
+ /* first_p = first_p */
+ last_p = left_last_p;
+ }
+ else {
+ /*
+ * neither partition is small, we'll have to push the larger one
+ * of them on the stack
+ */
+ if (split_c >= MAX_QSORT_SPLITS) {
+ /* sanity check here -- we should never get here */
+ abort();
+ }
+ if (size1 > size2) {
+ /* push the left partition on the stack */
+ firsts[split_c] = first_p;
+ lasts[split_c] = left_last_p;
+ split_c++;
+ /* continue handling the right side */
+ first_p = right_first_p;
+ /* last_p = last_p */
+ }
+ else {
+ /* push the right partition on the stack */
+ firsts[split_c] = right_first_p;
+ lasts[split_c] = last_p;
+ split_c++;
+ /* continue handling the left side */
+ /* first_p = first_p */
+ last_p = left_last_p;
+ }
+ }
+ }
+
+ return TABLE_ERROR_NONE;
+}
+
+/*************************** exported routines *******************************/
+
+/*
+ * table_t *table_alloc
+ *
+ * DESCRIPTION:
+ *
+ * Allocate a new table structure.
+ *
+ * RETURNS:
+ *
+ * A pointer to the new table structure which must be passed to
+ * table_free to be deallocated. On error a NULL is returned.
+ *
+ * ARGUMENTS:
+ *
+ * bucket_n - Number of buckets for the hash table. Our current hash
+ * value works best with base two numbers. Set to 0 to take the
+ * library default of 1024.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+table_t *table_alloc(const unsigned int bucket_n, int *error_p)
+{
+ table_t *table_p = NULL;
+ unsigned int buck_n;
+
+ /* allocate a table structure */
+ table_p = malloc(sizeof(table_t));
+ if (table_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ALLOC);
+ return NULL;
+ }
+
+ if (bucket_n > 0) {
+ buck_n = bucket_n;
+ }
+ else {
+ buck_n = DEFAULT_SIZE;
+ }
+
+ /* allocate the buckets which are NULLed */
+ table_p->ta_buckets = (table_entry_t **)calloc(buck_n,
+ sizeof(table_entry_t *));
+ if (table_p->ta_buckets == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ALLOC);
+ free(table_p);
+ return NULL;
+ }
+
+ /* initialize structure */
+ table_p->ta_magic = TABLE_MAGIC;
+ table_p->ta_flags = 0;
+ table_p->ta_bucket_n = buck_n;
+ table_p->ta_entry_n = 0;
+ table_p->ta_data_align = 0;
+ table_p->ta_linear.tl_magic = 0;
+ table_p->ta_linear.tl_bucket_c = 0;
+ table_p->ta_linear.tl_entry_c = 0;
+ table_p->ta_mmap = NULL;
+ table_p->ta_file_size = 0;
+ table_p->ta_mem_pool = NULL;
+ table_p->ta_alloc_func = NULL;
+ table_p->ta_resize_func = NULL;
+ table_p->ta_free_func = NULL;
+
+ SET_POINTER(error_p, TABLE_ERROR_NONE);
+ return table_p;
+}
+
+/*
+ * table_t *table_alloc_in_pool
+ *
+ * DESCRIPTION:
+ *
+ * Allocate a new table structure in a memory pool or using
+ * alternative allocation and free functions.
+ *
+ * RETURNS:
+ *
+ * A pointer to the new table structure which must be passed to
+ * table_free to be deallocated. On error a NULL is returned.
+ *
+ * ARGUMENTS:
+ *
+ * bucket_n - Number of buckets for the hash table. Our current hash
+ * value works best with base two numbers. Set to 0 to take the
+ * library default of 1024.
+ *
+ * mem_pool <-> Memory pool to associate with the table. Can be NULL.
+ *
+ * alloc_func -> Allocate function we are overriding malloc() with.
+ *
+ * resize_func -> Resize function we are overriding the standard
+ * memory resize/realloc with. This can be NULL in which cause the
+ * library will allocate, copy, and free itself.
+ *
+ * free_func -> Free function we are overriding free() with.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+table_t *table_alloc_in_pool(const unsigned int bucket_n,
+ void *mem_pool,
+ table_mem_alloc_t alloc_func,
+ table_mem_resize_t resize_func,
+ table_mem_free_t free_func, int *error_p)
+{
+ table_t *table_p = NULL;
+ unsigned int buck_n, size;
+
+ /* make sure we have real functions, mem_pool and resize_func can be NULL */
+ if (alloc_func == NULL || free_func == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ARG_NULL);
+ return NULL;
+ }
+
+ /* allocate a table structure */
+ table_p = alloc_func(mem_pool, sizeof(table_t));
+ if (table_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ALLOC);
+ return NULL;
+ }
+
+ if (bucket_n > 0) {
+ buck_n = bucket_n;
+ }
+ else {
+ buck_n = DEFAULT_SIZE;
+ }
+
+ /* allocate the buckets which are NULLed */
+ size = buck_n * sizeof(table_entry_t *);
+ table_p->ta_buckets = (table_entry_t **)alloc_func(mem_pool, size);
+ if (table_p->ta_buckets == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ALLOC);
+ (void)free_func(mem_pool, table_p, sizeof(table_t));
+ return NULL;
+ }
+ /*
+ * We zero it ourselves to save the necessity of having a
+ * table_mem_calloc_t memory override function.
+ */
+ memset(table_p->ta_buckets, 0, size);
+
+ /* initialize structure */
+ table_p->ta_magic = TABLE_MAGIC;
+ table_p->ta_flags = 0;
+ table_p->ta_bucket_n = buck_n;
+ table_p->ta_entry_n = 0;
+ table_p->ta_data_align = 0;
+ table_p->ta_linear.tl_magic = 0;
+ table_p->ta_linear.tl_bucket_c = 0;
+ table_p->ta_linear.tl_entry_c = 0;
+ table_p->ta_mmap = NULL;
+ table_p->ta_file_size = 0;
+ table_p->ta_mem_pool = mem_pool;
+ table_p->ta_alloc_func = alloc_func;
+ table_p->ta_resize_func = resize_func;
+ table_p->ta_free_func = free_func;
+
+ SET_POINTER(error_p, TABLE_ERROR_NONE);
+ return table_p;
+}
+
+/*
+ * int table_attr
+ *
+ * DESCRIPTION:
+ *
+ * Set the attributes for the table. The available attributes are
+ * specified at the top of table.h.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to a table structure which we will be altering.
+ *
+ * attr - Attribute(s) that we will be applying to the table.
+ */
+int table_attr(table_t *table_p, const int attr)
+{
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+
+ table_p->ta_flags = attr;
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_set_data_alignment
+ *
+ * DESCRIPTION:
+ *
+ * Set the alignment for the data in the table. This is used when you
+ * want to store binary data types and refer to them directly out of
+ * the table storage. For instance if you are storing integers as
+ * data in the table and want to be able to retrieve the location of
+ * the interger and then increment it as (*loc_p)++. Otherwise you
+ * would have to memcpy it out to an integer, increment it, and memcpy
+ * it back. If you are storing character data, no alignment is
+ * necessary.
+ *
+ * For most data elements, sizeof(long) is recommended unless you use
+ * smaller data types exclusively.
+ *
+ * WARNING: If necessary, you must set the data alignment before any
+ * data gets put into the table. Otherwise a TABLE_ERROR_NOT_EMPTY
+ * error will be returned.
+ *
+ * NOTE: there is no way to set the key data alignment although it
+ * should automatically be long aligned.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to a table structure which we will be altering.
+ *
+ * alignment - Alignment requested for the data. Must be a power of
+ * 2. Set to 0 for none.
+ */
+int table_set_data_alignment(table_t *table_p, const int alignment)
+{
+ int val;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (table_p->ta_entry_n > 0) {
+ return TABLE_ERROR_NOT_EMPTY;
+ }
+
+ /* defaults */
+ if (alignment < 2) {
+ table_p->ta_data_align = 0;
+ }
+ else {
+ /* verify we have a base 2 number */
+ for (val = 2; val < MAX_ALIGNMENT; val *= 2) {
+ if (val == alignment) {
+ break;
+ }
+ }
+ if (val >= MAX_ALIGNMENT) {
+ return TABLE_ERROR_ALIGNMENT;
+ }
+ table_p->ta_data_align = alignment;
+ }
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_clear
+ *
+ * DESCRIPTION:
+ *
+ * Clear out and free all elements in a table structure.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer that we will be clearing.
+ */
+int table_clear(table_t *table_p)
+{
+ int final = TABLE_ERROR_NONE;
+ table_entry_t *entry_p, *next_p;
+ table_entry_t **bucket_p, **bounds_p;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+
+#ifndef NO_MMAP
+ /* no mmap support so immediate error */
+ if (table_p->ta_mmap != NULL) {
+ return TABLE_ERROR_MMAP_OP;
+ }
+#endif
+
+ /* free the table allocation and table structure */
+ bounds_p = table_p->ta_buckets + table_p->ta_bucket_n;
+ for (bucket_p = table_p->ta_buckets; bucket_p < bounds_p; bucket_p++) {
+ for (entry_p = *bucket_p; entry_p != NULL; entry_p = next_p) {
+ /* record the next pointer before we free */
+ next_p = entry_p->te_next_p;
+ if (table_p->ta_free_func == NULL) {
+ free(entry_p);
+ }
+ else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p,
+ entry_size(table_p,
+ entry_p->te_key_size,
+ entry_p->te_data_size))) {
+ final = TABLE_ERROR_FREE;
+ }
+ }
+
+ /* clear the bucket entry after we free its entries */
+ *bucket_p = NULL;
+ }
+
+ /* reset table state info */
+ table_p->ta_entry_n = 0;
+ table_p->ta_linear.tl_magic = 0;
+ table_p->ta_linear.tl_bucket_c = 0;
+ table_p->ta_linear.tl_entry_c = 0;
+
+ return final;
+}
+
+/*
+ * int table_free
+ *
+ * DESCRIPTION:
+ *
+ * Deallocates a table structure.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer that we will be freeing.
+ */
+int table_free(table_t *table_p)
+{
+ int ret;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+
+#ifndef NO_MMAP
+ /* no mmap support so immediate error */
+ if (table_p->ta_mmap != NULL) {
+ return TABLE_ERROR_MMAP_OP;
+ }
+#endif
+
+ ret = table_clear(table_p);
+
+ if (table_p->ta_buckets != NULL) {
+ if (table_p->ta_free_func == NULL) {
+ free(table_p->ta_buckets);
+ }
+ else if (! table_p->ta_free_func(table_p->ta_mem_pool,
+ table_p->ta_buckets,
+ table_p->ta_bucket_n *
+ sizeof(table_entry_t *))) {
+ return TABLE_ERROR_FREE;
+ }
+ }
+ table_p->ta_magic = 0;
+ if (table_p->ta_free_func == NULL) {
+ free(table_p);
+ }
+ else if (! table_p->ta_free_func(table_p->ta_mem_pool, table_p,
+ sizeof(table_t))) {
+ if (ret == TABLE_ERROR_NONE) {
+ ret = TABLE_ERROR_FREE;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * int table_insert_kd
+ *
+ * DESCRIPTION:
+ *
+ * Like table_insert except it passes back a pointer to the key and
+ * the data buffers after they have been inserted into the table
+ * structure.
+ *
+ * This routine adds a key/data pair both of which are made up of a
+ * buffer of bytes and an associated size. Both the key and the data
+ * will be copied into buffers allocated inside the table. If the key
+ * exists already, the associated data will be replaced if the
+ * overwrite flag is set, otherwise an error is returned.
+ *
+ * NOTE: be very careful changing the values since the table library
+ * provides the pointers to its memory. The key can _never_ be
+ * changed otherwise you will not find it again. The data can be
+ * changed but its length can never be altered unless you delete and
+ * re-insert it into the table.
+ *
+ * WARNING: The pointers to the key and data are not in any specific
+ * alignment. Accessing the key and/or data as an short, integer, or
+ * long pointer directly can cause problems.
+ *
+ * WARNING: Replacing a data cell (not inserting) will cause the table
+ * linked list to be temporarily invalid. Care must be taken with
+ * multiple threaded programs which are relying on the first/next
+ * linked list to be always valid.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer into which we will be inserting a
+ * new key/data pair.
+ *
+ * key_buf - Buffer of bytes of the key that we are inserting. If you
+ * are storing an (int) as the key (for example) then key_buf should
+ * be a (int *).
+ *
+ * key_size - Size of the key_buf buffer. If set to < 0 then the
+ * library will do a strlen of key_buf and add 1 for the '\0'. If you
+ * are storing an (int) as the key (for example) then key_size should
+ * be sizeof(int).
+ *
+ * data_buf - Buffer of bytes of the data that we are inserting. If
+ * it is NULL then the library will allocate space for the data in the
+ * table without copying in any information. If data_buf is NULL and
+ * data_size is 0 then the library will associate a NULL data pointer
+ * with the key. If you are storing a (long) as the data (for
+ * example) then data_buf should be a (long *).
+ *
+ * data_size - Size of the data_buf buffer. If set to < 0 then the
+ * library will do a strlen of data_buf and add 1 for the '\0'. If
+ * you are storing an (long) as the key (for example) then key_size
+ * should be sizeof(long).
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the key storage that was allocated in the table. If you are
+ * storing an (int) as the key (for example) then key_buf_p should be
+ * (int **) i.e. the address of a (int *).
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that was allocated in the table. If you are
+ * storing an (long) as the data (for example) then data_buf_p should
+ * be (long **) i.e. the address of a (long *).
+ *
+ * overwrite - Flag which, if set to 1, will allow the overwriting of
+ * the data in the table with the new data if the key already exists
+ * in the table.
+ */
+int table_insert_kd(table_t *table_p,
+ const void *key_buf, const int key_size,
+ const void *data_buf, const int data_size,
+ void **key_buf_p, void **data_buf_p,
+ const char overwrite_b)
+{
+ int bucket;
+ unsigned int ksize, dsize, new_size, old_size, copy_size;
+ table_entry_t *entry_p, *last_p, *new_entry_p;
+ void *key_copy_p, *data_copy_p;
+
+ /* check the arguments */
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (key_buf == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ /* data_buf can be null but size must be >= 0, if it isn't null size != 0 */
+ if ((data_buf == NULL && data_size < 0)
+ || (data_buf != NULL && data_size == 0)) {
+ return TABLE_ERROR_SIZE;
+ }
+
+#ifndef NO_MMAP
+ /* no mmap support so immediate error */
+ if (table_p->ta_mmap != NULL) {
+ return TABLE_ERROR_MMAP_OP;
+ }
+#endif
+
+ /* determine sizes of key and data */
+ if (key_size < 0) {
+ ksize = strlen((char *)key_buf) + sizeof(char);
+ }
+ else {
+ ksize = key_size;
+ }
+ if (data_size < 0) {
+ dsize = strlen((char *)data_buf) + sizeof(char);
+ }
+ else {
+ dsize = data_size;
+ }
+
+ /* get the bucket number via a hash function */
+ bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n;
+
+ /* look for the entry in this bucket, only check keys of the same size */
+ last_p = NULL;
+ for (entry_p = table_p->ta_buckets[bucket];
+ entry_p != NULL;
+ last_p = entry_p, entry_p = entry_p->te_next_p) {
+ if (entry_p->te_key_size == ksize
+ && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) {
+ break;
+ }
+ }
+
+ /* did we find it? then we are in replace mode. */
+ if (entry_p != NULL) {
+
+ /* can we not overwrite existing data? */
+ if (! overwrite_b) {
+ SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p));
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ if (table_p->ta_data_align == 0) {
+ *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ *data_buf_p = entry_data_buf(table_p, entry_p);
+ }
+ }
+ }
+ return TABLE_ERROR_OVERWRITE;
+ }
+
+ /* re-alloc entry's data if the new size != the old */
+ if (dsize != entry_p->te_data_size) {
+
+ /*
+ * First we delete it from the list to keep the list whole.
+ * This properly preserves the linked list in case we have a
+ * thread marching through the linked list while we are
+ * inserting. Maybe this is an unnecessary protection but it
+ * should not harm that much.
+ */
+ if (last_p == NULL) {
+ table_p->ta_buckets[bucket] = entry_p->te_next_p;
+ }
+ else {
+ last_p->te_next_p = entry_p->te_next_p;
+ }
+
+ /*
+ * Realloc the structure which may change its pointer. NOTE:
+ * this may change any previous data_key_p and data_copy_p
+ * pointers.
+ */
+ new_size = entry_size(table_p, entry_p->te_key_size, dsize);
+ if (table_p->ta_resize_func == NULL) {
+ /* if the alloc function has not been overriden do realloc */
+ if (table_p->ta_alloc_func == NULL) {
+ entry_p = (table_entry_t *)realloc(entry_p, new_size);
+ if (entry_p == NULL) {
+ return TABLE_ERROR_ALLOC;
+ }
+ }
+ else {
+ old_size = new_size - dsize + entry_p->te_data_size;
+ /*
+ * if the user did override alloc but not resize, assume
+ * that the user's allocation functions can't grok realloc
+ * and do it ourselves the hard way.
+ */
+ new_entry_p =
+ (table_entry_t *)table_p->ta_alloc_func(table_p->ta_mem_pool,
+ new_size);
+ if (new_entry_p == NULL) {
+ return TABLE_ERROR_ALLOC;
+ }
+ if (new_size > old_size) {
+ copy_size = old_size;
+ }
+ else {
+ copy_size = new_size;
+ }
+ memcpy(new_entry_p, entry_p, copy_size);
+ if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p,
+ old_size)) {
+ return TABLE_ERROR_FREE;
+ }
+ entry_p = new_entry_p;
+ }
+ }
+ else {
+ old_size = new_size - dsize + entry_p->te_data_size;
+ entry_p = (table_entry_t *)
+ table_p->ta_resize_func(table_p->ta_mem_pool, entry_p,
+ old_size, new_size);
+ if (entry_p == NULL) {
+ return TABLE_ERROR_ALLOC;
+ }
+ }
+
+ /* add it back to the front of the list */
+ entry_p->te_data_size = dsize;
+ entry_p->te_next_p = table_p->ta_buckets[bucket];
+ table_p->ta_buckets[bucket] = entry_p;
+ }
+
+ /* copy or replace data in storage */
+ if (dsize > 0) {
+ if (table_p->ta_data_align == 0) {
+ data_copy_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ data_copy_p = entry_data_buf(table_p, entry_p);
+ }
+ if (data_buf != NULL) {
+ memcpy(data_copy_p, data_buf, dsize);
+ }
+ }
+ else {
+ data_copy_p = NULL;
+ }
+
+ SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p));
+ SET_POINTER(data_buf_p, data_copy_p);
+
+ /* returning from the section where we were overwriting table data */
+ return TABLE_ERROR_NONE;
+ }
+
+ /*
+ * It is a new entry.
+ */
+
+ /* allocate a new entry */
+ new_size = entry_size(table_p, ksize, dsize);
+ if (table_p->ta_alloc_func == NULL) {
+ entry_p = (table_entry_t *)malloc(new_size);
+ }
+ else {
+ entry_p =
+ (table_entry_t *)table_p->ta_alloc_func(table_p->ta_mem_pool, new_size);
+ }
+ if (entry_p == NULL) {
+ return TABLE_ERROR_ALLOC;
+ }
+
+ /* copy key into storage */
+ entry_p->te_key_size = ksize;
+ key_copy_p = ENTRY_KEY_BUF(entry_p);
+ memcpy(key_copy_p, key_buf, ksize);
+
+ /* copy data in */
+ entry_p->te_data_size = dsize;
+ if (dsize > 0) {
+ if (table_p->ta_data_align == 0) {
+ data_copy_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ data_copy_p = entry_data_buf(table_p, entry_p);
+ }
+ if (data_buf != NULL) {
+ memcpy(data_copy_p, data_buf, dsize);
+ }
+ }
+ else {
+ data_copy_p = NULL;
+ }
+
+ SET_POINTER(key_buf_p, key_copy_p);
+ SET_POINTER(data_buf_p, data_copy_p);
+
+ /* insert into list, no need to append */
+ entry_p->te_next_p = table_p->ta_buckets[bucket];
+ table_p->ta_buckets[bucket] = entry_p;
+
+ table_p->ta_entry_n++;
+
+ /* do we need auto-adjust? */
+ if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST)
+ && SHOULD_TABLE_GROW(table_p)) {
+ return table_adjust(table_p, table_p->ta_entry_n);
+ }
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_insert
+ *
+ * DESCRIPTION:
+ *
+ * Exactly the same as table_insert_kd except it does not pass back a
+ * pointer to the key after they have been inserted into the table
+ * structure. This is still here for backwards compatibility.
+ *
+ * See table_insert_kd for more information.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer into which we will be inserting a
+ * new key/data pair.
+ *
+ * key_buf - Buffer of bytes of the key that we are inserting. If you
+ * are storing an (int) as the key (for example) then key_buf should
+ * be a (int *).
+ *
+ * key_size - Size of the key_buf buffer. If set to < 0 then the
+ * library will do a strlen of key_buf and add 1 for the '\0'. If you
+ * are storing an (int) as the key (for example) then key_size should
+ * be sizeof(int).
+ *
+ * data_buf - Buffer of bytes of the data that we are inserting. If
+ * it is NULL then the library will allocate space for the data in the
+ * table without copying in any information. If data_buf is NULL and
+ * data_size is 0 then the library will associate a NULL data pointer
+ * with the key. If you are storing a (long) as the data (for
+ * example) then data_buf should be a (long *).
+ *
+ * data_size - Size of the data_buf buffer. If set to < 0 then the
+ * library will do a strlen of data_buf and add 1 for the '\0'. If
+ * you are storing an (long) as the key (for example) then key_size
+ * should be sizeof(long).
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that was allocated in the table. If you are
+ * storing an (long) as the data (for example) then data_buf_p should
+ * be (long **) i.e. the address of a (long *).
+ *
+ * overwrite - Flag which, if set to 1, will allow the overwriting of
+ * the data in the table with the new data if the key already exists
+ * in the table.
+ */
+int table_insert(table_t *table_p,
+ const void *key_buf, const int key_size,
+ const void *data_buf, const int data_size,
+ void **data_buf_p, const char overwrite_b)
+{
+ return table_insert_kd(table_p, key_buf, key_size, data_buf, data_size,
+ NULL, data_buf_p, overwrite_b);
+}
+
+/*
+ * int table_retrieve
+ *
+ * DESCRIPTION:
+ *
+ * This routine looks up a key made up of a buffer of bytes and an
+ * associated size in the table. If found then it returns the
+ * associated data information.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer into which we will be searching
+ * for the key.
+ *
+ * key_buf - Buffer of bytes of the key that we are searching for. If
+ * you are looking for an (int) as the key (for example) then key_buf
+ * should be a (int *).
+ *
+ * key_size - Size of the key_buf buffer. If set to < 0 then the
+ * library will do a strlen of key_buf and add 1 for the '\0'. If you
+ * are looking for an (int) as the key (for example) then key_size
+ * should be sizeof(int).
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that was allocated in the table and that is
+ * associated with the key. If a (long) was stored as the data (for
+ * example) then data_buf_p should be (long **) i.e. the address of a
+ * (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data stored in the table that is associated with
+ * the key.
+ */
+int table_retrieve(table_t *table_p,
+ const void *key_buf, const int key_size,
+ void **data_buf_p, int *data_size_p)
+{
+ int bucket;
+ unsigned int ksize;
+ table_entry_t *entry_p, **buckets;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (key_buf == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+
+ /* find key size */
+ if (key_size < 0) {
+ ksize = strlen((char *)key_buf) + sizeof(char);
+ }
+ else {
+ ksize = key_size;
+ }
+
+ /* get the bucket number via a has function */
+ bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n;
+
+ /* look for the entry in this bucket, only check keys of the same size */
+ buckets = table_p->ta_buckets;
+ for (entry_p = buckets[bucket];
+ entry_p != NULL;
+ entry_p = entry_p->te_next_p) {
+ entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p);
+ if (entry_p->te_key_size == ksize
+ && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) {
+ break;
+ }
+ }
+
+ /* not found? */
+ if (entry_p == NULL) {
+ return TABLE_ERROR_NOT_FOUND;
+ }
+
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ if (table_p->ta_data_align == 0) {
+ *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ *data_buf_p = entry_data_buf(table_p, entry_p);
+ }
+ }
+ }
+ SET_POINTER(data_size_p, entry_p->te_data_size);
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_delete
+ *
+ * DESCRIPTION:
+ *
+ * This routine looks up a key made up of a buffer of bytes and an
+ * associated size in the table. If found then it will be removed
+ * from the table. The associated data can be passed back to the user
+ * if requested.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * NOTE: this could be an allocation error if the library is to return
+ * the data to the user.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we will be deleteing
+ * the key.
+ *
+ * key_buf - Buffer of bytes of the key that we are searching for to
+ * delete. If you are deleting an (int) key (for example) then
+ * key_buf should be a (int *).
+ *
+ * key_size - Size of the key_buf buffer. If set to < 0 then the
+ * library will do a strlen of key_buf and add 1 for the '\0'. If you
+ * are deleting an (int) key (for example) then key_size should be
+ * sizeof(int).
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that was allocated in the table and that was
+ * associated with the key. If a (long) was stored as the data (for
+ * example) then data_buf_p should be (long **) i.e. the address of a
+ * (long *). If a pointer is passed in, the caller is responsible for
+ * freeing it after use. If data_buf_p is NULL then the library will
+ * free up the data allocation itself.
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that was stored in the table and that was
+ * associated with the key.
+ */
+int table_delete(table_t *table_p,
+ const void *key_buf, const int key_size,
+ void **data_buf_p, int *data_size_p)
+{
+ int bucket;
+ unsigned int ksize;
+ unsigned char *data_copy_p;
+ table_entry_t *entry_p, *last_p;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (key_buf == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+
+#ifndef NO_MMAP
+ /* no mmap support so immediate error */
+ if (table_p->ta_mmap != NULL) {
+ return TABLE_ERROR_MMAP_OP;
+ }
+#endif
+
+ /* get the key size */
+ if (key_size < 0) {
+ ksize = strlen((char *)key_buf) + sizeof(char);
+ }
+ else {
+ ksize = key_size;
+ }
+
+ /* find our bucket */
+ bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n;
+
+ /* look for the entry in this bucket, only check keys of the same size */
+ for (last_p = NULL, entry_p = table_p->ta_buckets[bucket];
+ entry_p != NULL;
+ last_p = entry_p, entry_p = entry_p->te_next_p) {
+ if (entry_p->te_key_size == ksize
+ && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) {
+ break;
+ }
+ }
+
+ /* did we find it? */
+ if (entry_p == NULL) {
+ return TABLE_ERROR_NOT_FOUND;
+ }
+
+ /*
+ * NOTE: we may want to adjust the linear counters here if the entry
+ * we are deleting is the one we are pointing on or is ahead of the
+ * one in the bucket list
+ */
+
+ /* remove entry from the linked list */
+ if (last_p == NULL) {
+ table_p->ta_buckets[bucket] = entry_p->te_next_p;
+ }
+ else {
+ last_p->te_next_p = entry_p->te_next_p;
+ }
+
+ /* free entry */
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ /*
+ * if we were storing it compacted, we now need to malloc some
+ * space if the user wants the value after the delete.
+ */
+ if (table_p->ta_alloc_func == NULL) {
+ *data_buf_p = malloc(entry_p->te_data_size);
+ }
+ else {
+ *data_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool,
+ entry_p->te_data_size);
+ }
+ if (*data_buf_p == NULL) {
+ return TABLE_ERROR_ALLOC;
+ }
+ if (table_p->ta_data_align == 0) {
+ data_copy_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ data_copy_p = entry_data_buf(table_p, entry_p);
+ }
+ memcpy(*data_buf_p, data_copy_p, entry_p->te_data_size);
+ }
+ }
+ SET_POINTER(data_size_p, entry_p->te_data_size);
+ if (table_p->ta_free_func == NULL) {
+ free(entry_p);
+ }
+ else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p,
+ entry_size(table_p,
+ entry_p->te_key_size,
+ entry_p->te_data_size))) {
+ return TABLE_ERROR_FREE;
+ }
+
+ table_p->ta_entry_n--;
+
+ /* do we need auto-adjust down? */
+ if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST)
+ && (table_p->ta_flags & TABLE_FLAG_ADJUST_DOWN)
+ && SHOULD_TABLE_SHRINK(table_p)) {
+ return table_adjust(table_p, table_p->ta_entry_n);
+ }
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_delete_first
+ *
+ * DESCRIPTION:
+ *
+ * This is like the table_delete routines except it deletes the first
+ * key/data pair in the table instead of an entry corresponding to a
+ * particular key. The associated key and data information can be
+ * passed back to the user if requested. This routines is handy to
+ * clear out a table.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * NOTE: this could be an allocation error if the library is to return
+ * the data to the user.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we will be deleteing
+ * the first key.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the first key that was allocated in the table.
+ * If an (int) was stored as the first key (for example) then
+ * key_buf_p should be (int **) i.e. the address of a (int *). If a
+ * pointer is passed in, the caller is responsible for freeing it
+ * after use. If key_buf_p is NULL then the library will free up the
+ * key allocation itself.
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that was stored in the table and that was
+ * associated with the key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that was allocated in the table and that was
+ * associated with the key. If a (long) was stored as the data (for
+ * example) then data_buf_p should be (long **) i.e. the address of a
+ * (long *). If a pointer is passed in, the caller is responsible for
+ * freeing it after use. If data_buf_p is NULL then the library will
+ * free up the data allocation itself.
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that was stored in the table and that was
+ * associated with the key.
+ */
+int table_delete_first(table_t *table_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p)
+{
+ unsigned char *data_copy_p;
+ table_entry_t *entry_p;
+ table_linear_t linear;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+
+#ifndef NO_MMAP
+ /* no mmap support so immediate error */
+ if (table_p->ta_mmap != NULL) {
+ return TABLE_ERROR_MMAP_OP;
+ }
+#endif
+
+ /* take the first entry */
+ entry_p = first_entry(table_p, &linear);
+ if (entry_p == NULL) {
+ return TABLE_ERROR_NOT_FOUND;
+ }
+
+ /*
+ * NOTE: we may want to adjust the linear counters here if the entry
+ * we are deleting is the one we are pointing on or is ahead of the
+ * one in the bucket list
+ */
+
+ /* remove entry from the linked list */
+ table_p->ta_buckets[linear.tl_bucket_c] = entry_p->te_next_p;
+
+ /* free entry */
+ if (key_buf_p != NULL) {
+ if (entry_p->te_key_size == 0) {
+ *key_buf_p = NULL;
+ }
+ else {
+ /*
+ * if we were storing it compacted, we now need to malloc some
+ * space if the user wants the value after the delete.
+ */
+ if (table_p->ta_alloc_func == NULL) {
+ *key_buf_p = malloc(entry_p->te_key_size);
+ }
+ else {
+ *key_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool,
+ entry_p->te_key_size);
+ }
+ if (*key_buf_p == NULL) {
+ return TABLE_ERROR_ALLOC;
+ }
+ memcpy(*key_buf_p, ENTRY_KEY_BUF(entry_p), entry_p->te_key_size);
+ }
+ }
+ SET_POINTER(key_size_p, entry_p->te_key_size);
+
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ /*
+ * if we were storing it compacted, we now need to malloc some
+ * space if the user wants the value after the delete.
+ */
+ if (table_p->ta_alloc_func == NULL) {
+ *data_buf_p = malloc(entry_p->te_data_size);
+ }
+ else {
+ *data_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool,
+ entry_p->te_data_size);
+ }
+ if (*data_buf_p == NULL) {
+ return TABLE_ERROR_ALLOC;
+ }
+ if (table_p->ta_data_align == 0) {
+ data_copy_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ data_copy_p = entry_data_buf(table_p, entry_p);
+ }
+ memcpy(*data_buf_p, data_copy_p, entry_p->te_data_size);
+ }
+ }
+ SET_POINTER(data_size_p, entry_p->te_data_size);
+ if (table_p->ta_free_func == NULL) {
+ free(entry_p);
+ }
+ else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p,
+ entry_size(table_p,
+ entry_p->te_key_size,
+ entry_p->te_data_size))) {
+ return TABLE_ERROR_FREE;
+ }
+
+ table_p->ta_entry_n--;
+
+ /* do we need auto-adjust down? */
+ if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST)
+ && (table_p->ta_flags & TABLE_FLAG_ADJUST_DOWN)
+ && SHOULD_TABLE_SHRINK(table_p)) {
+ return table_adjust(table_p, table_p->ta_entry_n);
+ }
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_info
+ *
+ * DESCRIPTION:
+ *
+ * Get some information about a table_p structure.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting
+ * information.
+ *
+ * num_buckets_p - Pointer to an integer which, if not NULL, will
+ * contain the number of buckets in the table.
+ *
+ * num_entries_p - Pointer to an integer which, if not NULL, will
+ * contain the number of entries stored in the table.
+ */
+int table_info(table_t *table_p, int *num_buckets_p, int *num_entries_p)
+{
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+
+ SET_POINTER(num_buckets_p, table_p->ta_bucket_n);
+ SET_POINTER(num_entries_p, table_p->ta_entry_n);
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_adjust
+ *
+ * DESCRIPTION:
+ *
+ * Set the number of buckets in a table to a certain value.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer of which we are adjusting.
+ *
+ * bucket_n - Number buckets to adjust the table to. Set to 0 to
+ * adjust the table to its number of entries.
+ */
+int table_adjust(table_t *table_p, const int bucket_n)
+{
+ table_entry_t *entry_p, *next_p;
+ table_entry_t **buckets, **bucket_p, **bounds_p;
+ int bucket;
+ unsigned int buck_n, bucket_size;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+
+#ifndef NO_MMAP
+ /* no mmap support so immediate error */
+ if (table_p->ta_mmap != NULL) {
+ return TABLE_ERROR_MMAP_OP;
+ }
+#endif
+
+ /*
+ * NOTE: we walk through the entries and rehash them. If we stored
+ * the hash value as a full int in the table-entry, all we would
+ * have to do is remod it.
+ */
+
+ /* normalize to the number of entries */
+ if (bucket_n == 0) {
+ buck_n = table_p->ta_entry_n;
+ }
+ else {
+ buck_n = bucket_n;
+ }
+
+ /* we must have at least 1 bucket */
+ if (buck_n == 0) {
+ buck_n = 1;
+ }
+
+ (void)printf("growing table to %d\n", buck_n);
+
+ /* make sure we have something to do */
+ if (buck_n == table_p->ta_bucket_n) {
+ return TABLE_ERROR_NONE;
+ }
+
+ /* allocate a new bucket list */
+ bucket_size = buck_n * sizeof(table_entry_t *);
+ if (table_p->ta_alloc_func == NULL) {
+ buckets = (table_entry_t **)malloc(bucket_size);
+ }
+ else {
+ buckets =
+ (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool,
+ bucket_size);
+ }
+ if (buckets == NULL) {
+ return TABLE_ERROR_ALLOC;
+ }
+ /*
+ * We zero it ourselves to save the necessity of having a
+ * table_mem_calloc_t memory override function.
+ */
+ memset(buckets, 0, bucket_size);
+
+ /*
+ * run through each of the items in the current table and rehash
+ * them into the newest bucket sizes
+ */
+ bounds_p = table_p->ta_buckets + table_p->ta_bucket_n;
+ for (bucket_p = table_p->ta_buckets; bucket_p < bounds_p; bucket_p++) {
+ for (entry_p = *bucket_p; entry_p != NULL; entry_p = next_p) {
+
+ /* hash the old data into the new table size */
+ bucket = hash(ENTRY_KEY_BUF(entry_p), entry_p->te_key_size, 0) % buck_n;
+
+ /* record the next one now since we overwrite next below */
+ next_p = entry_p->te_next_p;
+
+ /* insert into new list, no need to append */
+ entry_p->te_next_p = buckets[bucket];
+ buckets[bucket] = entry_p;
+
+ /*
+ * NOTE: we may want to adjust the bucket_c linear entry here to
+ * keep it current
+ */
+ }
+ /* remove the old table pointers as we go by */
+ *bucket_p = NULL;
+ }
+
+ /* replace the table buckets with the new ones */
+ if (table_p->ta_free_func == NULL) {
+ free(table_p->ta_buckets);
+ }
+ else if (! table_p->ta_free_func(table_p->ta_mem_pool,
+ table_p->ta_buckets,
+ table_p->ta_bucket_n *
+ sizeof(table_entry_t *))) {
+ return TABLE_ERROR_FREE;
+ }
+ table_p->ta_buckets = buckets;
+ table_p->ta_bucket_n = buck_n;
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_type_size
+ *
+ * DESCRIPTION:
+ *
+ * Return the size of the internal table type.
+ *
+ * RETURNS:
+ *
+ * The size of the table_t type.
+ *
+ * ARGUMENTS:
+ *
+ * None.
+ */
+int table_type_size(void)
+{
+ return sizeof(table_t);
+}
+
+/************************* linear access routines ****************************/
+
+/*
+ * int table_first
+ *
+ * DESCRIPTION:
+ *
+ * Find first element in a table and pass back information about the
+ * key/data pair. If any of the key/data pointers are NULL then they
+ * are ignored.
+ *
+ * NOTE: This function is not reentrant. More than one thread cannot
+ * be doing a first and next on the same table at the same time. Use
+ * the table_first_r version below for this.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * first element.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the first key that is allocated in the table. If
+ * an (int) is stored as the first key (for example) then key_buf_p
+ * should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the first key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the first key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the first key.
+ */
+int table_first(table_t *table_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p)
+{
+ table_entry_t *entry_p;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+
+ /* initialize our linear magic number */
+ table_p->ta_linear.tl_magic = LINEAR_MAGIC;
+
+ entry_p = first_entry(table_p, &table_p->ta_linear);
+ if (entry_p == NULL) {
+ return TABLE_ERROR_NOT_FOUND;
+ }
+
+ SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p));
+ SET_POINTER(key_size_p, entry_p->te_key_size);
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ if (table_p->ta_data_align == 0) {
+ *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ *data_buf_p = entry_data_buf(table_p, entry_p);
+ }
+ }
+ }
+ SET_POINTER(data_size_p, entry_p->te_data_size);
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_next
+ *
+ * DESCRIPTION:
+ *
+ * Find the next element in a table and pass back information about
+ * the key/data pair. If any of the key/data pointers are NULL then
+ * they are ignored.
+ *
+ * NOTE: This function is not reentrant. More than one thread cannot
+ * be doing a first and next on the same table at the same time. Use
+ * the table_next_r version below for this.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * next element.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the next key that is allocated in the table. If
+ * an (int) is stored as the next key (for example) then key_buf_p
+ * should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the next key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the next key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the next key.
+ */
+int table_next(table_t *table_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p)
+{
+ table_entry_t *entry_p;
+ int error;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (table_p->ta_linear.tl_magic != LINEAR_MAGIC) {
+ return TABLE_ERROR_LINEAR;
+ }
+
+ /* move to the next entry */
+ entry_p = next_entry(table_p, &table_p->ta_linear, &error);
+ if (entry_p == NULL) {
+ return error;
+ }
+
+ SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p));
+ SET_POINTER(key_size_p, entry_p->te_key_size);
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ if (table_p->ta_data_align == 0) {
+ *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ *data_buf_p = entry_data_buf(table_p, entry_p);
+ }
+ }
+ }
+ SET_POINTER(data_size_p, entry_p->te_data_size);
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_this
+ *
+ * DESCRIPTION:
+ *
+ * Find the current element in a table and pass back information about
+ * the key/data pair. If any of the key/data pointers are NULL then
+ * they are ignored.
+ *
+ * NOTE: This function is not reentrant. Use the table_current_r
+ * version below.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * current element.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the current key that is allocated in the table.
+ * If an (int) is stored as the current key (for example) then
+ * key_buf_p should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the current key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the current key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the current key.
+ */
+int table_this(table_t *table_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p)
+{
+ table_entry_t *entry_p = NULL;
+ int entry_c;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (table_p->ta_linear.tl_magic != LINEAR_MAGIC) {
+ return TABLE_ERROR_LINEAR;
+ }
+
+ /* if we removed an item that shorted the bucket list, we may get this */
+ if (table_p->ta_linear.tl_bucket_c >= table_p->ta_bucket_n) {
+ /*
+ * NOTE: this might happen if we delete an item which shortens the
+ * table bucket numbers.
+ */
+ return TABLE_ERROR_NOT_FOUND;
+ }
+
+ /* find the entry which is the nth in the list */
+ entry_p = table_p->ta_buckets[table_p->ta_linear.tl_bucket_c];
+ /* NOTE: we swap the order here to be more efficient */
+ for (entry_c = table_p->ta_linear.tl_entry_c; entry_c > 0; entry_c--) {
+ /* did we reach the end of the list? */
+ if (entry_p == NULL) {
+ break;
+ }
+ entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p;
+ }
+
+ /* is this a NOT_FOUND or a LINEAR error */
+ if (entry_p == NULL) {
+ return TABLE_ERROR_NOT_FOUND;
+ }
+
+ SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p));
+ SET_POINTER(key_size_p, entry_p->te_key_size);
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ if (table_p->ta_data_align == 0) {
+ *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ *data_buf_p = entry_data_buf(table_p, entry_p);
+ }
+ }
+ }
+ SET_POINTER(data_size_p, entry_p->te_data_size);
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_first_r
+ *
+ * DESCRIPTION:
+ *
+ * Reetrant version of the table_first routine above. Find first
+ * element in a table and pass back information about the key/data
+ * pair. If any of the key/data pointers are NULL then they are
+ * ignored.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * first element.
+ *
+ * linear_p - Pointer to a table linear structure which is initialized
+ * here. The same pointer should then be passed to table_next_r
+ * below.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the first key that is allocated in the table. If
+ * an (int) is stored as the first key (for example) then key_buf_p
+ * should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the first key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the first key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the first key.
+ */
+int table_first_r(table_t *table_p, table_linear_t *linear_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p)
+{
+ table_entry_t *entry_p;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (linear_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+
+ /* initialize our linear magic number */
+ linear_p->tl_magic = LINEAR_MAGIC;
+
+ entry_p = first_entry(table_p, linear_p);
+ if (entry_p == NULL) {
+ return TABLE_ERROR_NOT_FOUND;
+ }
+
+ SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p));
+ SET_POINTER(key_size_p, entry_p->te_key_size);
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ if (table_p->ta_data_align == 0) {
+ *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ *data_buf_p = entry_data_buf(table_p, entry_p);
+ }
+ }
+ }
+ SET_POINTER(data_size_p, entry_p->te_data_size);
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_next_r
+ *
+ * DESCRIPTION:
+ *
+ * Reetrant version of the table_next routine above. Find next
+ * element in a table and pass back information about the key/data
+ * pair. If any of the key/data pointers are NULL then they are
+ * ignored.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * next element.
+ *
+ * linear_p - Pointer to a table linear structure which is incremented
+ * here. The same pointer must have been passed to table_first_r
+ * first so that it can be initialized.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the next key that is allocated in the table. If
+ * an (int) is stored as the next key (for example) then key_buf_p
+ * should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the next key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the next key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the next key.
+ */
+int table_next_r(table_t *table_p, table_linear_t *linear_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p)
+{
+ table_entry_t *entry_p;
+ int error;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (linear_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (linear_p->tl_magic != LINEAR_MAGIC) {
+ return TABLE_ERROR_LINEAR;
+ }
+
+ /* move to the next entry */
+ entry_p = next_entry(table_p, linear_p, &error);
+ if (entry_p == NULL) {
+ return error;
+ }
+
+ SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p));
+ SET_POINTER(key_size_p, entry_p->te_key_size);
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ if (table_p->ta_data_align == 0) {
+ *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ *data_buf_p = entry_data_buf(table_p, entry_p);
+ }
+ }
+ }
+ SET_POINTER(data_size_p, entry_p->te_data_size);
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * int table_this_r
+ *
+ * DESCRIPTION:
+ *
+ * Reetrant version of the table_this routine above. Find current
+ * element in a table and pass back information about the key/data
+ * pair. If any of the key/data pointers are NULL then they are
+ * ignored.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * current element.
+ *
+ * linear_p - Pointer to a table linear structure which is accessed
+ * here. The same pointer must have been passed to table_first_r
+ * first so that it can be initialized.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of the current key that is allocated in the table.
+ * If an (int) is stored as the current key (for example) then
+ * key_buf_p should be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table and that is
+ * associated with the current key.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage that is allocated in the table and that is
+ * associated with the current key. If a (long) is stored as the data
+ * (for example) then data_buf_p should be (long **) i.e. the address
+ * of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table and that is
+ * associated with the current key.
+ */
+int table_this_r(table_t *table_p, table_linear_t *linear_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p)
+{
+ table_entry_t *entry_p;
+ int entry_c;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (linear_p->tl_magic != LINEAR_MAGIC) {
+ return TABLE_ERROR_LINEAR;
+ }
+
+ /* if we removed an item that shorted the bucket list, we may get this */
+ if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) {
+ /*
+ * NOTE: this might happen if we delete an item which shortens the
+ * table bucket numbers.
+ */
+ return TABLE_ERROR_NOT_FOUND;
+ }
+
+ /* find the entry which is the nth in the list */
+ for (entry_c = linear_p->tl_entry_c,
+ entry_p = table_p->ta_buckets[linear_p->tl_bucket_c];
+ entry_p != NULL && entry_c > 0;
+ entry_c--, entry_p = TABLE_POINTER(table_p, table_entry_t *,
+ entry_p)->te_next_p) {
+ }
+
+ if (entry_p == NULL) {
+ return TABLE_ERROR_NOT_FOUND;
+ }
+
+ SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p));
+ SET_POINTER(key_size_p, entry_p->te_key_size);
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ if (table_p->ta_data_align == 0) {
+ *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ *data_buf_p = entry_data_buf(table_p, entry_p);
+ }
+ }
+ }
+ SET_POINTER(data_size_p, entry_p->te_data_size);
+
+ return TABLE_ERROR_NONE;
+}
+
+/******************************* mmap routines *******************************/
+
+/*
+ * table_t *table_mmap
+ *
+ * DESCRIPTION:
+ *
+ * Mmap a table from a file that had been written to disk earlier via
+ * table_write.
+ *
+ * RETURNS:
+ *
+ * A pointer to the new table structure which must be passed to
+ * table_munmap to be deallocated. On error a NULL is returned.
+ *
+ * ARGUMENTS:
+ *
+ * path - Table file to mmap in.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+table_t *table_mmap(const char *path, int *error_p)
+{
+#ifdef NO_MMAP
+
+ /* no mmap support so immediate error */
+ SET_POINTER(error_p, TABLE_ERROR_MMAP_NONE);
+ return NULL;
+
+#else
+
+ table_t *table_p;
+ struct stat sbuf;
+ int fd, state;
+
+ table_p = (table_t *)malloc(sizeof(table_t));
+ if (table_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ALLOC);
+ return NULL;
+ }
+
+ /* open the mmap file */
+ fd = open(path, O_RDONLY, 0);
+ if (fd < 0) {
+ free(table_p);
+ SET_POINTER(error_p, TABLE_ERROR_OPEN);
+ return NULL;
+ }
+
+ /* get the file size */
+ if (fstat(fd, &sbuf) != 0) {
+ free(table_p);
+ SET_POINTER(error_p, TABLE_ERROR_OPEN);
+ return NULL;
+ }
+
+ /* mmap the space and close the file */
+#ifdef __alpha
+ state = (MAP_SHARED | MAP_FILE | MAP_VARIABLE);
+#else
+ state = MAP_SHARED;
+#endif
+
+ table_p->ta_mmap = (table_t *)mmap((caddr_t)0, sbuf.st_size, PROT_READ,
+ state, fd, 0);
+ (void)close(fd);
+
+ if (table_p->ta_mmap == (table_t *)MAP_FAILED) {
+ SET_POINTER(error_p, TABLE_ERROR_MMAP);
+ return NULL;
+ }
+
+ /* is the mmap file contain bad info or maybe another system type? */
+ if (table_p->ta_mmap->ta_magic != TABLE_MAGIC) {
+ SET_POINTER(error_p, TABLE_ERROR_PNT);
+ return NULL;
+ }
+
+ /* sanity check on the file size */
+ if (table_p->ta_mmap->ta_file_size != sbuf.st_size) {
+ SET_POINTER(error_p, TABLE_ERROR_SIZE);
+ return NULL;
+ }
+
+ /* copy the fields out of the mmap file into our memory version */
+ table_p->ta_magic = TABLE_MAGIC;
+ table_p->ta_flags = table_p->ta_mmap->ta_flags;
+ table_p->ta_bucket_n = table_p->ta_mmap->ta_bucket_n;
+ table_p->ta_entry_n = table_p->ta_mmap->ta_entry_n;
+ table_p->ta_data_align = table_p->ta_mmap->ta_data_align;
+ table_p->ta_buckets = TABLE_POINTER(table_p, table_entry_t **,
+ table_p->ta_mmap->ta_buckets);
+ table_p->ta_linear.tl_magic = 0;
+ table_p->ta_linear.tl_bucket_c = 0;
+ table_p->ta_linear.tl_entry_c = 0;
+ /* mmap is already set */
+ table_p->ta_file_size = table_p->ta_mmap->ta_file_size;
+
+ SET_POINTER(error_p, TABLE_ERROR_NONE);
+ return table_p;
+
+#endif
+}
+
+/*
+ * int table_munmap
+ *
+ * DESCRIPTION:
+ *
+ * Unmmap a table that was previously mmapped using table_mmap.
+ *
+ * RETURNS:
+ *
+ * Returns table error codes.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Mmaped table pointer to unmap.
+ */
+int table_munmap(table_t *table_p)
+{
+#ifdef NO_MMAP
+
+ /* no mmap support so immediate error */
+ return TABLE_ERROR_MMAP_NONE;
+
+#else
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (table_p->ta_mmap == NULL) {
+ return TABLE_ERROR_PNT;
+ }
+
+ (void)munmap((caddr_t)table_p->ta_mmap, table_p->ta_file_size);
+ table_p->ta_magic = 0;
+ free(table_p);
+ return TABLE_ERROR_NONE;
+
+#endif
+}
+
+/******************************* file routines *******************************/
+
+/*
+ * int table_read
+ *
+ * DESCRIPTION:
+ *
+ * Read in a table from a file that had been written to disk earlier
+ * via table_write.
+ *
+ * RETURNS:
+ *
+ * Success - Pointer to the new table structure which must be passed
+ * to table_free to be deallocated.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * path - Table file to read in.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+table_t *table_read(const char *path, int *error_p)
+{
+ unsigned int size;
+ int fd, ent_size;
+ FILE *infile;
+ table_entry_t entry, **bucket_p, *entry_p = NULL, *last_p;
+ unsigned long pos;
+ table_t *table_p;
+
+ /* open the file */
+ fd = open(path, O_RDONLY, 0);
+ if (fd < 0) {
+ SET_POINTER(error_p, TABLE_ERROR_OPEN);
+ return NULL;
+ }
+
+ /* allocate a table structure */
+ table_p = malloc(sizeof(table_t));
+ if (table_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ALLOC);
+ return NULL;
+ }
+
+ /* now open the fd to get buffered i/o */
+ infile = fdopen(fd, "r");
+ if (infile == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_OPEN);
+ return NULL;
+ }
+
+ /* read the main table struct */
+ if (fread(table_p, sizeof(table_t), 1, infile) != 1) {
+ SET_POINTER(error_p, TABLE_ERROR_READ);
+ free(table_p);
+ return NULL;
+ }
+ table_p->ta_file_size = 0;
+
+ /* is the mmap file contain bad info or maybe another system type? */
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ SET_POINTER(error_p, TABLE_ERROR_PNT);
+ return NULL;
+ }
+
+ /* allocate the buckets */
+ table_p->ta_buckets = (table_entry_t **)calloc(table_p->ta_bucket_n,
+ sizeof(table_entry_t *));
+ if (table_p->ta_buckets == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ALLOC);
+ free(table_p);
+ return NULL;
+ }
+
+ if (fread(table_p->ta_buckets, sizeof(table_entry_t *), table_p->ta_bucket_n,
+ infile) != (size_t)table_p->ta_bucket_n) {
+ SET_POINTER(error_p, TABLE_ERROR_READ);
+ free(table_p->ta_buckets);
+ free(table_p);
+ return NULL;
+ }
+
+ /* read in the entries */
+ for (bucket_p = table_p->ta_buckets;
+ bucket_p < table_p->ta_buckets + table_p->ta_bucket_n;
+ bucket_p++) {
+
+ /* skip null buckets */
+ if (*bucket_p == NULL) {
+ continue;
+ }
+
+ /* run through the entry list */
+ last_p = NULL;
+ for (pos = *(unsigned long *)bucket_p;;
+ pos = (unsigned long)entry_p->te_next_p) {
+
+ /* read in the entry */
+ if (fseek(infile, pos, SEEK_SET) != 0) {
+ SET_POINTER(error_p, TABLE_ERROR_SEEK);
+ free(table_p->ta_buckets);
+ free(table_p);
+ if (entry_p != NULL) {
+ free(entry_p);
+ }
+ /* the other table elements will not be freed */
+ return NULL;
+ }
+ if (fread(&entry, sizeof(struct table_shell_st), 1, infile) != 1) {
+ SET_POINTER(error_p, TABLE_ERROR_READ);
+ free(table_p->ta_buckets);
+ free(table_p);
+ if (entry_p != NULL) {
+ free(entry_p);
+ }
+ /* the other table elements will not be freed */
+ return NULL;
+ }
+
+ /* make a new entry */
+ ent_size = entry_size(table_p, entry.te_key_size, entry.te_data_size);
+ entry_p = (table_entry_t *)malloc(ent_size);
+ if (entry_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ALLOC);
+ free(table_p->ta_buckets);
+ free(table_p);
+ /* the other table elements will not be freed */
+ return NULL;
+ }
+ entry_p->te_key_size = entry.te_key_size;
+ entry_p->te_data_size = entry.te_data_size;
+ entry_p->te_next_p = entry.te_next_p;
+
+ if (last_p == NULL) {
+ *bucket_p = entry_p;
+ }
+ else {
+ last_p->te_next_p = entry_p;
+ }
+
+ /* determine how much more we have to read */
+ size = ent_size - sizeof(struct table_shell_st);
+ if (fread(ENTRY_KEY_BUF(entry_p), sizeof(char), size, infile) != size) {
+ SET_POINTER(error_p, TABLE_ERROR_READ);
+ free(table_p->ta_buckets);
+ free(table_p);
+ free(entry_p);
+ /* the other table elements will not be freed */
+ return NULL;
+ }
+
+ /* we are done if the next pointer is null */
+ if (entry_p->te_next_p == (unsigned long)0) {
+ break;
+ }
+ last_p = entry_p;
+ }
+ }
+
+ (void)fclose(infile);
+
+ SET_POINTER(error_p, TABLE_ERROR_NONE);
+ return table_p;
+}
+
+/*
+ * int table_write
+ *
+ * DESCRIPTION:
+ *
+ * Write a table from memory to file.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to the table that we are writing to the file.
+ *
+ * path - Table file to write out to.
+ *
+ * mode - Mode of the file. This argument is passed on to open when
+ * the file is created.
+ */
+int table_write(const table_t *table_p, const char *path, const int mode)
+{
+ int fd, rem, ent_size;
+ unsigned int bucket_c, bucket_size;
+ unsigned long size;
+ table_entry_t *entry_p, **buckets, **bucket_p, *next_p;
+ table_t main_tab;
+ FILE *outfile;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+
+ fd = open(path, O_WRONLY | O_CREAT, mode);
+ if (fd < 0) {
+ return TABLE_ERROR_OPEN;
+ }
+
+ outfile = fdopen(fd, "w");
+ if (outfile == NULL) {
+ return TABLE_ERROR_OPEN;
+ }
+
+ /* allocate a block of sizes for each bucket */
+ bucket_size = sizeof(table_entry_t *) * table_p->ta_bucket_n;
+ if (table_p->ta_alloc_func == NULL) {
+ buckets = (table_entry_t **)malloc(bucket_size);
+ }
+ else {
+ buckets =
+ (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool,
+ bucket_size);
+ }
+ if (buckets == NULL) {
+ return TABLE_ERROR_ALLOC;
+ }
+
+ /* make a copy of the main struct */
+ main_tab = *table_p;
+
+ /* start counting the bytes */
+ size = 0;
+ size += sizeof(table_t);
+
+ /* buckets go right after main struct */
+ main_tab.ta_buckets = (table_entry_t **)size;
+ size += sizeof(table_entry_t *) * table_p->ta_bucket_n;
+
+ /* run through and count the buckets */
+ for (bucket_c = 0; bucket_c < table_p->ta_bucket_n; bucket_c++) {
+ bucket_p = table_p->ta_buckets + bucket_c;
+ if (*bucket_p == NULL) {
+ buckets[bucket_c] = NULL;
+ continue;
+ }
+ buckets[bucket_c] = (table_entry_t *)size;
+ for (entry_p = *bucket_p; entry_p != NULL; entry_p = entry_p->te_next_p) {
+ size += entry_size(table_p, entry_p->te_key_size, entry_p->te_data_size);
+ /*
+ * We now have to round the file to the nearest long so the
+ * mmaping of the longs in the entry structs will work.
+ */
+ rem = size & (sizeof(long) - 1);
+ if (rem > 0) {
+ size += sizeof(long) - rem;
+ }
+ }
+ }
+ /* add a \0 at the end to fill the last section */
+ size++;
+
+ /* set the main fields */
+ main_tab.ta_linear.tl_magic = 0;
+ main_tab.ta_linear.tl_bucket_c = 0;
+ main_tab.ta_linear.tl_entry_c = 0;
+ main_tab.ta_mmap = NULL;
+ main_tab.ta_file_size = size;
+
+ /*
+ * Now we can start the writing because we got the bucket offsets.
+ */
+
+ /* write the main table struct */
+ size = 0;
+ if (fwrite(&main_tab, sizeof(table_t), 1, outfile) != 1) {
+ if (table_p->ta_free_func == NULL) {
+ free(buckets);
+ }
+ else {
+ (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, bucket_size);
+ }
+ return TABLE_ERROR_WRITE;
+ }
+ size += sizeof(table_t);
+ if (fwrite(buckets, sizeof(table_entry_t *), table_p->ta_bucket_n,
+ outfile) != (size_t)table_p->ta_bucket_n) {
+ if (table_p->ta_free_func == NULL) {
+ free(buckets);
+ }
+ else {
+ (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, bucket_size);
+ }
+ return TABLE_ERROR_WRITE;
+ }
+ size += sizeof(table_entry_t *) * table_p->ta_bucket_n;
+
+ /* write out the entries */
+ for (bucket_p = table_p->ta_buckets;
+ bucket_p < table_p->ta_buckets + table_p->ta_bucket_n;
+ bucket_p++) {
+ for (entry_p = *bucket_p; entry_p != NULL; entry_p = entry_p->te_next_p) {
+
+ ent_size = entry_size(table_p, entry_p->te_key_size,
+ entry_p->te_data_size);
+ size += ent_size;
+ /* round to nearest long here so we can write copy */
+ rem = size & (sizeof(long) - 1);
+ if (rem > 0) {
+ size += sizeof(long) - rem;
+ }
+ next_p = entry_p->te_next_p;
+ if (next_p != NULL) {
+ entry_p->te_next_p = (table_entry_t *)size;
+ }
+
+ /* now write to disk */
+ if (fwrite(entry_p, ent_size, 1, outfile) != 1) {
+ if (table_p->ta_free_func == NULL) {
+ free(buckets);
+ }
+ else {
+ (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets,
+ bucket_size);
+ }
+ return TABLE_ERROR_WRITE;
+ }
+
+ /* restore the next pointer */
+ if (next_p != NULL) {
+ entry_p->te_next_p = next_p;
+ }
+
+ /* now write the padding information */
+ if (rem > 0) {
+ rem = sizeof(long) - rem;
+ /*
+ * NOTE: this won't leave fseek'd space at the end but we
+ * don't care there because there is no accessed memory
+ * afterwards. We write 1 \0 at the end to make sure.
+ */
+ if (fseek(outfile, rem, SEEK_CUR) != 0) {
+ if (table_p->ta_free_func == NULL) {
+ free(buckets);
+ }
+ else {
+ (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets,
+ bucket_size);
+ }
+ return TABLE_ERROR_SEEK;
+ }
+ }
+ }
+ }
+ /*
+ * Write a \0 at the end of the file to make sure that the last
+ * fseek filled with nulls.
+ */
+ (void)fputc('\0', outfile);
+
+ (void)fclose(outfile);
+ if (table_p->ta_free_func == NULL) {
+ free(buckets);
+ }
+ else if (! table_p->ta_free_func(table_p->ta_mem_pool, buckets,
+ bucket_size)) {
+ return TABLE_ERROR_FREE;
+ }
+
+ return TABLE_ERROR_NONE;
+}
+
+/******************************** table order ********************************/
+
+/*
+ * table_entry_t *table_order
+ *
+ * DESCRIPTION:
+ *
+ * Order a table by building an array of table entry pointers and then
+ * sorting this array using the qsort function. To retrieve the
+ * sorted entries, you can then use the table_entry routine to access
+ * each entry in order.
+ *
+ * NOTE: This routine is thread safe and makes use of an internal
+ * status qsort function.
+ *
+ * RETURNS:
+ *
+ * Success - An allocated list of table-linear structures which must
+ * be freed by table_order_free later.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to the table that we are ordering.
+ *
+ * compare - Comparison function defined by the user. Its definition
+ * is at the top of the table.h file. If this is NULL then it will
+ * order the table my memcmp-ing the keys.
+ *
+ * num_entries_p - Pointer to an integer which, if not NULL, will
+ * contain the number of entries in the returned entry pointer array.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+table_entry_t **table_order(table_t *table_p, table_compare_t compare,
+ int *num_entries_p, int *error_p)
+{
+ table_entry_t *entry_p, **entries, **entries_p;
+ table_linear_t linear;
+ compare_t comp_func;
+ unsigned int entries_size;
+ int ret;
+
+ if (table_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ARG_NULL);
+ return NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ SET_POINTER(error_p, TABLE_ERROR_PNT);
+ return NULL;
+ }
+
+ /* there must be at least 1 element in the table for this to work */
+ if (table_p->ta_entry_n == 0) {
+ SET_POINTER(error_p, TABLE_ERROR_EMPTY);
+ return NULL;
+ }
+
+ entries_size = table_p->ta_entry_n * sizeof(table_entry_t *);
+ if (table_p->ta_alloc_func == NULL) {
+ entries = (table_entry_t **)malloc(entries_size);
+ }
+ else {
+ entries =
+ (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool,
+ entries_size);
+ }
+ if (entries == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ALLOC);
+ return NULL;
+ }
+
+ /* get a pointer to all entries */
+ entry_p = first_entry(table_p, &linear);
+ if (entry_p == NULL) {
+ if (table_p->ta_free_func == NULL) {
+ free(entries);
+ }
+ else {
+ (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size);
+ }
+ SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND);
+ return NULL;
+ }
+
+ /* add all of the entries to the array */
+ for (entries_p = entries;
+ entry_p != NULL;
+ entry_p = next_entry(table_p, &linear, &ret)) {
+ *entries_p++ = entry_p;
+ }
+
+ if (ret != TABLE_ERROR_NOT_FOUND) {
+ if (table_p->ta_free_func == NULL) {
+ free(entries);
+ }
+ else {
+ (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size);
+ }
+ SET_POINTER(error_p, ret);
+ return NULL;
+ }
+
+ if (compare == NULL) {
+ /* this is regardless of the alignment */
+ comp_func = local_compare;
+ }
+ else if (table_p->ta_data_align == 0) {
+ comp_func = external_compare;
+ }
+ else {
+ comp_func = external_compare_align;
+ }
+
+ /* now qsort the entire entries array from first to last element */
+ ret = split((unsigned char *)entries,
+ (unsigned char *)(entries + table_p->ta_entry_n - 1),
+ sizeof(table_entry_t *), comp_func, compare, table_p);
+ if (ret != TABLE_ERROR_NONE) {
+ if (table_p->ta_free_func == NULL) {
+ free(entries);
+ }
+ else {
+ (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size);
+ }
+ SET_POINTER(error_p, ret);
+ return NULL;
+ }
+
+ SET_POINTER(num_entries_p, table_p->ta_entry_n);
+
+ SET_POINTER(error_p, TABLE_ERROR_NONE);
+ return entries;
+}
+
+/*
+ * int table_order_free
+ *
+ * DESCRIPTION:
+ *
+ * Free the pointer returned by the table_order or table_order_pos
+ * routines.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to the table.
+ *
+ * table_entries - Allocated list of entry pointers returned by
+ * table_order.
+ *
+ * entry_n - Number of entries in the array as passed back by
+ * table_order or table_order_pos in num_entries_p.
+ */
+int table_order_free(table_t *table_p, table_entry_t **table_entries,
+ const int entry_n)
+{
+ int ret, final = TABLE_ERROR_NONE;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+
+ if (table_p->ta_free_func == NULL) {
+ free(table_entries);
+ }
+ else {
+ ret = table_p->ta_free_func(table_p->ta_mem_pool, table_entries,
+ sizeof(table_entry_t *) * entry_n);
+ if (ret != 1) {
+ final = TABLE_ERROR_FREE;
+ }
+ }
+
+ return final;
+}
+
+/*
+ * int table_entry
+ *
+ * DESCRIPTION:
+ *
+ * Get information about an element. The element is one from the
+ * array returned by the table_order function. If any of the key/data
+ * pointers are NULL then they are ignored.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * element.
+ *
+ * entry_p - Pointer to a table entry from the array returned by the
+ * table_order function.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of this entry that is allocated in the table. If an
+ * (int) is stored as this entry (for example) then key_buf_p should
+ * be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage of this entry that is allocated in the table.
+ * If a (long) is stored as this entry data (for example) then
+ * data_buf_p should be (long **) i.e. the address of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table.
+ */
+int table_entry(table_t *table_p, table_entry_t *entry_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p)
+{
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (entry_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+
+ SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p));
+ SET_POINTER(key_size_p, entry_p->te_key_size);
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ if (table_p->ta_data_align == 0) {
+ *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ *data_buf_p = entry_data_buf(table_p, entry_p);
+ }
+ }
+ }
+ SET_POINTER(data_size_p, entry_p->te_data_size);
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * table_linear_t *table_order_pos
+ *
+ * DESCRIPTION:
+ *
+ * Order a table by building an array of table linear structures and
+ * then sorting this array using the qsort function. To retrieve the
+ * sorted entries, you can then use the table_entry_pos routine to
+ * access each entry in order.
+ *
+ * NOTE: This routine is thread safe and makes use of an internal
+ * status qsort function.
+ *
+ * RETURNS:
+ *
+ * Success - An allocated list of table-linear structures which must
+ * be freed by table_order_pos_free later.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to the table that we are ordering.
+ *
+ * compare - Comparison function defined by the user. Its definition
+ * is at the top of the table.h file. If this is NULL then it will
+ * order the table my memcmp-ing the keys.
+ *
+ * num_entries_p - Pointer to an integer which, if not NULL, will
+ * contain the number of entries in the returned entry pointer array.
+ *
+ * error_p - Pointer to an integer which, if not NULL, will contain a
+ * table error code.
+ */
+table_linear_t *table_order_pos(table_t *table_p, table_compare_t compare,
+ int *num_entries_p, int *error_p)
+{
+ table_entry_t *entry_p;
+ table_linear_t linear, *linears, *linears_p;
+ compare_t comp_func;
+ int ret;
+
+ if (table_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ARG_NULL);
+ return NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ SET_POINTER(error_p, TABLE_ERROR_PNT);
+ return NULL;
+ }
+
+ /* there must be at least 1 element in the table for this to work */
+ if (table_p->ta_entry_n == 0) {
+ SET_POINTER(error_p, TABLE_ERROR_EMPTY);
+ return NULL;
+ }
+
+ if (table_p->ta_alloc_func == NULL) {
+ linears = (table_linear_t *)malloc(table_p->ta_entry_n *
+ sizeof(table_linear_t));
+ }
+ else {
+ linears =
+ (table_linear_t *)table_p->ta_alloc_func(table_p->ta_mem_pool,
+ table_p->ta_entry_n *
+ sizeof(table_linear_t));
+ }
+ if (linears == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_ALLOC);
+ return NULL;
+ }
+
+ /* get a pointer to all entries */
+ entry_p = first_entry(table_p, &linear);
+ if (entry_p == NULL) {
+ SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND);
+ return NULL;
+ }
+
+ /* add all of the entries to the array */
+ for (linears_p = linears;
+ entry_p != NULL;
+ entry_p = next_entry(table_p, &linear, &ret)) {
+ *linears_p++ = linear;
+ }
+
+ if (ret != TABLE_ERROR_NOT_FOUND) {
+ SET_POINTER(error_p, ret);
+ return NULL;
+ }
+
+ if (compare == NULL) {
+ /* this is regardless of the alignment */
+ comp_func = local_compare_pos;
+ }
+ else if (table_p->ta_data_align == 0) {
+ comp_func = external_compare_pos;
+ }
+ else {
+ comp_func = external_compare_align_pos;
+ }
+
+ /* now qsort the entire entries array from first to last element */
+ split((unsigned char *)linears,
+ (unsigned char *)(linears + table_p->ta_entry_n - 1),
+ sizeof(table_linear_t), comp_func, compare, table_p);
+
+ if (num_entries_p != NULL) {
+ *num_entries_p = table_p->ta_entry_n;
+ }
+
+ SET_POINTER(error_p, TABLE_ERROR_NONE);
+ return linears;
+}
+
+/*
+ * int table_order_pos_free
+ *
+ * DESCRIPTION:
+ *
+ * Free the pointer returned by the table_order or table_order_pos
+ * routines.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Pointer to the table.
+ *
+ * table_entries - Allocated list of entry pointers returned by
+ * table_order_pos.
+ *
+ * entry_n - Number of entries in the array as passed back by
+ * table_order or table_order_pos in num_entries_p.
+ */
+int table_order_pos_free(table_t *table_p, table_linear_t *table_entries,
+ const int entry_n)
+{
+ int ret, final = TABLE_ERROR_NONE;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+
+ if (table_p->ta_free_func == NULL) {
+ free(table_entries);
+ }
+ else {
+ ret = table_p->ta_free_func(table_p->ta_mem_pool, table_entries,
+ sizeof(table_linear_t) * entry_n);
+ if (ret != 1) {
+ final = TABLE_ERROR_FREE;
+ }
+ }
+
+ return final;
+}
+
+/*
+ * int table_entry_pos
+ *
+ * DESCRIPTION:
+ *
+ * Get information about an element. The element is one from the
+ * array returned by the table_order function. If any of the key/data
+ * pointers are NULL then they are ignored.
+ *
+ * RETURNS:
+ *
+ * Success - TABLE_ERROR_NONE
+ *
+ * Failure - Table error code.
+ *
+ * ARGUMENTS:
+ *
+ * table_p - Table structure pointer from which we are getting the
+ * element.
+ *
+ * linear_p - Pointer to a table linear structure from the array
+ * returned by the table_order function.
+ *
+ * key_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the storage of this entry that is allocated in the table. If an
+ * (int) is stored as this entry (for example) then key_buf_p should
+ * be (int **) i.e. the address of a (int *).
+ *
+ * key_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the key that is stored in the table.
+ *
+ * data_buf_p - Pointer which, if not NULL, will be set to the address
+ * of the data storage of this entry that is allocated in the table.
+ * If a (long) is stored as this entry data (for example) then
+ * data_buf_p should be (long **) i.e. the address of a (long *).
+ *
+ * data_size_p - Pointer to an integer which, if not NULL, will be set
+ * to the size of the data that is stored in the table.
+ */
+int table_entry_pos(table_t *table_p, table_linear_t *linear_p,
+ void **key_buf_p, int *key_size_p,
+ void **data_buf_p, int *data_size_p)
+{
+ table_entry_t *entry_p;
+ int ret;
+
+ if (table_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+ if (table_p->ta_magic != TABLE_MAGIC) {
+ return TABLE_ERROR_PNT;
+ }
+ if (linear_p == NULL) {
+ return TABLE_ERROR_ARG_NULL;
+ }
+
+ /* find the associated entry */
+ entry_p = this_entry(table_p, linear_p, &ret);
+ if (entry_p == NULL) {
+ return ret;
+ }
+
+ if (key_buf_p != NULL) {
+ *key_buf_p = ENTRY_KEY_BUF(entry_p);
+ }
+ if (key_size_p != NULL) {
+ *key_size_p = entry_p->te_key_size;
+ }
+ if (data_buf_p != NULL) {
+ if (entry_p->te_data_size == 0) {
+ *data_buf_p = NULL;
+ }
+ else {
+ if (table_p->ta_data_align == 0) {
+ *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p);
+ }
+ else {
+ *data_buf_p = entry_data_buf(table_p, entry_p);
+ }
+ }
+ }
+ if (data_size_p != NULL) {
+ *data_size_p = entry_p->te_data_size;
+ }
+
+ return TABLE_ERROR_NONE;
+}
+
+/*
+ * const char *table_strerror
+ *
+ * DESCRIPTION:
+ *
+ * Return the corresponding string for the error number.
+ *
+ * RETURNS:
+ *
+ * Success - String equivalient of the error.
+ *
+ * Failure - String "invalid error code"
+ *
+ * ARGUMENTS:
+ *
+ * error - Error number that we are converting.
+ */
+const char *table_strerror(const int error)
+{
+ error_str_t *err_p;
+
+ for (err_p = errors; err_p->es_error != 0; err_p++) {
+ if (err_p->es_error == error) {
+ return err_p->es_string;
+ }
+ }
+
+ return INVALID_ERROR;
+}
diff --git a/libs/libks/src/table_util.c b/libs/libks/src/table_util.c
new file mode 100644
index 0000000000..2fcfda3778
--- /dev/null
+++ b/libs/libks/src/table_util.c
@@ -0,0 +1,295 @@
+/*
+ * Hash table utility program.
+ *
+ * Copyright 2000 by Gray Watson
+ *
+ * This file is part of the table package.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies,
+ * and that the name of Gray Watson not be used in advertising or
+ * publicity pertaining to distribution of the document or software
+ * without specific, written prior permission.
+ *
+ * Gray Watson makes no representations about the suitability of the
+ * software described herein for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * The author may be reached via http://256.com/gray/
+ *
+ * $Id: table_util.c,v 1.5 2000/03/09 03:30:42 gray Exp $
+ */
+
+#include
+#include
+#include
+
+#include "table.h"
+
+static char *rcs_id =
+ "$Id: table_util.c,v 1.5 2000/03/09 03:30:42 gray Exp $";
+
+#define WRITE_MODE 0640 /* mode to write out table */
+#define SPECIAL_CHARS "e\033^^\"\"''\\\\n\nr\rt\tb\bf\fa\007"
+
+/*
+ * expand_chars
+ *
+ * DESCRIPTION:
+ *
+ * Copies a buffer into a output buffer while translates
+ * non-printables into %03o octal values. If it can, it will also
+ * translate certain \ characters (\r, \n, etc.) into \\%c. The
+ * routine is useful for printing out binary values.
+ *
+ * NOTE: It does _not_ add a \0 at the end of the output buffer.
+ *
+ * RETURNS:
+ *
+ * Returns the number of characters added to the output buffer.
+ *
+ * ARGUMENTS:
+ *
+ * buf - the buffer to convert.
+ *
+ * buf_size - size of the buffer. If < 0 then it will expand till it
+ * sees a \0 character.
+ *
+ * out - destination buffer for the convertion.
+ *
+ * out_size - size of the output buffer.
+ */
+int expand_chars(const void *buf, const int buf_size,
+ char *out, const int out_size)
+{
+ int buf_c;
+ const unsigned char *buf_p, *spec_p;
+ char *max_p, *out_p = out;
+
+ /* setup our max pointer */
+ max_p = out + out_size;
+
+ /* run through the input buffer, counting the characters as we go */
+ for (buf_c = 0, buf_p = (const unsigned char *)buf;; buf_c++, buf_p++) {
+
+ /* did we reach the end of the buffer? */
+ if (buf_size < 0) {
+ if (*buf_p == '\0') {
+ break;
+ }
+ }
+ else {
+ if (buf_c >= buf_size) {
+ break;
+ }
+ }
+
+ /* search for special characters */
+ for (spec_p = (unsigned char *)SPECIAL_CHARS + 1;
+ *(spec_p - 1) != '\0';
+ spec_p += 2) {
+ if (*spec_p == *buf_p) {
+ break;
+ }
+ }
+
+ /* did we find one? */
+ if (*(spec_p - 1) != '\0') {
+ if (out_p + 2 >= max_p) {
+ break;
+ }
+ (void)sprintf(out_p, "\\%c", *(spec_p - 1));
+ out_p += 2;
+ continue;
+ }
+
+ /* print out any 7-bit printable characters */
+ if (*buf_p < 128 && isprint(*buf_p)) {
+ if (out_p + 1 >= max_p) {
+ break;
+ }
+ *out_p = *(char *)buf_p;
+ out_p += 1;
+ }
+ else {
+ if (out_p + 4 >= max_p) {
+ break;
+ }
+ (void)sprintf(out_p, "\\%03o", *buf_p);
+ out_p += 4;
+ }
+ }
+
+ return out_p - out;
+}
+
+/*
+ * dump_table
+ *
+ * DESCRIPTION:
+ *
+ * Dump a table file to the screen.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * tab_p - a table pointer that we are dumping.
+ */
+static void dump_table(table_t *tab_p)
+{
+ char buf[10240];
+ void *key_p, *data_p;
+ int ret, key_size, data_size, len, entry_c;
+
+ for (ret = table_first(tab_p, (void **)&key_p, &key_size,
+ (void **)&data_p, &data_size), entry_c = 0;
+ ret == TABLE_ERROR_NONE;
+ ret = table_next(tab_p, (void **)&key_p, &key_size,
+ (void **)&data_p, &data_size), entry_c++) {
+ /* expand the key */
+ len = expand_chars(key_p, key_size, buf, sizeof(buf));
+ (void)printf("%d: key '%.*s' (%d), ", entry_c, len, buf, len);
+ /* now dump the data */
+ len = expand_chars(data_p, data_size, buf, sizeof(buf));
+ (void)printf("data '%.*s' (%d)\n", len, buf, len);
+ }
+}
+
+/*
+ * usage
+ *
+ * DESCRIPTION:
+ *
+ * Print the usage message to stderr.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * tab_p - a table pointer that we are dumping.
+ */
+static void usage(void)
+{
+ (void)fprintf(stderr,
+ "Usage: table_util\n"
+ " [-b number] or --buckets num buckets to adjust table\n"
+ " [-o file] or --out-file output filename\n"
+ " [-v] or --verbose verbose messages\n"
+ " file input table filename\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ table_t *tab_p;
+ char do_write = 0, verbose = 0;
+ char *out_file = NULL, *in_file;
+ int ret, entry_n, bucket_n, num_buckets = 0;
+
+ /* process the args */
+ for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) {
+
+ switch (*(*argv + 1)) {
+
+ case 'b':
+ argc--, argv++;
+ if (argc == 0) {
+ usage();
+ }
+ num_buckets = atoi(*argv);
+ break;
+
+ case 'o':
+ argc--, argv++;
+ if (argc == 0) {
+ usage();
+ }
+ out_file = *argv;
+ break;
+
+ case 'v':
+ verbose = 1;
+ break;
+
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (argc != 1) {
+ usage();
+ }
+
+ /* take the last argument as the input file */
+ in_file = *argv;
+
+ /* read in the table from disk */
+ tab_p = table_read(in_file, &ret);
+ if (tab_p == NULL) {
+ (void)fprintf(stderr, "table_util: unable to table_read from '%s': %s\n",
+ in_file, table_strerror(ret));
+ exit(1);
+ }
+
+ /* get info about the table */
+ ret = table_info(tab_p, &bucket_n, &entry_n);
+ if (ret != TABLE_ERROR_NONE) {
+ (void)fprintf(stderr,
+ "table_util: unable to get info on table in '%s': %s\n",
+ in_file, table_strerror(ret));
+ exit(1);
+ }
+
+ (void)printf("Read table of %d buckets and %d entries from '%s'\n",
+ bucket_n, entry_n, in_file);
+
+ if (verbose) {
+ dump_table(tab_p);
+ }
+
+ if (num_buckets > 0) {
+ /* adjust the table's buckets */
+ ret = table_adjust(tab_p, num_buckets);
+ if (ret != TABLE_ERROR_NONE) {
+ (void)fprintf(stderr,
+ "table_util: unable to adjust table to %d buckets: %s\n",
+ num_buckets, table_strerror(ret));
+ exit(1);
+ }
+ do_write = 1;
+ }
+
+ /* did we modify the table at all */
+ if (do_write) {
+ if (out_file == NULL) {
+ out_file = in_file;
+ }
+
+ /* write out our table */
+ ret = table_write(tab_p, out_file, WRITE_MODE);
+ if (ret != TABLE_ERROR_NONE) {
+ (void)fprintf(stderr, "table_util: unable to write table to '%s': %s\n",
+ out_file, table_strerror(ret));
+ exit(1);
+ }
+
+ (void)printf("Wrote table to '%s'\n", out_file);
+ }
+
+ /* free the table */
+ ret = table_free(tab_p);
+ if (ret != TABLE_ERROR_NONE) {
+ (void)fprintf(stderr, "table_util: unable to free table: %s\n",
+ table_strerror(ret));
+ /* NOTE: not a critical error */
+ }
+
+ exit(0);
+}
diff --git a/libs/libteletone/src/libteletone_generate.h b/libs/libteletone/src/libteletone_generate.h
index a49e45a658..25d5bf79d7 100644
--- a/libs/libteletone/src/libteletone_generate.h
+++ b/libs/libteletone/src/libteletone_generate.h
@@ -91,6 +91,7 @@ extern "C" {
#define __inline__ __inline
#endif
+#if !defined(_STDINT) && !defined(uint32_t)
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
@@ -99,6 +100,7 @@ typedef __int64 int64_t;
typedef __int32 int32_t;
typedef __int16 int16_t;
typedef __int8 int8_t;
+#endif
#else
#include
#endif
diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update
index 142a1e1a97..b50d284902 100644
--- a/libs/sofia-sip/.update
+++ b/libs/sofia-sip/.update
@@ -1 +1 @@
-Wed Aug 15 22:51:21 CDT 2012
+Tue Nov 13 15:22:19 CST 2012
diff --git a/libs/sofia-sip/Makefile.am b/libs/sofia-sip/Makefile.am
index 069007d300..7279695865 100644
--- a/libs/sofia-sip/Makefile.am
+++ b/libs/sofia-sip/Makefile.am
@@ -40,6 +40,9 @@ dist_man_MANS =
# man/man1/localinfo.1 man/man1/addrinfo.1 \
# man/man1/stunc.1 man/man1/sip-dig.1
+noop:
+ @echo ok
+
$(dist_man_MANS): manpages
manpages:
diff --git a/libs/sofia-sip/configure.ac b/libs/sofia-sip/configure.ac
index 196d815157..f882bc76b4 100644
--- a/libs/sofia-sip/configure.ac
+++ b/libs/sofia-sip/configure.ac
@@ -254,6 +254,9 @@ if test x"$have_check" = "xyes"; then
fi
AC_CHECK_HEADERS([fnmatch.h])
+AC_CHECK_LIB(pthread, pthread_setschedparam, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])])
+
+
dnl dl is currently used only in testing
AC_CHECK_LIB([dl], [dlopen], [
dnl Note: -ldl is not added to LIBS
diff --git a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c
index 087810ebc7..9c1ca218b5 100644
--- a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c
+++ b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c
@@ -744,7 +744,7 @@ void auth_check_digest(auth_mod_t *am,
auth_challenge_digest(am, as, ach);
as->as_blacklist = am->am_blacklist;
}
- SU_DEBUG_5(("auth_method_digest: response did not match\n"));
+ SU_DEBUG_5(("auth_method_digest: response did not match\n" VA_NONE));
return;
}
@@ -761,7 +761,7 @@ void auth_check_digest(auth_mod_t *am,
if (am->am_challenge)
auth_challenge_digest(am, as, ach);
- SU_DEBUG_7(("auth_method_digest: successful authentication\n"));
+ SU_DEBUG_7(("auth_method_digest: successful authentication\n" VA_NONE));
as->as_status = 0; /* Successful authentication! */
as->as_phrase = "";
@@ -1412,11 +1412,11 @@ int auth_validate_digest_nonce(auth_mod_t *am,
/* Check nonce */
if (!ar->ar_nonce) {
- SU_DEBUG_5(("auth_method_digest: no nonce\n"));
+ SU_DEBUG_5(("auth_method_digest: no nonce\n" VA_NONE));
return -1;
}
if (base64_d((void*)nonce, (sizeof nonce), ar->ar_nonce) != (sizeof nonce)) {
- SU_DEBUG_5(("auth_method_digest: too short nonce\n"));
+ SU_DEBUG_5(("auth_method_digest: too short nonce\n" VA_NONE));
return -1;
}
@@ -1426,7 +1426,7 @@ int auth_validate_digest_nonce(auth_mod_t *am,
auth_md5_hmac_digest(am, md5, hmac, sizeof hmac);
if (memcmp(nonce->digest, hmac, sizeof nonce->digest)) {
- SU_DEBUG_5(("auth_method_digest: bad nonce\n"));
+ SU_DEBUG_5(("auth_method_digest: bad nonce\n" VA_NONE));
return -1;
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c
index bd1e63b478..42539cf82d 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c
@@ -424,12 +424,12 @@ nea_server_t *nea_server_create(nta_agent_t *agent,
throttle = min_throttle;
if (!url) {
- SU_DEBUG_5(("nea_server_create(): invalid url\n"));
+ SU_DEBUG_5(("nea_server_create(): invalid url\n" VA_NONE));
return NULL;
}
if (min_expires > expires || expires > max_expires) {
- SU_DEBUG_5(("nea_server_create(): invalid expiration range\n"));
+ SU_DEBUG_5(("nea_server_create(): invalid expiration range\n" VA_NONE));
return NULL;
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
index e690b424e7..c9bbea2d6b 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
@@ -1276,7 +1276,7 @@ void agent_timer(su_root_magic_t *rm, su_timer_t *timer, nta_agent_t *agent)
if (next == latest) {
/* Do not set timer? */
- SU_DEBUG_9(("nta: timer not set\n"));
+ SU_DEBUG_9(("nta: timer not set\n" VA_NONE));
assert(!agent->sa_out.completed->q_head);
assert(!agent->sa_out.trying->q_head);
assert(!agent->sa_out.inv_calling->q_head);
@@ -2162,7 +2162,7 @@ int nta_agent_add_tport(nta_agent_t *self,
if (url_string_p(uri))
SU_DEBUG_1(("nta: %s: invalid bind URL\n", uri->us_str));
else
- SU_DEBUG_1(("nta: invalid bind URL\n"));
+ SU_DEBUG_1(("nta: invalid bind URL\n" VA_NONE));
su_seterrno(EINVAL);
return -1;
}
@@ -2249,19 +2249,19 @@ int nta_agent_add_tport(nta_agent_t *self,
/* XXX - when to use maddr? */
if ((agent_init_via(self, tport_primaries(self->sa_tports), 0)) < 0) {
error = su_errno();
- SU_DEBUG_1(("nta: cannot create Via headers\n"));
+ SU_DEBUG_1(("nta: cannot create Via headers\n" VA_NONE));
goto error;
}
else
- SU_DEBUG_9(("nta: Via fields initialized\n"));
+ SU_DEBUG_9(("nta: Via fields initialized\n" VA_NONE));
if ((agent_init_contact(self)) < 0) {
error = su_errno();
- SU_DEBUG_1(("nta: cannot create Contact header\n"));
+ SU_DEBUG_1(("nta: cannot create Contact header\n" VA_NONE));
goto error;
}
else
- SU_DEBUG_9(("nta: Contact header created\n"));
+ SU_DEBUG_9(("nta: Contact header created\n" VA_NONE));
su_free(self->sa_home, url);
ta_end(ta);
@@ -2286,7 +2286,7 @@ int agent_create_master_transport(nta_agent_t *self, tagi_t *tags)
if (!self->sa_tports)
return -1;
- SU_DEBUG_9(("nta: master transport created\n"));
+ SU_DEBUG_9(("nta: master transport created\n" VA_NONE));
return 0;
}
@@ -7713,7 +7713,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
home = msg_home(msg);
if (!sip->sip_request || sip_complete_message(msg) < 0) {
- SU_DEBUG_3(("nta: outgoing_create: incomplete request\n"));
+ SU_DEBUG_3(("nta: outgoing_create: incomplete request\n" VA_NONE));
return NULL;
}
@@ -7900,7 +7900,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
}
}
else {
- SU_DEBUG_1(("outgoing_create: ACK without INVITE\n"));
+ SU_DEBUG_1(("outgoing_create: ACK without INVITE\n" VA_NONE));
assert(!"INVITE found for ACK");
}
}
@@ -7987,11 +7987,11 @@ outgoing_prepare_send(nta_outgoing_t *orq)
outgoing_send_via(orq, tp);
}
else if (orq->orq_sips) {
- SU_DEBUG_3(("nta outgoing create: no secure transport\n"));
+ SU_DEBUG_3(("nta outgoing create: no secure transport\n" VA_NONE));
outgoing_reply(orq, SIP_416_UNSUPPORTED_URI, 1);
}
else {
- SU_DEBUG_3(("nta outgoing create: no transport protocol\n"));
+ SU_DEBUG_3(("nta outgoing create: no transport protocol\n" VA_NONE));
outgoing_reply(orq, 503, "No transport", 1);
}
}
@@ -8013,7 +8013,7 @@ outgoing_send_via(nta_outgoing_t *orq, tport_t *tp)
if (old_tp) tport_unref(old_tp);
if (outgoing_insert_via(orq, agent_tport_via(tp)) < 0) {
- SU_DEBUG_3(("nta outgoing create: cannot insert Via line\n"));
+ SU_DEBUG_3(("nta outgoing create: cannot insert Via line\n" VA_NONE));
outgoing_reply(orq, 503, "Cannot insert Via", 1);
return;
}
@@ -9211,7 +9211,7 @@ int outgoing_recv(nta_outgoing_t *_orq,
if (orq->orq_destroyed && 200 <= status && status < 300) {
if (orq->orq_uas && su_strcasecmp(sip->sip_to->a_tag, orq->orq_tag) != 0) {
/* Orphan 200 Ok to INVITE. ACK and BYE it */
- SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE\n"));
+ SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE %p\n", (void *)orq));
return nta_msg_ackbye(sa, msg);
}
return -1; /* Proxy statelessly (RFC3261 section 16.11) */
@@ -9273,7 +9273,7 @@ int outgoing_recv(nta_outgoing_t *_orq,
return outgoing_duplicate(orq, msg, sip);
/* Orphan 200 Ok to INVITE. ACK and BYE it */
- SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE"));
+ SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE" VA_NONE));
return nta_msg_ackbye(sa, msg);
}
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c b/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c
index 96442454fb..6a2cd5f80b 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c
@@ -911,7 +911,7 @@ int hc_resolve_and_send(nth_client_t * hc)
if (msg_serialize(msg, http) < 0) {
assert(hc->hc_tport);
- SU_DEBUG_3(("nth client create: invalid message"));
+ SU_DEBUG_3(("nth client create: invalid message" VA_NONE));
return -1;
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c b/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c
index 4daed06520..0c9b6182dc 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c
@@ -312,20 +312,20 @@ nth_site_t *nth_site_create(nth_site_t *parent,
is_path = url->url_path != NULL;
if (is_host && is_path) {
- SU_DEBUG_3(("nth_site_create(): virtual host and path simultanously\n"));
+ SU_DEBUG_3(("nth_site_create(): virtual host and path simultanously\n" VA_NONE));
errno = EINVAL;
goto error;
}
if (!parent && !is_host) {
- SU_DEBUG_3(("nth_site_create(): host is required\n"));
+ SU_DEBUG_3(("nth_site_create(): host is required\n" VA_NONE));
errno = EINVAL;
goto error;
}
if (parent) {
if (!parent->site_isdir) {
- SU_DEBUG_3(("nth_site_create(): invalid parent resource \n"));
+ SU_DEBUG_3(("nth_site_create(): invalid parent resource \n" VA_NONE));
errno = EINVAL;
goto error;
}
@@ -995,7 +995,7 @@ static void server_reply(server_t *srv, tport_t *tport,
if (tport_tqsend(tport, response, NULL,
TPTAG_CLOSE_AFTER(close),
TAG_END()) == -1) {
- SU_DEBUG_3(("server_reply(): cannot queue response\n"));
+ SU_DEBUG_3(("server_reply(): cannot queue response\n" VA_NONE));
tport_shutdown(tport, 2);
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c
index e7ec9fb890..a9fed48ffe 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c
@@ -1217,6 +1217,7 @@ int nua_base_client_check_restart(nua_client_request_t *cr,
status == 500 || status == 503 ||
status == 600 || status == 603) &&
sip->sip_retry_after &&
+ NH_PGET(nh, retry_after_enable) &&
sip->sip_retry_after->af_delta < 3200) {
su_timer_t *timer;
char phrase[18]; /* Retry After XXXX\0 */
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c
index 0f6a491dff..c63455fc91 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c
@@ -157,6 +157,7 @@ int nua_stack_set_defaults(nua_handle_t *nh,
NHP_SET(nhp, callee_caps, 0);
NHP_SET(nhp, service_route_enable, 1);
NHP_SET(nhp, path_enable, 1);
+ NHP_SET(nhp, retry_after_enable, 1);
NHP_SET(nhp, refer_expires, 300);
NHP_SET(nhp, refer_with_id, 1);
@@ -295,6 +296,7 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags)
* NUTAG_ONLY183_100REL() \n
* NUTAG_OUTBOUND() \n
* NUTAG_PATH_ENABLE() \n
+ * NUTAG_RETRY_AFTER_ENABLE() \n
* NUTAG_PROXY() (aka NTATAG_DEFAULT_PROXY()) \n
* NUTAG_REFER_EXPIRES() \n
* NUTAG_REFER_WITH_ID() \n
@@ -417,6 +419,7 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags)
* NUTAG_ONLY183_100REL() \n
* NUTAG_OUTBOUND() \n
* NUTAG_PATH_ENABLE() \n
+ * NUTAG_RETRY_AFTER_ENABLE() \n
* NUTAG_PROXY() (aka NTATAG_DEFAULT_PROXY()) \n
* NUTAG_REFER_EXPIRES() \n
* NUTAG_REFER_WITH_ID() \n
@@ -801,6 +804,10 @@ static int nhp_set_tags(su_home_t *home,
else if (tag == nutag_path_enable) {
NHP_SET(nhp, path_enable, value != 0);
}
+ /* NUTAG_RETRY_AFTER_ENABLE(retry_after_enable) */
+ else if (tag == nutag_retry_after_enable) {
+ NHP_SET(nhp, retry_after_enable, value != 0);
+ }
/* NUTAG_AUTH_CACHE(auth_cache) */
else if (tag == nutag_auth_cache) {
if (value >= 0 && value < (tag_value_t)_nua_auth_cache_invalid)
@@ -1494,6 +1501,7 @@ int nua_stack_set_smime_params(nua_t *nua, tagi_t const *tags)
* NUTAG_ONLY183_100REL() \n
* NUTAG_OUTBOUND() \n
* NUTAG_PATH_ENABLE() \n
+ * NUTAG_RETRY_AFTER_ENABLE() \n
* NUTAG_REFER_EXPIRES() \n
* NUTAG_REFER_WITH_ID() \n
* NUTAG_REFRESH_WITHOUT_SDP() \n
@@ -1669,6 +1677,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
TIF(NUTAG_MEDIA_FEATURES, media_features),
TIF(NUTAG_SERVICE_ROUTE_ENABLE, service_route_enable),
TIF(NUTAG_PATH_ENABLE, path_enable),
+ TIF(NUTAG_RETRY_AFTER_ENABLE, retry_after_enable),
TIF(NUTAG_AUTH_CACHE, auth_cache),
TIF(NUTAG_REFER_EXPIRES, refer_expires),
TIF(NUTAG_REFER_WITH_ID, refer_with_id),
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h
index 9fe4a98652..5c26e4ef13 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h
@@ -111,6 +111,10 @@ struct nua_handle_preferences
unsigned nhp_refer_with_id:1;
unsigned nhp_timer_autorequire:1;
+
+ /** Enable Retry-After */
+ unsigned nhp_retry_after_enable:1;
+
unsigned:0;
/* Default lifetime for implicit subscriptions created by REFER */
@@ -210,6 +214,7 @@ struct nua_handle_preferences
unsigned nhb_initial_route:1;
unsigned nhb_proxy:1;
unsigned nhb_timer_autorequire:1;
+ unsigned nhb_retry_after_enable:1;
unsigned :0;
} set_bits;
unsigned set_unsigned[2];
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c
index a0dcbb1c4e..a4ec4246af 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c
@@ -967,7 +967,7 @@ static int nua_register_client_response(nua_client_request_t *cr,
if (tport && tport != nr->nr_tport) {
if (nr->nr_error_report_id) {
if (tport_release(nr->nr_tport, nr->nr_error_report_id, NULL, NULL, nr, 0) < 0)
- SU_DEBUG_1(("nua_register: tport_release() failed\n"));
+ SU_DEBUG_1(("nua_register: tport_release() failed\n" VA_NONE));
nr->nr_error_report_id = 0;
}
tport_unref(nr->nr_tport);
@@ -996,7 +996,7 @@ static int nua_register_client_response(nua_client_request_t *cr,
if (nr->nr_tport) {
if (nr->nr_error_report_id) {
if (tport_release(nr->nr_tport, nr->nr_error_report_id, NULL, NULL, nr, 0) < 0)
- SU_DEBUG_1(("nua_register: tport_release() failed\n"));
+ SU_DEBUG_1(("nua_register: tport_release() failed\n" VA_NONE));
nr->nr_error_report_id = 0;
}
@@ -1028,7 +1028,7 @@ void nua_register_connection_closed(tp_stack_t *sip_stack,
pending = nr->nr_error_report_id;
if (tport_release(tport, pending, NULL, NULL, nr, 0) < 0)
- SU_DEBUG_1(("nua_register: tport_release() failed\n"));
+ SU_DEBUG_1(("nua_register: tport_release() failed\n" VA_NONE));
nr->nr_error_report_id = 0;
tpn = tport_name(nr->nr_tport);
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c
index c17b7b9bb0..9b862415a3 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c
@@ -1245,6 +1245,7 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
int status = 200;
char const *phrase = "OK", *reason = NULL;
char const *invite_branch;
+ char const *pl_s = NULL;
assert(cr->cr_orq);
assert(cr->cr_method == sip_method_invite);
@@ -1256,6 +1257,11 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
goto error;
}
+ tl_gets(tags,
+ SIPTAG_PAYLOAD_STR_REF(pl_s),
+ TAG_END());
+
+
assert(ds->ds_leg);
msg = nta_outgoing_getrequest(cr->cr_orq);
@@ -1305,7 +1311,7 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
while (sip->sip_supported)
sip_header_remove(msg, sip, (sip_header_t*)sip->sip_supported);
- if (ss == NULL || ss->ss_state > nua_callstate_ready)
+ if (ss == NULL || ss->ss_state > nua_callstate_ready || pl_s)
;
else if (cr->cr_offer_recv && !cr->cr_answer_sent) {
if (nh->nh_soa == NULL) {
@@ -3039,11 +3045,11 @@ nh_referral_check(nua_handle_t *nh, tagi_t const *tags)
ref->ref_event = sip_event_dup(nh->nh_home, event);
if (!nh_validate(nh->nh_nua, ref_handle)) {
- SU_DEBUG_3(("nua: invalid NOTIFY_REFER handle\n"));
+ SU_DEBUG_3(("nua: invalid NOTIFY_REFER handle\n" VA_NONE));
return -1;
}
else if (!ref->ref_event) {
- SU_DEBUG_3(("nua: NOTIFY event missing\n"));
+ SU_DEBUG_3(("nua: NOTIFY event missing\n" VA_NONE));
return -1;
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
index 5fe5d221d1..85f1647d3e 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
@@ -192,7 +192,7 @@ int nua_stack_init(su_root_t *root, nua_t *nua)
dnh->nh_ds->ds_leg == NULL ||
nta_agent_set_params(nua->nua_nta, NTATAG_UA(1), TAG_END()) < 0 ||
nua_stack_init_transport(nua, nua->nua_args) < 0) {
- SU_DEBUG_1(("nua: initializing SIP stack failed\n"));
+ SU_DEBUG_1(("nua: initializing SIP stack failed\n" VA_NONE));
return -1;
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c
index 491d485731..9e0c8d85ca 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c
@@ -126,6 +126,7 @@
* - NUTAG_M_USERNAME()
* - NUTAG_OUTBOUND()
* - NUTAG_PATH_ENABLE()
+ * - NUTAG_RETRY_AFTER_ENABLE()
* - NUTAG_SERVICE_ROUTE_ENABLE()
* Specifications:
* - @RFC3261 section 10, @RFC3327, @RFC3608, @RFC3680, @RFC3840,
@@ -2663,6 +2664,29 @@ tag_typedef_t nutag_path_enable = BOOLTAG_TYPEDEF(path_enable);
* Reference tag for NUTAG_PATH_ENABLE().
*/
+/**@def NUTAG_RETRY_AFTER_ENABLE(x)
+ *
+ * If true, support RFC 3261 Retry-After
+ *
+ * @par Used with
+ * - nua_create(), nua_set_params(), nua_get_params()
+ * - nua_handle(), nua_set_hparams(), nua_get_hparams()
+ * - nua_register()
+ *
+ * @par Parameter type
+ * int (boolean: nonzero is true, zero is false)
+ *
+ * @par Values
+ * - 0 (false) - Do not honor Retry-After
+ * - 1 (true) - honor Retry-After
+ *
+ */
+tag_typedef_t nutag_retry_after_enable = BOOLTAG_TYPEDEF(retry_after_enable);
+
+/**@def NUTAG_RETRY_AFTER_ENABLE_REF(x)
+ * Reference tag for NUTAG_RETRY_AFTER_ENABLE().
+ */
+
/**@def NUTAG_SERVICE_ROUTE_ENABLE(x)
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h b/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h
index 813e0d757a..be909d6911 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h
@@ -550,6 +550,11 @@ SOFIAPUBVAR tag_typedef_t nutag_path_enable;
#define NUTAG_PATH_ENABLE_REF(x) nutag_path_enable_ref, tag_bool_vr(&(x))
SOFIAPUBVAR tag_typedef_t nutag_path_enable_ref;
+#define NUTAG_RETRY_AFTER_ENABLE(x) nutag_retry_after_enable, tag_bool_v(x)
+SOFIAPUBVAR tag_typedef_t nutag_retry_after_enable;
+#define NUTAG_RETRY_AFTER_ENABLE_REF(x) nutag_retry_after_enable_ref, tag_bool_vr(&(x))
+SOFIAPUBVAR tag_typedef_t nutag_retry_after_enable_ref;
+
#define NUTAG_SERVICE_ROUTE_ENABLE(x) nutag_service_route_enable, tag_bool_v(x)
SOFIAPUBVAR tag_typedef_t nutag_service_route_enable;
#define NUTAG_SERVICE_ROUTE_ENABLE_REF(x) \
diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c
index 009ba80695..88a7fd389b 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c
@@ -3596,7 +3596,7 @@ sres_decode_msg(sres_resolver_t *res,
m->m_offset = sizeof(m->m_packet.mp_header);
if (m->m_size < m->m_offset) {
- SU_DEBUG_5(("sres_decode_msg: truncated message\n"));
+ SU_DEBUG_5(("sres_decode_msg: truncated message\n" VA_NONE));
return -1;
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/sresolv.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/sresolv.c
index fba22de731..0720265926 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sresolv/sresolv.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/sresolv.c
@@ -132,13 +132,13 @@ sres_resolver_create(su_root_t *root,
srs->srs_timer = t;
if (!srs->srs_timer)
- SU_DEBUG_3(("sres: cannot create timer\n"));
+ SU_DEBUG_3(("sres: cannot create timer\n" VA_NONE));
#if nomore
else if (su_timer_set_for_ever(t, sres_sofia_timer, srs) < 0)
- SU_DEBUG_3(("sres: cannot set timer\n"));
+ SU_DEBUG_3(("sres: cannot set timer\n" VA_NONE));
#else
else if (sres_resolver_set_timer_cb(res, sres_sofia_set_timer, srs) < 0)
- SU_DEBUG_3(("sres: cannot set timer cb\n"));
+ SU_DEBUG_3(("sres: cannot set timer cb\n" VA_NONE));
#endif
else
return res; /* Success! */
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_debug.h b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_debug.h
index 3764fbd9c7..3881a67701 100644
--- a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_debug.h
+++ b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_debug.h
@@ -73,13 +73,17 @@ SOFIA_BEGIN_DECLS
SOFIAPUBVAR su_log_t SU_LOG[];
#endif
+#define VA_NONE "%s",""
+
#define SU_DEBUG_DEF(level) \
su_inline void su_debug_##level(char const *fmt, ...) \
__attribute__ ((__format__ (printf, 1, 2))); \
su_inline void su_debug_##level(char const *fmt, ...) \
- { va_list ap; va_start(ap, fmt); su_vllog(SU_LOG, level, fmt, ap); va_end(ap); }
+ { va_list ap; va_start(ap, fmt); su_vllog(SU_LOG, level, fmt, ap); va_end(ap); }
+
+//SU_DEBUG_DEF(0)
+#define su_debug_0(_f, ...) su_llog(SU_LOG, 0, _f, __VA_ARGS__)
-SU_DEBUG_DEF(0)
/** Log messages at level 0.
*
* Fatal errors and panic messages should be logged at level 0.
@@ -100,7 +104,10 @@ SU_DEBUG_DEF(0)
#endif
#if SU_DEBUG_MAX >= 1
-SU_DEBUG_DEF(1)
+//SU_DEBUG_DEF(1)
+#define su_debug_1(_f, ...) su_llog(SU_LOG, 1, _f, __VA_ARGS__)
+
+
/**Log messages at level 1.
*
* Critical errors and minimal progress at subsystem level should be logged
@@ -114,7 +121,8 @@ SU_DEBUG_DEF(1)
#endif
#if SU_DEBUG_MAX >= 2
-SU_DEBUG_DEF(2)
+//SU_DEBUG_DEF(2)
+#define su_debug_2(_f, ...) su_llog(SU_LOG, 2, _f, __VA_ARGS__)
/**Log messages at level 2.
*
* Non-critical errors should be logged at level 2.
@@ -127,7 +135,8 @@ SU_DEBUG_DEF(2)
#endif
#if SU_DEBUG_MAX >= 3
-SU_DEBUG_DEF(3)
+//SU_DEBUG_DEF(3)
+#define su_debug_3(_f, ...) su_llog(SU_LOG, 3, _f, __VA_ARGS__)
/** Log messages at level 3.
*
* Warnings and progress messages should be logged at level 3.
@@ -140,7 +149,8 @@ SU_DEBUG_DEF(3)
#endif
#if SU_DEBUG_MAX >= 4
-SU_DEBUG_DEF(4)
+//SU_DEBUG_DEF(4)
+#define su_debug_4(_f, ...) su_llog(SU_LOG, 4, _f, __VA_ARGS__)
/** Log messages at level 4. */
#define SU_DEBUG_4(x) (SU_LOG_LEVEL >= 4 ? (su_debug_4 x) : (void)0)
#else
@@ -148,7 +158,8 @@ SU_DEBUG_DEF(4)
#endif
#if SU_DEBUG_MAX >= 5
-SU_DEBUG_DEF(5)
+//SU_DEBUG_DEF(5)
+#define su_debug_5(_f, ...) su_llog(SU_LOG, 5, _f, __VA_ARGS__)
/** Log messages at level 5.
*
* Signaling protocol actions (incoming packets, etc.) should be logged
@@ -162,7 +173,8 @@ SU_DEBUG_DEF(5)
#endif
#if SU_DEBUG_MAX >= 6
-SU_DEBUG_DEF(6)
+//SU_DEBUG_DEF(6)
+#define su_debug_6(_f, ...) su_llog(SU_LOG, 6, _f, __VA_ARGS__)
/** Log messages at level 6. */
#define SU_DEBUG_6(x) (SU_LOG_LEVEL >= 6 ? (su_debug_6 x) : (void)0)
#else
@@ -170,7 +182,8 @@ SU_DEBUG_DEF(6)
#endif
#if SU_DEBUG_MAX >= 7
-SU_DEBUG_DEF(7)
+//SU_DEBUG_DEF(7)
+#define su_debug_7(_f, ...) su_llog(SU_LOG, 7, _f, __VA_ARGS__)
/** Log messages at level 7.
*
* Media protocol actions (incoming packets, etc) should be logged at level 7.
@@ -183,7 +196,8 @@ SU_DEBUG_DEF(7)
#endif
#if SU_DEBUG_MAX >= 8
-SU_DEBUG_DEF(8)
+//SU_DEBUG_DEF(8)
+#define su_debug_8(_f, ...) su_llog(SU_LOG, 8, _f, __VA_ARGS__)
/** Log messages at level 8. */
#define SU_DEBUG_8(x) (SU_LOG_LEVEL >= 8 ? (su_debug_8 x) : (void)0)
#else
@@ -191,7 +205,8 @@ SU_DEBUG_DEF(8)
#endif
#if SU_DEBUG_MAX >= 9
-SU_DEBUG_DEF(9)
+//SU_DEBUG_DEF(9)
+#define su_debug_9(_f, ...) su_llog(SU_LOG, 9, _f, __VA_ARGS__)
/** Log messages at level 9.
*
* Entering/exiting functions, very verbatim progress should be logged at
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_log.h b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_log.h
index 128bf7aa76..d2916b2564 100644
--- a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_log.h
+++ b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_log.h
@@ -52,6 +52,15 @@ typedef struct su_log_s su_log_t;
SOFIA_BEGIN_DECLS
+#ifdef _MSC_VER
+#define __SOFIA_FUNC__ __FUNCTION__
+#else
+#define __SOFIA_FUNC__ (const char *)__func__
+#endif
+
+
+
+
/** Prototype for logging function */
typedef void (su_logger_f)(void *stream, char const *fmt, va_list ap);
@@ -77,9 +86,9 @@ enum { SU_LOG_MAX = 9 };
SOFIAPUBFUN void su_log(char const *fmt, ...)
__attribute__ ((__format__ (printf, 1, 2)));
-SOFIAPUBFUN void su_llog(su_log_t *log, unsigned level, char const *fmt, ...)
- __attribute__ ((__format__ (printf, 3, 4)));
-SOFIAPUBFUN void su_vllog(su_log_t *log, unsigned level,
+SOFIAPUBFUN void _su_llog(su_log_t *log, unsigned level, const char *file, const char *func, int line, char const *fmt, ...)
+ __attribute__ ((__format__ (printf, 6, 7)));
+SOFIAPUBFUN void _su_vllog(su_log_t *log, unsigned level, const char *file, const char *func, int line,
char const *fmt, va_list ap);
SOFIAPUBFUN void su_log_redirect(su_log_t *log, su_logger_f *f, void *stream);
SOFIAPUBFUN void su_log_set_level(su_log_t *log, unsigned level);
@@ -92,6 +101,9 @@ SOFIAPUBVAR su_log_t su_log_global[];
/** Log the latest su error message */
SOFIAPUBFUN void su_perror(char const *s);
+#define su_llog(_l, _ll, _f, ...) _su_llog(_l, _ll, __FILE__, __SOFIA_FUNC__, __LINE__, _f, __VA_ARGS__)
+#define su_vllog(_l, _ll, _f, ...) _su_vllog(_l, _ll, __FILE__, __SOFIA_FUNC__, __LINE__, _f, __VA_ARGS__)
+
/** Log the su error message. */
SOFIAPUBFUN void su_perror2(char const *s, int errcode);
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su.c b/libs/sofia-sip/libsofia-sip-ua/su/su.c
index 8067fdec60..c99d32f24d 100644
--- a/libs/sofia-sip/libsofia-sip-ua/su/su.c
+++ b/libs/sofia-sip/libsofia-sip-ua/su/su.c
@@ -510,13 +510,20 @@ issize_t su_vsend(su_socket_t s,
su_sockaddr_t const *su, socklen_t sulen)
{
struct msghdr hdr[1] = {{0}};
+ int rv;
hdr->msg_name = (void *)su;
hdr->msg_namelen = sulen;
hdr->msg_iov = (struct iovec *)iov;
hdr->msg_iovlen = iovlen;
- return sendmsg(s, hdr, flags);
+ do {
+ if ((rv = sendmsg(s, hdr, flags)) == -1) {
+ if (errno == EAGAIN) usleep(1000);
+ }
+ } while (rv == -1 && (errno == EAGAIN || errno == EINTR));
+
+ return rv;
}
issize_t su_vrecv(su_socket_t s, su_iovec_t iov[], isize_t iovlen, int flags,
@@ -531,7 +538,9 @@ issize_t su_vrecv(su_socket_t s, su_iovec_t iov[], isize_t iovlen, int flags,
hdr->msg_iov = (struct iovec *)iov;
hdr->msg_iovlen = iovlen;
- retval = recvmsg(s, hdr, flags);
+ do {
+ retval = recvmsg(s, hdr, flags);
+ } while (retval == -1 && errno == EINTR);
if (su && sulen)
*sulen = hdr->msg_namelen;
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c b/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c
index c1c4fd23df..2261ff6bac 100644
--- a/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c
+++ b/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c
@@ -1260,7 +1260,7 @@ int bsd_localinfo(su_localinfo_t const hints[1],
flags |= LI_NUMERIC;
if (!(li = calloc(1, sizeof(*li) + sulen + ifnamelen))) {
- SU_DEBUG_1(("su_getlocalinfo: memory exhausted\n"));
+ SU_DEBUG_1(("su_getlocalinfo: memory exhausted\n" VA_NONE));
error = ELI_MEMORY;
break;
}
@@ -1629,7 +1629,7 @@ int li_name(su_localinfo_t const *hints,
if (error) {
if ((flags & LI_NAMEREQD) == LI_NAMEREQD)
return 1;
- SU_DEBUG_7(("li_name: getnameinfo() failed\n"));
+ SU_DEBUG_7(("li_name: getnameinfo() failed\n" VA_NONE));
if (!su_inet_ntop(su->su_family, SU_ADDR(su), name, sizeof name))
return ELI_RESOLVER;
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_log.c b/libs/sofia-sip/libsofia-sip-ua/su/su_log.c
index ad977312bb..f56998f7c0 100644
--- a/libs/sofia-sip/libsofia-sip-ua/su/su_log.c
+++ b/libs/sofia-sip/libsofia-sip-ua/su/su_log.c
@@ -100,17 +100,23 @@ void su_log(char const *fmt, ...)
*
* @note This function is used mainly by SU_DEBUG_n() macros.
*/
-void su_llog(su_log_t *log, unsigned level, char const *fmt, ...)
+void _su_llog(su_log_t *log, unsigned level, const char *file, const char *func, int line,
+ char const *fmt, ...)
{
va_list ap;
-
+ char buf[512];
va_start(ap, fmt);
- su_vllog(log, level, fmt, ap);
+
+
+ snprintf(buf, sizeof(buf), "%s:%d %s() %s", file, line, func, fmt);
+
+ _su_vllog(log, level, file, func, line, buf, ap);
va_end(ap);
}
/** Log a message with level (stdarg version). */
-void su_vllog(su_log_t *log, unsigned level, char const *fmt, va_list ap)
+void _su_vllog(su_log_t *log, unsigned level, const char *file, const char *func, int line,
+ char const *fmt, va_list ap)
{
su_logger_f *logger;
void *stream;
@@ -133,8 +139,9 @@ void su_vllog(su_log_t *log, unsigned level, char const *fmt, va_list ap)
stream = su_log_default->log_stream;
}
- if (logger)
- logger(stream, fmt, ap);
+ if (logger) {
+ logger(stream, fmt, ap);
+ }
}
static char const not_initialized[1];
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_os_nw.c b/libs/sofia-sip/libsofia-sip-ua/su/su_os_nw.c
index 3dc882dd1e..d9ef55f2e9 100644
--- a/libs/sofia-sip/libsofia-sip-ua/su/su_os_nw.c
+++ b/libs/sofia-sip/libsofia-sip-ua/su/su_os_nw.c
@@ -105,7 +105,7 @@ void nw_changed_cb(SCDynamicStoreRef store,
su_network_changed_t *snc2;
su_msg_r rmsg = SU_MSG_R_INIT;
- SU_DEBUG_7(("nw_changed_cb: entering.\n"));
+ SU_DEBUG_7(("nw_changed_cb: entering.\n" VA_NONE));
if (su_msg_create(rmsg,
su_root_task(snc->su_root),
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c
index dfcd9ac901..d20eb709bd 100644
--- a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c
+++ b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c
@@ -263,11 +263,20 @@ int su_pthreaded_port_start(su_port_create_f *create,
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 244);
pthread_attr_getschedparam(&attr, ¶m);
- param.sched_priority = 1;
+ param.sched_priority = 99;
pthread_attr_setschedparam(&attr, ¶m);
pthread_mutex_lock(arg.mutex);
if (pthread_create(&tid, &attr, su_pthread_port_clone_main, &arg) == 0) {
+#ifdef HAVE_PTHREAD_SETSCHEDPARAM
+ int policy;
+ struct sched_param param;
+
+ pthread_getschedparam(tid, &policy, ¶m);
+ param.sched_priority = 99;
+ pthread_setschedparam(tid, policy, ¶m);
+#endif
+
pthread_cond_wait(arg.cv, arg.mutex);
thread_created = 1;
}
diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport.c
index cc94cf4681..eb79deba50 100644
--- a/libs/sofia-sip/libsofia-sip-ua/tport/tport.c
+++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport.c
@@ -3350,7 +3350,7 @@ tport_t *tport_tsend(tport_t *self,
if (!self) {
msg_set_errno(msg, su_errno());
- SU_DEBUG_9(("tport_socket failed in tsend\n"));
+ SU_DEBUG_9(("tport_socket failed in tsend\n" VA_NONE));
return NULL;
}
@@ -3406,7 +3406,7 @@ int tport_prepare_and_send(tport_t *self, msg_t *msg,
/* ...or we are connecting */
(self->tp_events & (SU_WAIT_CONNECT | SU_WAIT_OUT))) {
if (tport_queue(self, msg) < 0) {
- SU_DEBUG_9(("tport_queue failed in tsend\n"));
+ SU_DEBUG_9(("tport_queue failed in tsend\n" VA_NONE));
return -1;
}
return 0;
diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_connect.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_connect.c
index 72b212f728..42679d1675 100644
--- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_connect.c
+++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_connect.c
@@ -201,7 +201,7 @@ static tport_t *tport_http_connect(tport_primary_t *pri, su_addrinfo_t *ai,
msg_set_next(response, thci->thci_stackmsg = tport_msg_alloc(tport, 512));
if (tport_send_msg(tport, msg, tpn, NULL) < 0) {
- SU_DEBUG_9(("tport_send_msg failed in tpot_http_connect\n"));
+ SU_DEBUG_9(("tport_send_msg failed in tpot_http_connect\n" VA_NONE));
msg_destroy(msg);
tport_zap_secondary(tport);
return NULL;
diff --git a/libs/sofia-sip/scripts/lcov-report b/libs/sofia-sip/scripts/lcov-report
index 364f798128..77a0aaf40f 100755
--- a/libs/sofia-sip/scripts/lcov-report
+++ b/libs/sofia-sip/scripts/lcov-report
@@ -11,7 +11,7 @@
usage()
{
- test X$1 == X0 || exec >&2
+ test X$1 = X0 || exec >&2
cat << EOF
usage: coverage-report OPTIONS
where OPTIONS are
diff --git a/libs/sofia-sip/scripts/uncovered b/libs/sofia-sip/scripts/uncovered
index 80f14ffad4..bdd156c789 100755
--- a/libs/sofia-sip/scripts/uncovered
+++ b/libs/sofia-sip/scripts/uncovered
@@ -11,7 +11,7 @@
usage()
{
- test X$1 == X0 || exec >&2
+ test X$1 = X0 || exec >&2
cat <= 5448)
/* Table 4.4 Coefficients of the weighting filter */
/* This must be padded to a multiple of 4 for MMX to work */
static const union
diff --git a/libs/spandsp/src/spandsp/dds.h b/libs/spandsp/src/spandsp/dds.h
index 10bf99fdf7..c4b8b6bb13 100644
--- a/libs/spandsp/src/spandsp/dds.h
+++ b/libs/spandsp/src/spandsp/dds.h
@@ -28,6 +28,9 @@
#if !defined(_SPANDSP_DDS_H_)
#define _SPANDSP_DDS_H_
+#define DDS_PHASE_RATE(frequency) (int32_t) ((frequency)*65536.0f*65536.0f/SAMPLE_RATE)
+#define DDS_PHASE(angle) (int32_t) ((uint32_t) (((angle < 0.0f) ? (360.0f + angle) : angle)*65536.0f*65536.0f/360.0f))
+
#if defined(__cplusplus)
extern "C"
{
diff --git a/libs/spandsp/src/spandsp/private/t30.h b/libs/spandsp/src/spandsp/private/t30.h
index 1fede6ed79..9b70a7a73b 100644
--- a/libs/spandsp/src/spandsp/private/t30.h
+++ b/libs/spandsp/src/spandsp/private/t30.h
@@ -212,6 +212,9 @@ struct t30_state_s
/*! \brief TRUE once the far end FAX entity has been detected. */
int far_end_detected;
+
+ /*! \brief TRUE once the end of procedure condition has been detected. */
+ int end_of_procedure_detected;
/*! \brief TRUE if a local T.30 interrupt is pending. */
int local_interrupt_pending;
diff --git a/libs/spandsp/src/spandsp/private/v17rx.h b/libs/spandsp/src/spandsp/private/v17rx.h
index a968290010..9f22208e80 100644
--- a/libs/spandsp/src/spandsp/private/v17rx.h
+++ b/libs/spandsp/src/spandsp/private/v17rx.h
@@ -29,11 +29,10 @@
/* Target length for the equalizer is about 63 taps, to deal with the worst stuff
in V.56bis. */
/*! The length of the equalizer buffer */
-//#define V17_EQUALIZER_LEN 33
-#define V17_EQUALIZER_LEN 17
+#define V17_EQUALIZER_LEN 33
+
/*! Samples before the target position in the equalizer buffer */
-//#define V17_EQUALIZER_PRE_LEN 16
-#define V17_EQUALIZER_PRE_LEN 8
+#define V17_EQUALIZER_PRE_LEN 16
/*! The number of taps in the pulse shaping/bandpass filter */
#define V17_RX_FILTER_STEPS 27
@@ -202,10 +201,10 @@ struct v17_rx_state_s
This is only for performance analysis purposes. */
int total_baud_timing_correction;
- /*! \brief Starting phase angles for the coarse carrier aquisition step. */
- int32_t start_angles[2];
- /*! \brief History list of phase angles for the coarse carrier aquisition step. */
- int32_t angles[16];
+ /*! \brief The previous symbol phase angles for the coarse carrier aquisition step. */
+ int32_t last_angles[2];
+ /*! \brief History list of phase angle differences for the coarse carrier aquisition step. */
+ int32_t diff_angles[16];
/*! \brief A pointer to the current space map. There is a space map for
each trellis state. */
diff --git a/libs/spandsp/src/spandsp/private/v27ter_rx.h b/libs/spandsp/src/spandsp/private/v27ter_rx.h
index 92bf937d83..e10781f72e 100644
--- a/libs/spandsp/src/spandsp/private/v27ter_rx.h
+++ b/libs/spandsp/src/spandsp/private/v27ter_rx.h
@@ -183,10 +183,11 @@ struct v27ter_rx_state_s
This is only for performance analysis purposes. */
int total_baud_timing_correction;
- /*! \brief Starting phase angles for the coarse carrier aquisition step. */
- int32_t start_angles[2];
- /*! \brief History list of phase angles for the coarse carrier aquisition step. */
- int32_t angles[16];
+ /*! \brief The previous symbol phase angles for the coarse carrier aquisition step. */
+ int32_t last_angles[2];
+ /*! \brief History list of phase angle differences for the coarse carrier aquisition step. */
+ int32_t diff_angles[16];
+
/*! \brief Error and flow logging control */
logging_state_t logging;
};
diff --git a/libs/spandsp/src/spandsp/private/v29rx.h b/libs/spandsp/src/spandsp/private/v29rx.h
index 17e900582e..385c787dd6 100644
--- a/libs/spandsp/src/spandsp/private/v29rx.h
+++ b/libs/spandsp/src/spandsp/private/v29rx.h
@@ -184,10 +184,10 @@ struct v29_rx_state_s
This is only for performance analysis purposes. */
int total_baud_timing_correction;
- /*! \brief Starting phase angles for the coarse carrier aquisition step. */
- int32_t start_angles[2];
- /*! \brief History list of phase angles for the coarse carrier aquisition step. */
- int32_t angles[16];
+ /*! \brief The previous symbol phase angles for the coarse carrier aquisition step. */
+ int32_t last_angles[2];
+ /*! \brief History list of phase angle differences for the coarse carrier aquisition step. */
+ int32_t diff_angles[16];
/*! \brief The position of the current symbol in the constellation, used for
differential decoding. */
diff --git a/libs/spandsp/src/spandsp/telephony.h b/libs/spandsp/src/spandsp/telephony.h
index 7a09bbe044..132cce9bf8 100644
--- a/libs/spandsp/src/spandsp/telephony.h
+++ b/libs/spandsp/src/spandsp/telephony.h
@@ -88,6 +88,16 @@ typedef int (*span_tx_handler_t)(void *s, int16_t amp[], int max_len);
#define FP_Q_2_14(x) ((int16_t) (16384.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_1_15(x) ((int16_t) (32768.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
+#define FP_Q_9_7_32(x) ((int32_t) (128.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
+#define FP_Q_8_8_32(x) ((int32_t) (256.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
+#define FP_Q_7_9_32(x) ((int32_t) (512.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
+#define FP_Q_6_10_32(x) ((int32_t) (1024.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
+#define FP_Q_5_11_32(x) ((int32_t) (2048.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
+#define FP_Q_4_12_32(x) ((int32_t) (4096.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
+#define FP_Q_3_13_32(x) ((int32_t) (8192.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
+#define FP_Q_2_14_32(x) ((int32_t) (16384.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
+#define FP_Q_1_15_32(x) ((int32_t) (32768.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
+
#define FP_Q_9_23(x) ((int32_t) (65536.0*128.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_8_24(x) ((int32_t) (65536.0*256.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
#define FP_Q_7_25(x) ((int32_t) (65536.0*512.0*x + ((x >= 0.0) ? 0.5 : -0.5)))
diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c
index a12d357f76..7772459aba 100644
--- a/libs/spandsp/src/t30.c
+++ b/libs/spandsp/src/t30.c
@@ -132,19 +132,19 @@ enum
static const char *phase_names[] =
{
- "T30_PHASE_IDLE",
- "T30_PHASE_A_CED",
- "T30_PHASE_A_CNG",
- "T30_PHASE_B_RX",
- "T30_PHASE_B_TX",
- "T30_PHASE_C_NON_ECM_RX",
- "T30_PHASE_C_NON_ECM_TX",
- "T30_PHASE_C_ECM_RX",
- "T30_PHASE_C_ECM_TX",
- "T30_PHASE_D_RX",
- "T30_PHASE_D_TX",
- "T30_PHASE_E",
- "T30_PHASE_CALL_FINISHED"
+ "IDLE",
+ "A_CED",
+ "A_CNG",
+ "B_RX",
+ "B_TX",
+ "C_NON_ECM_RX",
+ "C_NON_ECM_TX",
+ "C_ECM_RX",
+ "C_ECM_TX",
+ "D_RX",
+ "D_TX",
+ "E",
+ "CALL_FINISHED"
};
/* These state names are modelled after places in the T.30 flow charts. */
@@ -184,6 +184,43 @@ enum
T30_STATE_CALL_FINISHED
};
+static const char *state_names[] =
+{
+ "NONE",
+ "ANSWERING",
+ "B",
+ "C",
+ "D",
+ "D_TCF",
+ "D_POST_TCF",
+ "F_TCF",
+ "F_CFR",
+ "F_FTT",
+ "F_DOC_NON_ECM",
+ "F_POST_DOC_NON_ECM",
+ "F_DOC_ECM",
+ "F_POST_DOC_ECM",
+ "F_POST_RCP_MCF",
+ "F_POST_RCP_PPR",
+ "F_POST_RCP_RNR",
+ "R",
+ "T",
+ "I",
+ "II",
+ "II_Q",
+ "III_Q_MCF",
+ "III_Q_RTP",
+ "III_Q_RTN",
+ "IV",
+ "IV_PPS_NULL",
+ "IV_PPS_Q",
+ "IV_PPS_RNR",
+ "IV_CTC",
+ "IV_EOR",
+ "IV_EOR_RNR",
+ "CALL_FINISHED"
+};
+
enum
{
T30_MIN_SCAN_20MS = 0,
@@ -1309,7 +1346,7 @@ static int build_dcs(t30_state_t *s)
int i;
int bad;
int row_squashing_ratio;
-
+
/* Make a DCS frame based on local issues and the latest received DIS/DTC frame. Negotiate
the result based on what both parties can do. */
s->dcs_frame[0] = ADDRESS_FIELD;
@@ -2017,7 +2054,7 @@ static int start_receiving_document(t30_state_t *s)
static void unexpected_non_final_frame(t30_state_t *s, const uint8_t *msg, int len)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %d\n", t30_frametype(msg[2]), s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %s\n", t30_frametype(msg[2]), state_names[s->state]);
if (s->current_status == T30_ERR_OK)
t30_set_status(s, T30_ERR_UNEXPECTED);
}
@@ -2025,7 +2062,7 @@ static void unexpected_non_final_frame(t30_state_t *s, const uint8_t *msg, int l
static void unexpected_final_frame(t30_state_t *s, const uint8_t *msg, int len)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %d\n", t30_frametype(msg[2]), s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %s\n", t30_frametype(msg[2]), state_names[s->state]);
if (s->current_status == T30_ERR_OK)
t30_set_status(s, T30_ERR_UNEXPECTED);
send_dcn(s);
@@ -2473,17 +2510,15 @@ static int send_response_to_pps(t30_state_t *s)
{
set_state(s, T30_STATE_F_POST_RCP_MCF);
send_simple_frame(s, T30_MCF);
+ return TRUE;
}
- else
- {
- /* We need to send the PPR frame we have created, to try to fill in the missing/bad data. */
- set_state(s, T30_STATE_F_POST_RCP_PPR);
- s->ecm_frame_map[0] = ADDRESS_FIELD;
- s->ecm_frame_map[1] = CONTROL_FIELD_FINAL_FRAME;
- s->ecm_frame_map[2] = (uint8_t) (T30_PPR | s->dis_received);
- send_frame(s, s->ecm_frame_map, 3 + 32);
- }
- return 0;
+ /* We need to send the PPR frame we have created, to try to fill in the missing/bad data. */
+ set_state(s, T30_STATE_F_POST_RCP_PPR);
+ s->ecm_frame_map[0] = ADDRESS_FIELD;
+ s->ecm_frame_map[1] = CONTROL_FIELD_FINAL_FRAME;
+ s->ecm_frame_map[2] = (uint8_t) (T30_PPR | s->dis_received);
+ send_frame(s, s->ecm_frame_map, 3 + 32);
+ return FALSE;
}
/*- End of function --------------------------------------------------------*/
@@ -2685,7 +2720,17 @@ static int process_rx_pps(t30_state_t *s, const uint8_t *msg, int len)
}
else
{
- send_response_to_pps(s);
+ if (send_response_to_pps(s))
+ {
+ switch (s->last_pps_fcf2)
+ {
+ case T30_PRI_EOP:
+ case T30_EOP:
+ span_log(&s->logging, SPAN_LOG_FLOW, "End of procedure detected\n");
+ s->end_of_procedure_detected = TRUE;
+ break;
+ }
+ }
}
break;
default:
@@ -3364,6 +3409,8 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
}
/* Fall through */
case T30_EOP:
+ span_log(&s->logging, SPAN_LOG_FLOW, "End of procedure detected\n");
+ s->end_of_procedure_detected = TRUE;
s->next_rx_step = fcf;
queue_phase(s, T30_PHASE_D_TX);
switch (copy_quality(s))
@@ -3397,7 +3444,6 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
send_simple_frame(s, T30_RTN);
break;
}
-
break;
case T30_DCN:
t30_set_status(s, T30_ERR_RX_DCNFAX);
@@ -3565,7 +3611,17 @@ static void process_state_f_post_rcp_rnr(t30_state_t *s, const uint8_t *msg, int
else
{
/* Now we send the deferred response */
- send_response_to_pps(s);
+ if (send_response_to_pps(s))
+ {
+ switch (s->last_pps_fcf2)
+ {
+ case T30_PRI_EOP:
+ case T30_EOP:
+ span_log(&s->logging, SPAN_LOG_FLOW, "End of procedure detected\n");
+ s->end_of_procedure_detected = TRUE;
+ break;
+ }
+ }
}
break;
case T30_CRP:
@@ -4656,7 +4712,7 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len)
/* The following handles context sensitive message types, which should
occur at the end of message sequences. They should, therefore have
the final frame flag set. */
- span_log(&s->logging, SPAN_LOG_FLOW, "Rx final frame in state %d\n", s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Rx final frame in state %s\n", state_names[s->state]);
switch (s->state)
{
@@ -4891,7 +4947,7 @@ static void set_state(t30_state_t *s, int state)
{
if (s->state != state)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "Changing from state %d to %d\n", s->state, state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Changing from state %s to %s\n", state_names[s->state], state_names[state]);
s->state = state;
}
s->step = 0;
@@ -4982,9 +5038,9 @@ static void repeat_last_command(t30_state_t *s)
default:
span_log(&s->logging,
SPAN_LOG_FLOW,
- "Repeat command called with nothing to repeat - phase %s, state %d\n",
+ "Repeat command called with nothing to repeat - phase %s, state %s\n",
phase_names[s->phase],
- s->state);
+ state_names[s->state]);
break;
}
}
@@ -5098,7 +5154,7 @@ static void timer_t2_t4_stop(t30_state_t *s)
static void timer_t0_expired(t30_state_t *s)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "T0 expired in state %d\n", s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T0 expired in state %s\n", state_names[s->state]);
t30_set_status(s, T30_ERR_T0_EXPIRED);
/* Just end the call */
disconnect(s);
@@ -5107,7 +5163,7 @@ static void timer_t0_expired(t30_state_t *s)
static void timer_t1_expired(t30_state_t *s)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "T1 expired in state %d\n", s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T1 expired in state %s\n", state_names[s->state]);
/* The initial connection establishment has timeout out. In other words, we
have been unable to communicate successfully with a remote machine.
It is time to abandon the call. */
@@ -5132,7 +5188,7 @@ static void timer_t1_expired(t30_state_t *s)
static void timer_t2_expired(t30_state_t *s)
{
if (s->timer_t2_t4_is != TIMER_IS_T2B)
- span_log(&s->logging, SPAN_LOG_FLOW, "T2 expired in phase %s, state %d\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T2 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
switch (s->state)
{
case T30_STATE_III_Q_MCF:
@@ -5202,7 +5258,7 @@ static void timer_t2_expired(t30_state_t *s)
static void timer_t1a_expired(t30_state_t *s)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "T1A expired in phase %s, state %d. An HDLC frame lasted too long.\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T1A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]);
t30_set_status(s, T30_ERR_HDLC_CARRIER);
disconnect(s);
}
@@ -5210,7 +5266,7 @@ static void timer_t1a_expired(t30_state_t *s)
static void timer_t2a_expired(t30_state_t *s)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "T2A expired in phase %s, state %d. An HDLC frame lasted too long.\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T2A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]);
t30_set_status(s, T30_ERR_HDLC_CARRIER);
disconnect(s);
}
@@ -5218,14 +5274,14 @@ static void timer_t2a_expired(t30_state_t *s)
static void timer_t2b_expired(t30_state_t *s)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "T2B expired in phase %s, state %d. The line is now quiet.\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T2B expired in phase %s, state %s. The line is now quiet.\n", phase_names[s->phase], state_names[s->state]);
timer_t2_expired(s);
}
/*- End of function --------------------------------------------------------*/
static void timer_t3_expired(t30_state_t *s)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "T3 expired in phase %s, state %d\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T3 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
t30_set_status(s, T30_ERR_T3_EXPIRED);
disconnect(s);
}
@@ -5235,7 +5291,7 @@ static void timer_t4_expired(t30_state_t *s)
{
/* There was no response (or only a corrupt response) to a command,
within the T4 timeout period. */
- span_log(&s->logging, SPAN_LOG_FLOW, "T4 expired in phase %s, state %d\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T4 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
/* Of course, things might just be a little late, especially if there are T.38
links in the path. There is no point in simply timing out, and resending,
if we are currently receiving something from the far end - its a half-duplex
@@ -5249,7 +5305,7 @@ static void timer_t4_expired(t30_state_t *s)
static void timer_t4a_expired(t30_state_t *s)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "T4A expired in phase %s, state %d. An HDLC frame lasted too long.\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T4A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]);
t30_set_status(s, T30_ERR_HDLC_CARRIER);
disconnect(s);
}
@@ -5257,7 +5313,7 @@ static void timer_t4a_expired(t30_state_t *s)
static void timer_t4b_expired(t30_state_t *s)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "T4B expired in phase %s, state %d. The line is now quiet.\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T4B expired in phase %s, state %s. The line is now quiet.\n", phase_names[s->phase], state_names[s->state]);
timer_t4_expired(s);
}
/*- End of function --------------------------------------------------------*/
@@ -5265,7 +5321,7 @@ static void timer_t4b_expired(t30_state_t *s)
static void timer_t5_expired(t30_state_t *s)
{
/* Give up waiting for the receiver to become ready in error correction mode */
- span_log(&s->logging, SPAN_LOG_FLOW, "T5 expired in phase %s, state %d\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "T5 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
t30_set_status(s, T30_ERR_TX_T5EXP);
}
/*- End of function --------------------------------------------------------*/
@@ -5351,7 +5407,7 @@ static void t30_non_ecm_rx_status(void *user_data, int status)
int was_trained;
s = (t30_state_t *) user_data;
- span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM signal status is %s (%d) in state %d\n", signal_status_to_str(status), status, s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM signal status is %s (%d) in state %s\n", signal_status_to_str(status), status, state_names[s->state]);
switch (status)
{
case SIG_STATUS_TRAINING_IN_PROGRESS:
@@ -5555,7 +5611,7 @@ SPAN_DECLARE_NONSTD(int) t30_non_ecm_get_bit(void *user_data)
bit = 0;
break;
default:
- span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get_bit in bad state %d\n", s->state);
+ span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get_bit in bad state %s\n", state_names[s->state]);
bit = SIG_STATUS_END_OF_DATA;
break;
}
@@ -5590,7 +5646,7 @@ SPAN_DECLARE(int) t30_non_ecm_get(void *user_data, uint8_t buf[], int max_len)
len = 0;
break;
default:
- span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get in bad state %d\n", s->state);
+ span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get in bad state %s\n", state_names[s->state]);
len = -1;
break;
}
@@ -5604,7 +5660,7 @@ static void t30_hdlc_rx_status(void *user_data, int status)
int was_trained;
s = (t30_state_t *) user_data;
- span_log(&s->logging, SPAN_LOG_FLOW, "HDLC signal status is %s (%d) in state %d\n", signal_status_to_str(status), status, s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "HDLC signal status is %s (%d) in state %s\n", signal_status_to_str(status), status, state_names[s->state]);
switch (status)
{
case SIG_STATUS_TRAINING_IN_PROGRESS:
@@ -5798,7 +5854,7 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status)
switch (status)
{
case T30_FRONT_END_SEND_STEP_COMPLETE:
- span_log(&s->logging, SPAN_LOG_FLOW, "Send complete in phase %s, state %d\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Send complete in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
/* We have finished sending our messages, so move on to the next operation. */
switch (s->state)
{
@@ -6025,12 +6081,12 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status)
disconnect from the far end overlaps something. */
break;
default:
- span_log(&s->logging, SPAN_LOG_FLOW, "Bad state for send complete in t30_front_end_status - %d\n", s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Bad state for send complete in t30_front_end_status - %s\n", state_names[s->state]);
break;
}
break;
case T30_FRONT_END_RECEIVE_COMPLETE:
- span_log(&s->logging, SPAN_LOG_FLOW, "Receive complete in phase %s, state %d\n", phase_names[s->phase], s->state);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Receive complete in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
/* Usually receive complete is notified by a carrier down signal. However,
in cases like a T.38 packet stream dying in the middle of reception
there needs to be a means to stop things. */
@@ -6175,8 +6231,12 @@ SPAN_DECLARE(void) t30_terminate(t30_state_t *s)
hussle things along. */
break;
default:
- /* The call terminated prematurely. */
- t30_set_status(s, T30_ERR_CALLDROPPED);
+ /* If we have seen a genuine EOP or PRI_EOP, that's good enough. */
+ if (!s->end_of_procedure_detected)
+ {
+ /* The call terminated prematurely. */
+ t30_set_status(s, T30_ERR_CALLDROPPED);
+ }
break;
}
if (s->phase_e_handler)
@@ -6268,6 +6328,7 @@ SPAN_DECLARE(int) t30_restart(t30_state_t *s)
s->rtp_events = 0;
s->local_interrupt_pending = FALSE;
s->far_end_detected = FALSE;
+ s->end_of_procedure_detected = FALSE;
s->timer_t0_t1 = ms_to_samples(DEFAULT_TIMER_T0);
if (s->calling_party)
{
diff --git a/libs/spandsp/src/t4_tx.c b/libs/spandsp/src/t4_tx.c
index 2e2f25c706..4fb764fa6f 100644
--- a/libs/spandsp/src/t4_tx.c
+++ b/libs/spandsp/src/t4_tx.c
@@ -661,7 +661,7 @@ static int make_header(t4_tx_state_t *s)
if ((s->header_text = malloc(132 + 1)) == NULL)
return -1;
}
- /* This is very English oriented, but then most FAX machines are. Some
+ /* This is very English oriented, but then most FAX machines are, too. Some
measure of i18n in the time and date, and even the header_info string, is
entirely possible, although the font area would need some serious work to
properly deal with East Asian script. There is no spec for what the header
@@ -733,26 +733,21 @@ static int header_row_read_handler(void *user_data, uint8_t buf[], size_t len)
return len;
}
}
- switch (s->tiff.image_type)
+ row = s->header_row/repeats;
+ pos = 0;
+ for (t = s->header_text; *t && pos <= len - 2; t++)
{
- case T4_IMAGE_TYPE_BILEVEL:
- row = s->header_row/repeats;
- pos = 0;
- for (t = s->header_text; *t && pos <= len - 2; t++)
- {
- pattern = header_font[(uint8_t) *t][row];
- buf[pos++] = (uint8_t) (pattern >> 8);
- buf[pos++] = (uint8_t) (pattern & 0xFF);
- }
- while (pos < len)
- buf[pos++] = 0;
- s->header_row++;
- if (s->header_row >= 16*repeats)
- {
- /* End of header. Change to normal image row data. */
- set_row_read_handler(s, s->row_handler, s->row_handler_user_data);
- }
- break;
+ pattern = header_font[(uint8_t) *t][row];
+ buf[pos++] = (uint8_t) (pattern >> 8);
+ buf[pos++] = (uint8_t) (pattern & 0xFF);
+ }
+ while (pos < len)
+ buf[pos++] = 0;
+ s->header_row++;
+ if (s->header_row >= 16*repeats)
+ {
+ /* End of header. Change to normal image row data. */
+ set_row_read_handler(s, s->row_handler, s->row_handler_user_data);
}
return len;
}
@@ -1113,7 +1108,7 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_tx_state_t *s)
break;
}
/* If there is a page header, create that first */
- if (s->header_info && s->header_info[0] && make_header(s) == 0)
+ if (s->tiff.image_type == T4_IMAGE_TYPE_BILEVEL && s->header_info && s->header_info[0] && make_header(s) == 0)
{
s->header_row = 0;
set_row_read_handler(s, header_row_read_handler, (void *) s);
diff --git a/libs/spandsp/src/v17rx.c b/libs/spandsp/src/v17rx.c
index 9d692a1548..b275270b49 100644
--- a/libs/spandsp/src/v17rx.c
+++ b/libs/spandsp/src/v17rx.c
@@ -718,9 +718,9 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
if (++s->training_count >= 100)
{
/* Record the current phase angle */
- s->angles[0] =
- s->start_angles[0] = arctan2(z.im, z.re);
s->training_stage = TRAINING_STAGE_LOG_PHASE;
+ vec_zeroi32(s->diff_angles, 16);
+ s->last_angles[0] = arctan2(z.im, z.re);
#if defined(SPANDSP_USE_FIXED_POINTx)
if (s->agc_scaling_save == 0)
s->agc_scaling_save = s->agc_scaling;
@@ -740,16 +740,16 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
/* We should already know the accurate carrier frequency. All we need to sort
out is the phase. */
/* Check if we just saw A or B */
- if ((uint32_t) (angle - s->start_angles[0]) < 0x80000000U)
+ if ((uint32_t) (angle - s->last_angles[0]) < 0x80000000U)
{
- angle = s->start_angles[0];
- s->angles[0] = 0xC0000000 + 219937506;
- s->angles[1] = 0x80000000 + 219937506;
+ angle = s->last_angles[0];
+ s->last_angles[0] = 0xC0000000 + 219937506;
+ s->last_angles[1] = 0x80000000 + 219937506;
}
else
{
- s->angles[0] = 0x80000000 + 219937506;
- s->angles[1] = 0xC0000000 + 219937506;
+ s->last_angles[0] = 0x80000000 + 219937506;
+ s->last_angles[1] = 0xC0000000 + 219937506;
}
/* Make a step shift in the phase, to pull it into line. We need to rotate the equalizer
buffer, as well as the carrier phase, for this to play out nicely. */
@@ -775,8 +775,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
}
else
{
- s->angles[1] =
- s->start_angles[1] = angle;
+ s->last_angles[1] = angle;
s->training_stage = TRAINING_STAGE_WAIT_FOR_CDBA;
}
break;
@@ -785,55 +784,32 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
angle = arctan2(z.im, z.re);
/* Look for the initial ABAB sequence to display a phase reversal, which will
signal the start of the scrambled CDBA segment */
- ang = angle - s->angles[(s->training_count - 1) & 0xF];
- s->angles[(s->training_count + 1) & 0xF] = angle;
-
- /* Do a coarse frequency adjustment about half way through the reversals, as if we wait until
- the end, we might have rotated too far to correct properly. */
- if (s->training_count == 100)
- {
- i = s->training_count;
- j = i & 0xF;
- ang = (s->angles[j] - s->start_angles[0])/i
- + (s->angles[j | 0x1] - s->start_angles[1])/i;
- s->carrier_phase_rate += 3*(ang/20);
- //span_log(&s->logging, SPAN_LOG_FLOW, "Angles %x, %x, %x, %x, dist %d\n", s->angles[j], s->start_angles[0], s->angles[j | 0x1], s->start_angles[1], i);
-
- s->start_angles[0] = s->angles[j];
- s->start_angles[1] = s->angles[j | 0x1];
- //span_log(&s->logging, SPAN_LOG_FLOW, "%d %d %d %d %d\n", s->angles[s->training_count & 0xF], s->start_angles[0], s->angles[(s->training_count | 0x1) & 0xF], s->start_angles[1], s->training_count);
- span_log(&s->logging, SPAN_LOG_FLOW, "First coarse carrier frequency %7.2f (%d)\n", dds_frequencyf(s->carrier_phase_rate), s->training_count);
-
- }
- if ((ang > 0x40000000 || ang < -0x40000000) && s->training_count >= 13)
+ i = s->training_count + 1;
+ ang = angle - s->last_angles[i & 1];
+ s->last_angles[i & 1] = angle;
+ s->diff_angles[i & 0xF] = s->diff_angles[(i - 2) & 0xF] + (ang >> 4);
+ if ((ang > DDS_PHASE(90.0f) || ang < DDS_PHASE(-90.0f)) && s->training_count >= 13)
{
span_log(&s->logging, SPAN_LOG_FLOW, "We seem to have a reversal at symbol %d\n", s->training_count);
/* We seem to have a phase reversal */
/* Slam the carrier frequency into line, based on the total phase drift over the last
section. Use the shift from the odd bits and the shift from the even bits to get
better jitter suppression. */
- /* TODO: We are supposed to deal with frequancy errors up to +-8Hz. Over 200+
- symbols that is more than half a cycle. We get confused an do crazy things.
- We can only cope with errors up to 5Hz right now. We need to implement
- greater tolerance to be compliant, although it doesn't really matter much
- these days. */
/* Step back a few symbols so we don't get ISI distorting things. */
i = (s->training_count - 8) & ~1;
/* Avoid the possibility of a divide by zero */
- if (i - 100 + 8)
+ if (i > 1)
{
j = i & 0xF;
- ang = (s->angles[j] - s->start_angles[0])/(i - 100 + 8)
- + (s->angles[j | 0x1] - s->start_angles[1])/(i - 100 + 8);
- s->carrier_phase_rate += 3*(ang/20);
- span_log(&s->logging, SPAN_LOG_FLOW, "Angles %x, %x, %x, %x, dist %d\n", s->angles[j], s->start_angles[0], s->angles[j | 0x1], s->start_angles[1], i);
+ ang = (s->diff_angles[j] + s->diff_angles[j | 0x1])/(i - 1);
+ s->carrier_phase_rate += 3*16*(ang/20);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Angles %x, %x, dist %d\n", s->last_angles[0], s->last_angles[1], i);
}
- //span_log(&s->logging, SPAN_LOG_FLOW, "%d %d %d %d %d\n", s->angles[s->training_count & 0xF], s->start_angles[0], s->angles[(s->training_count | 0x1) & 0xF], s->start_angles[1], s->training_count);
- span_log(&s->logging, SPAN_LOG_FLOW, "Second coarse carrier frequency %7.2f (%d)\n", dds_frequencyf(s->carrier_phase_rate), s->training_count);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Coarse carrier frequency %7.2f (%d)\n", dds_frequencyf(s->carrier_phase_rate), s->training_count);
/* Check if the carrier frequency is plausible */
- if (s->carrier_phase_rate < dds_phase_ratef(CARRIER_NOMINAL_FREQ - 20.0f)
+ if (s->carrier_phase_rate < DDS_PHASE_RATE(CARRIER_NOMINAL_FREQ - 20.0f)
||
- s->carrier_phase_rate > dds_phase_ratef(CARRIER_NOMINAL_FREQ + 20.0f))
+ s->carrier_phase_rate > DDS_PHASE_RATE(CARRIER_NOMINAL_FREQ + 20.0f))
{
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
/* Park this modem */
@@ -1025,8 +1001,8 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
/* Look for the initial ABAB sequence to display a phase reversal, which will
signal the start of the scrambled CDBA segment */
angle = arctan2(z.im, z.re);
- ang = angle - s->angles[s->training_count & 1];
- if (ang > 0x40000000 || ang < -0x40000000)
+ ang = angle - s->last_angles[s->training_count & 1];
+ if (ang > DDS_PHASE(90.0f) || ang < DDS_PHASE(-90.0f))
{
/* We seem to have a phase reversal */
/* We have just seen the first symbol of the scrambled sequence, so skip it. */
@@ -1507,8 +1483,8 @@ SPAN_DECLARE(int) v17_rx_restart(v17_rx_state_t *s, int bit_rate, int short_trai
#endif
if (short_train != 2)
s->short_train = short_train;
- memset(s->start_angles, 0, sizeof(s->start_angles));
- memset(s->angles, 0, sizeof(s->angles));
+ memset(s->last_angles, 0, sizeof(s->last_angles));
+ memset(s->diff_angles, 0, sizeof(s->diff_angles));
/* Initialise the TCM decoder parameters. */
/* The accumulated distance vectors are set so state zero starts
@@ -1544,7 +1520,7 @@ SPAN_DECLARE(int) v17_rx_restart(v17_rx_state_t *s, int bit_rate, int short_trai
}
else
{
- s->carrier_phase_rate = dds_phase_ratef(CARRIER_NOMINAL_FREQ);
+ s->carrier_phase_rate = DDS_PHASE_RATE(CARRIER_NOMINAL_FREQ);
equalizer_reset(s);
#if defined(SPANDSP_USE_FIXED_POINTx)
s->agc_scaling_save = 0;
@@ -1618,7 +1594,7 @@ SPAN_DECLARE(v17_rx_state_t *) v17_rx_init(v17_rx_state_t *s, int bit_rate, put_
s->short_train = FALSE;
s->scrambler_tap = 18 - 1;
v17_rx_signal_cutoff(s, -45.5f);
- s->carrier_phase_rate_save = dds_phase_ratef(CARRIER_NOMINAL_FREQ);
+ s->carrier_phase_rate_save = DDS_PHASE_RATE(CARRIER_NOMINAL_FREQ);
v17_rx_restart(s, bit_rate, s->short_train);
return s;
}
diff --git a/libs/spandsp/src/v22bis_rx.c b/libs/spandsp/src/v22bis_rx.c
index 41e3076042..d124d7bcd8 100644
--- a/libs/spandsp/src/v22bis_rx.c
+++ b/libs/spandsp/src/v22bis_rx.c
@@ -956,7 +956,7 @@ int v22bis_rx_restart(v22bis_state_t *s)
s->rx.training_count = 0;
s->rx.signal_present = FALSE;
- s->rx.carrier_phase_rate = dds_phase_ratef((s->calling_party) ? 2400.0f : 1200.0f);
+ s->rx.carrier_phase_rate = (s->calling_party) ? DDS_PHASE_RATE(2400.0f) : DDS_PHASE_RATE(1200.0f);
s->rx.carrier_phase = 0;
power_meter_init(&s->rx.rx_power, 5);
v22bis_rx_signal_cutoff(s, -45.5f);
diff --git a/libs/spandsp/src/v27ter_rx.c b/libs/spandsp/src/v27ter_rx.c
index b38481b87a..a4a9f5eeb9 100644
--- a/libs/spandsp/src/v27ter_rx.c
+++ b/libs/spandsp/src/v27ter_rx.c
@@ -566,15 +566,14 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
{
s->gardner_step = 32;
s->training_stage = TRAINING_STAGE_LOG_PHASE;
- s->angles[0] =
- s->start_angles[0] = arctan2(z.im, z.re);
+ vec_zeroi32(s->diff_angles, 16);
+ s->last_angles[0] = arctan2(z.im, z.re);
}
break;
case TRAINING_STAGE_LOG_PHASE:
/* Record the current alternate phase angle */
target = &zero;
- s->angles[1] =
- s->start_angles[1] = arctan2(z.im, z.re);
+ s->last_angles[1] = arctan2(z.im, z.re);
s->training_count = 1;
s->training_stage = TRAINING_STAGE_WAIT_FOR_HOP;
break;
@@ -583,9 +582,11 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
angle = arctan2(z.im, z.re);
/* Look for the initial ABAB sequence to display a phase reversal, which will
signal the start of the scrambled ABAB segment */
- ang = angle - s->angles[(s->training_count - 1) & 0xF];
- s->angles[(s->training_count + 1) & 0xF] = angle;
- if ((ang > 0x20000000 || ang < -0x20000000) && s->training_count >= 3)
+ i = s->training_count + 1;
+ ang = angle - s->last_angles[i & 1];
+ s->last_angles[i & 1] = angle;
+ s->diff_angles[i & 0xF] = s->diff_angles[(i - 2) & 0xF] + (ang >> 4);
+ if ((ang > DDS_PHASE(45.0f) || ang < DDS_PHASE(-45.0f)) && s->training_count >= 13)
{
/* We seem to have a phase reversal */
/* Slam the carrier frequency into line, based on the total phase drift over the last
@@ -595,20 +596,20 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t
/* Step back a few symbols so we don't get ISI distorting things. */
i = (s->training_count - 8) & ~1;
/* Avoid the possibility of a divide by zero */
- if (i)
+ if (i > 1)
{
j = i & 0xF;
- ang = (s->angles[j] - s->start_angles[0])/i + (s->angles[j | 0x1] - s->start_angles[1])/i;
+ ang = (s->diff_angles[j] + s->diff_angles[j | 0x1])/(i - 1);
if (s->bit_rate == 4800)
- s->carrier_phase_rate += ang/10;
+ s->carrier_phase_rate += 16*(ang/10);
else
- s->carrier_phase_rate += 3*(ang/40);
+ s->carrier_phase_rate += 3*16*(ang/40);
}
span_log(&s->logging, SPAN_LOG_FLOW, "Coarse carrier frequency %7.2f (%d)\n", dds_frequencyf(s->carrier_phase_rate), s->training_count);
/* Check if the carrier frequency is plausible */
- if (s->carrier_phase_rate < dds_phase_ratef(CARRIER_NOMINAL_FREQ - 20.0f)
+ if (s->carrier_phase_rate < DDS_PHASE_RATE(CARRIER_NOMINAL_FREQ - 20.0f)
||
- s->carrier_phase_rate > dds_phase_ratef(CARRIER_NOMINAL_FREQ + 20.0f))
+ s->carrier_phase_rate > DDS_PHASE_RATE(CARRIER_NOMINAL_FREQ + 20.0f))
{
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
/* Park this modem */
@@ -1065,7 +1066,7 @@ SPAN_DECLARE(int) v27ter_rx_restart(v27ter_rx_state_t *s, int bit_rate, int old_
}
else
{
- s->carrier_phase_rate = dds_phase_ratef(CARRIER_NOMINAL_FREQ);
+ s->carrier_phase_rate = DDS_PHASE_RATE(CARRIER_NOMINAL_FREQ);
#if defined(SPANDSP_USE_FIXED_POINT)
s->agc_scaling = (float) (1024.0f*FP_FACTOR)*1.414f/283.0f;
#else
diff --git a/libs/spandsp/src/v29rx.c b/libs/spandsp/src/v29rx.c
index a8a1ed9c94..dec0c1f277 100644
--- a/libs/spandsp/src/v29rx.c
+++ b/libs/spandsp/src/v29rx.c
@@ -600,8 +600,8 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
{
/* Record the current phase angle */
s->training_stage = TRAINING_STAGE_LOG_PHASE;
- s->angles[0] =
- s->start_angles[0] = arctan2(z.im, z.re);
+ vec_zeroi32(s->diff_angles, 16);
+ s->last_angles[0] = arctan2(z.im, z.re);
#if defined(SPANDSP_USE_FIXED_POINT)
if (s->agc_scaling_save == 0)
s->agc_scaling_save = s->agc_scaling;
@@ -614,8 +614,7 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
case TRAINING_STAGE_LOG_PHASE:
/* Record the current alternate phase angle */
target = &zero;
- s->angles[1] =
- s->start_angles[1] = arctan2(z.im, z.re);
+ s->last_angles[1] = arctan2(z.im, z.re);
s->training_count = 1;
s->training_stage = TRAINING_STAGE_WAIT_FOR_CDCD;
break;
@@ -624,9 +623,11 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
angle = arctan2(z.im, z.re);
/* Look for the initial ABAB sequence to display a phase reversal, which will
signal the start of the scrambled CDCD segment */
- ang = angle - s->angles[(s->training_count - 1) & 0xF];
- s->angles[(s->training_count + 1) & 0xF] = angle;
- if ((ang > 0x20000000 || ang < -0x20000000) && s->training_count >= 13)
+ i = s->training_count + 1;
+ ang = angle - s->last_angles[i & 1];
+ s->last_angles[i & 1] = angle;
+ s->diff_angles[i & 0xF] = s->diff_angles[(i - 2) & 0xF] + (ang >> 4);
+ if ((ang > DDS_PHASE(45.0f) || ang < DDS_PHASE(-45.0f)) && s->training_count >= 13)
{
/* We seem to have a phase reversal */
/* Slam the carrier frequency into line, based on the total phase drift over the last
@@ -636,17 +637,17 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
/* Step back a few symbols so we don't get ISI distorting things. */
i = (s->training_count - 8) & ~1;
/* Avoid the possibility of a divide by zero */
- if (i)
+ if (i > 1)
{
j = i & 0xF;
- ang = (s->angles[j] - s->start_angles[0])/i + (s->angles[j | 0x1] - s->start_angles[1])/i;
- s->carrier_phase_rate += 3*(ang/20);
+ ang = (s->diff_angles[j] + s->diff_angles[j | 0x1])/(i - 1);
+ s->carrier_phase_rate += 3*16*(ang/20);
}
span_log(&s->logging, SPAN_LOG_FLOW, "Coarse carrier frequency %7.2f\n", dds_frequencyf(s->carrier_phase_rate));
/* Check if the carrier frequency is plausible */
- if (s->carrier_phase_rate < dds_phase_ratef(CARRIER_NOMINAL_FREQ - 20.0f)
+ if (s->carrier_phase_rate < DDS_PHASE_RATE(CARRIER_NOMINAL_FREQ - 20.0f)
||
- s->carrier_phase_rate > dds_phase_ratef(CARRIER_NOMINAL_FREQ + 20.0f))
+ s->carrier_phase_rate > DDS_PHASE_RATE(CARRIER_NOMINAL_FREQ + 20.0f))
{
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
/* Park this modem */
@@ -1111,7 +1112,7 @@ SPAN_DECLARE(int) v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train)
}
else
{
- s->carrier_phase_rate = dds_phase_ratef(CARRIER_NOMINAL_FREQ);
+ s->carrier_phase_rate = DDS_PHASE_RATE(CARRIER_NOMINAL_FREQ);
equalizer_reset(s);
#if defined(SPANDSP_USE_FIXED_POINT)
s->agc_scaling_save = 0;
diff --git a/libs/spandsp/tests/fax_decode.c b/libs/spandsp/tests/fax_decode.c
index 722f40681f..ea6da19125 100644
--- a/libs/spandsp/tests/fax_decode.c
+++ b/libs/spandsp/tests/fax_decode.c
@@ -106,6 +106,7 @@ int image_width = 1728;
int octets_per_ecm_frame = 256;
int error_correcting_mode = FALSE;
int current_fallback = 0;
+int end_of_page_detected = FALSE;
static void decode_20digit_msg(const uint8_t *pkt, int len)
{
@@ -232,8 +233,6 @@ static int check_rx_dcs(const uint8_t *msg, int len)
if ((current_fallback = find_fallback_entry(dcs_frame[4] & (DISBIT6 | DISBIT5 | DISBIT4 | DISBIT3))) < 0)
printf("Remote asked for a modem standard we do not support\n");
error_correcting_mode = ((dcs_frame[6] & DISBIT3) != 0);
-
- //v17_rx_restart(&v17, fallback_sequence[fallback_entry].bit_rate, FALSE);
return 0;
}
/*- End of function --------------------------------------------------------*/
@@ -298,6 +297,7 @@ static void t4_begin(void)
t4_rx_start_page(&t4_rx_state);
t4_up = TRUE;
+ end_of_page_detected = FALSE;
for (i = 0; i < 256; i++)
ecm_len[i] = -1;
@@ -381,7 +381,9 @@ static void v17_put_bit(void *user_data, int bit)
if (t4_rx_put_bit(&t4_rx_state, bit))
{
t4_end();
- fprintf(stderr, "End of page detected\n");
+ if (!end_of_page_detected)
+ fprintf(stderr, "End of page detected\n");
+ end_of_page_detected = TRUE;
}
}
//printf("V.17 Rx bit %d - %d\n", rx_bits++, bit);
@@ -417,7 +419,9 @@ static void v29_put_bit(void *user_data, int bit)
if (t4_rx_put_bit(&t4_rx_state, bit))
{
t4_end();
- fprintf(stderr, "End of page detected\n");
+ if (!end_of_page_detected)
+ fprintf(stderr, "End of page detected\n");
+ end_of_page_detected = TRUE;
}
}
//printf("V.29 Rx bit %d - %d\n", rx_bits++, bit);
@@ -453,7 +457,9 @@ static void v27ter_put_bit(void *user_data, int bit)
if (t4_rx_put_bit(&t4_rx_state, bit))
{
t4_end();
- fprintf(stderr, "End of page detected\n");
+ if (!end_of_page_detected)
+ fprintf(stderr, "End of page detected\n");
+ end_of_page_detected = TRUE;
}
}
//printf("V.27ter Rx bit %d - %d\n", rx_bits++, bit);
diff --git a/libs/spandsp/tests/line_model_monitor.cpp b/libs/spandsp/tests/line_model_monitor.cpp
index d2c4f89bc9..8e57fe8a94 100644
--- a/libs/spandsp/tests/line_model_monitor.cpp
+++ b/libs/spandsp/tests/line_model_monitor.cpp
@@ -216,7 +216,7 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len)
#endif
}
s->in_ptr = 0;
-#if defined(HAVE_FFTW3_H)
+#if defined(HAVE_FFTW3_H)
fftw_execute(s->p);
#else
fftw_one(s->p, s->in, s->out);
@@ -227,7 +227,7 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len)
for (i = 0; i < 512; i++)
{
s->spec_re_plot[2*i] = i*4000.0/512.0;
-#if defined(HAVE_FFTW3_H)
+#if defined(HAVE_FFTW3_H)
s->spec_re_plot[2*i + 1] = 10.0*log10((s->out[i][0]*s->out[i][0] + s->out[i][1]*s->out[i][1])/(256.0*32768*256.0*32768) + 1.0e-10) + 3.14;
#else
s->spec_re_plot[2*i + 1] = 10.0*log10((s->out[i].re*s->out[i].re + s->out[i].im*s->out[i].im)/(256.0*32768*256.0*32768) + 1.0e-10) + 3.14;
@@ -395,7 +395,7 @@ int start_line_model_monitor(int len)
s->w->end();
s->w->show();
-#if defined(HAVE_FFTW3_H)
+#if defined(HAVE_FFTW3_H)
s->p = fftw_plan_dft_1d(1024, s->in, s->out, FFTW_BACKWARD, FFTW_ESTIMATE);
for (i = 0; i < 1024; i++)
{
diff --git a/libs/spandsp/unpack_gsm0610_data.sh b/libs/spandsp/unpack_gsm0610_data.sh
index d1f8b92a23..482334c79e 100755
--- a/libs/spandsp/unpack_gsm0610_data.sh
+++ b/libs/spandsp/unpack_gsm0610_data.sh
@@ -53,7 +53,7 @@ else
cd gsm0610
fi
-if [ $1x == --no-exe-runx ]
+if [ $1x = --no-exe-runx ]
then
# Run the .exe files, which should be here
./FR_A.EXE
@@ -77,7 +77,7 @@ rm -rf READ_FRA.TXT
rm -rf ACTION
rm -rf unpacked
-if [ $1x == --no-exex ]
+if [ $1x = --no-exex ]
then
# We need to prepare the .exe files to be run separately
rm -rf *.INP
diff --git a/libs/sqlite/Makefile.in b/libs/sqlite/Makefile.in
index 1d01aadf34..01ff7496a9 100644
--- a/libs/sqlite/Makefile.in
+++ b/libs/sqlite/Makefile.in
@@ -116,7 +116,7 @@ NAWK = @AWK@
# You should not have to change anything below this line
###############################################################################
-TCC += -DSQLITE_OMIT_LOAD_EXTENSION=1
+#TCC += -DSQLITE_OMIT_LOAD_EXTENSION=1
# Object files for the SQLite library.
#
diff --git a/libs/sqlite/src/os_common.h b/libs/sqlite/src/os_common.h
index 863e3cde2b..cd43f93a7e 100644
--- a/libs/sqlite/src/os_common.h
+++ b/libs/sqlite/src/os_common.h
@@ -26,7 +26,7 @@
#ifdef MEMORY_DEBUG
# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
#endif
-
+#undef SQLITE_OMIT_LOAD_EXTENSION
/*
* When testing, this global variable stores the location of the
diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c
index 787fd9c3d9..9a2ecbcb72 100644
--- a/libs/stfu/stfu.c
+++ b/libs/stfu/stfu.c
@@ -69,6 +69,7 @@ struct stfu_instance {
struct stfu_queue *old_queue;
struct stfu_frame *last_frame;
uint32_t cur_ts;
+ uint16_t cur_seq;
uint32_t last_wr_ts;
uint32_t last_rd_ts;
uint32_t samples_per_packet;
@@ -361,6 +362,7 @@ void stfu_n_reset(stfu_instance_t *i)
stfu_n_sync(i, 1);
i->cur_ts = 0;
+ i->cur_seq = 0;
i->last_wr_ts = 0;
i->last_rd_ts = 0;
i->miss_count = 0;
@@ -402,7 +404,7 @@ static void stfu_n_swap(stfu_instance_t *i)
i->out_queue->last_jitter = 0;
}
-stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last)
+stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last)
{
uint32_t index = 0;
stfu_frame_t *frame;
@@ -569,6 +571,7 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void
frame->pt = pt;
frame->ts = ts;
+ frame->seq = seq;
frame->dlen = cplen;
frame->was_read = 0;
@@ -649,6 +652,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
for (x = 0; x < i->out_queue->array_len; x++) {
if (!i->out_queue->array[x].was_read) {
i->cur_ts = i->out_queue->array[x].ts;
+ i->cur_seq = i->out_queue->array[x].seq;
break;
}
if (i->cur_ts == 0) {
@@ -660,6 +664,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
}
} else {
i->cur_ts = i->cur_ts + i->samples_per_packet;
+ i->cur_seq++;
}
found = stfu_n_find_frame(i, i->out_queue, i->last_wr_ts, i->cur_ts, &rframe);
@@ -678,12 +683,14 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
if (found) {
i->cur_ts = rframe->ts;
+ i->cur_seq = rframe->seq;
}
if (i->sync_out) {
if (!found) {
if ((found = stfu_n_find_any_frame(i, i->out_queue, &rframe))) {
i->cur_ts = rframe->ts;
+ i->cur_seq = rframe->seq;
}
if (stfu_log != null_logger && i->debug) {
@@ -782,6 +789,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
rframe->dlen = i->plc_len;
rframe->pt = i->plc_pt;
rframe->ts = i->cur_ts;
+ rframe->seq = i->cur_seq;
i->miss_count++;
if (stfu_log != null_logger && i->debug) {
@@ -798,6 +806,45 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
return rframe;
}
+STFU_DECLARE(int32_t) stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame)
+{
+ uint32_t i = 0, j = 0;
+#ifdef WIN32
+#pragma warning (disable:4204)
+#endif
+ stfu_queue_t *queues[] = { jb->out_queue, jb->in_queue, jb->old_queue};
+#ifdef WIN32
+#pragma warning (default:4204)
+#endif
+ stfu_queue_t *queue = NULL;
+ stfu_frame_t *frame = NULL;
+
+ uint32_t target_ts = 0;
+
+ seq = seq;
+ if (!next_frame) return 0;
+
+ target_ts = timestamp + (distance - 1) * jb->samples_per_packet;
+
+ for (i = 0; i < sizeof(queues)/sizeof(queues[0]); i++) {
+ queue = queues[i];
+
+ if (!queue) continue;
+
+ for(j = 0; j < queue->array_size; j++) {
+ frame = &queue->array[j];
+ /* FIXME: ts rollover happened? bad luck */
+ if (frame->ts > target_ts) {
+ memcpy(next_frame, frame, sizeof(stfu_frame_t));
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
#ifdef WIN32
#ifndef vsnprintf
#define vsnprintf _vsnprintf
@@ -926,7 +973,6 @@ static void default_logger(const char *file, const char *func, int line, int lev
}
-
/* For Emacs:
* Local Variables:
* mode:c
diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h
index 2b21419118..e1a0d439a3 100644
--- a/libs/stfu/stfu.h
+++ b/libs/stfu/stfu.h
@@ -49,7 +49,7 @@ extern "C" {
#endif
#ifdef _MSC_VER
-#ifndef uint32_t
+#if !defined(_STDINT) && !defined(uint32_t)
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
@@ -163,6 +163,7 @@ typedef enum {
struct stfu_frame {
uint32_t ts;
+ uint16_t seq;
uint32_t pt;
uint8_t data[STFU_DATALEN];
size_t dlen;
@@ -188,8 +189,9 @@ void stfu_n_report(stfu_instance_t *i, stfu_report_t *r);
void stfu_n_destroy(stfu_instance_t **i);
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second, uint32_t max_drift_ms);
stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen);
-stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last);
+stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last);
stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i);
+STFU_DECLARE(int32_t) stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame);
void stfu_n_reset(stfu_instance_t *i);
stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets);
void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata);
@@ -197,8 +199,8 @@ void stfu_n_debug(stfu_instance_t *i, const char *name);
int32_t stfu_n_get_drift(stfu_instance_t *i);
int32_t stfu_n_get_most_qlen(stfu_instance_t *i);
-#define stfu_im_done(i) stfu_n_add_data(i, 0, NULL, 0, 0, 1)
-#define stfu_n_eat(i,t,p,d,l,tt) stfu_n_add_data(i, t, p, d, l, tt, 0)
+#define stfu_im_done(i) stfu_n_add_data(i, 0, 0, NULL, 0, 0, 1)
+#define stfu_n_eat(i,t,s,p,d,l,tt) stfu_n_add_data(i, t, s, p, d, l, tt, 0)
#ifdef __cplusplus
}
diff --git a/libs/tiff-4.0.2/configure.ac b/libs/tiff-4.0.2/configure.ac
index ba3601edc7..164b08a059 100644
--- a/libs/tiff-4.0.2/configure.ac
+++ b/libs/tiff-4.0.2/configure.ac
@@ -777,7 +777,7 @@ AC_ARG_WITH(jpeg12-lib,
AS_HELP_STRING([--with-jpeg12-lib=LIBRARY],
[path to libjpeg 12bit library]),,)
-if test "x$enable_jpeg12" == "xyes" ; then
+if test "x$enable_jpeg12" = "xyes" ; then
if test "x$with_jpeg12_lib" != "x" ; then
LIBS="$with_jpeg12_lib $LIBS"
diff --git a/libs/tiff-4.0.2/tools/tiffgt.c b/libs/tiff-4.0.2/tools/tiffgt.c
index de420396c6..4c8e50923f 100644
--- a/libs/tiff-4.0.2/tools/tiffgt.c
+++ b/libs/tiff-4.0.2/tools/tiffgt.c
@@ -31,11 +31,16 @@
#include
#include
-#if HAVE_APPLE_OPENGL_FRAMEWORK
+#if HAVE_OPENGL_GL_H
# include
+#endif
+#if HAVE_GLUT_GLUT_H
# include
-#else
+#endif
+#if HAVE_GL_GL_H
# include
+#endif
+#if HAVE_GL_GLUT_H
# include
#endif
diff --git a/libs/unimrcp/libs/mpf/codecs/g711/g711.h b/libs/unimrcp/libs/mpf/codecs/g711/g711.h
index a8a0e92150..ae7e0e44aa 100644
--- a/libs/unimrcp/libs/mpf/codecs/g711/g711.h
+++ b/libs/unimrcp/libs/mpf/codecs/g711/g711.h
@@ -49,11 +49,13 @@ extern "C" {
#ifndef __inline__
#define __inline__ __inline
#endif
+#if !defined(_STDINT) && !defined(uint32_t)
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef unsigned __int16 uint16_t;
#endif
+#endif
#if defined(__i386__)
/*! \brief Find the bit position of the highest set bit in a word
diff --git a/libs/win32/apr-util/libaprutil.2010.vcxproj.filters b/libs/win32/apr-util/libaprutil.2010.vcxproj.filters
index 9ba92f9c27..66ad7f99e0 100644
--- a/libs/win32/apr-util/libaprutil.2010.vcxproj.filters
+++ b/libs/win32/apr-util/libaprutil.2010.vcxproj.filters
@@ -1,304 +1,307 @@
-
-
-
-
- {fefe4b16-83a4-46b0-ab4b-858531a32218}
-
-
- {66bee6b2-6ba2-4e7d-9c04-5e52ea75b8ee}
-
-
- {ec602915-b144-4258-81ce-f8931434e1eb}
-
-
- {47b5e91f-ec43-4b87-8d11-cc109d0f0733}
-
-
- {12d41721-8bc3-476e-bffa-6bab3ebbcfef}
-
-
- {aafe340f-5f94-4402-a3f4-977c302848c1}
-
-
- {627c064a-54af-49ae-b154-01343f2be90e}
-
-
- {3791a803-8653-410b-905e-934728270db6}
-
-
- {5133e514-d14d-46b5-9e37-3ab909e4ef28}
-
-
- {62959b64-29f8-483f-830f-91e3005c15b9}
-
-
- {ec299ad2-8fa6-4923-95f4-b8c7f6184dcf}
-
-
- {ef13505a-0a7a-4fdc-a55a-b47e92957a85}
-
-
- {80fa8ffc-4776-4a21-bd8b-bfa055f9f46d}
-
-
- {fdb27306-6946-4cf2-bdb6-39e03cdeeae6}
-
-
- {ee62af10-73ee-4af5-85d1-442efcd33aa2}
-
-
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\buckets
-
-
- Source Files\crypto
-
-
- Source Files\crypto
-
-
- Source Files\crypto
-
-
- Source Files\crypto
-
-
- Source Files\crypto
-
-
- Source Files\dbd
-
-
- Source Files\dbd
-
-
- Source Files\dbd
-
-
- Source Files\dbd
-
-
- Source Files\dbm
-
-
- Source Files\dbm
-
-
- Source Files\dbm
-
-
- Source Files\dbm
-
-
- Source Files\encoding
-
-
- Source Files\hooks
-
-
- Source Files\ldap
-
-
- Source Files\ldap
-
-
- Source Files\ldap
-
-
- Source Files\misc
-
-
- Source Files\misc
-
-
- Source Files\misc
-
-
- Source Files\misc
-
-
- Source Files\sdbm
-
-
- Source Files\sdbm
-
-
- Source Files\sdbm
-
-
- Source Files\sdbm
-
-
- Source Files\strmatch
-
-
- Source Files\uri
-
-
- Source Files\xlate
-
-
-
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
- Public Header Files
-
-
-
-
- Generated Files
-
-
- Generated Files
-
-
- Generated Files
-
-
- Generated Files
-
-
- Generated Files
-
-
- Generated Files
-
-
- Generated Files
-
-
- Generated Files
-
-
-
-
-
-
-
- Source Files\sdbm
-
-
- Source Files\sdbm
-
-
- Source Files\sdbm
-
-
-
-
- Generated Files
-
-
- Generated Files
-
-
- Generated Files
-
-
- Generated Files
-
-
- Generated Files
-
-
+
+
+
+
+ {fefe4b16-83a4-46b0-ab4b-858531a32218}
+
+
+ {66bee6b2-6ba2-4e7d-9c04-5e52ea75b8ee}
+
+
+ {ec602915-b144-4258-81ce-f8931434e1eb}
+
+
+ {47b5e91f-ec43-4b87-8d11-cc109d0f0733}
+
+
+ {12d41721-8bc3-476e-bffa-6bab3ebbcfef}
+
+
+ {aafe340f-5f94-4402-a3f4-977c302848c1}
+
+
+ {627c064a-54af-49ae-b154-01343f2be90e}
+
+
+ {3791a803-8653-410b-905e-934728270db6}
+
+
+ {5133e514-d14d-46b5-9e37-3ab909e4ef28}
+
+
+ {62959b64-29f8-483f-830f-91e3005c15b9}
+
+
+ {ec299ad2-8fa6-4923-95f4-b8c7f6184dcf}
+
+
+ {ef13505a-0a7a-4fdc-a55a-b47e92957a85}
+
+
+ {80fa8ffc-4776-4a21-bd8b-bfa055f9f46d}
+
+
+ {fdb27306-6946-4cf2-bdb6-39e03cdeeae6}
+
+
+ {ee62af10-73ee-4af5-85d1-442efcd33aa2}
+
+
+ {0ea472ce-22be-43c7-b06d-a50dd027a9fe}
+
+
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\buckets
+
+
+ Source Files\crypto
+
+
+ Source Files\crypto
+
+
+ Source Files\crypto
+
+
+ Source Files\crypto
+
+
+ Source Files\crypto
+
+
+ Source Files\dbd
+
+
+ Source Files\dbd
+
+
+ Source Files\dbd
+
+
+ Source Files\dbd
+
+
+ Source Files\dbm
+
+
+ Source Files\dbm
+
+
+ Source Files\dbm
+
+
+ Source Files\dbm
+
+
+ Source Files\encoding
+
+
+ Source Files\hooks
+
+
+ Source Files\ldap
+
+
+ Source Files\ldap
+
+
+ Source Files\ldap
+
+
+ Source Files\misc
+
+
+ Source Files\misc
+
+
+ Source Files\misc
+
+
+ Source Files\misc
+
+
+ Source Files\sdbm
+
+
+ Source Files\sdbm
+
+
+ Source Files\sdbm
+
+
+ Source Files\sdbm
+
+
+ Source Files\strmatch
+
+
+ Source Files\uri
+
+
+ Source Files\xlate
+
+
+
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+ Public Header Files
+
+
+
+
+ Generated Files
+
+
+ Generated Files
+
+
+ Generated Files
+
+
+ Generated Files
+
+
+ Generated Files
+
+
+ Generated Files
+
+
+ Generated Files
+
+
+ Generated Files
+
+
+
+
+
+
+
+ Source Files\sdbm
+
+
+ Source Files\sdbm
+
+
+ Source Files\sdbm
+
+
+
+
+ Generated Files
+
+
+ Generated Files
+
+
+ Generated Files
+
+
+ Generated Files
+
+
+ Generated Files
+
+
\ No newline at end of file
diff --git a/libs/win32/apr/apr.hw b/libs/win32/apr/apr.hw
index 903ad1b9a3..27be40106e 100644
--- a/libs/win32/apr/apr.hw
+++ b/libs/win32/apr/apr.hw
@@ -78,7 +78,7 @@
/* Restrict the server to a subset of Windows NT 4.0 header files by default
*/
-#define _WIN32_WINNT 0x0400
+#define _WIN32_WINNT 0x0501
#endif
#ifndef NOUSER
#define NOUSER
@@ -217,7 +217,7 @@
#define APR_HAVE_IN_ADDR 1
#define APR_HAVE_INET_ADDR 1
#define APR_HAVE_INET_NETWORK 0
-#define APR_HAVE_IPV6 0
+#define APR_HAVE_IPV6 1
#define APR_HAVE_MEMMOVE 1
#define APR_HAVE_SETRLIMIT 0
#define APR_HAVE_SIGACTION 0
diff --git a/libs/win32/util.vbs b/libs/win32/util.vbs
index 2c35dfdcb7..d47ccbd1b1 100644
--- a/libs/win32/util.vbs
+++ b/libs/win32/util.vbs
@@ -131,7 +131,9 @@ Sub UnCompress(Archive, DestFolder)
Do
WScript.Echo OExec.StdOut.ReadLine()
Loop While Not OExec.StdOut.atEndOfStream
- If FSO.FileExists(Left(Archive, Len(Archive)-3))Then
+ If FSO.FileExists(Left(Archive, Len(Archive)-3))Then
+ WScript.Sleep(100)
+ FSO.DeleteFile UtilsDir & batname, True
Set MyFile = fso.CreateTextFile(UtilsDir & batname, True)
MyFile.WriteLine("@" & quote & UtilsDir & "7za.exe" & quote & " x " & quote & Left(Archive, Len(Archive)-3) & quote & " -y -o" & quote & DestFolder & quote )
MyFile.Close
@@ -142,7 +144,9 @@ Sub UnCompress(Archive, DestFolder)
WScript.Sleep(500)
FSO.DeleteFile Left(Archive, Len(Archive)-3) ,true
End If
- If FSO.FileExists(Left(Archive, Len(Archive)-3) & "tar")Then
+ If FSO.FileExists(Left(Archive, Len(Archive)-3) & "tar")Then
+ WScript.Sleep(100)
+ FSO.DeleteFile UtilsDir & batname, True
Set MyFile = fso.CreateTextFile(UtilsDir & batname, True)
MyFile.WriteLine("@" & quote & UtilsDir & "7za.exe" & quote & " x " & quote & Left(Archive, Len(Archive)-3) & "tar" & quote & " -y -o" & quote & DestFolder & quote )
MyFile.Close
@@ -314,31 +318,6 @@ Function GetTimeUTC()
End Function
-Function GetWeekDay(DateTime)
-
- DayOfWeek = DatePart("w", DateTime)
-
- Select Case DayOfWeek
- Case 1 GetWeekDay = "Sun"
- Case 2 GetWeekDay = "Mon"
- Case 3 GetWeekDay = "Tue"
- Case 4 GetWeekDay = "Wed"
- Case 5 GetWeekDay = "Thu"
- Case 6 GetWeekDay = "Fri"
- Case 7 GetWeekDay = "Sat"
- End Select
-
-End Function
-
-Function GetMonthName(DateTime)
-
- Val = MonthName(Month(DateTime), True)
- Val = UCase(Left(Val, 1)) & Mid(Val, 2, 4)
-
- GetMonthName = Val
-
-End Function
-
Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest)
Dim oExec
@@ -364,7 +343,7 @@ Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest)
If IsNumeric(strFromProc) Then
lastChangedDateTime = DateAdd("s", strFromProc, "01/01/1970 00:00:00")
strLastCommit = YEAR(lastChangedDateTime) & Pd(Month(lastChangedDateTime), 2) & Pd(DAY(lastChangedDateTime), 2) & "T" & Pd(Hour(lastChangedDateTime), 2) & Pd(Minute(lastChangedDateTime), 2) & Pd(Second(lastChangedDateTime), 2) & "Z"
- strLastCommitHuman = GetWeekDay(lastChangedDateTime) & ", " & Pd(DAY(lastChangedDateTime), 2) & " " & GetMonthName(lastChangedDateTime) & " " & YEAR(lastChangedDateTime) & " " & Pd(Hour(lastChangedDateTime), 2) & ":" & Pd(Minute(lastChangedDateTime), 2) & ":" & Pd(Second(lastChangedDateTime), 2) & " Z"
+ strLastCommitHuman = YEAR(lastChangedDateTime) & "-" & Pd(Month(lastChangedDateTime), 2) & "-" & Pd(DAY(lastChangedDateTime), 2) & " " & Pd(Hour(lastChangedDateTime), 2) & ":" & Pd(Minute(lastChangedDateTime), 2) & ":" & Pd(Second(lastChangedDateTime), 2) & "Z"
Else
strLastCommit = ""
strLastCommitHuman = ""
@@ -372,17 +351,19 @@ Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest)
'Get revision hash
strRevision = ExecAndGetResult(tmpFolder, VersionDir, "git rev-list -n1 --abbrev=10 --abbrev-commit HEAD")
+ strRevisionHuman = ExecAndGetResult(tmpFolder, VersionDir, "git rev-list -n1 --abbrev=7 --abbrev-commit HEAD")
- If strLastCommit <> "" And strLastCommitHuman <> "" And strRevision <> "" Then
+ If strLastCommit <> "" And strLastCommitHuman <> "" And strRevision <> "" And strRevisionHuman <> "" Then
'Bild version string
strGitVer = "+git~" & strLastCommit & "~" & strRevision
- strVerHuman = strVerRev & "; git at commit " & strRevision & " on " & strLastCommitHuman
+ strVerHuman = "git " & strRevisionHuman & " " & strLastCommitHuman
'Check for local changes, if found, append to git revision string
If ShowUnclean Then
If ExecAndGetExitCode(tmpFolder, VersionDir, "git diff-index --quiet HEAD") <> 0 Then
lastChangedDateTime = GetTimeUTC()
strGitVer = strGitVer & "+unclean~" & YEAR(lastChangedDateTime) & Pd(Month(lastChangedDateTime), 2) & Pd(DAY(lastChangedDateTime), 2) & "T" & Pd(Hour(lastChangedDateTime), 2) & Pd(Minute(lastChangedDateTime), 2) & Pd(Second(lastChangedDateTime), 2) & "Z"
+ strVerHuman = strVerHuman & " unclean " & YEAR(lastChangedDateTime) & "-" & Pd(Month(lastChangedDateTime), 2) & "-" & Pd(DAY(lastChangedDateTime), 2) & " " & Pd(Hour(lastChangedDateTime), 2) & ":" & Pd(Minute(lastChangedDateTime), 2) & ":" & Pd(Second(lastChangedDateTime), 2) & "Z"
End If
End If
Else
@@ -393,7 +374,7 @@ Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest)
VERSION=VERSION & strGitVer
sLastVersion = ""
- Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, true, OpenAsASCII)
+ Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, True, OpenAsASCII)
If Not sLastFile.atEndOfStream Then
sLastVersion = sLastFile.ReadLine()
End If
diff --git a/libs/win32/xmlrpc-c/abyss.2008.vcproj b/libs/win32/xmlrpc-c/abyss.2008.vcproj
new file mode 100644
index 0000000000..b0f9a5d5e3
--- /dev/null
+++ b/libs/win32/xmlrpc-c/abyss.2008.vcproj
@@ -0,0 +1,410 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/win32/xmlrpc-c/abyss.2010.vcxproj b/libs/win32/xmlrpc-c/abyss.2010.vcxproj
new file mode 100644
index 0000000000..3ff1f3ab1c
--- /dev/null
+++ b/libs/win32/xmlrpc-c/abyss.2010.vcxproj
@@ -0,0 +1,197 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ abyss
+ {D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}
+ abyss
+
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(PlatformName)\abyss\$(Configuration)\
+ $(PlatformName)\abyss\$(Configuration)\
+ $(PlatformName)\abyss\$(Configuration)\
+ $(PlatformName)\abyss\$(Configuration)\
+
+
+
+ Disabled
+ ..\;..\include;..\lib\util\include;.;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ Level3
+ true
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+
+
+ X64
+
+
+ Disabled
+ ..\;..\include;..\lib\util\include;.;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ Level3
+ true
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ ..\;..\include;..\lib\util\include;.;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDLL
+ true
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+
+
+ X64
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ ..\;..\include;..\lib\util\include;.;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDLL
+ true
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/win32/xmlrpc-c/abyss.2010.vcxproj.filters b/libs/win32/xmlrpc-c/abyss.2010.vcxproj.filters
new file mode 100644
index 0000000000..dc60f95547
--- /dev/null
+++ b/libs/win32/xmlrpc-c/abyss.2010.vcxproj.filters
@@ -0,0 +1,69 @@
+
+
+
+
+ {8ac4971f-a9ba-4930-a7e3-b291ad24d6ca}
+ cpp;c;cxx;rc;def;r;odl;idl;hpj;bat
+
+
+ {05489d43-6c6b-4bb8-95db-414e8137ee9e}
+ h;hpp;hxx;hm;inl
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/libs/win32/xmlrpc-c/gennmtab.2008.vcproj b/libs/win32/xmlrpc-c/gennmtab.2008.vcproj
new file mode 100644
index 0000000000..f9fdea54e3
--- /dev/null
+++ b/libs/win32/xmlrpc-c/gennmtab.2008.vcproj
@@ -0,0 +1,404 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/win32/xmlrpc-c/gennmtab.2010.vcxproj b/libs/win32/xmlrpc-c/gennmtab.2010.vcxproj
new file mode 100644
index 0000000000..b7923e6e58
--- /dev/null
+++ b/libs/win32/xmlrpc-c/gennmtab.2010.vcxproj
@@ -0,0 +1,304 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {BED7539C-0099-4A14-AD5D-30828F15A171}
+ gennmtab
+
+
+
+ Application
+ false
+
+
+ Application
+ false
+
+
+ Application
+ false
+
+
+ Application
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(PlatformName)\$(Configuration)\
+ $(PlatformName)\$(Configuration)\
+ $(PlatformName)\gennmtab\$(Configuration)\
+ $(PlatformName)\gennmtab\$(Configuration)\
+ true
+ true
+ $(PlatformName)\$(Configuration)\
+ $(PlatformName)\$(Configuration)\
+ $(PlatformName)\gennmtab\$(Configuration)\
+ $(PlatformName)\gennmtab\$(Configuration)\
+ false
+ false
+ AllRules.ruleset
+ AllRules.ruleset
+
+
+
+
+ AllRules.ruleset
+ AllRules.ruleset
+
+
+
+
+ true
+ true
+ true
+ true
+ Clean
+ Clean
+ Clean
+ Clean
+
+
+
+ .\Debug\gennmtab/gennmtab.tlb
+
+
+
+
+ Disabled
+ ..;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+ Level3
+ true
+ EditAndContinue
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0809
+
+
+ true
+ true
+ Console
+ false
+
+
+ MachineX86
+
+
+ true
+ .\Debug\gennmtab/gennmtab.bsc
+
+
+ Generating nametab.h ...
+ $(OutDir)$(TargetName) > $(XMLRPCDir)lib\expat\xmltok\nametab.h
+
+
+
+
+
+
+ del $(XMLRPCDir)lib\expat\xmltok\nametab.h
+
+
+ NoOutput
+
+
+
+
+ .\Debug\gennmtab/gennmtab.tlb
+
+
+
+
+ Disabled
+ ..;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+ Level3
+ true
+ ProgramDatabase
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0809
+
+
+ $(OutDir)$(TargetName)$(TargetExt)
+ true
+ true
+ Console
+ false
+
+
+
+
+ true
+ .\Debug\gennmtab/gennmtab.bsc
+
+
+ Generating nametab.h ...
+ $(OutDir)$(TargetName) > $(XMLRPCDir)lib\expat\xmltok\nametab.h
+
+
+
+
+
+
+ del $(XMLRPCDir)lib\expat\xmltok\nametab.h
+
+
+ NoOutput
+
+
+
+
+ .\Release\gennmtab/gennmtab.tlb
+
+
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ ..;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+
+
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0809
+
+
+ true
+ Console
+ false
+
+
+ MachineX86
+
+
+ true
+ .\Release\gennmtab/gennmtab.bsc
+
+
+ Generating nametab.h ...
+ $(OutDir)$(TargetName) > $(XMLRPCDir)lib\expat\xmltok\nametab.h
+
+
+
+
+
+
+ NoOutput
+ del $(XMLRPCDir)lib\expat\xmltok\nametab.h
+
+
+
+
+ .\Release\gennmtab/gennmtab.tlb
+
+
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ ..;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+
+
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0809
+
+
+ $(OutDir)$(TargetName)$(TargetExt)
+ true
+ Console
+ false
+
+
+
+
+ true
+ .\Release\gennmtab/gennmtab.bsc
+
+
+ Generating nametab.h ...
+ $(OutDir)$(TargetName) > $(XMLRPCDir)lib\expat\xmltok\nametab.h
+
+
+
+
+
+
+ del $(XMLRPCDir)lib\expat\xmltok\nametab.h
+
+
+ NoOutput
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/xmlrpc-c/Windows/xmlparse.2008.vcproj b/libs/win32/xmlrpc-c/xmlparse.2008.vcproj
similarity index 80%
rename from libs/xmlrpc-c/Windows/xmlparse.2008.vcproj
rename to libs/win32/xmlrpc-c/xmlparse.2008.vcproj
index 15adb11dab..80a9332f72 100644
--- a/libs/xmlrpc-c/Windows/xmlparse.2008.vcproj
+++ b/libs/win32/xmlrpc-c/xmlparse.2008.vcproj
@@ -1,387 +1,394 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/xmlparse.2010.vcxproj b/libs/win32/xmlrpc-c/xmlparse.2010.vcxproj
similarity index 74%
rename from libs/xmlrpc-c/Windows/xmlparse.2010.vcxproj
rename to libs/win32/xmlrpc-c/xmlparse.2010.vcxproj
index a747e32b84..3c77a24ddf 100644
--- a/libs/xmlrpc-c/Windows/xmlparse.2010.vcxproj
+++ b/libs/win32/xmlrpc-c/xmlparse.2010.vcxproj
@@ -1,198 +1,254 @@
-
-
-
-
- Debug
- Win32
-
-
- Debug
- x64
-
-
- Release
- Win32
-
-
- Release
- x64
-
-
-
- xmlparse
- {0D108721-EAE8-4BAF-8102-D8960EC93647}
- xmlparse
-
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_ProjectFileVersion>10.0.30319.1
- $(PlatformName)\xmlparse\$(Configuration)\
- $(PlatformName)\xmlparse\$(Configuration)\
- $(PlatformName)\xmlparse\$(Configuration)\
- $(PlatformName)\xmlparse\$(Configuration)\
-
-
-
- MaxSpeed
- OnlyExplicitInline
- ..\lib\expat\xmltok;..\lib\expat\xmlwf;..;..\lib\util\include;..\include;.;%(AdditionalIncludeDirectories)
- NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
- true
- MultiThreaded
- true
- Level3
- true
-
-
- NDEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Release\xmlparse/xmlparse.bsc
-
-
-
-
- X64
-
-
- MaxSpeed
- OnlyExplicitInline
- ..\lib\expat\xmltok;..\lib\expat\xmlwf;..;..\lib\util\include;..\include;.;%(AdditionalIncludeDirectories)
- NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
- true
- MultiThreaded
- true
- Level3
- true
-
-
- NDEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Release\xmlparse/xmlparse.bsc
-
-
-
-
- Disabled
- ..\lib\expat\xmltok;..\lib\expat\xmlwf;..;..\lib\util\include;..\include;.;%(AdditionalIncludeDirectories)
- WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
- true
- EnableFastChecks
- MultiThreadedDebugDLL
- Level3
- true
- ProgramDatabase
-
-
- _DEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Debug\xmlparse/xmlparse.bsc
-
-
-
-
- X64
-
-
- Disabled
- ..\lib\expat\xmltok;..\lib\expat\xmlwf;..;..\lib\util\include;..\include;.;%(AdditionalIncludeDirectories)
- WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
- true
- EnableFastChecks
- MultiThreadedDebugDLL
- Level3
- true
- ProgramDatabase
-
-
- _DEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Debug\xmlparse/xmlparse.bsc
-
-
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
-
-
-
-
-
-
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ xmlparse
+ {0D108721-EAE8-4BAF-8102-D8960EC93647}
+ xmlparse
+
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(PlatformName)\xmlparse\$(Configuration)\
+ $(PlatformName)\xmlparse\$(Configuration)\
+ $(PlatformName)\xmlparse\$(Configuration)\
+ $(PlatformName)\xmlparse\$(Configuration)\
+ $(ProjectDir)..\version.h;$(ExtensionsToDeleteOnClean)
+ Clean
+ Clean
+ Clean
+ Clean
+
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ $(XMLRPCDir)lib\expat\xmltok;$(XMLRPCDir)lib\expat\xmlwf;%(AdditionalIncludeDirectories)
+ NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+ if not exist "$(XMLRPCDir)version.h" (
+pushd $(XMLRPCDir)Windows
+"ConfigureWin32.bat"
+popd
+)
+
+
+
+ pushd $(XMLRPCDir)Windows
+"$(XMLRPCDir)Windows\CleanWin32.bat"
+popd
+
+ NoOutput
+
+
+
+
+ X64
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ $(XMLRPCDir)lib\expat\xmltok;$(XMLRPCDir)lib\expat\xmlwf;%(AdditionalIncludeDirectories)
+ NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+ if not exist "$(XMLRPCDir)version.h" (
+pushd $(XMLRPCDir)Windows
+"ConfigureWin32.bat"
+popd
+)
+
+
+
+ pushd $(XMLRPCDir)Windows
+"$(XMLRPCDir)Windows\CleanWin32.bat"
+popd
+
+ NoOutput
+
+
+
+
+ Disabled
+ $(XMLRPCDir)lib\expat\xmltok;$(XMLRPCDir)lib\expat\xmlwf;%(AdditionalIncludeDirectories)
+ WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ Level3
+ true
+ ProgramDatabase
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+ if not exist "$(XMLRPCDir)version.h" (
+pushd $(XMLRPCDir)Windows
+"ConfigureWin32.bat"
+popd
+)
+
+
+
+ pushd $(XMLRPCDir)Windows
+"$(XMLRPCDir)Windows\CleanWin32.bat"
+popd
+
+ NoOutput
+
+
+
+
+ X64
+
+
+ Disabled
+ $(XMLRPCDir)lib\expat\xmltok;$(XMLRPCDir)lib\expat\xmlwf;%(AdditionalIncludeDirectories)
+ WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ Level3
+ true
+ ProgramDatabase
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+ if not exist "$(XMLRPCDir)version.h" (
+pushd $(XMLRPCDir)Windows
+"ConfigureWin32.bat"
+popd
+)
+
+
+
+ pushd $(XMLRPCDir)Windows
+"$(XMLRPCDir)Windows\CleanWin32.bat"
+popd
+
+ NoOutput
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/win32/xmlrpc-c/xmlrpc.2008.vcproj b/libs/win32/xmlrpc-c/xmlrpc.2008.vcproj
new file mode 100644
index 0000000000..09f7e73b3c
--- /dev/null
+++ b/libs/win32/xmlrpc-c/xmlrpc.2008.vcproj
@@ -0,0 +1,490 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/win32/xmlrpc-c/xmlrpc.2010.vcxproj b/libs/win32/xmlrpc-c/xmlrpc.2010.vcxproj
new file mode 100644
index 0000000000..dc5fc4bf2f
--- /dev/null
+++ b/libs/win32/xmlrpc-c/xmlrpc.2010.vcxproj
@@ -0,0 +1,240 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ xmlrpc
+ {CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}
+ xmlrpc
+
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(PlatformName)\xmlrpc\$(Configuration)\
+ $(PlatformName)\xmlrpc\$(Configuration)\
+ $(PlatformName)\xmlrpc\$(Configuration)\
+ $(PlatformName)\xmlrpc\$(Configuration)\
+
+
+
+
+
+ Disabled
+ $(XMLRPCDir)lib\expat\xmlparse;%(AdditionalIncludeDirectories)
+ _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ Level3
+ true
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+ X64
+
+
+ Disabled
+ $(XMLRPCDir)lib\expat\xmlparse;%(AdditionalIncludeDirectories)
+ _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ Level3
+ true
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+ .\Debug\xmlrpc/xmlrpc.bsc
+
+
+
+
+
+
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ $(XMLRPCDir)lib\expat\xmlparse;%(AdditionalIncludeDirectories)
+ NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDLL
+ true
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+ X64
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ $(XMLRPCDir)lib\expat\xmlparse;%(AdditionalIncludeDirectories)
+ NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDLL
+ true
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/win32/xmlrpc-c/xmlrpc.2010.vcxproj.filters b/libs/win32/xmlrpc-c/xmlrpc.2010.vcxproj.filters
new file mode 100644
index 0000000000..ac7abdea72
--- /dev/null
+++ b/libs/win32/xmlrpc-c/xmlrpc.2010.vcxproj.filters
@@ -0,0 +1,125 @@
+
+
+
+
+ {7ca2b8b9-bf59-4407-aedf-588e548fe34a}
+ cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/libs/xmlrpc-c/Windows/xmltok.2008.vcproj b/libs/win32/xmlrpc-c/xmltok.2008.vcproj
similarity index 75%
rename from libs/xmlrpc-c/Windows/xmltok.2008.vcproj
rename to libs/win32/xmlrpc-c/xmltok.2008.vcproj
index 0935ede8b6..670d1b670a 100644
--- a/libs/xmlrpc-c/Windows/xmltok.2008.vcproj
+++ b/libs/win32/xmlrpc-c/xmltok.2008.vcproj
@@ -1,455 +1,378 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/xmltok.2010.vcxproj b/libs/win32/xmlrpc-c/xmltok.2010.vcxproj
similarity index 71%
rename from libs/xmlrpc-c/Windows/xmltok.2010.vcxproj
rename to libs/win32/xmlrpc-c/xmltok.2010.vcxproj
index a34b3f1e1e..9685273024 100644
--- a/libs/xmlrpc-c/Windows/xmltok.2010.vcxproj
+++ b/libs/win32/xmlrpc-c/xmltok.2010.vcxproj
@@ -1,213 +1,199 @@
-
-
-
-
- Debug
- Win32
-
-
- Debug
- x64
-
-
- Release
- Win32
-
-
- Release
- x64
-
-
-
- xmltok
- {B535402E-38D2-4D54-8360-423ACBD17192}
- xmltok
-
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_ProjectFileVersion>10.0.30319.1
- $(PlatformName)\xmltok\$(Configuration)\
- $(PlatformName)\xmltok\$(Configuration)\
- $(PlatformName)\xmltok\$(Configuration)\
- $(PlatformName)\xmltok\$(Configuration)\
-
-
-
- Disabled
- ..;.;%(AdditionalIncludeDirectories)
- _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions)
- true
- EnableFastChecks
- MultiThreadedDebugDLL
- Level3
- true
-
-
- _DEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Debug\xmltok/xmltok.bsc
-
-
-
-
- X64
-
-
- Disabled
- ..;.;%(AdditionalIncludeDirectories)
- _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions)
- true
- EnableFastChecks
- MultiThreadedDebugDLL
- Level3
- true
-
-
- _DEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Debug\xmltok/xmltok.bsc
-
-
-
-
- MaxSpeed
- OnlyExplicitInline
- ..;.;%(AdditionalIncludeDirectories)
- NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
- true
- MultiThreaded
- true
- Level3
- true
-
-
- NDEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Release\xmltok/xmltok.bsc
-
-
-
-
- X64
-
-
- MaxSpeed
- OnlyExplicitInline
- ..;.;%(AdditionalIncludeDirectories)
- NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
- true
- MultiThreaded
- true
- Level3
- true
-
-
- NDEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Release\xmltok/xmltok.bsc
-
-
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ xmltok
+ {B535402E-38D2-4D54-8360-423ACBD17192}
+ xmltok
+
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+ StaticLibrary
+ false
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(PlatformName)\xmltok\$(Configuration)\
+ $(PlatformName)\xmltok\$(Configuration)\
+ $(PlatformName)\xmltok\$(Configuration)\
+ $(PlatformName)\xmltok\$(Configuration)\
+
+
+
+ Disabled
+ %(AdditionalIncludeDirectories)
+ _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ Level3
+ true
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+ .\Debug\xmltok/xmltok.bsc
+
+
+
+
+ X64
+
+
+ Disabled
+ %(AdditionalIncludeDirectories)
+ _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ Level3
+ true
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+ .\Debug\xmltok/xmltok.bsc
+
+
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ %(AdditionalIncludeDirectories)
+ NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+ .\Release\xmltok/xmltok.bsc
+
+
+
+
+ X64
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ %(AdditionalIncludeDirectories)
+ NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ true
+
+
+ true
+ .\Release\xmltok/xmltok.bsc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/win32/xmlrpc-c/xmltok.2010.vcxproj.filters b/libs/win32/xmlrpc-c/xmltok.2010.vcxproj.filters
new file mode 100644
index 0000000000..edcb1d2353
--- /dev/null
+++ b/libs/win32/xmlrpc-c/xmltok.2010.vcxproj.filters
@@ -0,0 +1,45 @@
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ {e8ec3017-8580-49f6-b5b5-4ba1c66c9b58}
+
+
+ {cf3bec2c-9e12-4a6c-8d1c-495721118adf}
+
+
+
\ No newline at end of file
diff --git a/libs/xmlrpc-c/.cvsignore b/libs/xmlrpc-c/.cvsignore
deleted file mode 100644
index f007c35453..0000000000
--- a/libs/xmlrpc-c/.cvsignore
+++ /dev/null
@@ -1,18 +0,0 @@
-Makefile.config
-autogen.sh
-autom4te.cache
-configure
-config.log
-stamp-h
-stamp-h1
-config.cache
-libtool
-config.status
-xmlrpc_config.h
-xmlrpc_amconfig.h
-xmlrpc-c-config
-xmlrpc-c-config.test
-xmlrpc-c-*.tar.gz
-xmlrpc-c.spec
-transport_config.h
-
diff --git a/libs/xmlrpc-c/.update b/libs/xmlrpc-c/.update
deleted file mode 100644
index 60fffd18f9..0000000000
--- a/libs/xmlrpc-c/.update
+++ /dev/null
@@ -1 +0,0 @@
-date
diff --git a/libs/xmlrpc-c/GNUmakefile b/libs/xmlrpc-c/GNUmakefile
index be7e4234b5..976e92cfb5 100644
--- a/libs/xmlrpc-c/GNUmakefile
+++ b/libs/xmlrpc-c/GNUmakefile
@@ -1,4 +1,4 @@
-include Makefile.srcdir
+include srcdir.mk
BLDDIR = $(CURDIR)
SUBDIR =
@@ -6,7 +6,6 @@ SUBDIR =
export SRCDIR
export BLDDIR
-include $(BLDDIR)/Makefile.version
include $(BLDDIR)/config.mk
SUBDIRS = include lib src tools examples
@@ -24,10 +23,25 @@ SUBDIRS = include lib src tools examples
DEFAULT_SUBDIRS = include lib src
+ifeq ($(BUILD_TOOLS),yes)
+ DEFAULT_SUBDIRS += tools
+endif
+
PROGRAMS_TO_INSTALL = xmlrpc-c-config
default: xmlrpc-c-config xmlrpc-c-config.test $(DEFAULT_SUBDIRS:%=%/all)
+# We don't want common.mk's rule for version.h
+OMIT_VERSION_H = Y
+
+# We don't want common.mk's rule for transport_config.h
+OMIT_TRANSPORT_CONFIG_H = Y
+
+# We don't want common.mk's rule for xmlrpc-c-config.test:
+OMIT_XMLRPC_C_CONFIG_TEST = Y
+
+include $(SRCDIR)/common.mk
+
.PHONY: all
all: xmlrpc-c-config xmlrpc-c-config.test $(SUBDIRS:%=%/all)
@@ -61,22 +75,15 @@ src/all: lib/all
MAJOR := $(XMLRPC_MAJOR_RELEASE)
MINOR := $(XMLRPC_MINOR_RELEASE)
POINT := $(XMLRPC_POINT_RELEASE)
-version.h: $(SRCDIR)/Makefile.version
+version.h: $(SRCDIR)/version.mk
rm -f $@
echo "/* Generated by make file rule */" >>$@
- echo "#define XMLRPC_C_VERSION" \
- \"Xmlrpc-c $(MAJOR).$(MINOR).$(POINT)"\"" >>$@
+ echo "#define XMLRPC_C_VERSION" \"$(MAJOR).$(MINOR).$(POINT)"\"" >>$@
echo "#define XMLRPC_VERSION_MAJOR $(MAJOR)" >>$@
echo "#define XMLRPC_VERSION_MINOR $(MINOR)" >>$@
echo "#define XMLRPC_VERSION_POINT $(POINT)" >>$@
-# We don't want common.mk's rule for version.h
-OMIT_VERSION_H = Y
-
-# We don't want common.mk's rule for transport_config.h
-OMIT_TRANSPORT_CONFIG_H = Y
-
-include transport_config.make
+include transport_config.mk
# shell_config is a fragment to place inside a Bourne shell program that
# sets variables that tell how the build is configured.
@@ -94,17 +101,15 @@ shell_config: $(BLDDIR)/config.mk
@echo 'MUST_BUILD_CURL_CLIENT="$(MUST_BUILD_CURL_CLIENT)"' >>$@
@echo 'MUST_BUILD_LIBWWW_CLIENT="$(MUST_BUILD_LIBWWW_CLIENT)"' >>$@
@echo 'NEED_RPATH="$(NEED_RPATH)"' >>$@
- @echo 'NEED_WL_RPATH="$(NEED_WL)RPATH)"' >>$@
+ @echo 'NEED_WL_RPATH="$(NEED_WL_RPATH)"' >>$@
+ @echo 'LIBXMLRPCPP_NAME="$(LIBXMLRPCPP_NAME)"' >>$@
@echo 'LSOCKET="$(LSOCKET)"' >>$@
@echo 'WININET_LDADD="$(WININET_LDADD)"' >>$@
- @echo 'WININET_RPATH="$(WININET_RPATH)"' >>$@
- @echo 'WININET_WL_RPATH="$(WININET_WL_RPATH)"' >>$@
+ @echo 'WININET_LIBDIR="$(WININET_LIBDIR)"' >>$@
@echo 'CURL_LDADD="$(CURL_LDADD)"' >>$@
- @echo 'CURL_RPATH="$(CURL_RPATH)"' >>$@
- @echo 'CURL_WL_RPATH="$(CURL_WL_RPATH)"' >>$@
+ @echo 'CURL_LIBDIR="$(CURL_LIBDIR)"' >>$@
@echo 'LIBWWW_LDADD="$(LIBWWW_LDADD)"' >>$@
- @echo 'LIBWWW_RPATH="$(LIBWWW_RPATH)"' >>$@
- @echo 'LIBWWW_WL_RPATH="$(LIBWWW_WL_RPATH)"' >>$@
+ @echo 'LIBWWW_LIBDIR="$(LIBWWW_LIBDIR)"' >>$@
@echo 'XMLRPC_MAJOR_RELEASE="$(XMLRPC_MAJOR_RELEASE)"' >>$@
@echo 'XMLRPC_MINOR_RELEASE="$(XMLRPC_MINOR_RELEASE)"' >>$@
@echo 'XMLRPC_POINT_RELEASE="$(XMLRPC_POINT_RELEASE)"' >>$@
@@ -116,9 +121,6 @@ shell_config: $(BLDDIR)/config.mk
@echo 'ABS_SRCDIR="$(ABS_SRCDIR)"' >>$@
@echo '#######################################################' >>$@
-# We don't want config.mk's xmlrpc-c-config.test rule:
-OMIT_XMLRPC_C_CONFIG_TEST = Y
-
xmlrpc-c-config xmlrpc-c-config.test:%: %.main shell_config
rm -f $@
@echo "Echoes to '$@' suppressed here ..."
@@ -140,7 +142,7 @@ clean-local:
distclean: $(SUBDIRS:%=%/distclean) distclean-common distclean-local
distclean-local: clean-local
- rm -f config.log config.status config.mk Makefile.srcdir
+ rm -f config.log config.status config.mk srcdir.mk
rm -f xmlrpc_config.h xmlrpc_amconfig.h stamp-h
rm -f shell_config xmlrpc-c-config xmlrpc-c-config.test
rm -f TAGS
@@ -162,11 +164,8 @@ xmlrpc_config.h xmlrpc_amconfig.h \
:%:%.in $(SRCDIR)/configure
$(SRCDIR)/configure
-include $(SRCDIR)/common.mk
-
-
# A trick to catch a common user error. When you don't run 'configure',
-# you don't have a Makefile.srcdir, which means $(SRCDIR) is null.
+# you don't have a srcdir.mk, which means $(SRCDIR) is null.
/common.mk:
@echo =======================================
diff --git a/libs/xmlrpc-c/Makefile.common b/libs/xmlrpc-c/Makefile.common
deleted file mode 100644
index bf510401a6..0000000000
--- a/libs/xmlrpc-c/Makefile.common
+++ /dev/null
@@ -1,272 +0,0 @@
-# -*-makefile-*- <-- an Emacs control
-
-# This file contains rules and variable settings for the convenience
-# of every other make file in the package.
-
-# No make file is required to use this file, but it usually saves a lot
-# of duplication.
-
-# The following make variables are meaningful as input to this file:
-#
-# SRCDIR: Name of directory which is the top of the Xmlrpc-c source tree.
-# BUILDDIR: Name of directory which is the top of the Xmlrpc-c build tree.
-
-LIBTOOL = $(SRCDIR)/libtool
-LINK = $(LIBTOOL) --mode=link $(CCLD)
-
-GCC_WARNINGS = -Wall -Wundef -Wimplicit -W -Winline
- # We need -Wwrite-strings after we fix all the missing consts
-
-GCC_C_WARNINGS = $(GCC_WARNINGS) \
- -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes
-
-GCC_CXX_WARNINGS = $(GCC_WARNINGS) -Woverloaded-virtual -Wsynth
-
-ifeq ($(C_COMPILER_GNU),yes)
- CFLAGS_COMMON = $(GCC_C_WARNINGS) $(COMPILER_CFLAGS) -fno-common -g
-else
- CFLAGS_COMMON = $(COMPILER_CFLAGS)
-endif
-
-ifeq ($(CXX_COMPILER_GNU),yes)
- CXXFLAGS_COMMON = $(GCC_CXX_WARNINGS) $(COMPILER_CXXFLAGS)
-else
- CXXFLAGS_COMMON = $(COMPILER_CXXFLAGS)
-endif
-
-DISTDIR = $(BUILDDIR)/$(PACKAGE)-$(VERSION)/$(SUBDIR)
-
-LDFLAGS_VERSINFO = -version-info 7:0:4
-
-# CURDIR was introduced in GNU Make 3.77.
-ifeq ($(CURDIR)x,x)
- CURDIR := $(shell /bin/pwd)
-endif
-
-##############################################################################
-# RULES #
-##############################################################################
-
-$(SUBDIRS:%=%/all): %/all: $(CURDIR)/%
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
- $(notdir $@)
-
-$(SUBDIRS:%=%/install): %/install: $(CURDIR)/%
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
- $(notdir $@)
-
-$(SUBDIRS:%=%/clean): %/clean: $(CURDIR)/%
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
- $(notdir $@)
-
-$(SUBDIRS:%=%/distclean): %/distclean: $(CURDIR)/%
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
- $(notdir $@)
-
-$(SUBDIRS:%=%/distdir): %/distdir: $(CURDIR)/%
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
- $(notdir $@)
-
-$(SUBDIRS:%=%/dep): %/dep: $(CURDIR)/%
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
- $(notdir $@)
-
-$(BUILDDIR)/lib/util/casprintf.lo: FORCE
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/util/Makefile $(notdir $@)
-
-$(BUILDDIR)/lib/expat/xmlparse/libxmlrpc_xmlparse.la: FORCE
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/expat/xmlparse/Makefile \
- $(notdir $@)
-
-$(BUILDDIR)/lib/expat/xmltok/libxmlrpc_xmltok.la: FORCE
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/expat/xmltok/Makefile \
- $(notdir $@)
-
-$(BUILDDIR)/lib/wininet_transport/xmlrpc_wininet_transport.lo: FORCE
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/wininet_transport/Makefile \
- $(notdir $@)
-
-$(BUILDDIR)/lib/curl_transport/xmlrpc_curl_transport.lo: FORCE
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/curl_transport/Makefile \
- $(notdir $@)
-
-$(BUILDDIR)/lib/libwww_transport/xmlrpc_libwww_transport.lo: FORCE
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/libwww_transport/Makefile \
- $(notdir $@)
-
-$(BUILDDIR)/src/libxmlrpc.la: FORCE
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/src/Makefile \
- $(notdir $@)
-
-$(BUILDDIR)/src/libxmlrpc_client.la: FORCE
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/src/Makefile \
- $(notdir $@)
-
-$(BUILDDIR)/src/libxmlrpc_server.la: FORCE
- $(MAKE) -C $(dir $@) -f $(SRCDIR)/src/Makefile \
- $(notdir $@)
-
-ifneq ($(OMIT_TRANSPORT_CONFIG_H),Y)
-$(BUILDDIR)/transport_config.h:
- $(MAKE) -C $(dir $@) $(notdir $@)
-endif
-
-MKINSTALLDIRS = $(SHELL) $(SRCDIR)/mkinstalldirs
-
-.PHONY: install-common install-libraries install-headers install-bin
-install-common: \
- install-ltlibraries install-libraries install-headers install-bin
-
-INSTALL_LIB_CMD = $(INSTALL_DATA) $$p $(DESTDIR)$(LIBINST_DIR)/$$p
-RANLIB_CMD = $(RANLIB) $(DESTDIR)$(LIBINST_DIR)/$$p
-
-install-libraries: $(LIBRARIES_TO_INSTALL)
- $(MKINSTALLDIRS) $(DESTDIR)$(LIBINST_DIR)
- @list='$(LIBRARIES_TO_INSTALL)'; for p in $$list; do \
- if test -f $$p; then \
- echo " $(INSTALL_LIB_CMD)"; \
- $(INSTALL_LIB_CMD); \
- else :; fi; \
- done
- @$(POST_INSTALL)
- @list='$(LIBRARIES_TO_INSTALL)'; for p in $$list; do \
- if test -f $$p; then \
- echo " $(RANLIB_CMD)"; \
- $(RANLIB_CMD); \
- else :; fi; \
- done
-
-LIBTOOL_INSTALL_CMD = $(LIBTOOL) --mode=install \
- $(INSTALL) $$p $(DESTDIR)$(LIBINST_DIR)/$$p
-
-install-ltlibraries: $(LTLIBRARIES_TO_INSTALL)
- $(MKINSTALLDIRS) $(DESTDIR)$(LIBINST_DIR)
- @list='$(LTLIBRARIES_TO_INSTALL)'; for p in $$list; do \
- if test -f $$p; then \
- echo " $(LIBTOOL_INSTALL_CMD)"; \
- $(LIBTOOL_INSTALL_CMD); \
- else :; fi; \
- done
-
-HEADERDESTDIR = $(DESTDIR)$(HEADERINST_DIR)
-INSTALL_HDR_CMD = $(INSTALL_DATA) $$d$$p $(HEADERDESTDIR)/$$p
-
-install-headers: $(HEADERS_TO_INSTALL)
- $(MKINSTALLDIRS) $(HEADERDESTDIR)
- $(MKINSTALLDIRS) $(HEADERDESTDIR)/xmlrpc-c
- @list='$(HEADERS_TO_INSTALL)'; for p in $$list; do \
- if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
- echo " $(INSTALL_HDR_CMD)"; \
- $(INSTALL_HDR_CMD); \
- done
-
-
-INSTALL_PROGRAM_CMD = $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p \
- $(DESTDIR)$(PROGRAMINST_DIR)/$$p
-
-install-bin: $(PROGRAMS_TO_INSTALL) $(DESTDIR)$(PROGRAMINST_DIR)
- @list='$(PROGRAMS_TO_INSTALL)'; \
- for p in $$list; do \
- echo "$(INSTALL_PROGRAM_CMD)"; \
- $(INSTALL_PROGRAM_CMD); \
- done
-
-$(DESTDIR)$(PROGRAMINST_DIR):
- $(MKINSTALLDIRS) $@
-
-
-.PHONY: clean-common
-clean-common:
- rm -f *.o *.a *.s *.i *.la *.lo
- rm -rf .libs
-
-.PHONY: distclean-common
-distclean-common:
-# Makefile.depend is generated by 'make dep' and contains only dependencies
-# that make parts get _rebuilt_ when parts upon which they depend change.
-# It does not contain dependencies that are necessary to cause a part to
-# get built in the first place. E.g. if foo.c uses bar.h and bar.h gets built
-# by a make rule, you must put the dependency of foo.c on bar.h somewhere
-# besides Makefile.depend.
-#
-# Because of this, a user doesn't need Makefile.depend, because he
-# doesn't modify source files. A developer, on the other hand, must make his
-# own Makefile.depend, because 'make dep' creates Makefile.depend with
-# absolute pathnames, specific to the developer's system.
-#
-# So we empty out Makefile.depend here. The developer must do 'make dep' if
-# he wants to edit and rebuild.
-#
-# Other projects have 'make distclean' _remove_ Makefile.depend and then
-# have 'make' automatically build Makefile.depend. We have
-# found that to be an utter disaster -- it's way too complicated and prone
-# to failure, especially with built .h files. Better not to burden the user,
-# who gains nothing from it, with that.
-#
- cat /dev/null >Makefile.depend
- rm -f TAGS
-
-
-.PHONY: distdir-common
-distdir-common:
- @for file in $(DISTFILES); do \
- d=$(SRCDIR); \
- if test -d $$d/$$file; then \
- cp -pr $$d/$$file $(DISTDIR)/$$file; \
- else \
- test -f $(DISTDIR)/$$file \
- || ln $$d/$$file $(DISTDIR)/$$file 2> /dev/null \
- || cp -p $$d/$$file $(DISTDIR)/$$file || :; \
- fi; \
- done
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
- tags=; \
- here=`pwd`; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
- fi; \
- done; \
- list='$(SOURCES) $(HEADERS)'; \
- unique=`for i in $$list; do echo $$i; done | \
- awk ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
- || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
-
-DEP_SOURCES = $(wildcard *.c *.cpp)
-
-# This is a filter to turn "foo.o:" rules into "foo.o foo.lo:" because Libtool
-# uses .lo for object files. I'd like to purge the build of Libtool some day
-# and eliminate this complication.
-
-LIBTOOL_DEPEND_MASSAGER = perl -walnpe's{^(.*)\.o:}{$$1.o $$1.lo:}'
-
-
-
-.PHONY: dep-common
-dep-common: FORCE
-ifneq ($(DEP_SOURCES)x,x)
- -$(CC) -MM -MG -I. $(INCLUDES) $(DEP_SOURCES) | \
- $(LIBTOOL_DEPEND_MASSAGER) \
- >Makefile.depend
-endif
-
-Makefile.depend:
- cat /dev/null >$@
-
-# The automatic dependency generation is a pain in the butt and
-# totally unnecessary for people just installing the distributed code,
-# so to avoid needless failures in the field and a complex build, the
-# 'distclean' target simply makes Makefile.depend an empty file. A
-# developer may do 'make dep' to create a Makefile.depend full of real
-# dependencies.
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
-
-
-# Use the FORCE target as a dependency to force a target to get remade
-FORCE:
diff --git a/libs/xmlrpc-c/Makefile.config.in b/libs/xmlrpc-c/Makefile.config.in
deleted file mode 100644
index efdcf4f8c2..0000000000
--- a/libs/xmlrpc-c/Makefile.config.in
+++ /dev/null
@@ -1,79 +0,0 @@
-# Makefile.config is generated by 'configure' using Makefile.config.in
-# as a template and information that 'configure' gathers from the build
-# system and from user options.
-
-# Makefile.config should someday replace most of the other files that
-# 'configure' generates, thus simplifying development and customization.
-# Makefile.config is intended to contain information specific to the
-# particular build environment or user build choices.
-
-# Furthermore, most of the logic in 'configure', and thus 'configure.in',
-# should go into the make files to simplify the build. Makefile.config
-# should just pass raw configure variables through to the make file.
-
-# Tokens of the form @TOKEN@ in the template file get replaced by
-# 'configure' with the values of variables of the same name within
-# 'configure', because of a AC_SUBST(TOKEN) statement in the
-# 'configure.in' from which 'configure' was built.
-
-# Here are the options the user chose on 'configure':
-
-ENABLE_ABYSS_SERVER = @ENABLE_ABYSS_SERVER@
-ENABLE_ABYSS_THREADS = @ENABLE_ABYSS_THREADS@
-ENABLE_CPLUSPLUS = @ENABLE_CPLUSPLUS@
-ENABLE_CGI_SERVER = @ENABLE_CGI_SERVER@
-ENABLE_LIBXML2_BACKEND = @ENABLE_LIBXML2_BACKEND@
-ENABLE_EFENCE = @ENABLE_EFENCE@
-
-MUST_BUILD_WININET_CLIENT = @MUST_BUILD_WININET_CLIENT@
-MUST_BUILD_CURL_CLIENT = @MUST_BUILD_CURL_CLIENT@
-MUST_BUILD_LIBWWW_CLIENT = @MUST_BUILD_LIBWWW_CLIENT@
-
-LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
-LIBXML2_LIBS = @LIBXML2_LIBS@
-
-MUST_BUILD_CLIENT = no
-ifeq ($(MUST_BUILD_WININET_CLIENT),yes)
- MUST_BUILD_CLIENT = yes
-endif
-ifeq ($(MUST_BUILD_CURL_CLIENT),yes)
- MUST_BUILD_CLIENT = yes
-endif
-ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes)
- MUST_BUILD_CLIENT = yes
-endif
-
-# Stuff 'configure' figured out about our build platform:
-
-SHELL = @SHELL@
-CC = @CC@
-CXX = @CXX@
-CCLD = $(CC)
-CXXLD = $(CXX)
-AR = ar
-RANLIB = @RANLIB@
-LN_S = @LN_S@
-INSTALL = @INSTALL@
-
-C_COMPILER_GNU = @C_COMPILER_GNU@
-CXX_COMPILER_GNU = @CXX_COMPILER_GNU@
-COMPILER_CFLAGS = @COMPILER_CFLAGS@
-COMPILER_CXXFLAGS = @COMPILER_CXXFLAGS@
-
-# Here are the commands 'make install' uses to install various kinds of files:
-
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-
-# Here are the locations at which 'make install' puts files:
-
-# DESTDIR is designed to be overriden at make time in order to relocate
-# the entire install into a subdirectory.
-DESTDIR =
-
-exec_prefix = @exec_prefix@
-prefix = @prefix@
-LIBINST_DIR = @libdir@
-HEADERINST_DIR = @includedir@
-PROGRAMINST_DIR = @bindir@
diff --git a/libs/xmlrpc-c/Windows/CleanWin32.bat b/libs/xmlrpc-c/Windows/CleanWin32.bat
index 907b32bd90..181c3aa3e9 100644
--- a/libs/xmlrpc-c/Windows/CleanWin32.bat
+++ b/libs/xmlrpc-c/Windows/CleanWin32.bat
@@ -1,43 +1,30 @@
-@echo Windows build
-@echo This batch file deletes the copied header files,
-@echo Deleting Win32 header files...
-@echo #####################################################
-@echo IF YOU HAVE MADE CHANGES IN ..\xmlrpc_config.h, ..\include\xmlrpc-c\config.h etc ...
-@echo THESE CHANGES WILL BE LOST!
-@echo You should run diffcfg.bat first to check for changes,
-@echo and updcfg.bat if you have made changes ...
-@echo #####################################################
-@echo ARE YOU SURE YOU WANT TO DO THIS? Ctrl+C to abort ...
-@echo #####################################################
-@pause
-@set TEMP1=
-@if NOT EXIST ..\include\xmlrpc-c\config.h goto DN1
-del ..\include\xmlrpc-c\config.h > nul
-@set TEMP1=%TEMP1% ..\include\xmlrpc-c\config.h
-:DN1
-@if NOT EXIST ..\xmlrpc_config.h goto DN2
-del ..\xmlrpc_config.h > nul
-@set TEMP1=%TEMP1% ..\xmlrpc_config.h
-:DN2
-@if NOT EXIST ..\transport_config.h goto DN3
-del ..\transport_config.h > nul
-@set TEMP1=%TEMP1% ..\transport_config.h
-:DN3
-@if NOT EXIST ..\version.h goto DN4
-del ..\version.h > nul
-@set TEMP1=%TEMP1% ..\version.h
-:DN4
-@if NOT EXIST ..\examples\config.h goto DN5
-del ..\examples\config.h > nul
-@set TEMP1=%TEMP1% ..\examples\config.h
-:DN5
-@if "%TEMP1%." == "." goto ALLDN
-@echo DELETED win32 header files.
-@echo %TEMP1%
-@goto END
-
-:ALLDN
-@echo NOne to DELETE ...
-@goto END
-
-:END
+@if NOT EXIST ..\include\xmlrpc-c\config.h goto DN1
+del ..\include\xmlrpc-c\config.h > nul
+@set TEMP1=%TEMP1% ..\include\xmlrpc-c\config.h
+:DN1
+@if NOT EXIST ..\xmlrpc_config.h goto DN2
+del ..\xmlrpc_config.h > nul
+@set TEMP1=%TEMP1% ..\xmlrpc_config.h
+:DN2
+@if NOT EXIST ..\transport_config.h goto DN3
+del ..\transport_config.h > nul
+@set TEMP1=%TEMP1% ..\transport_config.h
+:DN3
+@if NOT EXIST ..\version.h goto DN4
+del ..\version.h > nul
+@set TEMP1=%TEMP1% ..\version.h
+:DN4
+@if NOT EXIST ..\examples\config.h goto DN5
+del ..\examples\config.h > nul
+@set TEMP1=%TEMP1% ..\examples\config.h
+:DN5
+@if "%TEMP1%." == "." goto ALLDN
+@echo DELETED win32 header files.
+@echo %TEMP1%
+@goto END
+
+:ALLDN
+@echo NOne to DELETE ...
+@goto END
+
+:END
diff --git a/libs/xmlrpc-c/Windows/ReadMeWin32.txt b/libs/xmlrpc-c/Windows/ReadMeWin32.txt
index 2da1575b6f..c3d5d5d4dd 100644
--- a/libs/xmlrpc-c/Windows/ReadMeWin32.txt
+++ b/libs/xmlrpc-c/Windows/ReadMeWin32.txt
@@ -1,64 +1,66 @@
-Build Instructions For XML-RPC For C/C++ On Windows
----------------------------------------------------
-
-Latest Windows work was done by
-
- Geoff McLane
- 19 October, 2007
- home: http://geoffair.net
-
-
-1. Run the batch file ConfigureWin32.bat, found in the Windows
-directory. This will copy four(4) headers to the appropriate folders.
-
-2. Load xmlrpc.dsw in MSVC[7,8] or later, and build the Release or Debug
-configurations. DLL configurations are not included, and may not compile.
-
-This build requires that you have a Microsoft SDK, or Plaform SDK
-installed, since among other things, it uses , and
-HTTPAPI.LIB, from the SDK.
-
-Once built, the rpctest.exe, in the bin folder, should run with no errors,
-and the xmlrpc_sample_add_server.exe, using port 8080, and
-xmlrpc_sample_add_sync_client.exe should communicate ... proving 7+5 = 12 ;=))
-
-Have fun.
-
-PS: Several other batch files are included in the Windows folder ...
-
-delsln.bat - to delete all the MSVC7 and 8 solution file.
-
-diffcfg.bat - compare the headers in windows with the version used in
-the compile. Requires diff.exe to be in the path.
-
-updcfg.bat - copy the 3 manually maintained configuration files back
-to the Windows folder (for distribution).
-
-cleawin32.bat - deletes the headers used in the compile. That is does the
-opposite of ConfigureWin32.bat.
-
-cleanall.bat - to remove ALL the binary files created. Requires an xdelete
-program which will recursively delete an entire folder.
-
-
-There is some historical information in ReadMeOld.txt, which used to be
-the contents of this file. Some of it is still valid.
-
-
-Developing XML-RPC For C/C++ for Windows
-----------------------------------------
-
-If you fix or enhance something in the Windows build system, please send
-your updates to the Xmlrpc-c maintainer to be included in future releases
-so others don't have to repeat your work.
-
-Output of a Subversion 'diff' is usually the best way to send updates,
-but you can also send complete files or just a description of the
-change if that is easier.
-
-For the project files, we distribute only MSVC6-compatible DSP and DSW
-files (which are, of course, usable as input to later versions of MSVC
-as well). That means if you need to modify something in the project
-files and you are not using MSVC6, you must edit the project files
-manually as text files. Modifying them via the IDE would simply
-generate new files in a format that cannot be used with older MSVC.
+Build Instructions For XML-RPC For C/C++ On Windows
+---------------------------------------------------
+
+-------------------------------------------------------------------------
+These instructions are for static link libraries, using Microsoft Visual
+Studio 7 and later. There are project files to create DLLs, using
+Visual Studio 2008 or later, in the 'dll' subdirectory. People maintain
+those project files separately from the rest of the build system, so it's
+not uncommon for something to work with one but not the other.
+-------------------------------------------------------------------------
+
+
+1. Run the batch file ConfigureWin32.bat, found in the Windows
+directory. This will copy four(4) headers to the appropriate folders.
+
+2. Load xmlrpc.dsw in MSVC[7,8] or later, and build the Release or Debug
+configurations. DLL configurations are not included, and may not compile.
+
+This build requires that you have a Microsoft SDK, or Plaform SDK
+installed, since among other things, it uses , and
+HTTPAPI.LIB, from the SDK.
+
+Once built, the rpctest.exe, in the bin folder, should run with no errors,
+and the xmlrpc_sample_add_server.exe, using port 8080, and
+xmlrpc_sample_add_sync_client.exe should communicate ... proving 7+5 = 12 ;=))
+
+Have fun.
+
+PS: Several other batch files are included in the Windows folder ...
+
+delsln.bat - to delete all the MSVC7 and 8 solution file.
+
+diffcfg.bat - compare the headers in windows with the version used in
+the compile. Requires diff.exe to be in the path.
+
+updcfg.bat - copy the 3 manually maintained configuration files back
+to the Windows folder (for distribution).
+
+cleawin32.bat - deletes the headers used in the compile. That is does the
+opposite of ConfigureWin32.bat.
+
+cleanall.bat - to remove ALL the binary files created. Requires an xdelete
+program which will recursively delete an entire folder.
+
+
+There is some historical information in ReadMeOld.txt, which used to be
+the contents of this file. Some of it is still valid.
+
+
+Developing XML-RPC For C/C++ for Windows
+----------------------------------------
+
+If you fix or enhance something in the Windows build system, please send
+your updates to the Xmlrpc-c maintainer to be included in future releases
+so others don't have to repeat your work.
+
+Output of a Subversion 'diff' is usually the best way to send updates,
+but you can also send complete files or just a description of the
+change if that is easier.
+
+For the project files, we distribute only MSVC6-compatible DSP and DSW
+files (which are, of course, usable as input to later versions of MSVC
+as well). That means if you need to modify something in the project
+files and you are not using MSVC6, you must edit the project files
+manually as text files. Modifying them via the IDE would simply
+generate new files in a format that cannot be used with older MSVC.
diff --git a/libs/xmlrpc-c/Windows/abyss.2010.vcxproj b/libs/xmlrpc-c/Windows/abyss.2010.vcxproj
deleted file mode 100644
index 8f366a8c33..0000000000
--- a/libs/xmlrpc-c/Windows/abyss.2010.vcxproj
+++ /dev/null
@@ -1,437 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Debug
- x64
-
-
- Release
- Win32
-
-
- Release
- x64
-
-
-
- abyss
- {D2396DD7-7D38-473A-ABB7-6F96D65AE1B9}
- abyss
-
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_ProjectFileVersion>10.0.30319.1
- $(PlatformName)\abyss\$(Configuration)\
- $(PlatformName)\abyss\$(Configuration)\
- $(PlatformName)\abyss\$(Configuration)\
- $(PlatformName)\abyss\$(Configuration)\
-
-
-
- Disabled
- ..\;..\include;..\lib\util\include;.;%(AdditionalIncludeDirectories)
- WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions)
- true
- EnableFastChecks
- MultiThreadedDebugDLL
- Level3
- true
-
-
- _DEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Debug\abyss/abyss.bsc
-
-
-
-
- X64
-
-
- Disabled
- ..\;..\include;..\lib\util\include;.;%(AdditionalIncludeDirectories)
- WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions)
- true
- EnableFastChecks
- MultiThreadedDebugDLL
- Level3
- true
-
-
- _DEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Debug\abyss/abyss.bsc
-
-
-
-
- MaxSpeed
- OnlyExplicitInline
- ..\;..\include;..\lib\util\include;.;%(AdditionalIncludeDirectories)
- WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions)
- true
- MultiThreadedDLL
- true
- Level3
- true
-
-
- NDEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Release\Abyss/abyss.bsc
-
-
-
-
- X64
-
-
- MaxSpeed
- OnlyExplicitInline
- ..\;..\include;..\lib\util\include;.;%(AdditionalIncludeDirectories)
- WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions)
- true
- MultiThreadedDLL
- true
- Level3
- true
-
-
- NDEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Release\Abyss/abyss.bsc
-
-
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/libs/xmlrpc-c/Windows/abyss.2010.vcxproj.filters b/libs/xmlrpc-c/Windows/abyss.2010.vcxproj.filters
deleted file mode 100644
index 63a3cb3a34..0000000000
--- a/libs/xmlrpc-c/Windows/abyss.2010.vcxproj.filters
+++ /dev/null
@@ -1,131 +0,0 @@
-
-
-
-
- {8ac4971f-a9ba-4930-a7e3-b291ad24d6ca}
- cpp;c;cxx;rc;def;r;odl;idl;hpj;bat
-
-
- {05489d43-6c6b-4bb8-95db-414e8137ee9e}
- h;hpp;hxx;hm;inl
-
-
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
-
\ No newline at end of file
diff --git a/libs/xmlrpc-c/Windows/cpptest.dsp b/libs/xmlrpc-c/Windows/cpptest.dsp
index 9db8cccd21..49f52c1e51 100644
--- a/libs/xmlrpc-c/Windows/cpptest.dsp
+++ b/libs/xmlrpc-c/Windows/cpptest.dsp
@@ -1,121 +1,128 @@
-# Microsoft Developer Studio Project File - Name="cpptest" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=cpptest - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "cpptest.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "cpptest.mak" CFG="cpptest - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "cpptest - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "cpptest - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "cpptest - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release\cpptest"
-# PROP Intermediate_Dir "Release\cpptest"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /I "../include" /I "../lib/util/include" /I "../.." /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /D "_CRT_SECURE_NO_WARNINGS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ..\lib\xmlrpccpp.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib Wininet.lib /nologo /subsystem:console /machine:I386 /out:"..\bin\cpptest.exe"
-
-!ELSEIF "$(CFG)" == "cpptest - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug\cpptest"
-# PROP Intermediate_Dir "Debug\cpptest"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../.." /I ".." /I "../include" /I "../lib/util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /D "_CRT_SECURE_NO_WARNINGS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 ..\lib\xmlrpccppD.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib Wininet.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\bin\cpptestD.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "cpptest - Win32 Release"
-# Name "cpptest - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\cpp\test\registry.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\test\server_abyss.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\test\server_pstream.cpp
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\test\test.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\test\testclient_dummy.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\test\tools.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
+# Microsoft Developer Studio Project File - Name="cpptest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=cpptest - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "cpptest.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "cpptest.mak" CFG="cpptest - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "cpptest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "cpptest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "cpptest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release\cpptest"
+# PROP Intermediate_Dir "Release\cpptest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /I "../include" /I "../lib/util/include" /I "../.." /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /D "_CRT_SECURE_NO_WARNINGS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ..\lib\xmlrpccpp.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib Wininet.lib /nologo /subsystem:console /machine:I386 /out:"..\bin\cpptest.exe"
+
+!ELSEIF "$(CFG)" == "cpptest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug\cpptest"
+# PROP Intermediate_Dir "Debug\cpptest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../.." /I ".." /I "../include" /I "../lib/util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /D "_CRT_SECURE_NO_WARNINGS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\xmlrpccppD.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib Wininet.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\bin\cpptestD.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "cpptest - Win32 Release"
+# Name "cpptest - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\src\cpp\test\value.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\test\registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\test\server_abyss.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\test\server_pstream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\test\test.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\test\testclient_dummy.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\test\tools.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\socketpair.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/libs/xmlrpc-c/Windows/dll/cpptest.vcproj b/libs/xmlrpc-c/Windows/dll/cpptest.vcproj
new file mode 100644
index 0000000000..bac35dc593
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/cpptest.vcproj
@@ -0,0 +1,482 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/gennmtab.vcproj b/libs/xmlrpc-c/Windows/dll/gennmtab.vcproj
new file mode 100644
index 0000000000..a6ce199975
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/gennmtab.vcproj
@@ -0,0 +1,449 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/rpctest.vcproj b/libs/xmlrpc-c/Windows/dll/rpctest.vcproj
new file mode 100644
index 0000000000..eadf6b0b54
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/rpctest.vcproj
@@ -0,0 +1,574 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/sample_add_asynch_client.vcproj b/libs/xmlrpc-c/Windows/dll/sample_add_asynch_client.vcproj
new file mode 100644
index 0000000000..24b355d0f8
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/sample_add_asynch_client.vcproj
@@ -0,0 +1,443 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/sample_add_server.vcproj b/libs/xmlrpc-c/Windows/dll/sample_add_server.vcproj
new file mode 100644
index 0000000000..31a426e39c
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/sample_add_server.vcproj
@@ -0,0 +1,433 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/sample_add_server_w32httpsys.vcproj b/libs/xmlrpc-c/Windows/dll/sample_add_server_w32httpsys.vcproj
new file mode 100644
index 0000000000..d5575e1ac1
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/sample_add_server_w32httpsys.vcproj
@@ -0,0 +1,433 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/sample_add_sync_client.vcproj b/libs/xmlrpc-c/Windows/dll/sample_add_sync_client.vcproj
new file mode 100644
index 0000000000..0029b15992
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/sample_add_sync_client.vcproj
@@ -0,0 +1,435 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/sample_auth_client.vcproj b/libs/xmlrpc-c/Windows/dll/sample_auth_client.vcproj
new file mode 100644
index 0000000000..c6d44ace4d
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/sample_auth_client.vcproj
@@ -0,0 +1,435 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/tool_xmlrpc-transport.vcproj b/libs/xmlrpc-c/Windows/dll/tool_xmlrpc-transport.vcproj
new file mode 100644
index 0000000000..9cc9d9e835
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/tool_xmlrpc-transport.vcproj
@@ -0,0 +1,430 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/tool_xmlrpc.vcproj b/libs/xmlrpc-c/Windows/dll/tool_xmlrpc.vcproj
new file mode 100644
index 0000000000..110685fbf4
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/tool_xmlrpc.vcproj
@@ -0,0 +1,430 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc.sln b/libs/xmlrpc-c/Windows/dll/xmlrpc.sln
new file mode 100644
index 0000000000..cda05c14b2
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc.sln
@@ -0,0 +1,327 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmlparse", "xmlrpc_xmlparse.vcproj", "{40B0756D-AFEE-4A38-9F38-A372CE431404}"
+ ProjectSection(ProjectDependencies) = postProject
+ {BD9F6041-A272-462D-8C41-87CEF1F11408} = {BD9F6041-A272-462D-8C41-87CEF1F11408}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmltok", "xmlrpc_xmltok.vcproj", "{BD9F6041-A272-462D-8C41-87CEF1F11408}"
+ ProjectSection(ProjectDependencies) = postProject
+ {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412} = {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennmtab", "gennmtab.vcproj", "{99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_util", "xmlrpc_util.vcproj", "{29FBABB6-E36A-4559-9514-B3DAF6AE1416}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc", "xmlrpc.vcproj", "{226AB06F-60CA-4B21-9040-C6ECC0581522}"
+ ProjectSection(ProjectDependencies) = postProject
+ {40B0756D-AFEE-4A38-9F38-A372CE431404} = {40B0756D-AFEE-4A38-9F38-A372CE431404}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_abyss", "xmlrpc_abyss.vcproj", "{20A8F64B-F738-4D32-A798-A65AD8291541}"
+ ProjectSection(ProjectDependencies) = postProject
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server", "xmlrpc_server.vcproj", "{74B67128-BC84-4BCB-A256-9286B6371552}"
+ ProjectSection(ProjectDependencies) = postProject
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_abyss", "xmlrpc_server_abyss.vcproj", "{E98186CB-F1B0-40A6-87A5-77B13A3F1600}"
+ ProjectSection(ProjectDependencies) = postProject
+ {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552}
+ {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541}
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_cgi", "xmlrpc_server_cgi.vcproj", "{A2AAAF37-F382-4A11-8D86-53B589921616}"
+ ProjectSection(ProjectDependencies) = postProject
+ {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552}
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_w32httpsys", "xmlrpc_server_w32httpsys.vcproj", "{0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}"
+ ProjectSection(ProjectDependencies) = postProject
+ {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552}
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_client", "xmlrpc_client.vcproj", "{28BB53D9-D487-41DF-BBB3-FDB5846D1630}"
+ ProjectSection(ProjectDependencies) = postProject
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_asynch_client", "sample_add_asynch_client.vcproj", "{2D4A179E-E2BA-4ED9-934E-7E54C08F1652}"
+ ProjectSection(ProjectDependencies) = postProject
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server", "sample_add_server.vcproj", "{BEEB1B9C-BAF4-4B54-AB51-891156301702}"
+ ProjectSection(ProjectDependencies) = postProject
+ {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552}
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server_w32httpsys", "sample_add_server_w32httpsys.vcproj", "{B6887828-9480-4D4D-9CFC-AE4980D41707}"
+ ProjectSection(ProjectDependencies) = postProject
+ {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552}
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} = {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_sync_client", "sample_add_sync_client.vcproj", "{A7A81BBD-C84D-479A-A9BD-194ADA3B1710}"
+ ProjectSection(ProjectDependencies) = postProject
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_auth_client", "sample_auth_client.vcproj", "{29A2BBC4-9ED9-4162-817C-FEEB36FB1714}"
+ ProjectSection(ProjectDependencies) = postProject
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpctest", "rpctest.vcproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}"
+ ProjectSection(ProjectDependencies) = postProject
+ {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552}
+ {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541}
+ {40B0756D-AFEE-4A38-9F38-A372CE431404} = {40B0756D-AFEE-4A38-9F38-A372CE431404}
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600}
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc++", "xmlrpc__.vcproj", "{3E7064F3-6200-4C39-85BE-775931D21828}"
+ ProjectSection(ProjectDependencies) = postProject
+ {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552}
+ {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541}
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600}
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpptest", "cpptest.vcproj", "{26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}"
+ ProjectSection(ProjectDependencies) = postProject
+ {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552}
+ {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541}
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630}
+ {3E7064F3-6200-4C39-85BE-775931D21828} = {3E7064F3-6200-4C39-85BE-775931D21828}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "tool_xmlrpc.vcproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}"
+ ProjectSection(ProjectDependencies) = postProject
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc_transport", "tool_xmlrpc-transport.vcproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}"
+ ProjectSection(ProjectDependencies) = postProject
+ {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552}
+ {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522}
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416}
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug|Win32.ActiveCfg = Debug|Win32
+ {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug|Win32.Build.0 = Debug|Win32
+ {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug|x64.ActiveCfg = Debug|x64
+ {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug|x64.Build.0 = Debug|x64
+ {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release|Win32.ActiveCfg = Release|Win32
+ {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release|Win32.Build.0 = Release|Win32
+ {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release|x64.ActiveCfg = Release|x64
+ {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release|x64.Build.0 = Release|x64
+ {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug|Win32.Build.0 = Debug|Win32
+ {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug|x64.ActiveCfg = Debug|x64
+ {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug|x64.Build.0 = Debug|x64
+ {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release|Win32.ActiveCfg = Release|Win32
+ {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release|Win32.Build.0 = Release|Win32
+ {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release|x64.ActiveCfg = Release|x64
+ {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release|x64.Build.0 = Release|x64
+ {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug|Win32.ActiveCfg = Debug|Win32
+ {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug|Win32.Build.0 = Debug|Win32
+ {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug|x64.ActiveCfg = Debug|x64
+ {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug|x64.Build.0 = Debug|x64
+ {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release|Win32.ActiveCfg = Release|Win32
+ {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release|Win32.Build.0 = Release|Win32
+ {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release|x64.ActiveCfg = Release|x64
+ {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release|x64.Build.0 = Release|x64
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug|Win32.ActiveCfg = Debug|Win32
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug|Win32.Build.0 = Debug|Win32
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug|x64.ActiveCfg = Debug|x64
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug|x64.Build.0 = Debug|x64
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release|Win32.ActiveCfg = Release|Win32
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release|Win32.Build.0 = Release|Win32
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release|x64.ActiveCfg = Release|x64
+ {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release|x64.Build.0 = Release|x64
+ {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug|Win32.ActiveCfg = Debug|Win32
+ {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug|Win32.Build.0 = Debug|Win32
+ {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug|x64.ActiveCfg = Debug|x64
+ {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug|x64.Build.0 = Debug|x64
+ {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release|Win32.ActiveCfg = Release|Win32
+ {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release|Win32.Build.0 = Release|Win32
+ {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release|x64.ActiveCfg = Release|x64
+ {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release|x64.Build.0 = Release|x64
+ {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug|Win32.ActiveCfg = Debug|Win32
+ {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug|Win32.Build.0 = Debug|Win32
+ {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug|x64.ActiveCfg = Debug|x64
+ {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug|x64.Build.0 = Debug|x64
+ {20A8F64B-F738-4D32-A798-A65AD8291541}.Release|Win32.ActiveCfg = Release|Win32
+ {20A8F64B-F738-4D32-A798-A65AD8291541}.Release|Win32.Build.0 = Release|Win32
+ {20A8F64B-F738-4D32-A798-A65AD8291541}.Release|x64.ActiveCfg = Release|x64
+ {20A8F64B-F738-4D32-A798-A65AD8291541}.Release|x64.Build.0 = Release|x64
+ {74B67128-BC84-4BCB-A256-9286B6371552}.Debug|Win32.ActiveCfg = Debug|Win32
+ {74B67128-BC84-4BCB-A256-9286B6371552}.Debug|Win32.Build.0 = Debug|Win32
+ {74B67128-BC84-4BCB-A256-9286B6371552}.Debug|x64.ActiveCfg = Debug|x64
+ {74B67128-BC84-4BCB-A256-9286B6371552}.Debug|x64.Build.0 = Debug|x64
+ {74B67128-BC84-4BCB-A256-9286B6371552}.Release|Win32.ActiveCfg = Release|Win32
+ {74B67128-BC84-4BCB-A256-9286B6371552}.Release|Win32.Build.0 = Release|Win32
+ {74B67128-BC84-4BCB-A256-9286B6371552}.Release|x64.ActiveCfg = Release|x64
+ {74B67128-BC84-4BCB-A256-9286B6371552}.Release|x64.Build.0 = Release|x64
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug|Win32.Build.0 = Debug|Win32
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug|x64.ActiveCfg = Debug|x64
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug|x64.Build.0 = Debug|x64
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release|Win32.ActiveCfg = Release|Win32
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release|Win32.Build.0 = Release|Win32
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release|x64.ActiveCfg = Release|x64
+ {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release|x64.Build.0 = Release|x64
+ {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug|Win32.Build.0 = Debug|Win32
+ {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug|x64.ActiveCfg = Debug|x64
+ {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug|x64.Build.0 = Debug|x64
+ {A2AAAF37-F382-4A11-8D86-53B589921616}.Release|Win32.ActiveCfg = Release|Win32
+ {A2AAAF37-F382-4A11-8D86-53B589921616}.Release|Win32.Build.0 = Release|Win32
+ {A2AAAF37-F382-4A11-8D86-53B589921616}.Release|x64.ActiveCfg = Release|x64
+ {A2AAAF37-F382-4A11-8D86-53B589921616}.Release|x64.Build.0 = Release|x64
+ {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug|Win32.Build.0 = Debug|Win32
+ {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug|x64.ActiveCfg = Debug|x64
+ {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug|x64.Build.0 = Debug|x64
+ {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release|Win32.ActiveCfg = Release|Win32
+ {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release|Win32.Build.0 = Release|Win32
+ {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release|x64.ActiveCfg = Release|x64
+ {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release|x64.Build.0 = Release|x64
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug|Win32.ActiveCfg = Debug|Win32
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug|Win32.Build.0 = Debug|Win32
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug|x64.ActiveCfg = Debug|x64
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug|x64.Build.0 = Debug|x64
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release|Win32.ActiveCfg = Release|Win32
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release|Win32.Build.0 = Release|Win32
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release|x64.ActiveCfg = Release|x64
+ {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release|x64.Build.0 = Release|x64
+ {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug|Win32.Build.0 = Debug|Win32
+ {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug|x64.ActiveCfg = Debug|x64
+ {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug|x64.Build.0 = Debug|x64
+ {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release|Win32.ActiveCfg = Release|Win32
+ {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release|Win32.Build.0 = Release|Win32
+ {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release|x64.ActiveCfg = Release|x64
+ {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release|x64.Build.0 = Release|x64
+ {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug|Win32.Build.0 = Debug|Win32
+ {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug|x64.ActiveCfg = Debug|x64
+ {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug|x64.Build.0 = Debug|x64
+ {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release|Win32.ActiveCfg = Release|Win32
+ {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release|Win32.Build.0 = Release|Win32
+ {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release|x64.ActiveCfg = Release|x64
+ {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release|x64.Build.0 = Release|x64
+ {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug|Win32.Build.0 = Debug|Win32
+ {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug|x64.ActiveCfg = Debug|x64
+ {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug|x64.Build.0 = Debug|x64
+ {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release|Win32.ActiveCfg = Release|Win32
+ {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release|Win32.Build.0 = Release|Win32
+ {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release|x64.ActiveCfg = Release|x64
+ {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release|x64.Build.0 = Release|x64
+ {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug|Win32.Build.0 = Debug|Win32
+ {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug|x64.ActiveCfg = Debug|x64
+ {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug|x64.Build.0 = Debug|x64
+ {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release|Win32.ActiveCfg = Release|Win32
+ {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release|Win32.Build.0 = Release|Win32
+ {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release|x64.ActiveCfg = Release|x64
+ {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release|x64.Build.0 = Release|x64
+ {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug|Win32.ActiveCfg = Debug|Win32
+ {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug|Win32.Build.0 = Debug|Win32
+ {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug|x64.ActiveCfg = Debug|x64
+ {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug|x64.Build.0 = Debug|x64
+ {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release|Win32.ActiveCfg = Release|Win32
+ {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release|Win32.Build.0 = Release|Win32
+ {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release|x64.ActiveCfg = Release|x64
+ {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release|x64.Build.0 = Release|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug|Win32.Build.0 = Debug|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug|x64.ActiveCfg = Debug|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug|x64.Build.0 = Debug|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release|Win32.ActiveCfg = Release|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release|Win32.Build.0 = Release|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release|x64.ActiveCfg = Release|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release|x64.Build.0 = Release|x64
+ {3E7064F3-6200-4C39-85BE-775931D21828}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3E7064F3-6200-4C39-85BE-775931D21828}.Debug|Win32.Build.0 = Debug|Win32
+ {3E7064F3-6200-4C39-85BE-775931D21828}.Debug|x64.ActiveCfg = Debug|x64
+ {3E7064F3-6200-4C39-85BE-775931D21828}.Debug|x64.Build.0 = Debug|x64
+ {3E7064F3-6200-4C39-85BE-775931D21828}.Release|Win32.ActiveCfg = Release|Win32
+ {3E7064F3-6200-4C39-85BE-775931D21828}.Release|Win32.Build.0 = Release|Win32
+ {3E7064F3-6200-4C39-85BE-775931D21828}.Release|x64.ActiveCfg = Release|x64
+ {3E7064F3-6200-4C39-85BE-775931D21828}.Release|x64.Build.0 = Release|x64
+ {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug|Win32.ActiveCfg = Debug|Win32
+ {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug|Win32.Build.0 = Debug|Win32
+ {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug|x64.ActiveCfg = Debug|x64
+ {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug|x64.Build.0 = Debug|x64
+ {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release|Win32.ActiveCfg = Release|Win32
+ {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release|Win32.Build.0 = Release|Win32
+ {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release|x64.ActiveCfg = Release|x64
+ {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release|x64.Build.0 = Release|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug|Win32.Build.0 = Debug|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug|x64.ActiveCfg = Debug|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug|x64.Build.0 = Debug|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release|Win32.ActiveCfg = Release|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release|Win32.Build.0 = Release|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release|x64.ActiveCfg = Release|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release|x64.Build.0 = Release|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug|Win32.Build.0 = Debug|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug|x64.ActiveCfg = Debug|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug|x64.Build.0 = Debug|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release|Win32.ActiveCfg = Release|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release|Win32.Build.0 = Release|Win32
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release|x64.ActiveCfg = Release|x64
+ {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc.vcproj
new file mode 100644
index 0000000000..529fe86bc5
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc.vcproj
@@ -0,0 +1,479 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc__.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc__.vcproj
new file mode 100644
index 0000000000..b3762c8adc
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc__.vcproj
@@ -0,0 +1,1296 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/abyss.2008.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc_abyss.vcproj
similarity index 82%
rename from libs/xmlrpc-c/Windows/abyss.2008.vcproj
rename to libs/xmlrpc-c/Windows/dll/xmlrpc_abyss.vcproj
index 45508dba83..6ceba23c63 100644
--- a/libs/xmlrpc-c/Windows/abyss.2008.vcproj
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc_abyss.vcproj
@@ -1,1298 +1,1342 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc_client.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc_client.vcproj
new file mode 100644
index 0000000000..c1ee429e87
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc_client.vcproj
@@ -0,0 +1,425 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc_server.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc_server.vcproj
new file mode 100644
index 0000000000..da95f3ab96
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc_server.vcproj
@@ -0,0 +1,413 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc_server_abyss.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc_server_abyss.vcproj
new file mode 100644
index 0000000000..6fd9d54c7c
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc_server_abyss.vcproj
@@ -0,0 +1,401 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc_server_cgi.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc_server_cgi.vcproj
new file mode 100644
index 0000000000..9b2420c4fe
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc_server_cgi.vcproj
@@ -0,0 +1,401 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc_server_w32httpsys.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc_server_w32httpsys.vcproj
new file mode 100644
index 0000000000..03796277dd
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc_server_w32httpsys.vcproj
@@ -0,0 +1,405 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc_util.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc_util.vcproj
new file mode 100644
index 0000000000..26af27b017
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc_util.vcproj
@@ -0,0 +1,449 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc_xmlparse.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc_xmlparse.vcproj
new file mode 100644
index 0000000000..9e713fd36c
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc_xmlparse.vcproj
@@ -0,0 +1,417 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/dll/xmlrpc_xmltok.vcproj b/libs/xmlrpc-c/Windows/dll/xmlrpc_xmltok.vcproj
new file mode 100644
index 0000000000..e84fb0f005
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/dll/xmlrpc_xmltok.vcproj
@@ -0,0 +1,483 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/gennmtab.2008.vcproj b/libs/xmlrpc-c/Windows/gennmtab.2008.vcproj
deleted file mode 100644
index c4460dd645..0000000000
--- a/libs/xmlrpc-c/Windows/gennmtab.2008.vcproj
+++ /dev/null
@@ -1,242 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/libs/xmlrpc-c/Windows/mkvers.bat b/libs/xmlrpc-c/Windows/mkvers.bat
index 2f6ec1b81a..2ff46e062a 100644
--- a/libs/xmlrpc-c/Windows/mkvers.bat
+++ b/libs/xmlrpc-c/Windows/mkvers.bat
@@ -1,53 +1,53 @@
-@if EXIST ..\version.h goto SHOW
-@if NOT EXIST ..\Makefile.version goto ERR1
-@if NOT EXIST mkvers1.bat goto ERR2
-@echo updating/creating ..\version.h ...
-@set TEMP1=1
-@for /F "skip=8 tokens=3" %%i in (..\Makefile.version) do @call mkvers1 %%i
-@if "%TEMPX1%." == "." goto NOX1
-@if "%TEMPX2%." == "." goto NOX1
-@if "%TEMPX3%." == "." goto NOX1
-@set TEMP1=..\version.h
-@echo #ifndef XMLRPC_C_VERSION_INCLUDED > %TEMP1%
-@echo #define XMLRPC_C_VERSION_INCLUDED >> %TEMP1%
-@echo /* generated by Windows/mkvers.bat on %DATE% ... */ >> %TEMP1%
-@echo #define XMLRPC_C_VERSION "Xmlrpc-c %TEMPX1%.%TEMPX2%.%TEMPX3%" >> %TEMP1%
-@echo #define XMLRPC_VERSION_MAJOR %TEMPX1% >> %TEMP1%
-@echo #define XMLRPC_VERSION_MINOR %TEMPX2% >> %TEMP1%
-@echo #define XMLRPC_VERSION_POINT %TEMPX3% >> %TEMP1%
-@echo #endif >> %TEMP1%
-type %TEMP1%
-@echo ..\version.h set to the above ...
-@set TEMP1=
-@set TEMPX1=
-@set TEMPX2=
-@set TEMPX3=
-@goto END
-
-:NOX1
-@echo Some error occurred in the batch process ...
-@goto NOVER
-
-:NOVER
-@echo Failed to create ..\version.h .
-@pause
-@goto END
-
-
-:ERR1
-@echo Can not locate ..\Makefile.version ... check name, location ...
-@pause
-@goto END
-:ERR2
-@echo Can not locate mkvers1.bat ... check name, location ...
-@pause
-@goto END
-
-:SHOW
-@echo ..\version.h already exist, with version ...
-@type ..\version.h
-@echo Delete this file if you wish to redo it ...
-@pause
-@goto END
-
-:END
+@if EXIST ..\version.h goto SHOW
+@if NOT EXIST ..\version.mk goto ERR1
+@if NOT EXIST mkvers1.bat goto ERR2
+@echo updating/creating ..\version.h ...
+@set TEMP1=1
+@for /F "skip=8 tokens=3" %%i in (..\version.mk) do @call mkvers1 %%i
+@if "%TEMPX1%." == "." goto NOX1
+@if "%TEMPX2%." == "." goto NOX1
+@if "%TEMPX3%." == "." goto NOX1
+@set TEMP1=..\version.h
+@echo #ifndef XMLRPC_C_VERSION_INCLUDED > %TEMP1%
+@echo #define XMLRPC_C_VERSION_INCLUDED >> %TEMP1%
+@echo /* generated by Windows/mkvers.bat on %DATE% ... */ >> %TEMP1%
+@echo #define XMLRPC_C_VERSION "%TEMPX1%.%TEMPX2%.%TEMPX3%" >> %TEMP1%
+@echo #define XMLRPC_VERSION_MAJOR %TEMPX1% >> %TEMP1%
+@echo #define XMLRPC_VERSION_MINOR %TEMPX2% >> %TEMP1%
+@echo #define XMLRPC_VERSION_POINT %TEMPX3% >> %TEMP1%
+@echo #endif >> %TEMP1%
+type %TEMP1%
+@echo ..\version.h set to the above ...
+@set TEMP1=
+@set TEMPX1=
+@set TEMPX2=
+@set TEMPX3=
+@goto END
+
+:NOX1
+@echo Some error occurred in the batch process ...
+@goto NOVER
+
+:NOVER
+@echo Failed to create ..\version.h .
+@pause
+@goto END
+
+
+:ERR1
+@echo Can not locate ..\version.mk ... check name, location ...
+@pause
+@goto END
+:ERR2
+@echo Can not locate mkvers1.bat ... check name, location ...
+@pause
+@goto END
+
+:SHOW
+@echo ..\version.h already exist, with version ...
+@type ..\version.h
+@echo Delete this file if you wish to redo it ...
+@pause
+@goto END
+
+:END
diff --git a/libs/xmlrpc-c/Windows/query_meerkat.dsp b/libs/xmlrpc-c/Windows/query_meerkat.dsp
deleted file mode 100644
index 2ffb15b610..0000000000
--- a/libs/xmlrpc-c/Windows/query_meerkat.dsp
+++ /dev/null
@@ -1,100 +0,0 @@
-# Microsoft Developer Studio Project File - Name="query_meerkat" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=query_meerkat - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "query_meerkat.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "query_meerkat.mak" CFG="query_meerkat - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "query_meerkat - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "query_meerkat - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName "query_meerkat"
-# PROP Scc_LocalPath ".."
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "query_meerkat - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release\query_meerkat"
-# PROP Intermediate_Dir "Release\query_meerkat"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\\" /I "..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ..\lib\xmlrpc.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib WinInet.lib /nologo /subsystem:console /machine:I386 /out:"..\bin\query_meerkat.exe"
-
-!ELSEIF "$(CFG)" == "query_meerkat - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug\query_meerkat"
-# PROP Intermediate_Dir "Debug\query_meerkat"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\\" /I "..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 ..\lib\xmlrpcD.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib WinInet.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\bin\query_meerkatD.exe" /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "query_meerkat - Win32 Release"
-# Name "query_meerkat - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\examples\query-meerkat.c"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/libs/xmlrpc-c/Windows/rpctest.dsp b/libs/xmlrpc-c/Windows/rpctest.dsp
index 159692cce3..7a7b350b24 100644
--- a/libs/xmlrpc-c/Windows/rpctest.dsp
+++ b/libs/xmlrpc-c/Windows/rpctest.dsp
@@ -1,210 +1,218 @@
-# Microsoft Developer Studio Project File - Name="rpctest" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=rpctest - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "rpctest.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "rpctest.mak" CFG="rpctest - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "rpctest - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "rpctest - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "rpctest - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release\rpctest"
-# PROP Intermediate_Dir "Release\rpctest"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /I "../include" /I "../lib/util/include" /I "../.." /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "ABYSS_WIN32" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ..\lib\xmlrpc.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib Wininet.lib /nologo /subsystem:console /machine:I386 /out:"..\bin\rpctest.exe"
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Desc=Copy test files
-PostBuild_Cmds=if not exist ..\Bin\data md ..\Bin\data copy ..\src\test\data\*.* ..\Bin\data
-# End Special Build Tool
-
-!ELSEIF "$(CFG)" == "rpctest - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug\rpctest"
-# PROP Intermediate_Dir "Debug\rpctest"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../.." /I ".." /I "../include" /I "../lib/util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "ABYSS_WIN32" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 ..\lib\xmlrpcD.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib Wininet.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\bin\rpctestD.exe" /pdbtype:sept
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Desc=Copy test files
-PostBuild_Cmds=if not exist ..\Bin\data md ..\Bin\data copy ..\src\test\data\*.* ..\Bin\data
-# End Special Build Tool
-
-!ENDIF
-
-# Begin Target
-
-# Name "rpctest - Win32 Release"
-# Name "rpctest - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\src\test\abyss.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\cgi.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\client.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\casprintf.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\method_registry.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\parse_xml.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\serialize.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\serialize_value.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\server_abyss.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\test.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\token.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\value.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\xml_data.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\src\test\client.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\parse_xml.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\serialize.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\serialize_value.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\server_abyss.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\test.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\value.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\test\xml_data.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# Begin Group "TestFiles"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE="..\src\testdata\http-req-simple.txt"
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\testdata\req_no_params.xml
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\testdata\req_out_of_order.xml
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\testdata\req_value_name.xml
-# End Source File
-# End Group
-# End Target
-# End Project
+# Microsoft Developer Studio Project File - Name="rpctest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=rpctest - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "rpctest.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "rpctest.mak" CFG="rpctest - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "rpctest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "rpctest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "rpctest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release\rpctest"
+# PROP Intermediate_Dir "Release\rpctest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /I "../include" /I "../lib/util/include" /I "../.." /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "ABYSS_WIN32" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ..\lib\xmlrpc.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib Wininet.lib /nologo /subsystem:console /machine:I386 /out:"..\bin\rpctest.exe"
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Desc=Copy test files
+PostBuild_Cmds=if not exist ..\Bin\data md ..\Bin\data copy ..\src\test\data\*.* ..\Bin\data
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "rpctest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug\rpctest"
+# PROP Intermediate_Dir "Debug\rpctest"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../.." /I ".." /I "../include" /I "../lib/util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "ABYSS_WIN32" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\lib\xmlrpcD.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib Wininet.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\bin\rpctestD.exe" /pdbtype:sept
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Desc=Copy test files
+PostBuild_Cmds=if not exist ..\Bin\data md ..\Bin\data copy ..\src\test\data\*.* ..\Bin\data
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "rpctest - Win32 Release"
+# Name "rpctest - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\src\test\abyss.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\cgi.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\client.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\casprintf.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\method_registry.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\parse_xml.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\serialize.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\serialize_value.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\server_abyss.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\test.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\token.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\value.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\value_datetime.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\value_datetime.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\xml_data.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\src\test\client.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\parse_xml.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\serialize.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\serialize_value.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\server_abyss.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\test.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\value.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\test\xml_data.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Group "TestFiles"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE="..\src\testdata\http-req-simple.txt"
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\testdata\req_no_params.xml
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\testdata\req_out_of_order.xml
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\testdata\req_value_name.xml
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/libs/xmlrpc-c/Windows/socketpair.cpp b/libs/xmlrpc-c/Windows/socketpair.cpp
new file mode 100644
index 0000000000..77310eb585
--- /dev/null
+++ b/libs/xmlrpc-c/Windows/socketpair.cpp
@@ -0,0 +1,71 @@
+#include
+
+
+int
+xmlrpc_win32_socketpair(int const domain,
+ int const type,
+ int const protocol,
+ SOCKET socks[2]) {
+ bool error;
+
+ error = false; // initial value
+
+ SOCKET listener;
+ listener = socket(AF_INET, SOCK_STREAM, 0);
+ if (listener == INVALID_SOCKET)
+ error = true;
+ else {
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(0x7f000001);
+ addr.sin_port = 0;
+
+ int rc;
+ rc = bind(listener, (const struct sockaddr*) &addr, sizeof(addr));
+ if (rc == SOCKET_ERROR)
+ error = true;
+ else {
+ int addrlen;
+ int rc;
+ addrlen = sizeof(addr); // initial value
+ rc = getsockname(listener, (struct sockaddr*) &addr, &addrlen);
+ if (rc == SOCKET_ERROR)
+ error = true;
+ else {
+ int rc;
+
+ rc = listen(listener, 1);
+ if (rc == SOCKET_ERROR)
+ error = true;
+ else {
+ socks[0] = socket(AF_INET, SOCK_STREAM, 0);
+ if (socks[0] == INVALID_SOCKET)
+ error = true;
+ else {
+ int rc;
+ rc = connect(socks[0],
+ (const struct sockaddr*) &addr,
+ sizeof(addr));
+ if (rc == SOCKET_ERROR)
+ error = true;
+ else {
+ socks[1] = accept(listener, NULL, NULL);
+ if (socks[1] == INVALID_SOCKET)
+ error = true;
+ }
+ if (error)
+ closesocket(socks[0]);
+ }
+ }
+ }
+ }
+ closesocket(listener);
+ }
+
+ return error ? -1 : 0;
+}
+
+
+
+
diff --git a/libs/xmlrpc-c/Windows/transport_config.h b/libs/xmlrpc-c/Windows/transport_config.h
deleted file mode 100644
index 264216805c..0000000000
--- a/libs/xmlrpc-c/Windows/transport_config.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Win32 version of transport_config.h.
-
- For other platforms, this is generated automatically, but for Windows,
- someone generates it manually. Nonetheless, we keep it looking as much
- as possible like the automatically generated one to make it easier to
- maintain (e.g. you can compare the two and see why something builds
- differently for Windows that for some other platform).
-*/
-#define MUST_BUILD_WININET_CLIENT 1
-#define MUST_BUILD_CURL_CLIENT 0
-#define MUST_BUILD_LIBWWW_CLIENT 0
-static const char * const XMLRPC_DEFAULT_TRANSPORT =
-"wininet";
diff --git a/libs/xmlrpc-c/Windows/win32_config.h b/libs/xmlrpc-c/Windows/win32_config.h
index aabf9c27fb..a7e7a7d004 100644
--- a/libs/xmlrpc-c/Windows/win32_config.h
+++ b/libs/xmlrpc-c/Windows/win32_config.h
@@ -1,38 +1,42 @@
-#ifndef XMLRPC_C_CONFIG_H_INCLUDED
-#define XMLRPC_C_CONFIG_H_INCLUDED
-
-/* This file, part of XML-RPC For C/C++, is meant to
- define characteristics of this particular installation
- that the other header files need in
- order to compile correctly when #included in Xmlrpc-c
- user code.
-
- Those header files #include this one.
-
- This file was created by a make rule.
-*/
-#define XMLRPC_HAVE_WCHAR 1
-#ifdef WIN32
- /* SOCKET is a type defined by . Anyone who
- uses XMLRPC_SOCKET on a WIN32 system must #include
-
- */
- #define XMLRPC_SOCKET SOCKET
- #define XMLRPC_HAVE_TIMEVAL 0
- #define XMLRPC_HAVE_TIMESPEC 0
-#else
- #define XMLRPC_SOCKET int
- #define XMLRPC_HAVE_TIMEVAL 1
- #define XMLRPC_HAVE_TIMESPEC 1
-#endif
-
-#if defined(_MSC_VER)
- /* Newer MSVC has long long, but MSVC 6 does not */
- #define XMLRPC_INT64 __int64
- #define XMLRPC_INT32 __int32
-#else
- #define XMLRPC_INT64 long long
- #define XMLRPC_INT32 int
-#endif
-#endif
-
+#ifndef XMLRPC_C_CONFIG_H_INCLUDED
+#define XMLRPC_C_CONFIG_H_INCLUDED
+
+/* This file, part of XML-RPC For C/C++, is meant to
+ define characteristics of this particular installation
+ that the other header files need in
+ order to compile correctly when #included in Xmlrpc-c
+ user code.
+
+ Those header files #include this one.
+
+ This file was created by a make rule.
+*/
+#define XMLRPC_HAVE_WCHAR 1
+#ifdef WIN32
+ /* SOCKET is a type defined by . Anyone who
+ uses XMLRPC_SOCKET on a WIN32 system must #include
+
+ */
+ #define XMLRPC_SOCKET SOCKET
+ #define XMLRPC_HAVE_TIMEVAL 0
+ #define XMLRPC_HAVE_TIMESPEC 0
+ #define XMLRPC_HAVE_PTHREAD 0
+#else
+ #define XMLRPC_SOCKET int
+ #define XMLRPC_HAVE_TIMEVAL 1
+ #define XMLRPC_HAVE_TIMESPEC 1
+ #define XMLRPC_HAVE_PTHREAD 1
+#endif
+
+#if defined(_MSC_VER)
+ /* Newer MSVC has long long, but MSVC 6 does not */
+ #define XMLRPC_INT64 __int64
+ #define XMLRPC_INT32 __int32
+ #define XMLRPC_PRId64 PRId64
+#else
+ #define XMLRPC_INT64 long long
+ #define XMLRPC_INT32 int
+ #define XMLRPC_PRId64 "I64d"
+#endif
+#endif
+
diff --git a/libs/xmlrpc-c/Windows/xmlrpc-c/config.h b/libs/xmlrpc-c/Windows/xmlrpc-c/config.h
deleted file mode 100644
index aabf9c27fb..0000000000
--- a/libs/xmlrpc-c/Windows/xmlrpc-c/config.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef XMLRPC_C_CONFIG_H_INCLUDED
-#define XMLRPC_C_CONFIG_H_INCLUDED
-
-/* This file, part of XML-RPC For C/C++, is meant to
- define characteristics of this particular installation
- that the other header files need in
- order to compile correctly when #included in Xmlrpc-c
- user code.
-
- Those header files #include this one.
-
- This file was created by a make rule.
-*/
-#define XMLRPC_HAVE_WCHAR 1
-#ifdef WIN32
- /* SOCKET is a type defined by . Anyone who
- uses XMLRPC_SOCKET on a WIN32 system must #include
-
- */
- #define XMLRPC_SOCKET SOCKET
- #define XMLRPC_HAVE_TIMEVAL 0
- #define XMLRPC_HAVE_TIMESPEC 0
-#else
- #define XMLRPC_SOCKET int
- #define XMLRPC_HAVE_TIMEVAL 1
- #define XMLRPC_HAVE_TIMESPEC 1
-#endif
-
-#if defined(_MSC_VER)
- /* Newer MSVC has long long, but MSVC 6 does not */
- #define XMLRPC_INT64 __int64
- #define XMLRPC_INT32 __int32
-#else
- #define XMLRPC_INT64 long long
- #define XMLRPC_INT32 int
-#endif
-#endif
-
diff --git a/libs/xmlrpc-c/Windows/xmlrpc.2008.vcproj b/libs/xmlrpc-c/Windows/xmlrpc.2008.vcproj
deleted file mode 100644
index 6a16191335..0000000000
--- a/libs/xmlrpc-c/Windows/xmlrpc.2008.vcproj
+++ /dev/null
@@ -1,2042 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/libs/xmlrpc-c/Windows/xmlrpc.2010.vcxproj b/libs/xmlrpc-c/Windows/xmlrpc.2010.vcxproj
deleted file mode 100644
index bdc988cb1f..0000000000
--- a/libs/xmlrpc-c/Windows/xmlrpc.2010.vcxproj
+++ /dev/null
@@ -1,620 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Debug
- x64
-
-
- Release
- Win32
-
-
- Release
- x64
-
-
-
- xmlrpc
- {CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA}
- xmlrpc
-
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
- StaticLibrary
- false
- MultiByte
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_ProjectFileVersion>10.0.30319.1
- $(PlatformName)\xmlrpc\$(Configuration)\
- $(PlatformName)\xmlrpc\$(Configuration)\
- $(PlatformName)\xmlrpc\$(Configuration)\
- $(PlatformName)\xmlrpc\$(Configuration)\
-
-
-
- Disabled
- ../lib;../lib/util/include;../include;..;../lib/expat/xmlparse;../lib/abyss/src;../lib/wininet_transport;.;%(AdditionalIncludeDirectories)
- _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions)
- true
- EnableFastChecks
- MultiThreadedDebugDLL
- Level3
- true
-
-
- _DEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Debug\xmlrpc/xmlrpc.bsc
-
-
-
-
- X64
-
-
- Disabled
- ../lib;../lib/util/include;../include;..;../lib/expat/xmlparse;../lib/abyss/src;../lib/wininet_transport;.;%(AdditionalIncludeDirectories)
- _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions)
- true
- EnableFastChecks
- MultiThreadedDebugDLL
- Level3
- true
-
-
- _DEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Debug\xmlrpc/xmlrpc.bsc
-
-
-
-
- MaxSpeed
- OnlyExplicitInline
- ../lib;../lib/util/include;../include;..;../lib/expat/xmlparse;../lib/abyss/src;../lib/wininet_transport;.;%(AdditionalIncludeDirectories)
- NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions)
- true
- MultiThreadedDLL
- true
- Level3
- true
-
-
- NDEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Release\xmlrpc/xmlrpc.bsc
-
-
-
-
- X64
-
-
- MaxSpeed
- OnlyExplicitInline
- ../lib;../lib/util/include;../include;..;../lib/expat/xmlparse;../lib/abyss/src;../lib/wininet_transport;.;%(AdditionalIncludeDirectories)
- NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions)
- true
- MultiThreadedDLL
- true
- Level3
- true
-
-
- NDEBUG;%(PreprocessorDefinitions)
- 0x0409
-
-
- true
-
-
- true
- .\Release\xmlrpc/xmlrpc.bsc
-
-
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- true
- .;..\..\curl\include;%(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- .;..\..\curl\include;%(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- .;..\..\curl\include;%(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- .;..\..\curl\include;%(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- true
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
- %(AdditionalIncludeDirectories)
- %(PreprocessorDefinitions)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/libs/xmlrpc-c/Windows/xmlrpc.2010.vcxproj.filters b/libs/xmlrpc-c/Windows/xmlrpc.2010.vcxproj.filters
deleted file mode 100644
index 6886dfea4a..0000000000
--- a/libs/xmlrpc-c/Windows/xmlrpc.2010.vcxproj.filters
+++ /dev/null
@@ -1,287 +0,0 @@
-
-
-
-
- {7ca2b8b9-bf59-4407-aedf-588e548fe34a}
- cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc
-
-
- {28891c93-973b-487f-a8f9-3fae090e14e3}
- h;hpp;hxx;hm;inl
-
-
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
-
\ No newline at end of file
diff --git a/libs/xmlrpc-c/Windows/xmlrpc.dsp b/libs/xmlrpc-c/Windows/xmlrpc.dsp
index 15d20f0f8d..ce9680775d 100644
--- a/libs/xmlrpc-c/Windows/xmlrpc.dsp
+++ b/libs/xmlrpc-c/Windows/xmlrpc.dsp
@@ -1,469 +1,481 @@
-# Microsoft Developer Studio Project File - Name="xmlrpc" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=xmlrpc - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "xmlrpc.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "xmlrpc.mak" CFG="xmlrpc - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "xmlrpc - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "xmlrpc - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "xmlrpc - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release\xmlrpc"
-# PROP Intermediate_Dir "Release\xmlrpc"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../lib" /I "../lib/util/include" /I "../include" /I ".." /I "../lib/expat/xmlparse" /I "../lib/abyss/src" /I "../lib/wininet_transport" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\xmlrpc.lib"
-
-!ELSEIF "$(CFG)" == "xmlrpc - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug\xmlrpc"
-# PROP Intermediate_Dir "Debug\xmlrpc"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../lib/util/include" /I "../include" /I ".." /I "../lib/expat/xmlparse" /I "../lib/abyss/src" /I "../lib/wininet_transport" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\xmlrpcD.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "xmlrpc - Win32 Release"
-# Name "xmlrpc - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc"
-# Begin Source File
-
-SOURCE=..\lib\libutil\asprintf.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\libutil\error.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\libutil\make_printable.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\libutil\memblock.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\method.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\pthreadx_win32.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\parse_value.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\registry.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\resource.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\libutil\select.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\libutil\sleep.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\system_method.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\libutil\time.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\trace.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\version.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\libutil\utf8.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\double.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_array.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_authcookie.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_base64.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_build.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_client.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_client_global.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_server_info.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\curl_transport\xmlrpc_curl_transport.c
-
-!IF "$(CFG)" == "xmlrpc - Win32 Release"
-
-# ADD CPP /I "." /I "..\..\curl\include"
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "xmlrpc - Win32 Debug"
-
-# ADD CPP /I "." /I "..\..\curl\include"
-# PROP Exclude_From_Build 1
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_data.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_datetime.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_decompose.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_expat.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_libxml2.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_parse.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_serialize.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_server_abyss.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_server_w32httpsys.c
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_string.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\xmlrpc_struct.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\wininet_transport\xmlrpc_wininet_transport.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\http.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\abyss.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\abyss_info.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\abyss_winsock.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\base.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\base_int.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\include\bool.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\c_util.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\include\c_util.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\include\casprintf.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\channel.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\chanswitch.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\client.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\client_global.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\client_int.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\config.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\conn.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\date.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\file.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\include\girmath.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\handler.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\include\inline.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\include\linklist.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\include\mallocvar.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\double.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\method.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\include\pthreadx.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\parse_value.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\registry.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\server.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\server.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\server_abyss.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\server_cgi.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\server_w32httpsys.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\sleep_int.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\socket.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\socket_win.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\util\include\stdargx.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\string_int.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\system_method.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\thread.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\time_int.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\abyss\src\token.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\transport.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\transport_config.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\transport_int.h"
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\util_int.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\xml_rpc_alloc.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\expat\xmlparse\xmlparse.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\include\xmlrpc-c\xmlparser.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\xmlrpc_config.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\curl_transport\xmlrpc_curl_transport.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\wininet_transport\xmlrpc_wininet_transport.h
-# End Source File
-# End Group
-# End Target
-# End Project
+# Microsoft Developer Studio Project File - Name="xmlrpc" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=xmlrpc - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "xmlrpc.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "xmlrpc.mak" CFG="xmlrpc - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "xmlrpc - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "xmlrpc - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "xmlrpc - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release\xmlrpc"
+# PROP Intermediate_Dir "Release\xmlrpc"
+# PROP Target_Dir ""
+LINK32=link.exe -lib
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../lib" /I "../lib/util/include" /I "../include" /I ".." /I "../lib/expat/xmlparse" /I "../lib/abyss/src" /I "../lib/wininet_transport" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib\xmlrpc.lib"
+
+!ELSEIF "$(CFG)" == "xmlrpc - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug\xmlrpc"
+# PROP Intermediate_Dir "Debug\xmlrpc"
+# PROP Target_Dir ""
+LINK32=link.exe -lib
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../lib/util/include" /I "../include" /I ".." /I "../lib/expat/xmlparse" /I "../lib/abyss/src" /I "../lib/wininet_transport" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib\xmlrpcD.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "xmlrpc - Win32 Release"
+# Name "xmlrpc - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc"
+# Begin Source File
+
+SOURCE=..\lib\libutil\asprintf.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\libutil\base64.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\libutil\error.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\libutil\make_printable.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\libutil\memblock.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\method.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\pthreadx_win32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\parse_datetime.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\parse_value.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\registry.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\resource.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\libutil\select.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\libutil\sleep.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\system_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\libutil\time.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\trace.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\version.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\libutil\utf8.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\double.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_array.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_authcookie.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_base64.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_build.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_client.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_client_global.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_server_info.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\curl_transport\xmlrpc_curl_transport.c
+
+!IF "$(CFG)" == "xmlrpc - Win32 Release"
+
+# ADD CPP /I "." /I "..\..\curl\include"
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "xmlrpc - Win32 Debug"
+
+# ADD CPP /I "." /I "..\..\curl\include"
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_data.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_datetime.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_decompose.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_expat.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_libxml2.c
+# PROP Exclude_From_Build 1
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_parse.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_serialize.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_server_abyss.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_server_w32httpsys.c
+# PROP Exclude_From_Build 1
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_string.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\xmlrpc_struct.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\wininet_transport\xmlrpc_wininet_transport.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\http.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\abyss.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\abyss_info.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\abyss_winsock.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\base.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\base_int.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\include\bool.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\c_util.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\include\c_util.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\include\casprintf.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\channel.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\chanswitch.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\client.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\client_global.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\client_int.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\config.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\conn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\date.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\file.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\include\girmath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\handler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\include\inline.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\include\linklist.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\include\mallocvar.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\double.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\method.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\include\pthreadx.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\parse_datetime.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\parse_value.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\registry.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\server.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\server.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\server_abyss.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\server_cgi.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\server_w32httpsys.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\sleep_int.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\socket.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\socket_win.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\util\include\stdargx.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\string_int.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\system_method.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\thread.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\time_int.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\abyss\src\token.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\transport.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\transport_config.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\transport_int.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\util_int.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\xml_rpc_alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\expat\xmlparse\xmlparse.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\include\xmlrpc-c\xmlparser.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\xmlrpc_config.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\curl_transport\xmlrpc_curl_transport.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\wininet_transport\xmlrpc_wininet_transport.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/libs/xmlrpc-c/Windows/xmlrpc.dsw b/libs/xmlrpc-c/Windows/xmlrpc.dsw
index f7b676eed2..db3cb5a7a0 100644
--- a/libs/xmlrpc-c/Windows/xmlrpc.dsw
+++ b/libs/xmlrpc-c/Windows/xmlrpc.dsw
@@ -1,242 +1,272 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "abyss"=".\abyss.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "cpptest"=".\cpptest.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name xmlrpc
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name xmlrpccpp
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name abyss
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "gennmtab"=".\gennmtab.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "rpctest"=".\rpctest.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name xmlrpc
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name abyss
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "xmlhttpsys"=".\xmlhttpsys.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "xmlparse"=".\xmlparse.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name xmltok
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "xmlrpc"=".\xmlrpc.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name xmlparse
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name abyss
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "xmlrpccpp"=".\xmlrpccpp.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name xmlparse
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name abyss
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name xmlrpc
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "xmlrpc_sample_add_asynch_client"=".\xmlrpc_sample_add_asynch_client.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name xmlrpc
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "xmlrpc_sample_add_server"=".\xmlrpc_sample_add_server.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name xmlrpc
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name abyss
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "xmlrpc_sample_add_server_w32httpsys"=".\xmlrpc_sample_add_server_w32httpsys.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name xmlhttpsys
- End Project Dependency
- Begin Project Dependency
- Project_Dep_Name xmlrpc
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "xmlrpc_sample_add_sync_client"=".\xmlrpc_sample_add_sync_client.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name xmlrpc
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "xmlrpc_sample_auth_client"=".\xmlrpc_sample_auth_client.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name xmlrpc
- End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "xmltok"=".\xmltok.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name gennmtab
- End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "abyss"=".\abyss.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "cpptest"=".\cpptest.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmlrpc
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name xmlrpccpp
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name abyss
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "gennmtab"=".\gennmtab.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "rpctest"=".\rpctest.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmlrpc
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name abyss
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "xmlhttpsys"=".\xmlhttpsys.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "xmlparse"=".\xmlparse.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmltok
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "xmlrpc"=".\xmlrpc.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmlparse
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name abyss
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "xmlrpc_misc"=".\xmlrpc_misc.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "xmlrpcclient"=".\xmlrpcclient.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmlrpc
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name xmlrpc_misc
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "xmlrpccpp"=".\xmlrpccpp.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmlparse
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name abyss
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name xmlrpc
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "xmlrpc_sample_add_asynch_client"=".\xmlrpc_sample_add_asynch_client.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmlrpc
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "xmlrpc_sample_add_server"=".\xmlrpc_sample_add_server.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmlrpc
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name abyss
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "xmlrpc_sample_add_server_w32httpsys"=".\xmlrpc_sample_add_server_w32httpsys.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmlhttpsys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name xmlrpc
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "xmlrpc_sample_add_sync_client"=".\xmlrpc_sample_add_sync_client.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmlrpc
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "xmlrpc_sample_auth_client"=".\xmlrpc_sample_auth_client.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name xmlrpc
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "xmltok"=".\xmltok.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name gennmtab
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/libs/xmlrpc-c/Windows/xmlrpc_config.h b/libs/xmlrpc-c/Windows/xmlrpc_config.h
deleted file mode 100644
index 319dc2a953..0000000000
--- a/libs/xmlrpc-c/Windows/xmlrpc_config.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* Win32 version of xmlrpc_config.h.
-
- For other platforms, this is generated automatically, but for Windows,
- someone generates it manually. Nonetheless, we keep it looking as much
- as possible like the automatically generated one to make it easier to
- maintain (e.g. you can compare the two and see why something builds
- differently for Windows than for some other platform).
-
- The purpose of this file is to define stuff particular to the build
- environment being used to build Xmlrpc-c. Xmlrpc-c source files can
- #include this file and have build-environment-independent source code.
-
- A major goal of this file is to reduce conditional compilation in
- the other source files as much as possible. Even more, we want to avoid
- having to generate source code particular to a build environment
- except in this file.
-
- This file is NOT meant to be used by any code outside of the
- Xmlrpc-c source tree. There is a similar file that gets installed
- as that performs the same function for Xmlrpc-c
- interface header files that get compiled as part of a user's program.
-
- Logical macros are 0 or 1 instead of the more traditional defined and
- undefined. That's so we can distinguish when compiling code between
- "false" and some problem with the code.
-*/
-
-#ifndef XMLRPC_CONFIG_H_INCLUDED
-#define XMLRPC_CONFIG_H_INCLUDED
-
-/* From xmlrpc_amconfig.h */
-
-#define HAVE__STRICMP 1
-/* Name of package */
-#define PACKAGE "xmlrpc-c"
-/*----------------------------------*/
-
-#ifndef HAVE_SETGROUPS
-#define HAVE_SETGROUPS 0
-#endif
-#ifndef HAVE_ASPRINTF
-#define HAVE_ASPRINTF 0
-#endif
-#ifndef HAVE_SETENV
-#define HAVE_SETENV 0
-#endif
-#ifndef HAVE_PSELECT
-#define HAVE_PSELECT 0
-#endif
-#ifndef HAVE_WCSNCMP
-#define HAVE_WCSNCMP 1
-#endif
-#ifndef HAVE_GETTIMEOFDAY
-#define HAVE_GETTIMEOFDAY 0
-#endif
-#ifndef HAVE_LOCALTIME_R
-#define HAVE_LOCALTIME_R 0
-#endif
-#ifndef HAVE_GMTIME_R
-#define HAVE_GMTIME_R 0
-#endif
-#ifndef HAVE_STRCASECMP
-#define HAVE_STRCASECMP 0
-#endif
-#ifndef HAVE_STRICMP
-#define HAVE_STRICMP 0
-#endif
-#ifndef HAVE__STRICMP
-#define HAVE__STRICMP 0
-#endif
-
-#define HAVE_WCHAR_H 1
-#define HAVE_SYS_FILIO_H 0
-#define HAVE_SYS_IOCTL_H 0
-
-#define VA_LIST_IS_ARRAY 0
-
-#define HAVE_LIBWWW_SSL 0
-
-/* Used to mark an unused function parameter */
-#define ATTR_UNUSED
-
-#define DIRECTORY_SEPARATOR "\\"
-
-#define HAVE_UNICODE_WCHAR 1
-
-/* Xmlrpc-c code uses __inline__ to declare functions that should
- be compiled as inline code. GNU C recognizes the __inline__ keyword.
- Others recognize 'inline' or '__inline' or nothing at all to say
- a function should be inlined.
-
- We could make 'configure' simply do a trial compile to figure out
- which one, but for now, this approximation is easier:
-*/
-#if (!defined(__GNUC__))
- #if (!defined(__inline__))
- #if (defined(__sgi) || defined(_AIX) || defined(_MSC_VER))
- #define __inline__ __inline
- #else
- #define __inline__
- #endif
- #endif
-#endif
-
-/* MSVCRT means we're using the Microsoft Visual C++ runtime library */
-
-#ifdef _MSC_VER
-/* The compiler is Microsoft Visual C++. */
- #define MSVCRT _MSC_VER
-#else
- #define MSVCRT 0
-#endif
-
-#if MSVCRT
- /* The MSVC runtime library _does_ have a 'struct timeval', but it is
- part of the Winsock interface (along with select(), which is probably
- its intended use), so isn't intended for use for general timekeeping.
- */
- #define HAVE_TIMEVAL 0
- #define HAVE_TIMESPEC 0
-#else
- #define HAVE_TIMEVAL 1
- /* timespec is Posix.1b. If we need to work on a non-Posix.1b non-Windows
- system, we'll have to figure out how to make Configure determine this.
- */
- #define HAVE_TIMESPEC 1
-#endif
-
-#if MSVCRT
- #define XMLRPC_VSNPRINTF _vsnprintf
-#else
- #define XMLRPC_VSNPRINTF vsnprintf
-#endif
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-/* Starting with MSVC 8, the runtime library defines various POSIX functions
- such as strdup() whose names violate the ISO C standard (the standard
- says the strXXX names are reserved for the standard), but warns you of
- the standards violation. That warning is 4996, along with other warnings
- that tell you you're using a function that Microsoft thinks you
- shouldn't.
-
- Well, POSIX is more important than that element of ISO C, so we disable
- that warning.
-
- FYI, msvcrt also defines _strdup(), etc, which doesn't violate the
- naming standard. But since other environments don't define _strdup(),
- we can't use it in portable code.
-*/
-#pragma warning(disable:4996)
-#endif
-
-#define snprintf _snprintf
-#define popen _popen
-#define strtoll _strtoui64
-#define strtoull _strtoui64
-
-#endif
diff --git a/libs/xmlrpc-c/Windows/xmlrpc_win32_config.h b/libs/xmlrpc-c/Windows/xmlrpc_win32_config.h
index e4e34fd44f..798b5b2002 100644
--- a/libs/xmlrpc-c/Windows/xmlrpc_win32_config.h
+++ b/libs/xmlrpc-c/Windows/xmlrpc_win32_config.h
@@ -31,6 +31,8 @@
/* From xmlrpc_amconfig.h */
#define HAVE__STRICMP 1
+#define HAVE__STRTOUI64 1
+
/* Name of package */
#define PACKAGE "xmlrpc-c"
/*----------------------------------*/
@@ -72,6 +74,7 @@
#define HAVE_WCHAR_H 1
#define HAVE_SYS_FILIO_H 0
#define HAVE_SYS_IOCTL_H 0
+#define HAVE_SYS_SELECT_H 0
#define VA_LIST_IS_ARRAY 0
@@ -126,12 +129,42 @@
#define HAVE_TIMESPEC 1
#endif
+#if MSVCRT
+ #define HAVE_WINDOWS_THREAD 1
+#else
+ #define HAVE_WINDOWS_THREAD 0
+#endif
+
+/* Some people have and use pthreads on Windows. See
+ http://sourceware.org/pthreads-win32 . For that case, we can set
+ HAVE_PTHREAD to 1. The builder prefers to use pthreads if it has
+ a choice.
+*/
+#define HAVE_PTHREAD 0
+
+/* Note that the return value of XMLRPC_VSNPRINTF is int on Windows,
+ ssize_t on POSIX.
+*/
#if MSVCRT
#define XMLRPC_VSNPRINTF _vsnprintf
#else
#define XMLRPC_VSNPRINTF vsnprintf
#endif
+#if MSVCRT
+ #define HAVE_REGEX 0
+#else
+ #define HAVE_REGEX 1
+#endif
+
+#if MSVCRT
+ #define XMLRPC_SOCKETPAIR xmlrpc_win32_socketpair
+ #define XMLRPC_CLOSESOCKET closesocket
+#else
+ #define XMLRPC_SOCKETPAIR socketpair
+ #define XMLRPC_CLOSESOCKET close
+#endif
+
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
/* Starting with MSVC 8, the runtime library defines various POSIX functions
such as strdup() whose names violate the ISO C standard (the standard
@@ -149,10 +182,42 @@
*/
#pragma warning(disable:4996)
#endif
+/* Warning C4090 is "different 'const' qualifiers".
+
+ We disable this warning because MSVC erroneously issues it when there is
+ in fact no difference in const qualifiers:
+
+ const char ** p;
+ void * q;
+ q = p;
+
+ Note that both p and q are pointers to non-const.
+
+ We have seen this in MSVC 7.1, 8, and 9 (but not 6).
+*/
+#pragma warning(disable:4090)
+
+#if HAVE_STRTOLL
+ # define XMLRPC_STRTOLL strtoll
+#elif HAVE_STRTOQ
+ # define XMLRPC_STRTOLL strtoq /* Interix */
+#elif HAVE___STRTOLL
+ # define XMLRPC_STRTOLL __strtoll /* HP-UX <= 11.11 */
+#elif HAVE__STRTOUI64
+ #define XMLRPC_STRTOLL _strtoui64 /* Windows MSVC */
+#endif
+
+#if HAVE_STRTOULL
+ # define XMLRPC_STRTOULL strtoull
+#elif HAVE_STRTOUQ
+ # define XMLRPC_STRTOULL strtouq /* Interix */
+#elif HAVE___STRTOULL
+ # define XMLRPC_STRTOULL __strtoull /* HP-UX <= 11.11 */
+#elif HAVE__STRTOUI64
+ #define XMLRPC_STRTOULL _strtoui64 /* Windows MSVC */
+#endif
#define snprintf _snprintf
#define popen _popen
-#define strtoll _strtoui64
-#define strtoull _strtoui64
#endif
diff --git a/libs/xmlrpc-c/lib/expat/gennmtab/gennmtab.dsp b/libs/xmlrpc-c/Windows/xmlrpcclient.dsp
similarity index 64%
rename from libs/xmlrpc-c/lib/expat/gennmtab/gennmtab.dsp
rename to libs/xmlrpc-c/Windows/xmlrpcclient.dsp
index 917dc44969..97061b0323 100644
--- a/libs/xmlrpc-c/lib/expat/gennmtab/gennmtab.dsp
+++ b/libs/xmlrpc-c/Windows/xmlrpcclient.dsp
@@ -1,34 +1,32 @@
-# Microsoft Developer Studio Project File - Name="gennmtab" - Package Owner=<4>
+# Microsoft Developer Studio Project File - Name="xmlrpcclient" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
-CFG=gennmtab - Win32 Release
+CFG=xmlrpcclient - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
-!MESSAGE NMAKE /f "gennmtab.mak".
+!MESSAGE NMAKE /f "xmlrpcclient.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
-!MESSAGE NMAKE /f "gennmtab.mak" CFG="gennmtab - Win32 Release"
+!MESSAGE NMAKE /f "xmlrpcclient.mak" CFG="xmlrpcclient - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
-!MESSAGE "gennmtab - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "gennmtab - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "xmlrpcclient - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "xmlrpcclient - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName "gennmtab"
-# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
-!IF "$(CFG)" == "gennmtab - Win32 Release"
+!IF "$(CFG)" == "xmlrpcclient - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
@@ -37,12 +35,13 @@ RSC=rc.exe
# PROP BASE Target_Dir "."
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release\gennmtab"
-# PROP Intermediate_Dir "Release\gennmtab"
+# PROP Output_Dir "Release\xmlrpcclient"
+# PROP Intermediate_Dir "Release\xmlrpcclient"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir "."
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /I "..\lib\util\include" /I "..\tools\lib\include" /I "..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
@@ -50,13 +49,9 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"..\..\..\Bin\gennmtab.exe"
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=..\..\..\Bin\gennmtab.exe >..\xmltok\nametab.h
-# End Special Build Tool
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wininet.lib /nologo /subsystem:console /machine:I386 /out:"..\bin\xmlrpcclient.exe"
-!ELSEIF "$(CFG)" == "gennmtab - Win32 Debug"
+!ELSEIF "$(CFG)" == "xmlrpcclient - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
@@ -65,12 +60,13 @@ PostBuild_Cmds=..\..\..\Bin\gennmtab.exe >..\xmltok\nametab.h
# PROP BASE Target_Dir "."
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug\gennmtab"
-# PROP Intermediate_Dir "Debug\gennmtab"
+# PROP Output_Dir "Debug\xmlrpcclient"
+# PROP Intermediate_Dir "Debug\xmlrpcclient"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir "."
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I ".." /I "..\lib\util\include" /I "..\tools\lib\include" /I "..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
@@ -78,24 +74,24 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\..\..\Bin\gennmtabD.exe"
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=..\..\..\Bin\gennmtabD.exe >..\xmltok\nametab.h
-# End Special Build Tool
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wininet.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\bin\xmlrpcclientD.exe"
!ENDIF
# Begin Target
-# Name "gennmtab - Win32 Release"
-# Name "gennmtab - Win32 Debug"
+# Name "xmlrpcclient - Win32 Release"
+# Name "xmlrpcclient - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
-SOURCE=.\gennmtab.c
+SOURCE=..\tools\xmlrpc\xmlrpc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\tools\lib\dumpvalue.c
# End Source File
# End Group
# Begin Group "Header Files"
diff --git a/libs/xmlrpc-c/Windows/xmlrpccpp.dsp b/libs/xmlrpc-c/Windows/xmlrpccpp.dsp
index fedf4e28f5..0ee50defd4 100644
--- a/libs/xmlrpc-c/Windows/xmlrpccpp.dsp
+++ b/libs/xmlrpc-c/Windows/xmlrpccpp.dsp
@@ -1,179 +1,182 @@
-# Microsoft Developer Studio Project File - Name="xmlrpccpp" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=xmlrpccpp - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "xmlrpccpp.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "xmlrpccpp.mak" CFG="xmlrpccpp - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "xmlrpccpp - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "xmlrpccpp - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "xmlrpccpp - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release\xmlrpccpp"
-# PROP Intermediate_Dir "Release\xmlrpccpp"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "../lib" /I "../lib/curl_transport" /I "../lib/util/include" /I "../include" /I ".." /I "../lib/expat/xmlparse" /I "../lib/abyss/src" /I "../lib/wininet_transport" /I "../.." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\xmlrpccpp.lib"
-
-!ELSEIF "$(CFG)" == "xmlrpccpp - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug\xmlrpccpp"
-# PROP Intermediate_Dir "Debug\xmlrpccpp"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /GR /Gm /GX /ZI /Od /I "../lib" /I "../lib/curl_transport" /I "../lib/util/include" /I "../include" /I ".." /I "../lib/expat/xmlparse" /I "../lib/abyss/src" /I "../lib/wininet_transport" /I "../.." /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\xmlrpccppD.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "xmlrpccpp - Win32 Release"
-# Name "xmlrpccpp - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc"
-# Begin Source File
-
-SOURCE=..\src\cpp\base64.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\client.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\client_simple.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\curl.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\env_wrap.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\fault.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\girerr.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\girmem.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\libwww.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\outcome.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\packetsocket.cpp
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\param_list.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\pstream.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\registry.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\server_abyss.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\server_pstream.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\value.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\wininet.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\xml.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\cpp\XmlRpcCpp.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\src\cpp\env_wrap.hpp
-# End Source File
-# End Group
-# End Target
-# End Project
+# Microsoft Developer Studio Project File - Name="xmlrpccpp" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=xmlrpccpp - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "xmlrpccpp.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "xmlrpccpp.mak" CFG="xmlrpccpp - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "xmlrpccpp - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "xmlrpccpp - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "xmlrpccpp - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release\xmlrpccpp"
+# PROP Intermediate_Dir "Release\xmlrpccpp"
+# PROP Target_Dir ""
+LINK32=link.exe -lib
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "../lib" /I "../lib/curl_transport" /I "../lib/util/include" /I "../include" /I ".." /I "../lib/expat/xmlparse" /I "../lib/abyss/src" /I "../lib/wininet_transport" /I "../.." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib\xmlrpccpp.lib"
+
+!ELSEIF "$(CFG)" == "xmlrpccpp - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug\xmlrpccpp"
+# PROP Intermediate_Dir "Debug\xmlrpccpp"
+# PROP Target_Dir ""
+LINK32=link.exe -lib
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /GR /Gm /GX /ZI /Od /I "../lib" /I "../lib/curl_transport" /I "../lib/util/include" /I "../include" /I ".." /I "../lib/expat/xmlparse" /I "../lib/abyss/src" /I "../lib/wininet_transport" /I "../.." /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "ABYSS_WIN32" /D "CURL_STATICLIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib\xmlrpccppD.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "xmlrpccpp - Win32 Release"
+# Name "xmlrpccpp - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc"
+# Begin Source File
+
+SOURCE=..\src\cpp\base64.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\client_simple.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\curl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\env_wrap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\fault.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\girerr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\girmem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\libwww.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\outcome.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\packetsocket.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\param_list.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\pstream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\server_abyss.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\server_pstream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\server_pstream_conn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\value.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\wininet.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\xml.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\cpp\XmlRpcCpp.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\src\cpp\env_wrap.hpp
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/libs/xmlrpc-c/Windows/xmltok.dsp b/libs/xmlrpc-c/Windows/xmltok.dsp
index eaaebde7ba..3c69d642d2 100644
--- a/libs/xmlrpc-c/Windows/xmltok.dsp
+++ b/libs/xmlrpc-c/Windows/xmltok.dsp
@@ -1,138 +1,138 @@
-# Microsoft Developer Studio Project File - Name="xmltok" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=xmltok - Win32 Release
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "xmltok.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "xmltok.mak" CFG="xmltok - Win32 Release"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "xmltok - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "xmltok - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "xmltok - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\Release"
-# PROP BASE Intermediate_Dir ".\Release"
-# PROP BASE Target_Dir "."
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release\xmltok"
-# PROP Intermediate_Dir "Release\xmltok"
-# PROP Target_Dir "."
-MTL=midl.exe
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /D "NDEBUG" /D "XML_NS" /D "WIN32" /D "_WINDOWS" /D "XML_DTD" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\xmltok.lib"
-
-!ELSEIF "$(CFG)" == "xmltok - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\Debug"
-# PROP BASE Intermediate_Dir ".\Debug"
-# PROP BASE Target_Dir "."
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug\xmltok"
-# PROP Intermediate_Dir "Debug\xmltok"
-# PROP Target_Dir "."
-MTL=midl.exe
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I ".." /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "XML_DTD" /D "XML_NS" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib\xmltokD.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "xmltok - Win32 Release"
-# Name "xmltok - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
-# Begin Source File
-
-SOURCE=..\lib\expat\xmltok\xmlrole.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\expat\xmltok\xmltok.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
-# Begin Source File
-
-SOURCE=..\lib\expat\xmltok\asciitab.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\expat\xmltok\iasciitab.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\expat\xmltok\latin1tab.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\expat\xmltok\nametab.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\expat\xmltok\utf8tab.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\expat\xmltok\xmldef.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\expat\xmltok\xmlrole.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\lib\expat\xmltok\xmltok.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
+# Microsoft Developer Studio Project File - Name="xmltok" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=xmltok - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "xmltok.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "xmltok.mak" CFG="xmltok - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "xmltok - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "xmltok - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "xmltok - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir ".\Release"
+# PROP BASE Intermediate_Dir ".\Release"
+# PROP BASE Target_Dir "."
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release\xmltok"
+# PROP Intermediate_Dir "Release\xmltok"
+# PROP Target_Dir "."
+MTL=midl.exe
+LINK32=link.exe -lib
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /I "..\lib\util\include" /D "NDEBUG" /D "XML_NS" /D "WIN32" /D "_WINDOWS" /D "XML_DTD" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib\xmltok.lib"
+
+!ELSEIF "$(CFG)" == "xmltok - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir ".\Debug"
+# PROP BASE Intermediate_Dir ".\Debug"
+# PROP BASE Target_Dir "."
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug\xmltok"
+# PROP Intermediate_Dir "Debug\xmltok"
+# PROP Target_Dir "."
+MTL=midl.exe
+LINK32=link.exe -lib
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I ".." /I "..\lib\util\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "XML_DTD" /D "XML_NS" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib\xmltokD.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "xmltok - Win32 Release"
+# Name "xmltok - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
+# Begin Source File
+
+SOURCE=..\lib\expat\xmltok\xmlrole.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\expat\xmltok\xmltok.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
+# Begin Source File
+
+SOURCE=..\lib\expat\xmltok\asciitab.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\expat\xmltok\iasciitab.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\expat\xmltok\latin1tab.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\expat\xmltok\nametab.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\expat\xmltok\utf8tab.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\expat\xmltok\xmldef.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\expat\xmltok\xmlrole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\lib\expat\xmltok\xmltok.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/libs/xmlrpc-c/common.mk b/libs/xmlrpc-c/common.mk
index 5b89fa1ff0..a20bf429da 100644
--- a/libs/xmlrpc-c/common.mk
+++ b/libs/xmlrpc-c/common.mk
@@ -9,7 +9,7 @@
# SRCDIR: Name of directory which is the top of the Xmlrpc-c source tree.
# BLDDIR: Name of directory which is the top of the Xmlrpc-c build tree.
-include $(SRCDIR)/Makefile.version
+include $(SRCDIR)/version.mk
# .DELETE_ON_ERROR is a special predefined Make target that says to delete
# the target if a command in the rule for it fails. That's important,
@@ -17,13 +17,27 @@ include $(SRCDIR)/Makefile.version
# fully made.
.DELETE_ON_ERROR:
-GCC_WARNINGS = -Wall -Wundef -Wimplicit -W -Winline -Wundef
+GCC_WARNINGS = -Wall -W -Wno-uninitialized -Wundef -Wimplicit -Winline \
+ -Wno-unknown-pragmas
# We need -Wwrite-strings after we fix all the missing consts
+ #
+ # -Wuninitialized catches some great bugs, but it also flags a whole lot
+ # of perfectly good code that can't be written any better. Too bad there's
+ # no way to annotate particular variables as being OK, so we could turn
+ # on -Wuninitialized for all the others.
GCC_C_WARNINGS = $(GCC_WARNINGS) \
-Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes
-GCC_CXX_WARNINGS = $(GCC_WARNINGS) -Woverloaded-virtual -Wsynth
+GCC_CXX_WARNINGS = $(GCC_WARNINGS) -Wsynth
+
+# Before 09.05.20, we had -Woverloaded-virtual, but it doesn't seem to do
+# anything useful. It causes a warning that a method was hidden, but
+# experiments show nothing is actually hidden. The GCC manual's description
+# of what it does does not match empirical evidence. The option causes
+# warnings when a derived class of xmlrpc_c::method2 overrides one of the
+# execute() methods and not the other (as cpp/test/registry.cpp does), but the
+# code works fine.
# The NDEBUG macro says not to build code that assumes there are no bugs.
# This makes the code go faster. The main thing it does is tell the C library
@@ -55,12 +69,21 @@ ifeq ($(CURDIR)x,x)
CURDIR := $(shell /bin/pwd)
endif
+# The package XmlRpc++ on Sourceforge includes a library named
+# libxmlrpc++ just as Xmlrpc-c does. To use them both, you may need
+# to rename one. To rename the Xmlrpc-c one, set the make variable
+# LIBXMLRPCPP_NAME, e.g. on the 'make' command line.
+
+ifeq ($(LIBXMLRPCPP_NAME),)
+ LIBXMLRPCPP_NAME := xmlrpc++
+endif
+
##############################################################################
# STATIC LINK LIBRARY RULES #
##############################################################################
-# To use this rule, the including make file must set a target_specific
+# To use this rule, the including make file must set a target-specific
# variable LIBOBJECTS (and declare dependencies that include LIBOBJECTS).
# Example:
# FOO_OBJECTS = foo1.o foo2.o
@@ -81,19 +104,19 @@ $(TARGET_STATIC_LIBRARIES):
##############################################################################
ifeq ($(SHARED_LIB_TYPE),unix)
- include $(SRCDIR)/unix-common.make
+ include $(SRCDIR)/unix-common.mk
endif
ifeq ($(SHARED_LIB_TYPE),irix)
- include $(SRCDIR)/irix-common.make
+ include $(SRCDIR)/irix-common.mk
endif
ifeq ($(SHARED_LIB_TYPE),dll)
- include $(SRCDIR)/dll-common.make
+ include $(SRCDIR)/dll-common.mk
endif
ifeq ($(SHARED_LIB_TYPE),dylib)
- include $(SRCDIR)/dylib-common.make
+ include $(SRCDIR)/dylib-common.mk
endif
ifeq ($(SHARED_LIB_TYPE),NONE)
@@ -127,10 +150,10 @@ endif
#------ the actual rules ----------------------------------------------------
$(TARGET_SHARED_LIBRARIES) dummyshlib:
- $(CCLD) $(LDFLAGS_SHLIB) $(LIBDEP) -o $@ $(LIBOBJECTS) $(LADD)
+ $(CCLD) $(LADD) $(LDFLAGS_SHLIB) $(LIBOBJECTS) $(LIBDEP) -o $@
$(TARGET_SHARED_LIBS_PP) dummyshlibpp:
- $(CXXLD) $(LDFLAGS_SHLIB) $(LIBDEP) -o $@ $(LIBOBJECTS) $(LADD)
+ $(CXXLD) $(LADD) $(LDFLAGS_SHLIB) $(LIBOBJECTS) $(LIBDEP) -o $@
#----------------------------------------------------------------------------
LIBXMLRPC_UTIL_DIR = $(BLDDIR)/lib/libutil
@@ -186,7 +209,6 @@ LIBXMLRPC_ABYSS = \
LIBXMLRPC_ABYSS_A = $(LIBXMLRPC_ABYSS_DIR)/libxmlrpc_abyss.a
endif
-ifneq ($(OMIT_CPP_LIB_RULES),Y)
LIBXMLRPC_CPP = \
$(call shliblefn, $(BLDDIR)/src/cpp/libxmlrpc_cpp)
LIBXMLRPC_CPP_A = $(BLDDIR)/src/cpp/libxmlrpc_cpp.a
@@ -208,7 +230,6 @@ LIBXMLRPC_SERVER_ABYSSPP_A = $(BLDDIR)/src/cpp/libxmlrpc_server_abyss++.a
LIBXMLRPC_SERVER_PSTREAMPP = \
$(call shliblefn, $(BLDDIR)/src/cpp/libxmlrpc_server_pstream++)
LIBXMLRPC_SERVER_PSTREAMPP_A = $(BLDDIR)/src/cpp/libxmlrpc_server_pstream++.a
-endif
# LIBXMLRPC_XML is the list of Xmlrpc-c libraries we need to parse
# XML. If we're using an external library to parse XML, this is null.
@@ -239,31 +260,41 @@ endif
# foo.o foo.osh: INCLUDES = -Iinclude -I/usr/include/foostuff
# bar.o bar.osh: INCLUDES = -Iinclude -I/usr/include/barstuff
#
-# include Makefile.common
+# include common.mk
#
# The above generates rules to build foo.o, bar.o, foo.osh, and bar.osh
#
# For C++ source files, use TARGET_MODS_PP instead.
-# CFLAGS and CXXFLAGS are designed to be overridden on the make command
-# line. We pile all the options except -I into these variables so the
-# user can override them all if he wants.
+# CFLAGS and CXXFLAGS are designed to be picked up as environment
+# variables. The user may use them to add inclusion search directories
+# (-I) or control 32/64 bitness or the like. Using these is always
+# iffy, because the options one might include can interact in unpredictable
+# ways with what the make file is trying to do. But at least some users
+# get useful results.
+
+CFLAGS_ALL = $(CFLAGS_COMMON) $(CFLAGS_LOCAL) $(CFLAGS) \
+ $(INCLUDES) $(CFLAGS_PERSONAL) $(CADD)
+
+CXXFLAGS_ALL = $(CXXFLAGS_COMMON) $(CFLAGS_LOCAL) $(CXXFLAGS) \
+ $(INCLUDES) $(CFLAGS_PERSONAL) $(CADD)
+
$(TARGET_MODS:%=%.o):%.o:%.c
- $(CC) -c -o $@ $(INCLUDES) $(CFLAGS) $<
+ $(CC) -c -o $@ $(CFLAGS_ALL) $<
$(TARGET_MODS:%=%.osh): CFLAGS_COMMON += $(CFLAGS_SHLIB)
$(TARGET_MODS:%=%.osh):%.osh:%.c
- $(CC) -c -o $@ $(INCLUDES) $(CFLAGS) $(CFLAGS_SHLIB) $<
+ $(CC) -c -o $@ $(INCLUDES) $(CFLAGS_ALL) $(CFLAGS_SHLIB) $<
$(TARGET_MODS_PP:%=%.o):%.o:%.cpp
- $(CXX) -c -o $@ $(INCLUDES) $(CXXFLAGS) $<
+ $(CXX) -c -o $@ $(INCLUDES) $(CXXFLAGS_ALL) $<
$(TARGET_MODS_PP:%=%.osh): CXXFLAGS_COMMON += $(CFLAGS_SHLIB)
$(TARGET_MODS_PP:%=%.osh):%.osh:%.cpp
- $(CXX) -c -o $@ $(INCLUDES) $(CXXFLAGS) $<
+ $(CXX) -c -o $@ $(INCLUDES) $(CXXFLAGS_ALL) $<
##############################################################################
@@ -278,11 +309,6 @@ $(TARGET_MODS_PP:%=%.osh):%.osh:%.cpp
# to rebuild the symbolic link. So we don't make $(SRCDIR) a
# dependency of 'srcdir'.
-# We should do the same for 'blddir'. We did once before, then undid
-# it in an erroneous effort to enable parallel make. It's a little harder
-# with blddir; when we did it before, we had to use the non-symlink
-# version in a few places.
-
srcdir:
$(LN_S) $(SRCDIR) $@
blddir:
@@ -343,6 +369,12 @@ endif
ifneq ($(OMIT_CURL_TRANSPORT_RULE),Y)
$(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport.o \
$(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport.osh \
+$(BLDDIR)/lib/curl_transport/curltransaction.o \
+$(BLDDIR)/lib/curl_transport/curltransaction.osh \
+$(BLDDIR)/lib/curl_transport/curlmulti.o \
+$(BLDDIR)/lib/curl_transport/curlmulti.osh \
+$(BLDDIR)/lib/curl_transport/lock_pthread.o \
+$(BLDDIR)/lib/curl_transport/lock_pthread.osh \
: FORCE
$(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/curl_transport/Makefile \
$(notdir $@)
@@ -385,6 +417,8 @@ $(LIBXMLRPC_ABYSS) $(LIBXMLRPC_ABYSS_A): FORCE
$(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/abyss/src/Makefile \
$(notdir $@)
+ifneq ($(OMIT_CPP_LIB_RULES),Y)
+
$(LIBXMLRPCPP) $(LIBXMLRPCPP_A) \
$(LIBXMLRPC_PACKETSOCKET) $(LIBXMLRPC_PACKETSOCKET_A) \
$(LIBXMLRPC_CLIENTPP) $(LIBXMLRPC_CLIENTPP_A) \
@@ -394,6 +428,7 @@ $(LIBXMLRPC_SERVER_PSTREAMPP) $(LIBXMLRPC_SERVER_PSTREAMPP_A) \
$(LIBXMLRPC_CPP) $(LIBXMLRPC_CPP_A) : FORCE
$(MAKE) -C $(dir $@) -f $(SRCDIR)/src/cpp/Makefile \
$(notdir $@)
+endif
# For the following utilities, we don't bother with a library -- we
# just explicitly link the object file we need. This is to save
@@ -421,12 +456,12 @@ CASPRINTF = $(UTIL_DIR)/casprintf.o
# About version.h: This is a built header file, which means it is a supreme
# pain in the ass. The biggest problem is that when we automatically make
-# dependencies (Makefile.depend), it doesn't exist yet. This means Gcc
+# dependencies (depend.mk), it doesn't exist yet. This means Gcc
# generates a dependency on it being in the local directory. Therefore,
# we generate it in the local directory, as a symbolic link, wherever it
# is needed. But the original is always in the top level directory,
# generated by a rule in that directory's make file. Problem 2 is that
-# the top directory's make file includes Makefile.common, so the rules
+# the top directory's make file includes common.mk, so the rules
# below conflict with it. That's what OMIT_VERSION_H is for.
ifneq ($(OMIT_VERSION_H),Y)
@@ -471,10 +506,10 @@ $(SUBDIRS:%=$(CURDIR)/%):
MKINSTALLDIRS = $(SHELL) $(SRCDIR)/mkinstalldirs
-.PHONY: install-common install-ltlibraries install-headers install-bin
+.PHONY: install-common install-headers install-bin install-man
install-common: \
- install-ltlibraries install-static-libraries install-shared-libraries \
- install-headers install-bin
+ install-static-libraries install-shared-libraries \
+ install-headers install-bin install-man
INSTALL_LIB_CMD = $(INSTALL_DATA) $$p $(DESTDIR)$(LIBINST_DIR)/$$p
RANLIB_CMD = $(RANLIB) $(DESTDIR)$(LIBINST_DIR)/$$p
@@ -520,6 +555,16 @@ install-bin: $(PROGRAMS_TO_INSTALL) $(DESTDIR)$(PROGRAMINST_DIR)
$(DESTDIR)$(PROGRAMINST_DIR):
$(MKINSTALLDIRS) $@
+MANDESTDIR = $(DESTDIR)$(MANINST_DIR)
+INSTALL_MAN_CMD = $(INSTALL_DATA) $$p $(MANDESTDIR)/$$p
+
+install-man: $(MAN_FILES_TO_INSTALL)
+ $(MKINSTALLDIRS) $(MANDESTDIR)
+ @list='$(MAN_FILES_TO_INSTALL)'; \
+ for p in $$list; do \
+ echo "$(MAN_FILES_TO_INSTALL)"; \
+ $(INSTALL_MAN_CMD); \
+ done
##############################################################################
# MISCELLANEOUS RULES #
@@ -536,29 +581,30 @@ endif
.PHONY: distclean-common
distclean-common:
-# Makefile.depend is generated by 'make dep' and contains only dependencies
+# depend.mk is generated by 'make dep' and contains only dependencies
# that make parts get _rebuilt_ when parts upon which they depend change.
# It does not contain dependencies that are necessary to cause a part to
# get built in the first place. E.g. if foo.c uses bar.h and bar.h gets built
# by a make rule, you must put the dependency of foo.c on bar.h somewhere
-# besides Makefile.depend.
+# besides depend.mk.
#
-# Because of this, a user doesn't need Makefile.depend, because he
+# Because of this, a user doesn't need depend.mk, because he
# doesn't modify source files. A developer, on the other hand, must make his
-# own Makefile.depend, because 'make dep' creates Makefile.depend with
+# own depend.mk, because 'make dep' creates depend.mk with
# absolute pathnames, specific to the developer's system.
#
-# So we obliterate Makefile.depend here. The build will automatically
-# create an empty Makefile.depend when it is needed for the user. The
+# So we obliterate depend.mk here. The build will automatically
+# create an empty depend.mk when it is needed for the user. The
# developer must do 'make dep' if he wants to edit and rebuild.
#
# Other projects have the build automatically build a true
-# Makefile.depend, suitable for a developer. We have found that to be
+# depend.mk, suitable for a developer. We have found that to be
# an utter disaster -- it's way too complicated and prone to failure,
# especially with built .h files. Better not to burden the user, who
# gains nothing from it, with that.
#
- rm -f Makefile.depend
+ rm -f depend.mk
+ rm -f Makefile.depend # We used to create a file by this name
rm -f srcdir blddir
.PHONY: distdir-common
@@ -589,17 +635,17 @@ dep-common: FORCE
ifneq ($(DEP_SOURCES)x,x)
-$(CC) -MM -MG -I. $(INCLUDES) $(DEP_SOURCES) | \
$(DEPEND_MASSAGER) \
- >Makefile.depend
+ >depend.mk
endif
-Makefile.depend:
+depend.mk:
cat /dev/null >$@
# The automatic dependency generation is a pain in the butt and
# totally unnecessary for people just installing the distributed code,
# so to avoid needless failures in the field and a complex build, the
-# 'distclean' target simply makes Makefile.depend an empty file. A
-# developer may do 'make dep' to create a Makefile.depend full of real
+# 'distclean' target simply makes depend.mk an empty file. A
+# developer may do 'make dep' to create a depend.mk full of real
# dependencies.
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/libs/xmlrpc-c/conf/abyss_root/conf/abyss.conf b/libs/xmlrpc-c/conf/abyss_root/conf/abyss.conf
deleted file mode 100644
index f9c09f2a6d..0000000000
--- a/libs/xmlrpc-c/conf/abyss_root/conf/abyss.conf
+++ /dev/null
@@ -1,56 +0,0 @@
-# ABYSS Web Server configuration file
-# (C) Moez Mahfoudh - 2000
-
-# Cases in option names are ignored,
-# that means that PORT=port=PoRT=..
-
-# When writing paths, do not worry about / or \ use.
-# ABYSS will substitute / with \ on Win32 systems.
-
-# Options which are system specific (such as User) are
-# ignored on systems which do not handle them.
-
-# The Port option tells the server on which TCP port to listen.
-# default is 80
-Port 8080
-
-# The name or #number of the user to run the server as if it is
-# launched as root (UNIX specific)
-User nobody
-
-# The Server Root (UNIX systems style)
-ServerRoot conf/abyss_root
-
-# The Server Root (Win32 systems style)
-# ServerRoot G:\XML\xmlrpc-c-0.9.5\conf\abyss_root
-
-# The Path option specifies the web files path.
-Path htdocs
-
-# The Default option contains the name of the files the server should
-# look for when only a path is given (e.g. http://myserver/info/).
-Default index.html index.htm INDEX.HTM INDEX.HTML
-
-# The KeepAlive option is used to set the maximum number of requests
-# served using the same persistent connection.
-KeepAlive 10
-
-# The TimeOut option tells the server how much seconds to wait for
-# an idle connection before closing it.
-TimeOut 10
-
-# The MimeTypes option specifies the location of the file
-# containing the mapping of MIME types and files extensions
-MimeTypes conf/mime.types
-
-# The path of the log file
-LogFile log/access.log
-
-# The file where the pid of the server is logged (UNIX specific)
-PidFile log/abyss.pid
-
-# If AdvertiseServer if set to no, then no server field would be
-# appended to the responses. This is the way to make the server
-# identity unknown to some malicious people which can profit from
-# well known security holes in the software to crash it.
-AdvertiseServer yes
diff --git a/libs/xmlrpc-c/conf/abyss_root/conf/mime.types b/libs/xmlrpc-c/conf/abyss_root/conf/mime.types
deleted file mode 100644
index d53db0f4e8..0000000000
--- a/libs/xmlrpc-c/conf/abyss_root/conf/mime.types
+++ /dev/null
@@ -1,276 +0,0 @@
-# This is a comment. I love comments.
-
-# This file controls what Internet media types are sent to the client for
-# given file extension(s). Sending the correct media type to the client
-# is important so they know how to handle the content of the file.
-# Extra types can either be added here or by using an AddType directive
-# in your config files. For more information about Internet media types,
-# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
-# registry is at .
-
-# MIME type Extension
-application/EDI-Consent
-application/EDI-X12
-application/EDIFACT
-application/activemessage
-application/andrew-inset ez
-application/applefile
-application/atomicmail
-application/cals-1840
-application/commonground
-application/cybercash
-application/dca-rft
-application/dec-dx
-application/eshop
-application/hyperstudio
-application/iges
-application/mac-binhex40 hqx
-application/mac-compactpro cpt
-application/macwriteii
-application/marc
-application/mathematica
-application/msword doc
-application/news-message-id
-application/news-transmission
-application/octet-stream bin dms lha lzh exe class
-application/oda oda
-application/pdf pdf
-application/pgp-encrypted
-application/pgp-keys
-application/pgp-signature
-application/pkcs10
-application/pkcs7-mime
-application/pkcs7-signature
-application/postscript ai eps ps
-application/prs.alvestrand.titrax-sheet
-application/prs.cww
-application/prs.nprend
-application/remote-printing
-application/riscos
-application/rtf rtf
-application/set-payment
-application/set-payment-initiation
-application/set-registration
-application/set-registration-initiation
-application/sgml
-application/sgml-open-catalog
-application/slate
-application/smil smi smil
-application/vemmi
-application/vnd.3M.Post-it-Notes
-application/vnd.FloGraphIt
-application/vnd.acucobol
-application/vnd.anser-web-certificate-issue-initiation
-application/vnd.anser-web-funds-transfer-initiation
-application/vnd.audiograph
-application/vnd.businessobjects
-application/vnd.claymore
-application/vnd.comsocaller
-application/vnd.dna
-application/vnd.dxr
-application/vnd.ecdis-update
-application/vnd.ecowin.chart
-application/vnd.ecowin.filerequest
-application/vnd.ecowin.fileupdate
-application/vnd.ecowin.series
-application/vnd.ecowin.seriesrequest
-application/vnd.ecowin.seriesupdate
-application/vnd.enliven
-application/vnd.epson.salt
-application/vnd.fdf
-application/vnd.ffsns
-application/vnd.framemaker
-application/vnd.fujitsu.oasys
-application/vnd.fujitsu.oasys2
-application/vnd.fujitsu.oasys3
-application/vnd.fujitsu.oasysgp
-application/vnd.fujitsu.oasysprs
-application/vnd.fujixerox.docuworks
-application/vnd.hp-HPGL
-application/vnd.hp-PCL
-application/vnd.hp-PCLXL
-application/vnd.hp-hps
-application/vnd.ibm.MiniPay
-application/vnd.ibm.modcap
-application/vnd.intercon.formnet
-application/vnd.intertrust.digibox
-application/vnd.intertrust.nncp
-application/vnd.is-xpr
-application/vnd.japannet-directory-service
-application/vnd.japannet-jpnstore-wakeup
-application/vnd.japannet-payment-wakeup
-application/vnd.japannet-registration
-application/vnd.japannet-registration-wakeup
-application/vnd.japannet-setstore-wakeup
-application/vnd.japannet-verification
-application/vnd.japannet-verification-wakeup
-application/vnd.koan
-application/vnd.lotus-1-2-3
-application/vnd.lotus-approach
-application/vnd.lotus-freelance
-application/vnd.lotus-organizer
-application/vnd.lotus-screencam
-application/vnd.lotus-wordpro
-application/vnd.meridian-slingshot
-application/vnd.mif mif
-application/vnd.minisoft-hp3000-save
-application/vnd.mitsubishi.misty-guard.trustweb
-application/vnd.ms-artgalry
-application/vnd.ms-asf
-application/vnd.ms-excel xls
-application/vnd.ms-powerpoint ppt
-application/vnd.ms-project
-application/vnd.ms-tnef
-application/vnd.ms-works
-application/vnd.music-niff
-application/vnd.musician
-application/vnd.netfpx
-application/vnd.noblenet-directory
-application/vnd.noblenet-sealer
-application/vnd.noblenet-web
-application/vnd.novadigm.EDM
-application/vnd.novadigm.EDX
-application/vnd.novadigm.EXT
-application/vnd.osa.netdeploy
-application/vnd.powerbuilder6
-application/vnd.powerbuilder6-s
-application/vnd.rapid
-application/vnd.seemail
-application/vnd.shana.informed.formtemplate
-application/vnd.shana.informed.interchange
-application/vnd.shana.informed.package
-application/vnd.street-stream
-application/vnd.svd
-application/vnd.swiftview-ics
-application/vnd.truedoc
-application/vnd.visio
-application/vnd.webturbo
-application/vnd.wrq-hp3000-labelled
-application/vnd.wt.stf
-application/vnd.xara
-application/vnd.yellowriver-custom-menu
-application/wita
-application/wordperfect5.1
-application/x-bcpio bcpio
-application/x-cdlink vcd
-application/x-chess-pgn pgn
-application/x-compress
-application/x-cpio cpio
-application/x-csh csh
-application/x-director dcr dir dxr
-application/x-dvi dvi
-application/x-futuresplash spl
-application/x-gtar gtar
-application/x-gzip
-application/x-hdf hdf
-application/x-javascript js
-application/x-koan skp skd skt skm
-application/x-latex latex
-application/x-netcdf nc cdf
-application/x-sh sh
-application/x-shar shar
-application/x-shockwave-flash swf
-application/x-stuffit sit
-application/x-sv4cpio sv4cpio
-application/x-sv4crc sv4crc
-application/x-tar tar
-application/x-tcl tcl
-application/x-tex tex
-application/x-texinfo texinfo texi
-application/x-troff t tr roff
-application/x-troff-man man
-application/x-troff-me me
-application/x-troff-ms ms
-application/x-ustar ustar
-application/x-wais-source src
-application/x400-bp
-application/xml
-application/zip zip
-audio/32kadpcm
-audio/basic au snd
-audio/midi mid midi kar
-audio/mpeg mpga mp2 mp3
-audio/vnd.qcelp
-audio/x-aiff aif aiff aifc
-audio/x-pn-realaudio ram rm
-audio/x-pn-realaudio-plugin rpm
-audio/x-realaudio ra
-audio/x-wav wav
-chemical/x-pdb pdb xyz
-image/bmp bmp
-image/cgm
-image/g3fax
-image/gif gif
-image/ief ief
-image/jpeg jpeg jpg jpe
-image/naplps
-image/png png
-image/prs.btif
-image/tiff tiff tif
-image/vnd.dwg
-image/vnd.dxf
-image/vnd.fpx
-image/vnd.net-fpx
-image/vnd.svf
-image/vnd.xiff
-image/x-cmu-raster ras
-image/x-portable-anymap pnm
-image/x-portable-bitmap pbm
-image/x-portable-graymap pgm
-image/x-portable-pixmap ppm
-image/x-rgb rgb
-image/x-xbitmap xbm
-image/x-xpixmap xpm
-image/x-xwindowdump xwd
-message/delivery-status
-message/disposition-notification
-message/external-body
-message/http
-message/news
-message/partial
-message/rfc822
-model/iges igs iges
-model/mesh msh mesh silo
-model/vnd.dwf
-model/vrml wrl vrml
-multipart/alternative
-multipart/appledouble
-multipart/byteranges
-multipart/digest
-multipart/encrypted
-multipart/form-data
-multipart/header-set
-multipart/mixed
-multipart/parallel
-multipart/related
-multipart/report
-multipart/signed
-multipart/voice-message
-text/css css
-text/directory
-text/enriched
-text/html html htm
-text/plain asc txt
-text/prs.lines.tag
-text/rfc822-headers
-text/richtext rtx
-text/rtf rtf
-text/sgml sgml sgm
-text/tab-separated-values tsv
-text/uri-list
-text/vnd.abc
-text/vnd.flatland.3dml
-text/vnd.fmi.flexstor
-text/vnd.in3d.3dml
-text/vnd.in3d.spot
-text/vnd.latex-z
-text/x-setext etx
-text/xml xml
-video/mpeg mpeg mpg mpe
-video/quicktime qt mov
-video/vnd.motorola.video
-video/vnd.motorola.videop
-video/vnd.vivo
-video/x-msvideo avi
-video/x-sgi-movie movie
-x-conference/x-cooltalk ice
diff --git a/libs/xmlrpc-c/conf/abyss_root/htdocs/index.htm b/libs/xmlrpc-c/conf/abyss_root/htdocs/index.htm
deleted file mode 100644
index f0369a5503..0000000000
--- a/libs/xmlrpc-c/conf/abyss_root/htdocs/index.htm
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-ABYSS is working !!!
-
-
-
Congratulations, ABYSS is working !!!
-
-
-ABYSS Web Server is working correctly on your system. You should now change this
-page with yours.
-
-Please include in your web pages (at least the first), the 'Powered by ABYSS'
-banner to promote the use of ABYSS.
-
-
diff --git a/libs/xmlrpc-c/config.mk.in b/libs/xmlrpc-c/config.mk.in
index b583e6e661..bebfa54046 100644
--- a/libs/xmlrpc-c/config.mk.in
+++ b/libs/xmlrpc-c/config.mk.in
@@ -27,16 +27,15 @@ ENABLE_LIBXML2_BACKEND = @ENABLE_LIBXML2_BACKEND@
MUST_BUILD_WININET_CLIENT = @MUST_BUILD_WININET_CLIENT@
MUST_BUILD_CURL_CLIENT = @MUST_BUILD_CURL_CLIENT@
MUST_BUILD_LIBWWW_CLIENT = @MUST_BUILD_LIBWWW_CLIENT@
+BUILD_TOOLS = @BUILD_TOOLS@
+BUILD_XMLRPC_PSTREAM = @BUILD_XMLRPC_PSTREAM@
LSOCKET = @LSOCKET@
WININET_LDADD = @WININET_LDADD@
-WININET_RPATH = @WININET_RPATH@
-WININET_WL_RPATH = @WININET_WL_RPATH@
+WININET_LIBDIR = @WININET_LIBDIR@
CURL_LDADD = @CURL_LDADD@
-CURL_RPATH = @CURL_RPATH@
-CURL_WL_RPATH = @CURL_WL_RPATH@
+CURL_LIBDIR = @CURL_LIBDIR@
LIBWWW_LDADD = @LIBWWW_LDADD@
-LIBWWW_RPATH = @LIBWWW_RPATH@
-LIBWWW_WL_RPATH = @LIBWWW_WL_RPATH@
+LIBWWW_LIBDIR = @LIBWWW_LIBDIR@
FEATURE_LIST = @FEATURE_LIST@
ABS_SRCDIR = @abs_srcdir@
PREFIX = @prefix@
@@ -164,7 +163,10 @@ MUST_BUILD_SHLIBLE = N
shlibfn = $(1:%=%.shlibdummy)
shliblefn = $(1:%=%.shlibledummy)
-ifeq ($(HOST_OS),linux-gnu)
+# HOST_OS is usually has a version number suffix, e.g. "aix5.3.0.0", so
+# we compare based on prefix.
+
+ifeq ($(patsubst linux-gnu%,linux-gnu,$(HOST_OS)),linux-gnu)
# Assume linker is GNU Compiler (gcc)
SHARED_LIB_TYPE = unix
MUST_BUILD_SHLIB = Y
@@ -177,20 +179,28 @@ ifeq ($(HOST_OS),linux-gnu)
CFLAGS_SHLIB=-fPIC
endif
-ifeq ($(findstring solaris,$(HOST_OS)),solaris)
+ifeq ($(patsubst solaris%,solaris,$(HOST_OS)),solaris)
SHARED_LIB_TYPE = unix
MUST_BUILD_SHLIB = Y
MUST_BUILD_SHLIBLE = Y
SHLIB_SUFFIX = so
shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN))
shliblefn = $(1:%=%.$(SHLIB_SUFFIX))
+ # We assume Sun compiler and linker here. It isn't clear what to do
+ # about a user who uses GNU compiler and Ld instead. For that, the
+ # options should be the same as "linux-gnu" platform, above, except
+ # with NEED_WL_RPATH. If the user uses the GNU compiler but the Sun
+ # linker, it's even more complicated: we need an rpath option of the
+ # form -Wl,-R .
+
# Solaris compiler (Sun C 5.5) can't take multiple ld options as
# -Wl,-a,-b . Ld sees -a,-b in that case.
LDFLAGS_SHLIB = -Wl,-Bdynamic -Wl,-G -Wl,-h -Wl,$(SONAME)
CFLAGS_SHLIB = -Kpic
+ NEED_RPATH=yes
endif
-ifeq ($(HOST_OS),aix)
+ifeq ($(patsubst aix%,aix,$(HOST_OS)),aix)
SHARED_LIB_TYPE = unix
MUST_BUILD_SHLIB = Y
MUST_BUILD_SHLIBLE = Y
@@ -200,7 +210,7 @@ ifeq ($(HOST_OS),aix)
LDFLAGS_SHLIB = -qmkshrobj
endif
-ifeq ($(HOST_OS),hpux)
+ifeq ($(patsubst hpux%,hpux,$(HOST_OS)),hpux)
SHARED_LIB_TYPE = unix
MUST_BUILD_SHLIB = Y
MUST_BUILD_SHLIBLE = Y
@@ -210,7 +220,7 @@ ifeq ($(HOST_OS),hpux)
LDFLAGS_SHLIB: -shared -fPIC
endif
-ifeq ($(HOST_OS),osf)
+ifeq ($(patsubst osf%,osf,$(HOST_OS)),osf)
SHARED_LIB_TYPE = unix
MUST_BUILD_SHLIB = Y
MUST_BUILD_SHLIBLE = Y
@@ -220,7 +230,7 @@ ifeq ($(HOST_OS),osf)
LDFLAGS_SHLIB = -shared -expect_unresolved
endif
-ifeq ($(findstring netbsd,$(HOST_OS)),netbsd)
+ifeq ($(patsubst netbsd%,netbsd,$(HOST_OS)),netbsd)
SHARED_LIB_TYPE = unix
SHLIB_SUFFIX = so
MUST_BUILD_SHLIB = Y
@@ -232,7 +242,31 @@ ifeq ($(findstring netbsd,$(HOST_OS)),netbsd)
NEED_WL_RPATH=yes
endif
-ifeq ($(HOST_OS),dragonfly)
+ifeq ($(patsubst freebsd%,freebsd,$(HOST_OS)),freebsd)
+ SHARED_LIB_TYPE = unix
+ SHLIB_SUFFIX = so
+ MUST_BUILD_SHLIB = Y
+ MUST_BUILD_SHLIBLE = Y
+ shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN))
+ shliblefn = $(1:%=%.$(SHLIB_SUFFIX))
+ CFLAGS_SHLIB = -fpic
+ LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB)
+ NEED_WL_RPATH=yes
+endif
+
+ifeq ($(findstring interix,$(HOST_OS)),interix)
+ SHARED_LIB_TYPE = unix
+ SHLIB_SUFFIX = so
+ MUST_BUILD_SHLIB = Y
+ MUST_BUILD_SHLIBLE = Y
+ shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN))
+ shliblefn = $(1:%=%.$(SHLIB_SUFFIX))
+ CFLAGS_SHLIB =
+ LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB)
+ NEED_WL_RPATH=yes
+endif
+
+ifeq ($(patsubst dragonfly%,dragonfly,$(HOST_OS)),dragonfly)
SHARED_LIB_TYPE = unix
MUST_BUILD_SHLIB = Y
MUST_BUILD_SHLIBLE = Y
@@ -243,7 +277,7 @@ ifeq ($(HOST_OS),dragonfly)
LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB)
endif
-ifeq ($(HOST_OS),beos)
+ifeq ($(patsubst beos%,beos,$(HOST_OS)),beos)
SHARED_LIB_TYPE = unix
MUST_BUILD_SHLIB = Y
MUST_BUILD_SHLIBLE = Y
@@ -253,18 +287,18 @@ ifeq ($(HOST_OS),beos)
LDFLAGS_SHLIB = -nostart
endif
-ifeq ($(patsubst darwin%, darwin, $(HOST_OS)), darwin)
- # (I once saw a system that generated 'darwin8.10.1').
+ifeq ($(patsubst darwin%,darwin,$(HOST_OS)),darwin)
SHARED_LIB_TYPE = dylib
MUST_BUILD_SHLIB = Y
MUST_BUILD_SHLIBLE = Y
SHLIB_SUFFIX = dylib
shlibfn = $(1:%=%.$(MAJ).$(MIN).$(SHLIB_SUFFIX))
shliblefn = $(1:%=%.$(SHLIB_SUFFIX))
- LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB)
+ LDFLAGS_SHLIB = -dynamiclib -undefined suppress -single_module \
+ -flat_namespace $(SHLIB_CLIB)
endif
-ifeq ($(HOST_OS),irix)
+ifeq ($(patsubst irix%,irix,$(HOST_OS)),irix)
SHARED_LIB_TYPE = irix
MUST_BUILD_SHLIB = Y
MUST_BUILD_SHLIBLE = Y
@@ -278,13 +312,13 @@ ifeq ($(HOST_OS),irix)
-set_version $(shell perl -e '$(VERSIONPERLPROG)') -lc
endif
-ifeq ($(HOST_OS),cygwin)
+ifeq ($(patsubst cygwin%,cygwin,$(HOST_OS)),cygwin)
SHARED_LIB_TYPE = dll
MUST_BUILD_SHLIB = Y
MUST_BUILD_SHLIBLE = N
SHLIB_SUFFIX = dll
- shlibfn = $(1:lib%=$(SHLIB_PREFIX)%.$(SHLIB_SUFFIX).$(MAJ).$(MIN))
- shliblefn = $(1:%=%.shlibledummy)
+ shlibfn = $(1:%=%.$(SHLIB_SUFFIX))
+ shliblefn = $(1:%=%.$(SHLIB_SUFFIX))
LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB)
endif
@@ -293,12 +327,12 @@ endif
##############################################################################
# BUILDTOOL_CC is the compiler to use to generate build tools, which we
-# will then run to build product. The typical reason this would be
+# will then run to build the product. The typical reason this would be
# different from CC is that you're cross-compiling: the product will run
# in Environment A, but you're building in Environment B, so you must
-# build the build toos for Environment B.
+# build the build tools for Environment B.
-# The cross compiling user can update Makefile.config or override
+# The cross compiling user can update config.mk or override
# BUILDTOOL_CC on a make command.
BUILDTOOL_CC = $(CC)
@@ -316,9 +350,18 @@ INSTALL_SCRIPT = $(INSTALL) -c -m 755
# PREFIX is designed to be overridden at make time if the user decides
# he doesn't like the default specified at 'configure' time.
-LIBINST_DIR = $(PREFIX)/lib
-HEADERINST_DIR = $(PREFIX)/include
-PROGRAMINST_DIR = $(PREFIX)/bin
+prefix = $(PREFIX)
+
+#datarootdir is the new Autoconf(2.60) name for datadir, which is still
+#accepted, but a warning is issued if datarootdir is not also used.
+
+exec_prefix = @exec_prefix@
+DATAROOT_DIR = @datarootdir@
+DATAINST_DIR = @datadir@
+LIBINST_DIR = @libdir@
+HEADERINST_DIR = @includedir@
+PROGRAMINST_DIR = @bindir@
+MANINST_DIR = @mandir@/man1
# DESTDIR is designed to be overridden at make time in order to relocate
# the entire install into a subdirectory.
diff --git a/libs/xmlrpc-c/configure.gnu b/libs/xmlrpc-c/configure.gnu
deleted file mode 100644
index dda9b7dde0..0000000000
--- a/libs/xmlrpc-c/configure.gnu
+++ /dev/null
@@ -1,4 +0,0 @@
-#! /bin/sh
-srcpath=$(dirname $0 2>/dev/null ) || srcpath="."
-$srcpath/configure "$@" --disable-cplusplus --disable-wininet-client --disable-libwww-client --disable-shared --with-pic --disable-curl-client
-
diff --git a/libs/xmlrpc-c/configure.in b/libs/xmlrpc-c/configure.in
index 231a1d3bbd..8fbe80a739 100644
--- a/libs/xmlrpc-c/configure.in
+++ b/libs/xmlrpc-c/configure.in
@@ -86,10 +86,45 @@ AC_MSG_RESULT($MUST_BUILD_LIBWWW_CLIENT)
AC_SUBST(MUST_BUILD_LIBWWW_CLIENT)
+AC_ARG_ENABLE(tools,
+ [ --enable-tools Build the tools], ,
+[enable_tools=no])
+
+# The first AC_CHECK_LIB has to be in unconditional code because as a
+# side effect, it determines what the object file suffix is on this system,
+# and if it is statically present even though not actually executed, Autoconf
+# later thinks it has already computed the object file suffix and uses it
+# without computing it. This was with Autoconf 2.59
+AC_CHECK_LIB(ncurses, main, [have_libncurses=yes], [have_libncurses=no])
+AC_CHECK_LIB(readline, main, [have_libreadline=yes], [have_libreadline=no])
+
+AC_MSG_CHECKING(whether to build tools)
+
+BUILD_XMLRPC_PSTREAM=no
+
+if test $enable_tools = yes; then
+ if ! test "$MUST_BUILD_WININET_CLIENT $MUST_BUILD_CURL_CLIENT $MUST_BUILD_LIBWWW_CLIENT" = "no no no"; then
+ if test $have_libreadline = yes && test $have_libncurses = yes; then
+ BUILD_XMLRPC_PSTREAM=yes
+ fi
+ BUILD_TOOLS=yes
+ fi
+else
+ BUILD_TOOLS=$enable_tools
+fi
+
+AC_MSG_RESULT($BUILD_TOOLS)
+AC_SUBST(BUILD_TOOLS)
+
+if test $BUILD_TOOLS = yes; then
+ AC_MSG_CHECKING(whether to build the xmlrpc_pstream tool)
+ AC_MSG_RESULT($BUILD_XMLRPC_PSTREAM)
+ AC_SUBST(BUILD_XMLRPC_PSTREAM)
+fi
+
+
dnl Set up the appropriate Makefile substitutions.
-LIBXMLRPC_CLIENT_LA=libxmlrpc_client.la
-AC_SUBST(LIBXMLRPC_CLIENT_LA)
CLIENTTEST=clienttest
AC_SUBST(CLIENTTEST)
XMLRPC_CLIENT_H=xmlrpc_client.h
@@ -126,7 +161,6 @@ AC_SUBST(ENABLE_ABYSS_SERVER)
dnl Set up the appropriate Makefile substitutions.
ABYSS_SUBDIR=
-LIBXMLRPC_ABYSS_SERVER_LA=
SERVERTEST=
VALIDATEE=
XMLRPC_ABYSS_H=
@@ -134,14 +168,12 @@ SERVER=
if test x"$enable_abyss_server" != xno; then
FEATURE_LIST="abyss-server $FEATURE_LIST"
ABYSS_SUBDIR=abyss
- LIBXMLRPC_ABYSS_SERVER_LA=libxmlrpc_abyss_server.la
SERVERTEST=servertest
VALIDATEE=validatee
XMLRPC_ABYSS_H=xmlrpc_abyss.h
SERVER=server
fi
AC_SUBST(ABYSS_SUBDIR)
-AC_SUBST(LIBXMLRPC_ABYSS_SERVER_LA)
AC_SUBST(SERVERTEST)
AC_SUBST(VALIDATEE)
AC_SUBST(XMLRPC_ABYSS_H)
@@ -198,7 +230,9 @@ dnl Checks for programs.
dnl =======================================================================
AC_PROG_CC
-AC_PROG_CXX
+if test x"$enable_cplusplus" != xno; then
+ AC_PROG_CXX
+fi
dnl =======================================================================
@@ -272,6 +306,14 @@ else
fi
AC_SUBST(HAVE_SYS_IOCTL_H_DEFINE)
+AC_CHECK_HEADERS(sys/select.h)
+if test x"$ac_cv_header_sys_select_h" = xyes; then
+ HAVE_SYS_SELECT_H_DEFINE=1
+else
+ HAVE_SYS_SELECT_H_DEFINE=0
+fi
+AC_SUBST(HAVE_SYS_SELECT_H_DEFINE)
+
AC_CHECK_HEADERS(stdarg.h, , [
AC_MSG_ERROR(stdarg.h is required to build this library)
@@ -329,7 +371,7 @@ AC_CHECK_FUNCS(setgroups)
AC_CHECK_FUNCS(asprintf)
-AC_CHECK_FUNCS(setenv)
+AC_CHECK_FUNCS(setenv strtoll strtoull strtoq strtouq __strtoll __strtoull)
dnl uclib doesn't have pselect
AC_CHECK_FUNCS(pselect)
@@ -380,22 +422,22 @@ dnl you will need to configure this way..
if test $MUST_BUILD_WININET_CLIENT = yes; then
- dnl You can control which of these gets chosen by fooling around with PATH.
+ dnl You can control which of these gets chosen by controlling PATH.
AC_PATH_PROGS(WININET_CONFIG, wininet-xmlrpc-config wininet-config, no)
if test "x$WININET_CONFIG" = "xno"; then
- AC_MSG_ERROR(wininet lib not found; see './configure --help')
+ AC_MSG_ERROR(Configure INTERNAL ERROR - first wininet-config found, then not found)
fi
dnl Get our wininet version.
dnl Adapted from a macro which called gtk-config.
AC_MSG_CHECKING(for wininet version >= 1.0.0)
- W3VER=`$WININET_CONFIG --version`
+ W3VER=$($WININET_CONFIG --version)
WININET_MAJOR=\
-`echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/')
WININET_MINOR=\
-`echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/')
WININET_MICRO=\
-`echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
+$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/')
AC_MSG_RESULT($WININET_MAJOR.$WININET_MINOR.$WININET_MICRO)
dnl Check to make sure our version is OK.
@@ -417,61 +459,44 @@ if test $MUST_BUILD_WININET_CLIENT = yes; then
fi
dnl Get the necessary CFLAGS, and merge them into our master list.
- WININET_CFLAGS="`$WININET_CONFIG --cflags`"
+ WININET_CFLAGS=$($WININET_CONFIG --cflags)
AC_SUBST(WININET_CFLAGS)
CFLAGS="$CFLAGS $WININET_CFLAGS"
dnl Get the huge list of libraries we need to link against.
- WININET_LDADD="`$WININET_CONFIG --libs`"
+ WININET_LDADD=$($WININET_CONFIG --libs)
AC_SUBST(WININET_LDADD)
- dnl Oh, such massive brain damage! Because there may be another copy
- dnl of libwww in the default dynamic loader search path, we need to
- dnl adjust the search patch manually. Just gag me with a backquote, OK?
AC_MSG_CHECKING(for wininet library directory)
- if $WININET_CONFIG --rpath-dir > /dev/null 2>&1; then
- dnl Yay! We're using our smart version of wininet.
- WININET_LIBDIR="`$WININET_CONFIG --rpath-dir`"
- else
- dnl Yawn. We're using the regular boring version.
- WININET_LIBDIR="`$WININET_CONFIG --prefix`/lib"
- fi
+ WININET_LIBDIR="$($WININET_CONFIG --prefix)/lib"
AC_MSG_RESULT($WININET_LIBDIR)
AC_SUBST(WININET_LIBDIR)
- WININET_RPATH="-rpath $WININET_LIBDIR"
- AC_SUBST(WININET_RPATH)
- WININET_WL_RPATH="-Wl,--rpath -Wl,$WININET_LIBDIR"
- AC_SUBST(WININET_WL_RPATH)
fi # MUST_BUILD_WININET_CLIENT
dnl =======================================================================
dnl Finding w3c-libwww
dnl =======================================================================
-dnl Once upon a time, we used a patched copy of libwww that needed to
-dnl co-exist with the system copy of libwww. We have some vestigal function
-dnl for keeping track of libwww's rpath, although this is no longer really
-dnl necessary.
if test $MUST_BUILD_LIBWWW_CLIENT = yes; then
- dnl First of all, locate the semi-broken libwww config program.
- dnl You can control which of these gets chosen by fooling around with PATH.
+ dnl First of all, locate the libwww config program.
+ dnl You can control which of these gets chosen by controlling PATH.
AC_PATH_PROGS(LIBWWW_CONFIG, libwww-xmlrpc-config libwww-config, no)
if test "x$LIBWWW_CONFIG" = "xno"; then
- AC_MSG_ERROR(w3c-libwww not found; see './configure --help')
+ AC_MSG_ERROR(Configure INTERNAL ERROR - first libwww-config found, then not found)
fi
dnl Get our libwww version.
dnl Adapted from a macro which called gtk-config.
AC_MSG_CHECKING(for w3c-libwww version >= 5.2.8)
- W3VER=`$LIBWWW_CONFIG --version`
+ W3VER=$($LIBWWW_CONFIG --version)
LIBWWW_MAJOR=\
-`echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/')
LIBWWW_MINOR=\
-`echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/')
LIBWWW_MICRO=\
-`echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
+$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/')
AC_MSG_RESULT($LIBWWW_MAJOR.$LIBWWW_MINOR.$LIBWWW_MICRO)
dnl Check to make sure our version is OK.
@@ -493,78 +518,46 @@ if test $MUST_BUILD_LIBWWW_CLIENT = yes; then
fi
dnl Get the huge list of libraries we need to link against.
- LIBWWW_LDADD="`$LIBWWW_CONFIG --libs`"
+ LIBWWW_LDADD=$(LIBWWW_CONFIG --libs)
AC_SUBST(LIBWWW_LDADD)
- dnl Oh, such massive brain damage! Because there may be another copy
- dnl of libwww in the default dynamic loader search path, we need to
- dnl adjust the search patch manually. Just gag me with a backquote, OK?
AC_MSG_CHECKING(for libwww library directory)
- if $LIBWWW_CONFIG --rpath-dir > /dev/null 2>&1; then
- dnl Yay! We're using our smart version of libwww.
- LIBWWW_LIBDIR="`$LIBWWW_CONFIG --rpath-dir`"
- else
- dnl Yawn. We're using the regular boring version.
- LIBWWW_LIBDIR="`$LIBWWW_CONFIG --prefix`/lib"
- fi
+ LIBWWW_LIBDIR="$(LIBWWW_CONFIG --prefix)/lib"
AC_MSG_RESULT($LIBWWW_LIBDIR)
AC_SUBST(LIBWWW_LIBDIR)
- # Some ancient rpath stuff, now disabled. I turned this off because it
- # breaks Debian (and Mandrake?) policy, and we don't use it anymore.
- # If you have multiple copies of w3c-libwww lying around, you can turn
- # it back on.
- #LIBWWW_RPATH="-rpath $LIBWWW_LIBDIR"
- LIBWWW_RPATH=""
- AC_SUBST(LIBWWW_RPATH)
- #LIBWWW_WL_RPATH="-Wl,--rpath -Wl,$LIBWWW_LIBDIR"
- LIBWWW_WL_RPATH=""
- AC_SUBST(LIBWWW_WL_RPATH)
-
fi # MUST_BUILD_LIBWWW_CLIENT
dnl =======================================================================
-dnl Finding cURL
+dnl Finding Curl
dnl =======================================================================
if test $MUST_BUILD_CURL_CLIENT = yes; then
- dnl First of all, locate the curl config program.
- dnl You can control which of these gets chosen by fooling around with PATH.
+ dnl First of all, locate the Curl config program.
+ dnl You can control which of these gets chosen by controlling PATH.
AC_PATH_PROGS(CURL_CONFIG, curl-xmlrpc-config curl-config, no)
if test "x$CURL_CONFIG" = "xno"; then
- AC_MSG_ERROR(cURL not found; see './configure --help')
+ AC_MSG_ERROR(Configure INTERNAL ERROR - first curl-config found, then not found)
fi
dnl There used to be code here to check the Curl version and make sure
dnl it is at least 7.8. But there were bugs both in the code and in
- dnl curl (curl-config --vernum, at least in older versios of Curl,
+ dnl curl (curl-config --vernum, at least in older versions of Curl,
dnl omits the leading zero). So it didn't work. Plus, checking version
dnl numbers isn't a good idea. Better to check for feature presence.
dnl So we don't do any check now. If we find out there's a problem with
dnl older Curls, we will revisit that.
- dnl Get the huge list of libraries we need to link against.
- dnl MRB-20010516-For some reason, curl-config
- dnl does not list itself '-lcurl'. 2004.12.12. It seems to do so
- dnl now.
- CURL_LDADD=`$CURL_CONFIG --libs`
+ CURL_LDADD=$($CURL_CONFIG --libs)
AC_SUBST(CURL_LDADD)
- dnl Oh, such massive brain damage! Because there may be another copy
- dnl of curl in the default dynamic loader search path, we need to
- dnl adjust the search path manually. Just gag me with a backquote, OK?
- AC_MSG_CHECKING(for curl library directory)
- dnl Yawn. We're using the regular boring version.
- CURL_LIBDIR="`$CURL_CONFIG --prefix`/lib"
+ AC_MSG_CHECKING(for Curl library directory)
+ CURL_LIBDIR="$($CURL_CONFIG --prefix)/lib"
AC_MSG_RESULT($CURL_LIBDIR)
AC_SUBST(CURL_LIBDIR)
- CURL_RPATH="-rpath $CURL_LIBDIR"
- AC_SUBST(CURL_RPATH)
- CURL_WL_RPATH="-Wl,--rpath -Wl,$CURL_LIBDIR"
- AC_SUBST(CURL_WL_RPATH)
fi # MUST_BUILD_CURL_CLIENT
@@ -620,7 +613,7 @@ CPP_WARN_FLAGS=
AC_SUBST(CPP_WARN_FLAGS)
-BUILDDIR=`pwd`
+BUILDDIR=$(pwd)
AC_SUBST(BUILDDIR)
@@ -632,7 +625,7 @@ dnl Note that AM_CONFIG_HEADER at the top of this file outputs another
dnl result: xmlrpc_amconfig.h .
AC_OUTPUT( \
- Makefile.srcdir \
+ srcdir.mk \
config.mk \
xmlrpc_config.h \
)
@@ -647,7 +640,9 @@ fi
if test "$MUST_BUILD_WININET_CLIENT $MUST_BUILD_CURL_CLIENT $MUST_BUILD_LIBWWW_CLIENT" = "no no no"; then
- AC_MSG_NOTICE([\n\n==>We are not building any client XML transport (see earlier messages explaining why), therefore WE WILL NOT BUILD THE CLIENT LIBRARY.])
+ AC_MSG_NOTICE([==>])
+ AC_MSG_NOTICE([==>We are not building any client XML transport (see earlier messages explaining why), therefore WE WILL NOT BUILD THE CLIENT LIBRARY.])
+ AC_MSG_NOTICE([==>])
fi
diff --git a/libs/xmlrpc-c/debian/README.Debian b/libs/xmlrpc-c/debian/README.Debian
deleted file mode 100644
index 830df77a30..0000000000
--- a/libs/xmlrpc-c/debian/README.Debian
+++ /dev/null
@@ -1,7 +0,0 @@
-xmlrpc-c for Debian
--------------------
-
-This is my first attempt at porting my RPM packages to Debian. User
-beware!
-
- -- Eric Kidd , Tue, 26 Jun 2001 12:39:39 -0400
diff --git a/libs/xmlrpc-c/debian/changelog b/libs/xmlrpc-c/debian/changelog
deleted file mode 100644
index 848fac8ad6..0000000000
--- a/libs/xmlrpc-c/debian/changelog
+++ /dev/null
@@ -1,22 +0,0 @@
-xmlrpc-c (0.9.10-1) unstable; urgency=low
-
- * Updated from new upstream release.
-
- -- Eric Kidd Sun, 1 Jul 2001 10:45:51 -0400
-
-xmlrpc-c (0.9.9-2) unstable; urgency=low
-
- * Added man pages.
- * Improved depends for xmlrpc-c-dev.
-
- -- Eric Kidd Wed, 27 Jun 2001 12:25:52 -0400
-
-xmlrpc-c (0.9.9-1) unstable; urgency=low
-
- * Initial Release.
-
- -- Eric Kidd Tue, 26 Jun 2001 12:39:39 -0400
-
-Local variables:
-mode: debian-changelog
-End:
diff --git a/libs/xmlrpc-c/debian/control b/libs/xmlrpc-c/debian/control
deleted file mode 100644
index 45bd0202e7..0000000000
--- a/libs/xmlrpc-c/debian/control
+++ /dev/null
@@ -1,30 +0,0 @@
-Source: xmlrpc-c
-Section: devel
-Priority: optional
-Maintainer: Eric Kidd
-Build-Depends: debhelper (>> 3.0.0), libwww0 (>= 5.3.2), libwww-dev (>= 5.3.2)
-Standards-Version: 3.5.2
-
-Package: xmlrpc-c0
-Architecture: any
-Depends: ${shlibs:Depends}
-Description: A library implementing XML-based remote procedure calls
- XML-RPC is a lightweight RPC protocol based on XML and HTTP. This package
- is used by XML-RPC clients and servers written in C and C++.
-
-Package: xmlrpc-c-dev
-Architecture: any
-Depends: xmlrpc-c0 (= ${Source-Version}), libc6-dev, libstdc++-dev, libfrontier-rpc-perl
-Description: Libraries and header files for developing XML-RPC applications
- Static libraries and header files for writing XML-RPC applications in C and
- C++.
-
-Package: xmlrpc-c-apps
-Architecture: any
-Depends: xmlrpc-c0 (= ${Source-Version}), ${shlibs:Depends}
-Description: Sample XML-RPC applications
- Some handy XML-RPC demo applications based on the Meerkat Open Wire Service
- (found at http://www.oreillynet.com/meerkat/). You can use 'query-meerkat' to
- perform a regex search on recent news items, or 'meerkat-app-list' to get
- a list of recent Linux software releases.
-
diff --git a/libs/xmlrpc-c/debian/copyright b/libs/xmlrpc-c/debian/copyright
deleted file mode 100644
index 8873b9dac0..0000000000
--- a/libs/xmlrpc-c/debian/copyright
+++ /dev/null
@@ -1,128 +0,0 @@
-This software package is covered by the XML-RPC C Library License.
-Additionally, certain parts of this library are derived from pre-existing
-code, which may carry its own license.
-
-In particular, the Expat Licence applies to the contents of the directory
-lib/expat, the ABYSS Web Server License applies to the contents of the
-directory lib/abyss and parts of the file src/xmlrpc_abyss.c, and the
-Python 1.5.2 license applies to parts of the file src/xmlrpc_base64.c.
-
-And as for the tools/ directory, you'll have to examine the licenses on
-your own.
-
-
- XML-RPC C Library License
- -------------------------
-
-Copyright (C) 2001 by First Peer, Inc. All rights reserved.
-Copyright (C) 2001 by Eric Kidd. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-
- Expat License
- -------------
-
-Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- ABYSS Web Server License
- ------------------------
-
-Copyright (C) 2000 by Moez Mahfoudh . All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-
-
- Python 1.5.2 License
- --------------------
-
-Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
-Amsterdam, The Netherlands.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the names of Stichting Mathematisch
-Centrum or CWI or Corporation for National Research Initiatives or
-CNRI not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-While CWI is the initial source for this software, a modified version
-is made available by the Corporation for National Research Initiatives
-(CNRI) at the Internet address ftp://ftp.python.org.
-
-STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
-CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
diff --git a/libs/xmlrpc-c/debian/postinst b/libs/xmlrpc-c/debian/postinst
deleted file mode 100644
index a7b0408cb9..0000000000
--- a/libs/xmlrpc-c/debian/postinst
+++ /dev/null
@@ -1,47 +0,0 @@
-#! /bin/sh
-# postinst script for xmlrpc-c
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-# * `configure'
-# * `abort-upgrade'
-# * `abort-remove' `in-favour'
-#
-# * `abort-deconfigure' `in-favour'
-# `removing'
-#
-# for details, see /usr/share/doc/packaging-manual/
-#
-# quoting from the policy:
-# Any necessary prompting should almost always be confined to the
-# post-installation script, and should be protected with a conditional
-# so that unnecessary prompting doesn't happen if a package's
-# installation fails and the `postinst' is called with `abort-upgrade',
-# `abort-remove' or `abort-deconfigure'.
-
-case "$1" in
- configure)
- ldconfig
- ;;
-
- abort-upgrade|abort-remove|abort-deconfigure)
-
- ;;
-
- *)
- echo "postinst called with unknown argument \`$1'" >&2
- exit 0
- ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/libs/xmlrpc-c/debian/postrm b/libs/xmlrpc-c/debian/postrm
deleted file mode 100644
index 3294e0a93e..0000000000
--- a/libs/xmlrpc-c/debian/postrm
+++ /dev/null
@@ -1,39 +0,0 @@
-#! /bin/sh
-# postrm script for xmlrpc-c
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-# * `remove'
-# * `purge'
-# * `upgrade'
-# * `failed-upgrade'
-# * `abort-install'
-# * `abort-install'
-# * `abort-upgrade'
-# * `disappear' overwrit>r>
-# for details, see /usr/share/doc/packaging-manual/
-
-case "$1" in
- remove)
- ldconfig
- ;;
-
- purge|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
-
- ;;
-
- *)
- echo "postrm called with unknown argument \`$1'" >&2
- exit 0
-
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-
diff --git a/libs/xmlrpc-c/debian/rules b/libs/xmlrpc-c/debian/rules
deleted file mode 100644
index c7c728cc7d..0000000000
--- a/libs/xmlrpc-c/debian/rules
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/make -f
-# Sample debian/rules that uses debhelper.
-# GNU copyright 1997 to 1999 by Joey Hess.
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-# This is the debhelper compatability version to use.
-export DH_COMPAT=3
-
-# shared library versions, option 1
-#version=2.0.5
-#major=2
-# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
-version=`ls src/.libs/lib*.so.* | \
- awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
-major=`ls src/.libs/lib*.so.* | \
- awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
-
-configure: configure-stamp
-configure-stamp:
- dh_testdir
- # Add here commands to configure the package.
- ./configure --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
-
- touch configure-stamp
-
-build: configure-stamp build-stamp
-build-stamp:
- dh_testdir
-
- # Add here commands to compile the package.
- $(MAKE)
- $(MAKE) check
-
- touch build-stamp
-
-clean:
- dh_testdir
- dh_testroot
- rm -f build-stamp configure-stamp
-
- # Add here commands to clean up after the build process.
- -$(MAKE) distclean
-
- dh_clean
-
-install: build
- dh_testdir
- dh_testroot
- dh_clean -k
- dh_installdirs
-
- # Add here commands to install the package into debian/tmp
- $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
-
-
-# Build architecture-independent files here.
-binary-indep: build install
-# We have nothing to do by default.
-
-# Build architecture-dependent files here.
-binary-arch: build install
- dh_testdir
- dh_testroot
- dh_movefiles
-
-# dh_installdebconf
- dh_installdocs
- dh_installexamples
- dh_installmenu
-# dh_installlogrotate
-# dh_installemacsen
-# dh_installpam
-# dh_installmime
-# dh_installinit
- dh_installcron
-# dh_installman debian/xmlrpc-c.7
-# dh_installman -p xmlrpc-c-dev debian/xml-rpc-api2cpp.1 debian/xml-rpc-api2txt.1 debian/xmlrpc-c-config.1
-# dh_installman -p xmlrpc-c-apps debian/meerkat-app-list.1 debian/query-meerkat.1
- dh_installinfo
-# dh_undocumented
- dh_installchangelogs
- dh_link
- dh_strip
- dh_compress
- dh_fixperms
- dh_makeshlibs
- dh_installdeb
-# dh_perl
- dh_shlibdeps -l"$(CURDIR)/debian/xmlrpc-c0/usr/lib/:$$LD_LIBRARY_PATH"
- dh_gencontrol
- dh_md5sums
- dh_builddeb
-
-binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/libs/xmlrpc-c/debian/xmlrpc-c-apps.files b/libs/xmlrpc-c/debian/xmlrpc-c-apps.files
deleted file mode 100644
index 3f005c61f2..0000000000
--- a/libs/xmlrpc-c/debian/xmlrpc-c-apps.files
+++ /dev/null
@@ -1,4 +0,0 @@
-usr/bin/query-meerkat
-usr/bin/meerkat-app-list
-usr/share/man/man1/query-meerkat.1
-usr/share/man/man1/meerkat-app-list.1
diff --git a/libs/xmlrpc-c/debian/xmlrpc-c-dev.files b/libs/xmlrpc-c/debian/xmlrpc-c-dev.files
deleted file mode 100644
index f1cc55d369..0000000000
--- a/libs/xmlrpc-c/debian/xmlrpc-c-dev.files
+++ /dev/null
@@ -1,10 +0,0 @@
-usr/bin/xmlrpc-c-config
-usr/bin/xml-rpc-api2txt
-usr/bin/xml-rpc-api2cpp
-usr/include/*
-usr/lib/lib*.a
-usr/lib/lib*.la
-usr/lib/lib*.so
-usr/share/man/man1/xmlrpc-c-config.1
-usr/share/man/man1/xml-rpc-api2txt.1
-usr/share/man/man1/xml-rpc-api2cpp.1
diff --git a/libs/xmlrpc-c/debian/xmlrpc-c0.docs b/libs/xmlrpc-c/debian/xmlrpc-c0.docs
deleted file mode 100644
index 6df52b918f..0000000000
--- a/libs/xmlrpc-c/debian/xmlrpc-c0.docs
+++ /dev/null
@@ -1,6 +0,0 @@
-BUGS
-NEWS
-README
-CREDITS
-SECURITY
-doc/*.txt
diff --git a/libs/xmlrpc-c/debian/xmlrpc-c0.examples b/libs/xmlrpc-c/debian/xmlrpc-c0.examples
deleted file mode 100644
index d510cc52a8..0000000000
--- a/libs/xmlrpc-c/debian/xmlrpc-c0.examples
+++ /dev/null
@@ -1,3 +0,0 @@
-examples/*.c
-examples/*.cc
-conf
diff --git a/libs/xmlrpc-c/debian/xmlrpc-c0.files b/libs/xmlrpc-c/debian/xmlrpc-c0.files
deleted file mode 100644
index 6f825921f5..0000000000
--- a/libs/xmlrpc-c/debian/xmlrpc-c0.files
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/lib/lib*.so.*
-usr/share/man/man7/xmlrpc-c.7
diff --git a/libs/xmlrpc-c/dll-common.make b/libs/xmlrpc-c/dll-common.mk
similarity index 61%
rename from libs/xmlrpc-c/dll-common.make
rename to libs/xmlrpc-c/dll-common.mk
index 0d53c17c4f..9840709b5e 100644
--- a/libs/xmlrpc-c/dll-common.make
+++ b/libs/xmlrpc-c/dll-common.mk
@@ -1,7 +1,7 @@
# -*-makefile-*- <-- an Emacs control
-# See unix-common.make for an explanation of this file. This file is
-# analogous to unix-common.make, but is for a Windows system
+# See unix-common.mk for an explanation of this file. This file is
+# analogous to unix-common.mk, but is for a Windows system
SONAME = $@
IMPLIB = $(@:%:%.dll.a)
@@ -17,6 +17,6 @@ SHLIB_INSTALL_TARGETS = $(SHARED_LIBS_TO_INSTALL:%=%/install)
install-shared-libraries: $(SHLIB_INSTALL_TARGETS)
-$(SHLIB_INSTALL_TARGETS):lib%/install:$(SHLIB_PREFIX)%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)
-# $< is a library file name, e.g. cygfoo.so.3.1 .
+$(SHLIB_INSTALL_TARGETS):%/install:%.$(SHLIB_SUFFIX)
+# $< is a library file name, e.g. libfoo.dll .
$(INSTALL_SHLIB) $< $(DESTDIR)$(LIBINST_DIR)/$<
diff --git a/libs/xmlrpc-c/doc/INSTALL b/libs/xmlrpc-c/doc/INSTALL
index 76881fa90c..2790010383 100644
--- a/libs/xmlrpc-c/doc/INSTALL
+++ b/libs/xmlrpc-c/doc/INSTALL
@@ -82,6 +82,48 @@ you have to have a -f option and set SRCDIR and BLDDIR on your 'make'
command.
+CROSS-COMPILING
+---------------
+
+Cross compiling is building code on one machine to be run on another,
+particularly when the two machines are different enough that it matters,
+e.g. one executes x86 instructions and the other executes PowerPC
+instructions.
+
+The machine that will run the code is called the target machine. The one
+that will build the code is the build machine.
+
+To cross-compile, you set up nearly all of the build environment for the
+target machine (that includes such things as the default include file search
+path for the compiler and library search path for the linker). On your
+'configure' command, you use a --host option to identify the kind of target
+machine (rather than let it default to the kind of machine on which
+'configure' is running). It's a nontrivial task, and beyond the scope of
+this document as it is not specific to Xmlrpc-c.
+
+There is one area that requires special attention and is specific to Xmlrpc-c:
+The Xmlrpc-c build does part of its job by compiling a program from C source
+code and running that program as part of the build. That compile, unlike all
+the regular ones, must be done for the build machine, not the target
+machine.
+
+To facilitate that, there are the BUILDTOOL_CC and BUILDTOOL_CCLD make
+variables. BUILDTOOL_CC is the command name for the appropriate compiler
+which which to build a build tool, i.e. a compiler that generates code to run
+on the build system. BUILDTOOL_CCLD is similarly for the linker, and should
+be the kind of linker command that invokes a combined compiler/linker,
+e.g. "gcc" instead of "ld".
+
+You can set these make variables on the Make command line, or if you prefer,
+by modifying the file 'config.mk' after 'configure' creates it. The default
+value of these variables (as set in 'config.mk') is the same compile and link
+commands as for building target code.
+
+(There is probably a way to do this with GNU Autoconf facilities and avoid the
+BUILDTOOL_CC complication. If you know how (without using Automake), tell the
+Xmlrpc-c maintainer and he will change the build system to use it).
+
+
COMMON PROBLEMS
---------------
@@ -135,7 +177,7 @@ to have it. The make file obviously specifies the path to the current
libraries that the user just built in the link library search order,
but the link is picking up the old system version instead. Why?
Because the link options say to search /usr/lib _before_ the local
-build directory. And it does that because curl-config erroneously
+build directory. And they do that because curl-config erroneously
says that you need a -L /usr/lib link option to find the Curl library.
diff --git a/libs/xmlrpc-c/dylib-common.make b/libs/xmlrpc-c/dylib-common.mk
similarity index 80%
rename from libs/xmlrpc-c/dylib-common.make
rename to libs/xmlrpc-c/dylib-common.mk
index a72d416690..c9ac6c50de 100644
--- a/libs/xmlrpc-c/dylib-common.make
+++ b/libs/xmlrpc-c/dylib-common.mk
@@ -1,13 +1,13 @@
# -*-makefile-*- <-- an Emacs control
-# See unix-common.make for an explanation of this file. This file is
-# analogous to unix-common.make, but is for an Irix system.
+# See unix-common.mk for an explanation of this file. This file is
+# analogous to unix-common.mk, but is for an Irix system.
SONAME = $(@:%.$(MIN)=%)
-SHLIB_CMD = $(CCLD) $(LDFLAGS_SHLIB) -o $@ $^ $(LADD)
+SHLIB_CMD = $(CCLD) $(LADD) $(LDFLAGS_SHLIB) -o $@ $^
-SHLIBPP_CMD = $(CXXLD) $(LDFLAGS_SHLIB) -o $@ $^ $(LADD)
+SHLIBPP_CMD = $(CXXLD) $(LADD) $(LDFLAGS_SHLIB) -o $@ $^
SHLIB_LE_TARGETS = $(call shliblefn, $(SHARED_LIBS_TO_BUILD))
diff --git a/libs/xmlrpc-c/examples/.cvsignore b/libs/xmlrpc-c/examples/.cvsignore
deleted file mode 100644
index 792265c708..0000000000
--- a/libs/xmlrpc-c/examples/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-gen_sample_add_xml
-meerkat-app-list
-query-meerkat
-synch_client
-xmlrpc_asynch_client
-auth_client
-xmlrpc_loop_server
-xmlrpc_sample_add_client
-xmlrpc_sample_add_server
-xmlrpc_server_validatee
-*.cgi
diff --git a/libs/xmlrpc-c/examples/Makefile b/libs/xmlrpc-c/examples/Makefile
index 5a9fd19de3..c441c9fbbd 100644
--- a/libs/xmlrpc-c/examples/Makefile
+++ b/libs/xmlrpc-c/examples/Makefile
@@ -1,8 +1,8 @@
-# Since the programs in this directories are examples for the user, this
-# make file should be as ordinary as possible. It should not rely heavily
-# on included make files or configuration parameters. It should not use
-# libtool. Also, we don't try to build or rebuild the libraries on which
-# these programs depend.
+# Since the programs in this directory are examples for the user, this make
+# file should be as ordinary as possible. It should not rely heavily on
+# included make files or configuration parameters. Also, we don't try to
+# build or rebuild the libraries on which these programs depend or even
+# recognize that they've changed on their own.
ifeq ($(SRCDIR),)
@@ -15,8 +15,8 @@ include $(BLDDIR)/config.mk
default: all
-CFLAGS = $(CFLAGS_COMMON) $(CFLAGS_PERSONAL) $(CADD)
-LDFLAGS = $(LADD)
+CFLAGS = $(CFLAGS_PERSONAL) $(CADD)
+LDFLAGS += $(LADD)
# If this were a real application, working from an installed copy of
# Xmlrpc-c, XMLRPC_C_CONFIG would just be 'xmlrpc-c-config'. It would be
@@ -25,6 +25,7 @@ XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test
CLIENTPROGS = \
auth_client \
+ compound_value_client \
synch_client \
xmlrpc_sample_add_client \
xmlrpc_asynch_client \
@@ -37,6 +38,7 @@ SERVERPROGS_CGI = \
xmlrpc_sample_add_server.cgi
SERVERPROGS_ABYSS = \
+ compound_value_server \
interrupted_server \
xmlrpc_inetd_server \
xmlrpc_socket_server \
@@ -44,15 +46,19 @@ SERVERPROGS_ABYSS = \
xmlrpc_sample_add_server \
xmlrpc_server_validatee \
+BASIC_PROGS = \
+ json \
+ gen_sample_add_xml \
+
# Build up PROGS:
PROGS =
+PROGS += $(BASIC_PROGS)
+
ifeq ($(ENABLE_ABYSS_SERVER),yes)
PROGS += $(SERVERPROGS_ABYSS)
endif
-PROGS += gen_sample_add_xml
-
ifeq ($(MUST_BUILD_CLIENT),yes)
PROGS += $(CLIENTPROGS)
endif
@@ -63,17 +69,17 @@ endif
INCLUDES = -I. $(shell $(XMLRPC_C_CONFIG) client abyss-server --cflags)
-LDADD_CLIENT = \
- $(shell $(XMLRPC_C_CONFIG) client --ldadd)
+LIBS_CLIENT = \
+ $(shell $(XMLRPC_C_CONFIG) client --libs)
-LDADD_SERVER_ABYSS = \
- $(shell $(XMLRPC_C_CONFIG) abyss-server --ldadd)
+LIBS_SERVER_ABYSS = \
+ $(shell $(XMLRPC_C_CONFIG) abyss-server --libs)
-LDADD_SERVER_CGI = \
- $(shell $(XMLRPC_C_CONFIG) cgi-server --ldadd)
+LIBS_SERVER_CGI = \
+ $(shell $(XMLRPC_C_CONFIG) cgi-server --libs)
-LDADD_BASE = \
- $(shell $(XMLRPC_C_CONFIG) --ldadd)
+LIBS_BASE = \
+ $(shell $(XMLRPC_C_CONFIG) --libs)
all: $(PROGS)
@@ -90,16 +96,17 @@ $(BLDDIR)/examples/cpp:
mkdir $@
$(CLIENTPROGS):%:%.o
- $(CCLD) -o $@ $(LDFLAGS) $^ $(LDADD_CLIENT)
+ $(CCLD) -o $@ $^ $(LIBS_CLIENT) $(LDFLAGS)
$(SERVERPROGS_CGI):%.cgi:%_cgi.o
- $(CCLD) -o $@ $(LDFLAGS) $^ $(LDADD_SERVER_CGI)
+ $(CCLD) -o $@ $^ $(LIBS_SERVER_CGI) $(LDFLAGS)
$(SERVERPROGS_ABYSS):%:%.o
- $(CCLD) -o $@ $(LDFLAGS) $^ $(LDADD_SERVER_ABYSS)
+ $(CCLD) -o $@ $^ $(LIBS_SERVER_ABYSS) $(LDFLAGS)
+
+$(BASIC_PROGS):%:%.o
+ $(CCLD) -o $@ $^ $(LIBS_BASE) $(LDFLAGS)
-gen_sample_add_xml:%:%.o
- $(CCLD) -o $@ $(LDFLAGS) $^ $(LDADD_BASE)
OBJECTS = $(patsubst %,%.o,$(patsubst %.cgi,%_cgi,$(PROGS)))
@@ -119,11 +126,9 @@ config.h:
xmlrpc_amconfig.h:
$(LN_S) $(BLDDIR)/$@ .
-include $(SRCDIR)/common.mk
-
.PHONY: clean
-clean: clean-common
- rm -f $(PROGS) config.h xmlrpc_amconfig.h
+clean:
+ rm -f $(PROGS) *.o config.h xmlrpc_amconfig.h
$(MAKE) -C cpp clean
.PHONY: distclean
diff --git a/libs/xmlrpc-c/examples/README b/libs/xmlrpc-c/examples/README
index 46b02b4fed..6691f8a62e 100644
--- a/libs/xmlrpc-c/examples/README
+++ b/libs/xmlrpc-c/examples/README
@@ -1,15 +1,12 @@
This directory contains working examples of uses of XML-RPC-c. There
are XML-RPC servers and XML-RPC clients that use the Xmlrpc-c libraries.
-The simplest example is the 'query-meerkat' program, which contacts an
-XML-RPC server that O'Reilly operates on the Internet called Meerkat.
-Meerkat provides an RPC that returns a list of new articles that match
-a specified search pattern. Run 'query-meerkat' like this example:
-
- $ ./query-meerkat Linux
-
-This responds with a list of new articles that contain the work "Linux",
-according to O'reilly's Meerkat service.
+The make file is a combination of an example of how to build programs
+that use Xmlrpc-c libraries and something that actually does build the
+programs in this directory. As such, it isn't perfect for either of
+those purposes. To build the examples, you must first build the
+libraries (make dependencies will not take care of that for you). Then
+you can issue a simple 'make' in this directory.
The simplest server program is 'xmlrpc_sample_add_server'. This
diff --git a/libs/xmlrpc-c/examples/auth_client.c b/libs/xmlrpc-c/examples/auth_client.c
index 50047f4ab4..fbbd0a98a9 100644
--- a/libs/xmlrpc-c/examples/auth_client.c
+++ b/libs/xmlrpc-c/examples/auth_client.c
@@ -35,7 +35,7 @@ die_if_fault_occurred(xmlrpc_env * const envP) {
int
main(int const argc,
- const char ** const argv ATTR_UNUSED) {
+ const char ** const argv) {
xmlrpc_env env;
xmlrpc_server_info * serverP;
diff --git a/libs/xmlrpc-c/examples/compound_value_client.c b/libs/xmlrpc-c/examples/compound_value_client.c
new file mode 100644
index 0000000000..92baad1e4f
--- /dev/null
+++ b/libs/xmlrpc-c/examples/compound_value_client.c
@@ -0,0 +1,161 @@
+/* An XML-RPC client program written in C, as an example of using
+ compound XML-RPC values.
+
+ For a simple client program that just deals with integer values,
+ see xmlrpc_sample_add_client.c. This example focuses just on the
+ compound XML-RPC values and not the client functions.
+
+ This client invokes the example.divide XML-RPC method that the example
+ server program compound_value_server.c provides. That method takes a
+ list of pairs of numbers and returns the list of their quotients.
+
+ Compound XML-RPC values are arrays and structures. We call them compound
+ because they are made up of other XML-RPC values (e.g. an array of XML-RPC
+ integers).
+
+ The arguments to the example.divide method are specified as follows:
+
+ There are two arguments:
+
+ Argument 0: Integer. Version number of this argument protocol. Must
+ be 1.
+
+
+ Argument 1: Array. One element for each pair of numbers you want the
+ server to divide. Each element is structure, with these
+ members:
+
+ KEY: "dividend"
+ VALUE: floating point number. The dividend.
+
+ KEY: "divisor"
+ VALUE: floating point number. The divisor.
+
+ The result of the method is an array. It has one member for each pair of
+ numbers in the arguments (So it is the same size as Argument 1). That
+ member is a floating point number. It is the quotient of the numbers
+ in the corresponding element of Argument 1.
+
+ The client sends the RPC to the server running on the local system
+ ("localhost"), HTTP Port 8080.
+*/
+
+#include
+#include
+
+#include
+#include
+
+#include "config.h" /* information about this build environment */
+
+#define NAME "Xmlrpc-c Test Client"
+#define VERSION "1.0"
+
+static void
+dieIfFaultOccurred (xmlrpc_env * const envP) {
+ if (envP->fault_occurred) {
+ fprintf(stderr, "ERROR: %s (%d)\n",
+ envP->fault_string, envP->fault_code);
+ exit(1);
+ }
+}
+
+
+
+struct ratio {
+ double dividend;
+ double divisor;
+};
+
+
+
+int
+main(int const argc,
+ const char ** const argv) {
+
+ const char * const serverUrl = "http://localhost:8080/RPC2";
+ const char * const methodName = "example.divide";
+ unsigned int const argVersion = 1;
+ struct ratio const data[] = {{1,2},{12,3},{10,3},{89,3000}};
+ xmlrpc_env env;
+ xmlrpc_value * resultP;
+ unsigned int i;
+ xmlrpc_value * ratioArrayP;
+ unsigned int quotientCt;
+
+ if (argc-1 > 0) {
+ fprintf(stderr, "This program has no arguments\n");
+ exit(1);
+ }
+
+ xmlrpc_env_init(&env);
+
+ xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0);
+ dieIfFaultOccurred(&env);
+
+ /* Build the 2nd method argument: the array of ratios */
+
+ ratioArrayP = xmlrpc_array_new(&env);
+ dieIfFaultOccurred(&env);
+
+ for (i = 0; i < 4; ++i) {
+ xmlrpc_value * dividendP;
+ xmlrpc_value * divisorP;
+ xmlrpc_value * ratioP;
+
+ dividendP = xmlrpc_double_new(&env, data[i].dividend);
+ dieIfFaultOccurred(&env);
+ divisorP = xmlrpc_double_new(&env, data[i].divisor);
+ dieIfFaultOccurred(&env);
+
+ ratioP = xmlrpc_struct_new(&env);
+ dieIfFaultOccurred(&env);
+
+ xmlrpc_struct_set_value(&env, ratioP, "DIVIDEND", dividendP);
+ dieIfFaultOccurred(&env);
+ xmlrpc_struct_set_value(&env, ratioP, "DIVISOR", divisorP);
+ dieIfFaultOccurred(&env);
+
+ xmlrpc_array_append_item(&env, ratioArrayP, ratioP);
+ dieIfFaultOccurred(&env);
+
+ xmlrpc_DECREF(ratioP);
+ xmlrpc_DECREF(divisorP);
+ xmlrpc_DECREF(dividendP);
+ }
+
+ /* Make the call */
+
+ resultP = xmlrpc_client_call(&env, serverUrl, methodName, "(iA)",
+ (xmlrpc_int32) argVersion, ratioArrayP);
+ dieIfFaultOccurred(&env);
+
+ /* Print out the quotients returned */
+
+ quotientCt = xmlrpc_array_size(&env, resultP);
+ dieIfFaultOccurred(&env);
+
+ for (i = 0; i < quotientCt; ++i) {
+ xmlrpc_value * quotientP;
+ xmlrpc_double quotient;
+
+ xmlrpc_array_read_item(&env, resultP, i, "ientP);
+ dieIfFaultOccurred(&env);
+
+ xmlrpc_read_double(&env, quotientP, "ient);
+ dieIfFaultOccurred(&env);
+
+ printf("Server says quotient %u is %f\n", i, quotient);
+
+ xmlrpc_DECREF(quotientP);
+ }
+
+ xmlrpc_DECREF(resultP);
+
+ xmlrpc_env_clean(&env);
+
+ xmlrpc_client_cleanup();
+
+ return 0;
+}
+
diff --git a/libs/xmlrpc-c/examples/compound_value_server.c b/libs/xmlrpc-c/examples/compound_value_server.c
new file mode 100644
index 0000000000..99d11276f8
--- /dev/null
+++ b/libs/xmlrpc-c/examples/compound_value_server.c
@@ -0,0 +1,199 @@
+/* An XML-RPC server program written in C, as an example of using
+ compound XML-RPC values.
+
+ For a simple server program that just deals with integer values,
+ see xmlrpc_sample_add_server.c. This example focuses just on the
+ compound XML-RPC values and not the server functions.
+
+ This server provides the example.divide XML-RPC method that the example
+ client program compound_value_client.c invokes. See that program for
+ details on what the method does.
+
+ The program takes one argument: the HTTP port number on which the server
+ is to accept connections, in decimal.
+
+ Example:
+
+ $ ./compound_value_server 8080&
+ $ ./compound_value_client
+*/
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include "config.h" /* information about this build environment */
+
+
+
+static void
+computeQuotient(xmlrpc_env * const envP,
+ xmlrpc_value * const ratioP,
+ xmlrpc_double * const quotientP) {
+
+ xmlrpc_value * dividendP;
+
+ xmlrpc_struct_find_value(envP, ratioP, "DIVIDEND", ÷ndP);
+
+ if (!envP->fault_occurred) {
+ if (!dividendP)
+ xmlrpc_env_set_fault(
+ envP, 0, "Structure is missing 'DIVIDEND' member");
+ else {
+ xmlrpc_value * divisorP;
+
+ xmlrpc_struct_find_value(envP, ratioP, "DIVISOR", &divisorP);
+
+ if (!envP->fault_occurred) {
+ if (!divisorP)
+ xmlrpc_env_set_fault(
+ envP, 0, "Structure is missing 'DIVISOR' member");
+ else {
+ xmlrpc_double dividend;
+
+ xmlrpc_read_double(envP, dividendP, ÷nd);
+
+ if (!envP->fault_occurred) {
+ xmlrpc_double divisor;
+
+ xmlrpc_read_double(envP, divisorP, &divisor);
+
+ if (!envP->fault_occurred)
+ *quotientP = dividend / divisor;
+ }
+ xmlrpc_DECREF(divisorP);
+ }
+ }
+ xmlrpc_DECREF(dividendP);
+ }
+ }
+}
+
+
+
+static void
+computeQuotients(xmlrpc_env * const envP,
+ xmlrpc_value * const ratioArrayP,
+ xmlrpc_value ** const quotientArrayPP) {
+
+ xmlrpc_value * quotientArrayP;
+
+ quotientArrayP = xmlrpc_array_new(envP);
+ if (!envP->fault_occurred) {
+
+ unsigned int const ratioCt = xmlrpc_array_size(envP, ratioArrayP);
+
+ unsigned int i;
+
+ for (i = 0; i < ratioCt && !envP->fault_occurred; ++i) {
+ xmlrpc_value * ratioP;
+
+ xmlrpc_array_read_item(envP, ratioArrayP, i, &ratioP);
+
+ if (!envP->fault_occurred) {
+ xmlrpc_double quotient;
+
+ computeQuotient(envP, ratioP, "ient);
+
+ if (!envP->fault_occurred) {
+ xmlrpc_value * quotientP;
+
+ quotientP = xmlrpc_double_new(envP, quotient);
+
+ if (!envP->fault_occurred) {
+ xmlrpc_array_append_item(envP, quotientArrayP,
+ quotientP);
+
+ xmlrpc_DECREF(quotientP);
+ }
+ }
+ xmlrpc_DECREF(ratioP);
+ }
+ }
+ if (envP->fault_occurred)
+ xmlrpc_DECREF(quotientArrayP);
+ else
+ *quotientArrayPP = quotientArrayP;
+ }
+}
+
+
+
+static xmlrpc_value *
+example_divide(xmlrpc_env * const envP,
+ xmlrpc_value * const paramArrayP,
+ void * const serverInfo,
+ void * const channelInfo) {
+
+ xmlrpc_value * retvalP;
+ xmlrpc_int32 argVersion;
+ xmlrpc_value * ratioArrayP;
+
+ xmlrpc_decompose_value(envP, paramArrayP, "(iA)",
+ &argVersion, &ratioArrayP);
+ if (envP->fault_occurred)
+ return NULL;
+
+ if (argVersion != 1) {
+ xmlrpc_env_set_fault(envP, 0, "Parameter list version must be 1");
+ return NULL;
+ }
+
+ computeQuotients(envP, ratioArrayP, &retvalP);
+
+ xmlrpc_DECREF(ratioArrayP);
+
+ if (envP->fault_occurred)
+ return NULL;
+
+ return retvalP;
+}
+
+
+
+int
+main(int const argc,
+ const char ** const argv) {
+
+ struct xmlrpc_method_info3 const methodInfo = {
+ /* .methodName = */ "example.divide",
+ /* .methodFunction = */ &example_divide,
+ };
+ xmlrpc_server_abyss_parms serverparm;
+ xmlrpc_registry * registryP;
+ xmlrpc_env env;
+
+ if (argc-1 != 1) {
+ fprintf(stderr, "You must specify 1 argument: The TCP port "
+ "number on which the server will accept connections "
+ "for RPCs (8080 is a common choice). "
+ "You specified %d arguments.\n", argc-1);
+ exit(1);
+ }
+
+ xmlrpc_env_init(&env);
+
+ registryP = xmlrpc_registry_new(&env);
+
+ xmlrpc_registry_add_method3(&env, registryP, &methodInfo);
+
+ /* In the modern form of the Abyss API, we supply parameters in memory
+ like a normal API. We select the modern form by setting
+ config_file_name to NULL:
+ */
+ serverparm.config_file_name = NULL;
+ serverparm.registryP = registryP;
+ serverparm.port_number = atoi(argv[1]);
+ serverparm.log_file_name = "/tmp/xmlrpc_log";
+
+ printf("Running XML-RPC server...\n");
+
+ xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name));
+
+ /* xmlrpc_server_abyss() never returns */
+
+ return 0;
+}
diff --git a/libs/xmlrpc-c/examples/cpp/.cvsignore b/libs/xmlrpc-c/examples/cpp/.cvsignore
deleted file mode 100644
index fedad6b608..0000000000
--- a/libs/xmlrpc-c/examples/cpp/.cvsignore
+++ /dev/null
@@ -1,4 +0,0 @@
-meerkat-app-list
-xmlrpc_sample_add_server
-xmlrpc_sample_add_client
-sample_add_client_complex
diff --git a/libs/xmlrpc-c/examples/cpp/Makefile b/libs/xmlrpc-c/examples/cpp/Makefile
index 1c8b930dd3..18798cb022 100644
--- a/libs/xmlrpc-c/examples/cpp/Makefile
+++ b/libs/xmlrpc-c/examples/cpp/Makefile
@@ -15,8 +15,8 @@ include $(BLDDIR)/config.mk
default: all
-CXXFLAGS = $(CXXFLAGS_COMMON) $(CFLAGS_PERSONAL) $(CADD)
-LDFLAGS = $(LADD)
+CXXFLAGS = $(CFLAGS_PERSONAL) $(CADD)
+LDFLAGS += $(LADD)
# If this were a real application, working from an installed copy of
# Xmlrpc-c, XMLRPC_C_CONFIG would just be 'xmlrpc-c-config'. It would be
@@ -24,10 +24,14 @@ LDFLAGS = $(LADD)
XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test
+SERVERPROGS_CGI = \
+ xmlrpc_sample_add_server.cgi
+
SERVERPROGS_ABYSS = \
xmlrpc_inetd_server \
xmlrpc_loop_server \
xmlrpc_sample_add_server \
+ callinfo_abyss_server \
CLIENTPROGS = \
xmlrpc_sample_add_client \
@@ -45,7 +49,11 @@ ifeq ($(MUST_BUILD_CLIENT),yes)
PROGS += $(CLIENTPROGS)
endif
-PROGS += pstream_inetd_server
+ifeq ($(ENABLE_CGI_SERVER),yes)
+ PROGS += $(SERVERPROGS_CGI)
+endif
+
+PROGS += pstream_inetd_server pstream_serial_server
ifeq ($(MUST_BUILD_CLIENT),yes)
PROGS += pstream_client
@@ -53,37 +61,43 @@ endif
INCLUDES = -I. $(shell $(XMLRPC_C_CONFIG) c++2 client abyss-server --cflags)
-LDADD_SERVER_ABYSS = \
- $(shell $(XMLRPC_C_CONFIG) c++2 abyss-server --ldadd)
+LIBS_SERVER_ABYSS = \
+ $(shell $(XMLRPC_C_CONFIG) c++2 abyss-server --libs)
-LDADD_CLIENT = \
- $(shell $(XMLRPC_C_CONFIG) c++2 client --ldadd)
+LIBS_SERVER_CGI = \
+ $(shell $(XMLRPC_C_CONFIG) c++2 cgi-server --libs)
-LDADD_BASE = \
- $(shell $(XMLRPC_C_CONFIG) c++2 --ldadd)
+LIBS_CLIENT = \
+ $(shell $(XMLRPC_C_CONFIG) c++2 client --libs)
+
+LIBS_BASE = \
+ $(shell $(XMLRPC_C_CONFIG) c++2 --libs)
all: $(PROGS)
+$(SERVERPROGS_CGI):%.cgi:%_cgi.o
+ $(CXXLD) -o $@ $^ $(LIBS_SERVER_CGI) $(LDFLAGS)
+
$(SERVERPROGS_ABYSS):%:%.o
- $(CXXLD) -o $@ $(LDFLAGS) $^ $(LDADD_SERVER_ABYSS)
+ $(CXXLD) -o $@ $^ $(LIBS_SERVER_ABYSS) $(LDFLAGS)
$(CLIENTPROGS):%:%.o
- $(CXXLD) -o $@ $(LDFLAGS) $^ $(LDADD_CLIENT)
+ $(CXXLD) -o $@ $^ $(LIBS_CLIENT) $(LDFLAGS)
-LDADD_PSTREAM_CLIENT = \
- $(shell $(XMLRPC_C_CONFIG) c++2 client --ldadd)
+LIBS_PSTREAM_CLIENT = \
+ $(shell $(XMLRPC_C_CONFIG) c++2 client --libs)
pstream_client:%:%.o
- $(CXXLD) -o $@ $(LDFLAGS) $^ $(LDADD_PSTREAM_CLIENT)
+ $(CXXLD) -o $@ $^ $(LIBS_PSTREAM_CLIENT) $(LDFLAGS)
-LDADD_PSTREAM_SERVER = \
- $(shell $(XMLRPC_C_CONFIG) c++2 pstream-server --ldadd)
+LIBS_PSTREAM_SERVER = \
+ $(shell $(XMLRPC_C_CONFIG) c++2 pstream-server --libs)
-pstream_inetd_server:%:%.o
- $(CXXLD) -o $@ $(LDFLAGS) $^ $(LDADD_PSTREAM_SERVER)
+pstream_inetd_server pstream_serial_server:%:%.o
+ $(CXXLD) -o $@ $^ $(LIBS_PSTREAM_SERVER) $(LDFLAGS)
-OBJECTS = $(PROGS:%=%.o)
+OBJECTS = $(patsubst %,%.o,$(patsubst %.cgi,%_cgi,$(PROGS)))
$(OBJECTS):%.o:%.cpp
$(CXX) -c $(INCLUDES) $(CXXFLAGS) $<
@@ -97,11 +111,9 @@ config.h:
xmlrpc_amconfig.h:
$(LN_S) $(BLDDIR)/$@ .
-include $(SRCDIR)/common.mk
-
.PHONY: clean
-clean: clean-common
- rm -f $(PROGS) config.h xmlrpc_amconfig.h
+clean:
+ rm -f $(PROGS) *.o config.h xmlrpc_amconfig.h
.PHONY: distclean
distclean: clean
diff --git a/libs/xmlrpc-c/examples/cpp/callinfo_abyss_server.cpp b/libs/xmlrpc-c/examples/cpp/callinfo_abyss_server.cpp
new file mode 100644
index 0000000000..a297b8ea0a
--- /dev/null
+++ b/libs/xmlrpc-c/examples/cpp/callinfo_abyss_server.cpp
@@ -0,0 +1,133 @@
+// A simple standalone XML-RPC server written in C++.
+//
+// This server returns to the caller his IP address and port number,
+// as a demonstration of how to access such information.
+//
+// This works only on Unix (to wit, something that uses Abyss's
+// ChanSwitchUnix channel switch to accept TCP connections from clients).
+//
+// See xmlrpc_sample_add_server.cpp for a more basic example.
+//
+// To run this:
+//
+// $ ./callinfo_abyss_server &
+// $ xmlrpc localhost:8080 getCallInfo
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+
+struct tcpPortAddr {
+ unsigned char ipAddr[4];
+ unsigned short portNumber;
+};
+
+
+static struct tcpPortAddr
+tcpAddrFromSockAddr(struct sockaddr const sockAddr) {
+
+ const struct sockaddr_in * const sockAddrInP(
+ static_cast((void *)&sockAddr));
+
+ const unsigned char * const ipAddr(
+ static_cast(
+ (const void *)&sockAddrInP->sin_addr.s_addr)
+ ); // 4 byte array
+
+ assert(sockAddrInP->sin_family == AF_INET);
+
+ struct tcpPortAddr retval;
+
+ retval.ipAddr[0] = ipAddr[0];
+ retval.ipAddr[1] = ipAddr[1];
+ retval.ipAddr[2] = ipAddr[2];
+ retval.ipAddr[3] = ipAddr[3];
+ retval.portNumber = ntohs(sockAddrInP->sin_port);
+
+ return retval;
+}
+
+
+
+static std::string
+rpcIpAddrMsg(xmlrpc_c::callInfo_serverAbyss const& callInfo) {
+
+ void * chanInfoPtr;
+ SessionGetChannelInfo(callInfo.abyssSessionP, &chanInfoPtr);
+
+ struct abyss_unix_chaninfo * const chanInfoP(
+ static_cast(chanInfoPtr));
+
+ struct tcpPortAddr const tcpAddr(tcpAddrFromSockAddr(chanInfoP->peerAddr));
+
+ char msg[128];
+
+ sprintf(msg, "RPC is from IP address %u.%u.%u.%u, Port %hu",
+ tcpAddr.ipAddr[0],
+ tcpAddr.ipAddr[1],
+ tcpAddr.ipAddr[2],
+ tcpAddr.ipAddr[3],
+ tcpAddr.portNumber);
+
+ return std::string(msg);
+}
+
+
+
+class getCallInfoMethod : public xmlrpc_c::method2 {
+public:
+ void
+ execute(xmlrpc_c::paramList const& paramList,
+ const xmlrpc_c::callInfo * const callInfoPtr,
+ xmlrpc_c::value * const retvalP) {
+
+ const xmlrpc_c::callInfo_serverAbyss * const callInfoP(
+ dynamic_cast(callInfoPtr));
+
+ paramList.verifyEnd(0);
+
+ // Because this gets called via a xmlrpc_c::serverAbyss:
+ assert(callInfoP != NULL);
+
+ *retvalP = xmlrpc_c::value_string(rpcIpAddrMsg(*callInfoP));
+ }
+};
+
+
+
+int
+main(int const,
+ const char ** const) {
+
+ try {
+ xmlrpc_c::registry myRegistry;
+
+ xmlrpc_c::methodPtr const getCallInfoMethodP(new getCallInfoMethod);
+
+ myRegistry.addMethod("getCallInfo", getCallInfoMethodP);
+
+ xmlrpc_c::serverAbyss myAbyssServer(xmlrpc_c::serverAbyss::constrOpt()
+ .registryP(&myRegistry)
+ .portNumber(8080)
+ );
+
+ myAbyssServer.run();
+ // xmlrpc_c::serverAbyss.run() never returns
+ assert(false);
+ } catch (exception const& e) {
+ cerr << "Something failed. " << e.what() << endl;
+ }
+ return 0;
+}
diff --git a/libs/xmlrpc-c/examples/cpp/meerkat-app-list.cpp b/libs/xmlrpc-c/examples/cpp/meerkat-app-list.cpp
deleted file mode 100644
index c2bd1e3221..0000000000
--- a/libs/xmlrpc-c/examples/cpp/meerkat-app-list.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// List recently-released Linux applications. (Written in C++.)
-// For more details about O'Reilly's excellent Meerkat news service, see:
-// http://www.oreillynet.com/pub/a/rss/2000/11/14/meerkat_xmlrpc.html */
-
-#include
-#include
-#include
-
-using namespace std;
-
-#include
-
-#define NAME "XML-RPC C++ Meerkat Query Demo"
-#define VERSION "0.1"
-#define MEERKAT_URL "http://www.oreillynet.com/meerkat/xml-rpc/server.php"
-#define SOFTWARE_LINUX (6)
-
-static void list_apps (int hours) {
-
- // Build our time_period parameter.
- ostringstream time_period_stream;
- time_period_stream << hours << "HOUR";
- string time_period = time_period_stream.str();
-
- // Assemble our meerkat query recipe.
- XmlRpcValue recipe = XmlRpcValue::makeStruct();
- recipe.structSetValue("category", XmlRpcValue::makeInt(SOFTWARE_LINUX));
- recipe.structSetValue("time_period", XmlRpcValue::makeString(time_period));
- recipe.structSetValue("descriptions", XmlRpcValue::makeInt(76));
-
- // Build our parameter array.
- XmlRpcValue param_array = XmlRpcValue::makeArray();
- param_array.arrayAppendItem(recipe);
-
- // Create a client pointing to Meerkat.
- XmlRpcClient meerkat (MEERKAT_URL);
-
- // Perform the query.
- XmlRpcValue apps = meerkat.call("meerkat.getItems", param_array);
-
- // Print our results.
- int first = 1;
- size_t app_count = apps.arraySize();
- for (size_t i = 0; i < app_count; i++) {
- XmlRpcValue app = apps.arrayGetItem(i);
-
- // Get some information about our application.
- string title = app.structGetValue("title").getString();
- string link = app.structGetValue("link").getString();
- string description = app.structGetValue("description").getString();
-
- // Print a separator line if necessary.
- if (first)
- first = 0;
- else
- cout << endl;
-
- // Print this application entry.
- if (description.size() > 0) {
- cout << title << endl << description << endl << link << endl;
- } else {
- cout << title << endl << description << endl << link << endl;
- }
- }
-}
-
-// Print out a usage message.
-static void usage (void)
-{
- cerr << "Usage: meekat-app-list [hours]" << endl;
- cerr << "Data from ." << endl;
- exit(1);
-}
-
-int main (int argc, char **argv) {
- int status = 0;
- int hours = 25;
-
- // Parse our command-line arguments.
- if (argc == 1) {
- // Use default value for hours.
- } else if (argc == 2) {
- hours = atoi(argv[1]);
- }
- if (hours == 0)
- usage();
- if (hours > 49) {
- cerr << "It's not nice to ask for > 49 hours at once." << endl;
- exit(1);
- }
-
- // Start up our client library.
- XmlRpcClient::Initialize(NAME, VERSION);
-
- // Call our implementation, and watch out for faults.
- try {
- list_apps(hours);
- } catch (XmlRpcFault& fault) {
- cerr << argv[0] << ": XML-RPC fault #" << fault.getFaultCode()
- << ": " << fault.getFaultString() << endl;
- status = 1;
- }
-
- // Shut down our client library.
- XmlRpcClient::Terminate();
-
- return status;
-}
diff --git a/libs/xmlrpc-c/examples/cpp/pstream_client.cpp b/libs/xmlrpc-c/examples/cpp/pstream_client.cpp
index 7a8f3224b5..738e8bad74 100644
--- a/libs/xmlrpc-c/examples/cpp/pstream_client.cpp
+++ b/libs/xmlrpc-c/examples/cpp/pstream_client.cpp
@@ -25,7 +25,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/libs/xmlrpc-c/examples/cpp/pstream_inetd_server.cpp b/libs/xmlrpc-c/examples/cpp/pstream_inetd_server.cpp
index 65f1aa5f4d..00d930c376 100644
--- a/libs/xmlrpc-c/examples/cpp/pstream_inetd_server.cpp
+++ b/libs/xmlrpc-c/examples/cpp/pstream_inetd_server.cpp
@@ -22,7 +22,7 @@
#endif
#include
#include
-#include
+#include
#include
#include
@@ -76,12 +76,7 @@ main(int const,
.socketFd(STDIN_FILENO)
.registryP(&myRegistry));
- for (bool clientHasDisconnected = false; !clientHasDisconnected;)
- server.runOnce(&clientHasDisconnected);
- // This reads one packet (containing an XML-RPC call message)
- // from Standard Input, executes the indicated RPC, and writes
- // one packet containing the XML-RPC response message to
- // Standard Input.
+ server.run();
} catch (exception const& e) {
cerr << "Something threw an error: " << e.what() << endl;
diff --git a/libs/xmlrpc-c/examples/cpp/pstream_serial_server.cpp b/libs/xmlrpc-c/examples/cpp/pstream_serial_server.cpp
new file mode 100644
index 0000000000..aba2fbead9
--- /dev/null
+++ b/libs/xmlrpc-c/examples/cpp/pstream_serial_server.cpp
@@ -0,0 +1,84 @@
+/* A simple standalone RPC server based on an Xmlrpc-c packet socket.
+
+ This program expects the invoker to provide a socket in listen mode
+ as Standard Input.
+
+ This is not an XML-RPC server, because it uses a simple packet socket
+ instead of HTTP. See xmlrpc_sample_add_server.cpp for an example of
+ an XML-RPC server.
+
+ The advantage of this example over XML-RPC is that it has a connection
+ concept. The client can be connected indefinitely and the server gets
+ notified when the client terminates, even if it gets aborted by its OS.
+
+ Here's an example of running this:
+
+ $ socketexec -listen -local_port=8080 ./pstream_serial_server
+*/
+
+#ifndef WIN32
+#include
+#endif
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+using namespace std;
+
+
+class sampleAddMethod : public xmlrpc_c::method {
+public:
+ sampleAddMethod() {
+ // signature and help strings are documentation -- the client
+ // can query this information with a system.methodSignature and
+ // system.methodHelp RPC.
+ this->_signature = "i:ii"; // method's arguments are two integers
+ this->_help = "This method adds two integers together";
+ }
+ void
+ execute(xmlrpc_c::paramList const& paramList,
+ xmlrpc_c::value * const retvalP) {
+
+ int const addend(paramList.getInt(0));
+ int const adder(paramList.getInt(1));
+
+ paramList.verifyEnd(2);
+
+ *retvalP = xmlrpc_c::value_int(addend + adder);
+ }
+};
+
+
+
+int
+main(int const,
+ const char ** const) {
+
+ // It's a good idea to disable SIGPIPE signals; if client closes his end
+ // of the pipe/socket, we'd rather see a failure to send a response than
+ // get killed by the OS.
+ signal(SIGPIPE, SIG_IGN);
+
+ try {
+ xmlrpc_c::registry myRegistry;
+
+ xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod);
+
+ myRegistry.addMethod("sample.add", sampleAddMethodP);
+
+ xmlrpc_c::serverPstream server(
+ xmlrpc_c::serverPstream::constrOpt()
+ .socketFd(STDIN_FILENO)
+ .registryP(&myRegistry));
+
+ server.runSerial();
+
+ } catch (exception const& e) {
+ cerr << "Something threw an error: " << e.what() << endl;
+ }
+ return 0;
+}
diff --git a/libs/xmlrpc-c/examples/cpp/xmlrpc_inetd_server.cpp b/libs/xmlrpc-c/examples/cpp/xmlrpc_inetd_server.cpp
index 0dd902a95f..3bfe18654e 100644
--- a/libs/xmlrpc-c/examples/cpp/xmlrpc_inetd_server.cpp
+++ b/libs/xmlrpc-c/examples/cpp/xmlrpc_inetd_server.cpp
@@ -1,6 +1,25 @@
/* A simple XML-RPC server that runs under Inetd. I.e. it lets the invoking
program handle all the connection switching and simply processes one
RPC on the provided connection (Standard Input) and exits.
+
+ A typical example of where this would be useful is with an Inetd
+ "super server."
+
+ xmlrpc_sample_add_server.cpp is a server that does the same thing,
+ but you give it a TCP port number and it listens for TCP connections
+ and processes RPCs ad infinitum. xmlrpc_socket_server.c is halfway
+ in between those -- you give it an already bound and listening
+ socket, and it listens for TCP connections and processes RPCs ad
+ infinitum.
+
+ Here is an easy way to test this program:
+
+ socketexec --accept --local_port=8080 --stdin -- ./xmlrpc_inetd_server
+
+ Now run the client program 'xmlrpc_sample_add_client'. Socketexec
+ will accept the connection that the client program requests and pass it
+ to this program on Standard Input. This program will perform the RPC,
+ respond to the client, then exit.
*/
#ifndef WIN32
@@ -49,10 +68,8 @@ main(int const,
myRegistry.addMethod("sample.add", sampleAddMethodP);
xmlrpc_c::serverAbyss myAbyssServer(
- myRegistry,
- 8080, // TCP port on which to listen
- "/tmp/xmlrpc_log" // Log file
- );
+ xmlrpc_c::serverAbyss::constrOpt()
+ .registryP(&myRegistry));
myAbyssServer.runConn(STDIN_FILENO);
/* This reads the HTTP POST request from Standard Input and
diff --git a/libs/xmlrpc-c/examples/cpp/xmlrpc_sample_add_server.cpp b/libs/xmlrpc-c/examples/cpp/xmlrpc_sample_add_server.cpp
index ff96ae2a1e..f499e5afc0 100644
--- a/libs/xmlrpc-c/examples/cpp/xmlrpc_sample_add_server.cpp
+++ b/libs/xmlrpc-c/examples/cpp/xmlrpc_sample_add_server.cpp
@@ -62,10 +62,9 @@ main(int const,
myRegistry.addMethod("sample.add", sampleAddMethodP);
xmlrpc_c::serverAbyss myAbyssServer(
- myRegistry,
- 8080, // TCP port on which to listen
- "/tmp/xmlrpc_log" // Log file
- );
+ xmlrpc_c::serverAbyss::constrOpt()
+ .registryP(&myRegistry)
+ .portNumber(8080));
myAbyssServer.run();
// xmlrpc_c::serverAbyss.run() never returns
diff --git a/libs/xmlrpc-c/examples/cpp/xmlrpc_sample_add_server_cgi.cpp b/libs/xmlrpc-c/examples/cpp/xmlrpc_sample_add_server_cgi.cpp
new file mode 100644
index 0000000000..9b80603030
--- /dev/null
+++ b/libs/xmlrpc-c/examples/cpp/xmlrpc_sample_add_server_cgi.cpp
@@ -0,0 +1,62 @@
+/* A CGI script that effects a simple XML-RPC server, written in C++.
+
+ See the identically named C program source code for hints on running
+ this example.
+
+*/
+
+#include
+#include
+
+#include
+#include
+#include
+
+using namespace std;
+
+class sampleAddMethod : public xmlrpc_c::method {
+public:
+ sampleAddMethod() {
+ // signature and help strings are documentation -- the client
+ // can query this information with a system.methodSignature and
+ // system.methodHelp RPC.
+ this->_signature = "i:ii"; // method's arguments, result are integers
+ this->_help = "This method adds two integers together";
+ }
+ void
+ execute(xmlrpc_c::paramList const& paramList,
+ xmlrpc_c::value * const retvalP) {
+
+ int const addend(paramList.getInt(0));
+ int const adder(paramList.getInt(1));
+
+ paramList.verifyEnd(2);
+
+ *retvalP = xmlrpc_c::value_int(addend + adder);
+ }
+};
+
+
+
+int
+main(int const,
+ const char ** const) {
+
+ try {
+ xmlrpc_c::registry myRegistry;
+
+ xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod);
+
+ myRegistry.addMethod("sample.add", sampleAddMethodP);
+
+ xmlrpc_c::serverCgi myServer(
+ xmlrpc_c::serverCgi::constrOpt()
+ .registryP(&myRegistry));
+
+ myServer.processCall();
+
+ } catch (exception const& e) {
+ cerr << "Something failed. " << e.what() << endl;
+ }
+ return 0;
+}
diff --git a/libs/xmlrpc-c/examples/gen_sample_add_xml.c b/libs/xmlrpc-c/examples/gen_sample_add_xml.c
index 736d822005..dd65699f82 100644
--- a/libs/xmlrpc-c/examples/gen_sample_add_xml.c
+++ b/libs/xmlrpc-c/examples/gen_sample_add_xml.c
@@ -28,7 +28,7 @@ die_if_fault_occurred(xmlrpc_env * const envP) {
int
main(int const argc,
- const char ** const argv ATTR_UNUSED) {
+ const char ** const argv) {
char * const methodName = "sample.add";
diff --git a/libs/xmlrpc-c/examples/interrupted_client.c b/libs/xmlrpc-c/examples/interrupted_client.c
index 89cd4e84c8..1652be2398 100644
--- a/libs/xmlrpc-c/examples/interrupted_client.c
+++ b/libs/xmlrpc-c/examples/interrupted_client.c
@@ -2,6 +2,7 @@
both by timeout and by control-C.
*/
+#define _XOPEN_SOURCE 600
#include
#include
#include
@@ -110,7 +111,7 @@ addInterruptibly(xmlrpc_client * const clientP,
int
main(int const argc,
- const char ** const argv ATTR_UNUSED) {
+ const char ** const argv) {
const char * const serverUrl = "http://localhost:8080/RPC2";
diff --git a/libs/xmlrpc-c/examples/interrupted_server.c b/libs/xmlrpc-c/examples/interrupted_server.c
index 9d5c59334d..56bac81ccf 100644
--- a/libs/xmlrpc-c/examples/interrupted_server.c
+++ b/libs/xmlrpc-c/examples/interrupted_server.c
@@ -1,4 +1,4 @@
-/* A simple standalone XML-RPC server based on Abyss.
+/* A simple standalone XML-RPC server program based on Abyss.
You can terminate this server in controlled fashion with a SIGTERM
signal.
@@ -7,6 +7,7 @@
simpler code, but it is not interruptible with SIGTERM.
*/
+#define _XOPEN_SOURCE 600
#include
#include
#include
@@ -36,7 +37,7 @@ dieIfFailed(const char * const description,
static xmlrpc_server_abyss_t * serverToTerminateP;
static void
-sigtermHandler(int const signalClass ATTR_UNUSED) {
+sigtermHandler(int const signalClass) {
xmlrpc_env env;
@@ -82,8 +83,8 @@ restoreSigtermHandler(void){
static xmlrpc_value *
sample_add(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const serverInfo ATTR_UNUSED,
- void * const channelInfo ATTR_UNUSED) {
+ void * const serverInfo,
+ void * const channelInfo) {
xmlrpc_int x, y, z;
@@ -105,6 +106,11 @@ int
main(int const argc,
const char ** const argv) {
+ struct xmlrpc_method_info3 const methodInfo = {
+ .methodName = "sample.add",
+ .methodFunction = &sample_add,
+ .serverInfo = NULL
+ };
xmlrpc_server_abyss_parms serverparm;
xmlrpc_server_abyss_t * serverP;
xmlrpc_registry * registryP;
@@ -126,8 +132,7 @@ main(int const argc,
registryP = xmlrpc_registry_new(&env);
dieIfFailed("xmlrpc_registry_new", env);
- xmlrpc_registry_add_method2(
- &env, registryP, "sample.add", &sample_add, NULL, NULL, NULL);
+ xmlrpc_registry_add_method3(&env, registryP, &methodInfo);
dieIfFailed("xmlrpc_registry_add_method2", env);
serverparm.config_file_name = NULL;
diff --git a/libs/xmlrpc-c/examples/json.c b/libs/xmlrpc-c/examples/json.c
new file mode 100644
index 0000000000..89fe82b4db
--- /dev/null
+++ b/libs/xmlrpc-c/examples/json.c
@@ -0,0 +1,115 @@
+/*
+ This example program demonstrates the JSON parsing and generating
+ capabilities of Xmlrpc-c.
+
+ The program reads JSON text from Standard Input and displays its value as
+ XML-RPC XML text. It then re-generates JSON from the intermediate
+ parsed information and displays that.
+*/
+#include
+#include
+
+#include
+
+
+
+static void
+dieIfFaultOccurred(xmlrpc_env * const envP) {
+ if (envP->fault_occurred) {
+ fprintf(stderr, "ERROR: %s (%d)\n",
+ envP->fault_string, envP->fault_code);
+ exit(1);
+ }
+}
+
+
+
+void
+printAsXml(xmlrpc_value * const valP) {
+
+ xmlrpc_env env;
+ xmlrpc_mem_block out;
+
+ xmlrpc_env_init(&env);
+
+ XMLRPC_MEMBLOCK_INIT(char, &env, &out, 0);
+
+ dieIfFaultOccurred(&env);
+
+ xmlrpc_serialize_value(&env, &out, valP);
+
+ printf("XML-RPC XML:\n");
+
+ printf("%.*s\n",
+ XMLRPC_MEMBLOCK_SIZE(char, &out),
+ XMLRPC_MEMBLOCK_CONTENTS(char, &out));
+
+ XMLRPC_MEMBLOCK_CLEAN(char, &out);
+ xmlrpc_env_clean(&env);
+}
+
+
+
+void
+printAsJson(xmlrpc_value * const valP) {
+
+ xmlrpc_env env;
+ xmlrpc_mem_block out;
+ xmlrpc_value * val2P;
+
+ xmlrpc_env_init(&env);
+
+ XMLRPC_MEMBLOCK_INIT(char, &env, &out, 0);
+
+ dieIfFaultOccurred(&env);
+
+ xmlrpc_serialize_json(&env, valP, &out);
+
+ dieIfFaultOccurred(&env);
+
+ printf("JSON:\n");
+
+ printf("%.*s\n",
+ XMLRPC_MEMBLOCK_SIZE(char, &out),
+ XMLRPC_MEMBLOCK_CONTENTS(char, &out));
+
+ XMLRPC_MEMBLOCK_CLEAN(char, &out);
+ xmlrpc_env_clean(&env);
+}
+
+
+
+int
+main(int argc, const char *argv[]) {
+
+ xmlrpc_env env;
+ char buf[1024];
+ xmlrpc_value * valP;
+ size_t bytesRead;
+
+ xmlrpc_env_init(&env);
+
+ if (argc-1 > 0) {
+ fprintf(stderr, "This program has no arguments. "
+ "JSON input is from Standard Input\n");
+ exit(1);
+ }
+
+ bytesRead = fread(buf, 1, sizeof(buf), stdin);
+ buf[bytesRead] = '\0';
+
+ valP = xmlrpc_parse_json(&env, buf);
+
+ dieIfFaultOccurred(&env);
+
+ printAsXml(valP);
+
+ printAsJson(valP);
+
+ xmlrpc_DECREF(valP);
+ xmlrpc_env_clean(&env);
+
+ return 0;
+}
+
+
diff --git a/libs/xmlrpc-c/examples/query-meerkat.c b/libs/xmlrpc-c/examples/query-meerkat.c
deleted file mode 100644
index e566654461..0000000000
--- a/libs/xmlrpc-c/examples/query-meerkat.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* A simple news-searcher, written in C to demonstrate how to use the
- xmplrpc-c client library.
-
- This program connects to an XMLRPC server that O'Reilly runs on the
- Internet, gets some information, and displays it on Standard Output.
-
- Note that that server is not in any way designed specifically for xmlrpc-c.
- It simply implements the XMLRPC protocol, and works with any client that
- implements XMLRPC.
-
- The service that the aforementioned server provides is that it gives you
- a list of news articles that match a certain regular expression. You give
- that regular expression an argument to this client program.
-
- For more details about O'Reilly's excellent Meerkat news service, see:
- http://www.oreillynet.com/pub/a/rss/2000/11/14/meerkat_xmlrpc.html
-*/
-
-#include
-#include
-#include
-
-#include
-#include
-
-#include "config.h" /* information about this build environment */
-
-#define NAME "XML-RPC C Meerkat Query Demo"
-#define VERSION "1.0"
-#define MEERKAT_URL "http://www.oreillynet.com/meerkat/xml-rpc/server.php"
-
-struct cmdline {
- const char * searchArg;
- int hours;
-};
-
-
-static void
-parseCommandLine(int const argc,
- const char ** const argv,
- struct cmdline * const cmdlineP) {
-
- if (argc-1 < 1) {
- fprintf(stderr, "Need at least one argument: "
- "A mysql regular expression "
- "search pattern. Try 'query-meerkat Linux'\n");
- exit(1);
- } else {
- cmdlineP->searchArg = argv[1];
-
- if (argc-1 < 2) {
- cmdlineP->hours = 24;
- } else {
- cmdlineP->hours = atoi(argv[2]);
- if (cmdlineP->hours > 49) {
- fprintf(stderr, "It's not nice to ask for > 49 hours "
- "at once.\n");
- exit(1);
- }
- if (argc-1 > 2) {
- fprintf(stderr, "There are at most 2 arguments: "
- "search pattern "
- "and number of hours.");
- exit(1);
- }
- }
- }
-}
-
-
-
-static void
-die_if_fault_occurred(xmlrpc_env * const env) {
- /* We're a command-line utility, so we abort if an error occurs. */
- if (env->fault_occurred) {
- fprintf(stderr, "XML-RPC Fault #%d: %s\n",
- env->fault_code, env->fault_string);
- exit(1);
- }
-}
-
-
-
-/* Hey! We fit in one function. */
-int
-main(int const argc,
- const char** const argv) {
-
- struct cmdline cmdline;
- char time_period[16];
- xmlrpc_env env;
- xmlrpc_value *stories, *story;
- size_t size, i;
- int first;
-
- parseCommandLine(argc, argv, &cmdline);
-
- snprintf(time_period, sizeof(time_period), "%dHOUR", cmdline.hours);
-
- xmlrpc_env_init(&env);
-
- /* Set up our client. */
- xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0);
-
- die_if_fault_occurred(&env);
-
- /* Ask Meerkat to look for matching stories. */
- stories = xmlrpc_client_call(&env, MEERKAT_URL,
- "meerkat.getItems", "({s:s,s:i,s:s})",
- "search", cmdline.searchArg,
- "descriptions", (xmlrpc_int32) 76,
- "time_period", time_period);
- die_if_fault_occurred(&env);
-
- /* Loop over the stories. */
- size = xmlrpc_array_size(&env, stories);
- die_if_fault_occurred(&env);
- first = 1;
- for (i = 0; i < size; i++) {
- const char * title;
- const char * link;
- const char * description;
-
- /* Extract the useful information from our story. */
- story = xmlrpc_array_get_item(&env, stories, i);
- die_if_fault_occurred(&env);
- xmlrpc_decompose_value(&env, story, "{s:s,s:s,s:s,*}",
- "title", &title,
- "link", &link,
- "description", &description);
- die_if_fault_occurred(&env);
-
- /* Print a separator line if necessary. */
- if (first)
- first = 0;
- else
- printf("\n");
-
- /* Print the story. */
- if (strlen(description) > 0) {
- printf("%s\n%s\n%s\n", title, description, link);
- } else {
- printf("%s\n%s\n", title, link);
- }
- free((char*)title);
- free((char*)link);
- free((char*)description);
- }
-
- /* Shut down our client. */
- xmlrpc_DECREF(stories);
- xmlrpc_env_clean(&env);
- xmlrpc_client_cleanup();
-
- return 0;
-}
diff --git a/libs/xmlrpc-c/examples/synch_client.c b/libs/xmlrpc-c/examples/synch_client.c
index 589aa7b5d3..b9b62a2d68 100644
--- a/libs/xmlrpc-c/examples/synch_client.c
+++ b/libs/xmlrpc-c/examples/synch_client.c
@@ -1,4 +1,4 @@
-/* A simple synchronous XML-RPC client written in C. */
+/* A simple synchronous XML-RPC client program written in C. */
#include
#include
@@ -24,7 +24,7 @@ die_if_fault_occurred(xmlrpc_env * const envP) {
int
main(int const argc,
- const char ** const argv ATTR_UNUSED) {
+ const char ** const argv) {
xmlrpc_env env;
xmlrpc_value * resultP;
diff --git a/libs/xmlrpc-c/examples/xmlrpc_asynch_client.c b/libs/xmlrpc-c/examples/xmlrpc_asynch_client.c
index ec3bd31460..ff56dfdb8b 100644
--- a/libs/xmlrpc-c/examples/xmlrpc_asynch_client.c
+++ b/libs/xmlrpc-c/examples/xmlrpc_asynch_client.c
@@ -1,4 +1,4 @@
-/* A simple asynchronous XML-RPC client written in C, as an example of
+/* A simple asynchronous XML-RPC client program written in C, as an example of
Xmlrpc-c asynchronous RPC facilities. This is the same as the
simpler synchronous client xmlprc_sample_add_client.c, except that
it adds 3 different pairs of numbers with the summation RPCs going on
@@ -35,7 +35,7 @@ static void
handle_sample_add_response(const char * const serverUrl,
const char * const methodName,
xmlrpc_value * const paramArrayP,
- void * const user_data ATTR_UNUSED,
+ void * const user_data,
xmlrpc_env * const faultP,
xmlrpc_value * const resultP) {
@@ -70,7 +70,7 @@ handle_sample_add_response(const char * const serverUrl,
int
main(int const argc,
- const char ** const argv ATTR_UNUSED) {
+ const char ** const argv) {
const char * const serverUrl = "http://localhost:8080/RPC2";
const char * const methodName = "sample.add";
diff --git a/libs/xmlrpc-c/examples/xmlrpc_inetd_server.c b/libs/xmlrpc-c/examples/xmlrpc_inetd_server.c
index 196b42a2b4..8b1bb488ed 100644
--- a/libs/xmlrpc-c/examples/xmlrpc_inetd_server.c
+++ b/libs/xmlrpc-c/examples/xmlrpc_inetd_server.c
@@ -1,4 +1,4 @@
-/* A simple standalone XML-RPC server based on Abyss that processes a
+/* A simple standalone XML-RPC server program based on Abyss that processes a
single RPC from an existing TCP connection on Standard Input.
A typical example of where this would be useful is with an Inetd
@@ -21,6 +21,7 @@
respond to the client, then exit.
*/
+#define _XOPEN_SOURCE 600
#include
#include
#include
@@ -63,8 +64,8 @@ setupSignalHandlers(void) {
static xmlrpc_value *
sample_add(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const serverInfo ATTR_UNUSED,
- void * const channelInfo ATTR_UNUSED) {
+ void * const serverInfo,
+ void * const channelInfo) {
xmlrpc_int x, y, z;
@@ -86,6 +87,11 @@ int
main(int const argc,
const char ** const argv) {
+ struct xmlrpc_method_info3 const methodInfo = {
+ .methodName = "sample.add",
+ .methodFunction = &sample_add,
+ .serverInfo = NULL
+ };
TServer abyssServer;
xmlrpc_registry * registryP;
xmlrpc_env env;
@@ -101,8 +107,7 @@ main(int const argc,
registryP = xmlrpc_registry_new(&env);
- xmlrpc_registry_add_method2(
- &env, registryP, "sample.add", &sample_add, NULL, NULL, NULL);
+ xmlrpc_registry_add_method3(&env, registryP, &methodInfo);
ServerCreateNoAccept(&abyssServer, "XmlRpcServer", NULL, NULL);
diff --git a/libs/xmlrpc-c/examples/xmlrpc_loop_server.c b/libs/xmlrpc-c/examples/xmlrpc_loop_server.c
index 2553ea6173..af0c750f75 100644
--- a/libs/xmlrpc-c/examples/xmlrpc_loop_server.c
+++ b/libs/xmlrpc-c/examples/xmlrpc_loop_server.c
@@ -1,11 +1,14 @@
-/* A simple standalone XML-RPC server based on Abyss that contains a
+/* A simple standalone XML-RPC server program based on Abyss that contains a
simple one-thread request processing loop.
+ This uses the "provide your own Abyss server" mode of operation.
+
xmlrpc_sample_add_server.c is a server that does the same thing, but
does it by running a full Abyss daemon in the background, so it has
less control over how the requests are served.
*/
+#define _XOPEN_SOURCE 600
#include
#include
#include
@@ -66,7 +69,7 @@ printPeerIpAddr(TSession * const abyssSessionP) {
static xmlrpc_value *
sample_add(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const serverInfo ATTR_UNUSED,
+ void * const serverInfo,
void * const channelInfo) {
xmlrpc_int x, y, z;
@@ -117,6 +120,11 @@ int
main(int const argc,
const char ** const argv) {
+ struct xmlrpc_method_info3 const methodInfo = {
+ .methodName = "sample.add",
+ .methodFunction = &sample_add,
+ .serverInfo = NULL
+ };
TServer abyssServer;
xmlrpc_registry * registryP;
xmlrpc_env env;
@@ -136,8 +144,7 @@ main(int const argc,
registryP = xmlrpc_registry_new(&env);
- xmlrpc_registry_add_method2(
- &env, registryP, "sample.add", &sample_add, NULL, NULL, NULL);
+ xmlrpc_registry_add_method3(&env, registryP, &methodInfo);
xmlrpc_registry_set_shutdown(registryP,
&requestShutdown, &terminationRequested);
diff --git a/libs/xmlrpc-c/examples/xmlrpc_sample_add_client.c b/libs/xmlrpc-c/examples/xmlrpc_sample_add_client.c
index f675a925a8..3a219ddf16 100644
--- a/libs/xmlrpc-c/examples/xmlrpc_sample_add_client.c
+++ b/libs/xmlrpc-c/examples/xmlrpc_sample_add_client.c
@@ -1,7 +1,10 @@
-/* A simple synchronous XML-RPC client written in C, as an example of
+/* A simple synchronous XML-RPC client program written in C, as an example of
an Xmlrpc-c client. This invokes the sample.add procedure that the
- Xmlrpc-c example server.c server provides. I.e. it adds to numbers
- together, the hard way.
+ Xmlrpc-c example xmlrpc_sample_add_server.c server provides. I.e. it adds
+ two numbers together, the hard way.
+
+ This sends the RPC to the server running on the local system ("localhost"),
+ HTTP Port 8080.
*/
#include
@@ -16,9 +19,9 @@
#define VERSION "1.0"
static void
-die_if_fault_occurred (xmlrpc_env * const envP) {
+dieIfFaultOccurred (xmlrpc_env * const envP) {
if (envP->fault_occurred) {
- fprintf(stderr, "XML-RPC Fault: %s (%d)\n",
+ fprintf(stderr, "ERROR: %s (%d)\n",
envP->fault_string, envP->fault_code);
exit(1);
}
@@ -28,7 +31,7 @@ die_if_fault_occurred (xmlrpc_env * const envP) {
int
main(int const argc,
- const char ** const argv ATTR_UNUSED) {
+ const char ** const argv) {
xmlrpc_env env;
xmlrpc_value * resultP;
@@ -46,7 +49,7 @@ main(int const argc,
/* Start up our XML-RPC client library. */
xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0);
- die_if_fault_occurred(&env);
+ dieIfFaultOccurred(&env);
printf("Making XMLRPC call to server url '%s' method '%s' "
"to request the sum "
@@ -55,11 +58,11 @@ main(int const argc,
/* Make the remote procedure call */
resultP = xmlrpc_client_call(&env, serverUrl, methodName,
"(ii)", (xmlrpc_int32) 5, (xmlrpc_int32) 7);
- die_if_fault_occurred(&env);
+ dieIfFaultOccurred(&env);
/* Get our sum and print it out. */
xmlrpc_read_int(&env, resultP, &sum);
- die_if_fault_occurred(&env);
+ dieIfFaultOccurred(&env);
printf("The sum is %d\n", sum);
/* Dispose of our result value. */
diff --git a/libs/xmlrpc-c/examples/xmlrpc_sample_add_server.c b/libs/xmlrpc-c/examples/xmlrpc_sample_add_server.c
index dbd2861363..a4a4370617 100644
--- a/libs/xmlrpc-c/examples/xmlrpc_sample_add_server.c
+++ b/libs/xmlrpc-c/examples/xmlrpc_sample_add_server.c
@@ -1,4 +1,24 @@
-/* A simple standalone XML-RPC server written in C. */
+/* A simple standalone XML-RPC server program written in C. */
+
+/* This server knows one RPC class (besides the system classes):
+ "sample.add".
+
+ The program takes one argument: the HTTP port number on which the server
+ is to accept connections, in decimal.
+
+ You can use the example program 'xmlrpc_sample_add_client' to send an RPC
+ to this server.
+
+ Example:
+
+ $ ./xmlrpc_sample_add_server 8080&
+ $ ./xmlrpc_sample_add_client
+
+ For more fun, run client and server in separate terminals and turn on
+ tracing for each:
+
+ $ export XMLRPC_TRACE_XML=1
+*/
#include
#include
@@ -25,8 +45,8 @@
static xmlrpc_value *
sample_add(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const serverInfo ATTR_UNUSED,
- void * const channelInfo ATTR_UNUSED) {
+ void * const serverInfo,
+ void * const channelInfo) {
xmlrpc_int32 x, y, z;
@@ -54,6 +74,10 @@ int
main(int const argc,
const char ** const argv) {
+ struct xmlrpc_method_info3 const methodInfo = {
+ /* .methodName = */ "sample.add",
+ /* .methodFunction = */ &sample_add,
+ };
xmlrpc_server_abyss_parms serverparm;
xmlrpc_registry * registryP;
xmlrpc_env env;
@@ -70,8 +94,7 @@ main(int const argc,
registryP = xmlrpc_registry_new(&env);
- xmlrpc_registry_add_method2(
- &env, registryP, "sample.add", &sample_add, NULL, NULL, NULL);
+ xmlrpc_registry_add_method3(&env, registryP, &methodInfo);
/* In the modern form of the Abyss API, we supply parameters in memory
like a normal API. We select the modern form by setting
diff --git a/libs/xmlrpc-c/examples/xmlrpc_sample_add_server_cgi.c b/libs/xmlrpc-c/examples/xmlrpc_sample_add_server_cgi.c
index fa476a7816..e34c4d7ae1 100644
--- a/libs/xmlrpc-c/examples/xmlrpc_sample_add_server_cgi.c
+++ b/libs/xmlrpc-c/examples/xmlrpc_sample_add_server_cgi.c
@@ -1,4 +1,22 @@
-/* A simple standalone XML-RPC server written in C. */
+/* A CGI script written in C to effect a simple XML-RPC server.
+
+ Example of use:
+
+ - Compile this as the executable 'xmlrpc_sample_add_server.cgi'
+
+ - Place the .cgi file in web server www.example.com's /cgi-bin
+ directory.
+
+ - Configure the web server to permit CGI scripts in /cgi-bin
+ (Apache ExecCgi directory option).
+
+ - Configure the web server to recognize this .cgi file as a CGI
+ script (Apache "AddHandler cgi-script ..." or ScriptAlias).
+
+ - $ xmlrpc http://www.example.com/cgi-bin/xmlrpc_sample_add_server.cgi \
+ sample.add i/5 i/7
+*/
+
#include
#include
@@ -12,7 +30,7 @@
static xmlrpc_value *
sample_add(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const user_data ATTR_UNUSED) {
+ void * const user_data) {
xmlrpc_int32 x, y, z;
diff --git a/libs/xmlrpc-c/examples/xmlrpc_server_validatee.c b/libs/xmlrpc-c/examples/xmlrpc_server_validatee.c
index 927da8a0c2..ad613a896d 100644
--- a/libs/xmlrpc-c/examples/xmlrpc_server_validatee.c
+++ b/libs/xmlrpc-c/examples/xmlrpc_server_validatee.c
@@ -66,7 +66,7 @@
static xmlrpc_value *
array_of_structs(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const user_data ATTR_UNUSED) {
+ void * const user_data) {
xmlrpc_value * arrayP;
xmlrpc_value * retval;
@@ -114,7 +114,7 @@ array_of_structs(xmlrpc_env * const envP,
static xmlrpc_value *
count_entities(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const user_data ATTR_UNUSED) {
+ void * const user_data) {
const char * str;
size_t len, i;
@@ -154,7 +154,7 @@ count_entities(xmlrpc_env * const envP,
static xmlrpc_value *
easy_struct(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const user_data ATTR_UNUSED) {
+ void * const user_data) {
xmlrpc_int32 larry, moe, curly;
@@ -179,7 +179,7 @@ easy_struct(xmlrpc_env * const envP,
static xmlrpc_value *
echo_struct(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const user_data ATTR_UNUSED) {
+ void * const user_data) {
xmlrpc_value * sP;
@@ -198,9 +198,9 @@ echo_struct(xmlrpc_env * const envP,
*/
static xmlrpc_value *
-many_types(xmlrpc_env * const env ATTR_UNUSED,
+many_types(xmlrpc_env * const env,
xmlrpc_value * const param_array,
- void * const user_data ATTR_UNUSED) {
+ void * const user_data) {
/* Create another reference to our argument array and return it as is. */
xmlrpc_INCREF(param_array);
@@ -244,7 +244,7 @@ concatenate(xmlrpc_env * const envP,
static xmlrpc_value *
moderate_array(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const user_data ATTR_UNUSED) {
+ void * const user_data) {
xmlrpc_value * retval;
xmlrpc_value * arrayP;
@@ -295,7 +295,7 @@ moderate_array(xmlrpc_env * const envP,
static xmlrpc_value *
nested_struct(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const user_data ATTR_UNUSED) {
+ void * const user_data) {
xmlrpc_value * yearsP;
xmlrpc_value * retval;
@@ -333,7 +333,7 @@ nested_struct(xmlrpc_env * const envP,
static xmlrpc_value *
struct_return(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const user_data ATTR_UNUSED) {
+ void * const user_data) {
xmlrpc_int32 i;
diff --git a/libs/xmlrpc-c/examples/xmlrpc_socket_server.c b/libs/xmlrpc-c/examples/xmlrpc_socket_server.c
index 2e2cd8b484..9cbc5aac89 100644
--- a/libs/xmlrpc-c/examples/xmlrpc_socket_server.c
+++ b/libs/xmlrpc-c/examples/xmlrpc_socket_server.c
@@ -1,5 +1,5 @@
-/* A simple standalone XML-RPC server written in C as an example of use of
- the Xmlrpc-c libraries.
+/* A simple standalone XML-RPC server program written in C as an example of
+ use of the Xmlrpc-c libraries.
This example expects an already bound socket on Standard Input, ready to
be listened on for client connections. Also see xmlrpc_sample_add_server,
@@ -7,7 +7,11 @@
creates the socket itself. Also see xmlrpc_inetd_server.c, which is
the same thing except you give it a socket which is already connected
to a client.
- */
+
+ Example:
+
+ $ socketexec -local_port=8080 ./xmlrpc_socket_server
+*/
#include
#include
@@ -33,7 +37,8 @@
static xmlrpc_value *
sample_add(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
- void * const user_data ATTR_UNUSED) {
+ void * const serverInfo,
+ void * const channelInfo) {
xmlrpc_int32 x, y, z;
@@ -61,6 +66,11 @@ int
main(int const argc,
const char ** const argv) {
+ struct xmlrpc_method_info3 const methodInfo = {
+ .methodName = "sample.add",
+ .methodFunction = &sample_add,
+ .serverInfo = NULL
+ };
xmlrpc_server_abyss_parms serverparm;
xmlrpc_registry * registryP;
xmlrpc_env env;
@@ -77,8 +87,7 @@ main(int const argc,
registryP = xmlrpc_registry_new(&env);
- xmlrpc_registry_add_method(
- &env, registryP, NULL, "sample.add", &sample_add, NULL);
+ xmlrpc_registry_add_method3(&env, registryP, &methodInfo);
/* In the modern form of the Abyss API, we supply parameters in memory
like a normal API. We select the modern form by setting
diff --git a/libs/xmlrpc-c/include/Makefile b/libs/xmlrpc-c/include/Makefile
index d396ca7c45..28fd00be00 100644
--- a/libs/xmlrpc-c/include/Makefile
+++ b/libs/xmlrpc-c/include/Makefile
@@ -36,18 +36,22 @@ xmlrpc-c/config.h: $(BLDDIR)/$(SUBDIR)/xmlrpc-c
@echo ' #define XMLRPC_SOCKET SOCKET' >>$@
@echo ' #define XMLRPC_HAVE_TIMEVAL 0' >>$@
@echo ' #define XMLRPC_HAVE_TIMESPEC 0' >>$@
+ @echo ' #define XMLRPC_HAVE_PTHREAD 0' >>$@
@echo '#else' >>$@
@echo ' #define XMLRPC_SOCKET int' >>$@
@echo ' #define XMLRPC_HAVE_TIMEVAL 1' >>$@
@echo ' #define XMLRPC_HAVE_TIMESPEC 1' >>$@
+ @echo ' #define XMLRPC_HAVE_PTHREAD 1' >>$@
@echo '#endif' >>$@
@echo '' >>$@
@echo '#if defined(_MSC_VER)' >>$@
@echo ' /* Newer MSVC has long long, but MSVC 6 does not */' >>$@
@echo ' #define XMLRPC_INT64 __int64' >>$@
+ @echo ' #define XMLRPC_PRId64 "I64"' >>$@
@echo ' #define XMLRPC_INT32 __int32' >>$@
@echo '#else' >>$@
@echo ' #define XMLRPC_INT64 long long' >>$@
+ @echo ' #define XMLRPC_PRId64 "lld"' >>$@
@echo ' #define XMLRPC_INT32 int' >>$@
@echo '#endif' >>$@
@echo '#endif' >>$@
@@ -58,7 +62,7 @@ $(BLDDIR)/$(SUBDIR)/xmlrpc-c:
COMPAT_LINK_CMDS = \
$(LN_S) xmlrpc-c/oldxmlrpc.h xmlrpc.h; \
$(LN_S) xmlrpc-c/server.h xmlrpc_server.h; \
- $(LN_S) xmlrpc-c/server_abyss.h xmlrpc_server_abyss.h; \
+ $(LN_S) xmlrpc-c/server_abyss.h xmlrpc_abyss.h; \
$(LN_S) xmlrpc-c/server_w32httpsys.h xmlrpc_server_w32httpsys.h; \
HEADERS_TO_INSTALL = \
@@ -67,6 +71,7 @@ HEADERS_TO_INSTALL = \
xmlrpc-c/c_util.h \
xmlrpc-c/util.h \
xmlrpc-c/base.h \
+ xmlrpc-c/json.h \
xmlrpc-c/abyss.h \
xmlrpc-c/abyss_unixsock.h \
xmlrpc-c/abyss_winsock.h \
@@ -119,22 +124,25 @@ default: all
all:
.PHONY: install-compat-hdr
-install-compat-hdr:
+install-compat-hdr: install-headers
# Install old names of header files for backward compatibility
cd $(DESTDIR)$(HEADERINST_DIR); \
rm -f xmlrpc.h xmlrpc_client.h xmlrpc_server.h xmlrpc_cgi.h \
- xmlrpc_server_abyss.h xmlrpc_server_w32httpsys.h \
+ xmlrpc_server_abyss.h xmlrpc_abyss.h \
+ xmlrpc_server_w32httpsys.h \
XmlRpcCpp.h; \
$(COMPAT_LINK_CMDS)
.PHONY: install
install: install-common install-compat-hdr
-.PHONY: clean distclean dep
+.PHONY: clean
clean:
-distclean:
rm -f xmlrpc-c/config.h
+.PHONY: distclean
+distclean: clean
+
.PHONY: check
check:
diff --git a/libs/xmlrpc-c/include/xmlrpc-c/abyss.h b/libs/xmlrpc-c/include/xmlrpc-c/abyss.h
index e044008f1c..627e8728e7 100644
--- a/libs/xmlrpc-c/include/xmlrpc-c/abyss.h
+++ b/libs/xmlrpc-c/include/xmlrpc-c/abyss.h
@@ -21,6 +21,7 @@ extern "C" {
#include
+#include
#include
/****************************************************************************
@@ -33,9 +34,11 @@ typedef int abyss_bool;
GLOBAL (STATIC) PROGRAM STUFF
****************************************************************************/
+XMLRPC_DLLEXPORT
void
AbyssInit(const char ** const errorP);
+XMLRPC_DLLEXPORT
void
AbyssTerm(void);
@@ -45,23 +48,29 @@ AbyssTerm(void);
typedef struct MIMEType MIMEType;
+XMLRPC_DLLEXPORT
MIMEType *
MIMETypeCreate(void);
+XMLRPC_DLLEXPORT
void
MIMETypeDestroy(MIMEType * const MIMETypeP);
+XMLRPC_DLLEXPORT
void
MIMETypeInit(void);
+XMLRPC_DLLEXPORT
void
MIMETypeTerm(void);
+XMLRPC_DLLEXPORT
abyss_bool
MIMETypeAdd2(MIMEType * const MIMETypeP,
const char * const type,
const char * const ext);
+XMLRPC_DLLEXPORT
abyss_bool
MIMETypeAdd(const char * const type,
const char * const ext);
@@ -81,9 +90,11 @@ typedef struct _TSocket TSocket;
#include
#endif
+XMLRPC_DLLEXPORT
void
ChanSwitchInit(const char ** const errorP);
+XMLRPC_DLLEXPORT
void
ChanSwitchTerm(void);
@@ -92,18 +103,23 @@ ChanSwitchTerm(void);
in abyss_unixsock.h, etc.
*/
+XMLRPC_DLLEXPORT
void
ChanSwitchDestroy(TChanSwitch * const chanSwitchP);
+XMLRPC_DLLEXPORT
void
ChannelInit(const char ** const errorP);
+XMLRPC_DLLEXPORT
void
ChannelTerm(void);
+XMLRPC_DLLEXPORT
void
ChannelDestroy(TChannel * const channelP);
+XMLRPC_DLLEXPORT
void
SocketDestroy(TSocket * const socketP);
@@ -120,6 +136,7 @@ typedef struct {
typedef struct _TSession TSession;
+XMLRPC_DLLEXPORT
abyss_bool
ServerCreate(TServer * const serverP,
const char * const name,
@@ -127,11 +144,13 @@ ServerCreate(TServer * const serverP,
const char * const filespath,
const char * const logfilename);
+XMLRPC_DLLEXPORT
void
ServerCreateSwitch(TServer * const serverP,
TChanSwitch * const chanSwitchP,
const char ** const errorP);
+XMLRPC_DLLEXPORT
abyss_bool
ServerCreateSocket(TServer * const serverP,
const char * const name,
@@ -140,71 +159,87 @@ ServerCreateSocket(TServer * const serverP,
const char * const logfilename);
#define HAVE_SERVER_CREATE_SOCKET_2
+XMLRPC_DLLEXPORT
void
ServerCreateSocket2(TServer * const serverP,
TSocket * const socketP,
const char ** const errorP);
+XMLRPC_DLLEXPORT
abyss_bool
ServerCreateNoAccept(TServer * const serverP,
const char * const name,
const char * const filespath,
const char * const logfilename);
+XMLRPC_DLLEXPORT
void
ServerFree(TServer * const serverP);
+XMLRPC_DLLEXPORT
void
ServerSetName(TServer * const serverP,
const char * const name);
+XMLRPC_DLLEXPORT
void
ServerSetFilesPath(TServer * const serverP,
const char * const filesPath);
+XMLRPC_DLLEXPORT
void
ServerSetLogFileName(TServer * const serverP,
const char * const logFileName);
#define HAVE_SERVER_SET_KEEPALIVE_TIMEOUT 1
+XMLRPC_DLLEXPORT
void
ServerSetKeepaliveTimeout(TServer * const serverP,
xmlrpc_uint32_t const keepaliveTimeout);
#define HAVE_SERVER_SET_KEEPALIVE_MAX_CONN 1
+XMLRPC_DLLEXPORT
void
ServerSetKeepaliveMaxConn(TServer * const serverP,
xmlrpc_uint32_t const keepaliveMaxConn);
#define HAVE_SERVER_SET_TIMEOUT 1
+XMLRPC_DLLEXPORT
void
ServerSetTimeout(TServer * const serverP,
xmlrpc_uint32_t const timeout);
#define HAVE_SERVER_SET_ADVERTISE 1
+XMLRPC_DLLEXPORT
void
ServerSetAdvertise(TServer * const serverP,
abyss_bool const advertise);
#define HAVE_SERVER_SET_MIME_TYPE 1
+XMLRPC_DLLEXPORT
void
ServerSetMimeType(TServer * const serverP,
MIMEType * const MIMETypeP);
+XMLRPC_DLLEXPORT
int
ServerInit(TServer * const serverP);
+XMLRPC_DLLEXPORT
void
ServerRun(TServer * const serverP);
+XMLRPC_DLLEXPORT
void
ServerRunOnce(TServer * const serverP);
/* ServerRunOnce2() is obsolete. See user's guide. */
+XMLRPC_DLLEXPORT
void
ServerRunOnce2(TServer * const serverP,
enum abyss_foreback const foregroundBackground);
+XMLRPC_DLLEXPORT
void
ServerRunChannel(TServer * const serverP,
TChannel * const channelP,
@@ -212,24 +247,30 @@ ServerRunChannel(TServer * const serverP,
const char ** const errorP);
#define HAVE_SERVER_RUN_CONN_2
+XMLRPC_DLLEXPORT
void
ServerRunConn2(TServer * const serverP,
TSocket * const connectedSocketP,
const char ** const errorP);
+XMLRPC_DLLEXPORT
void
ServerRunConn(TServer * const serverP,
TOsSocket const connectedSocket);
+XMLRPC_DLLEXPORT
void
ServerDaemonize(TServer * const serverP);
+XMLRPC_DLLEXPORT
void
ServerTerminate(TServer * const serverP);
+XMLRPC_DLLEXPORT
void
ServerResetTerminate(TServer * const serverP);
+XMLRPC_DLLEXPORT
void
ServerUseSigchld(TServer * const serverP);
@@ -242,15 +283,31 @@ typedef abyss_bool (*URIHandler) (TSession *); /* deprecated */
struct URIHandler2;
-typedef void (*initHandlerFn)(struct URIHandler2 *,
- abyss_bool *);
+typedef void (*initHandlerFn)(struct URIHandler2 *, abyss_bool *);
typedef void (*termHandlerFn)(void *);
+typedef void (*handleReq3Fn)(void *,
+ TSession *,
+ abyss_bool *);
+
typedef void (*handleReq2Fn)(struct URIHandler2 *,
TSession *,
abyss_bool *);
+struct ServerReqHandler3 {
+ termHandlerFn term;
+ handleReq3Fn handleReq;
+ void * userdata;
+ size_t handleReqStackSize; /* zero = default */
+};
+
+XMLRPC_DLLEXPORT
+void
+ServerAddHandler3(TServer * const serverP,
+ const struct ServerReqHandler3 * const handlerP,
+ abyss_bool * const successP);
+
typedef struct URIHandler2 {
initHandlerFn init;
termHandlerFn term;
@@ -259,11 +316,13 @@ typedef struct URIHandler2 {
void * userdata;
} URIHandler2;
+XMLRPC_DLLEXPORT
void
ServerAddHandler2(TServer * const srvP,
URIHandler2 * const handlerP,
abyss_bool * const successP);
+XMLRPC_DLLEXPORT
abyss_bool
ServerAddHandler(TServer * const srvP,
URIHandler const handler);
@@ -274,6 +333,7 @@ typedef abyss_bool (*THandlerDflt) (TSession *);
for the same type
*/
+XMLRPC_DLLEXPORT
void
ServerDefaultHandler(TServer * const srvP,
THandlerDflt const handler);
@@ -283,10 +343,12 @@ ServerDefaultHandler(TServer * const srvP,
inappropriate for an API.
*/
+XMLRPC_DLLEXPORT
abyss_bool
ConfReadServerFile(const char * const filename,
TServer * const srvP);
+XMLRPC_DLLEXPORT
void
LogWrite(TServer * const srvP,
const char * const c);
@@ -309,7 +371,7 @@ typedef struct {
const char * query;
/* The query part of the URI (stuff after '?'). NULL if none. */
const char * host;
- /* NOT the value of the host: header. Rather, the name of the
+ /* NOT the value of the host: header field. Rather, the name of the
target host (could be part of the host: value; could be from the
URI). No port number. NULL if request does not specify a host
name.
@@ -319,7 +381,7 @@ typedef struct {
const char * referer;
const char * requestline;
const char * user;
- /* Requesting user (from authorization: header). NULL if
+ /* Requesting user (from authorization: header field). NULL if
request doesn't specify or handler has not authenticated it.
*/
xmlrpc_uint16_t port;
@@ -329,98 +391,157 @@ typedef struct {
abyss_bool keepalive;
} TRequestInfo;
+XMLRPC_DLLEXPORT
abyss_bool
SessionRefillBuffer(TSession * const sessionP);
+XMLRPC_DLLEXPORT
size_t
SessionReadDataAvail(TSession * const sessionP);
+XMLRPC_DLLEXPORT
void
SessionGetReadData(TSession * const sessionP,
size_t const max,
const char ** const outStartP,
size_t * const outLenP);
+XMLRPC_DLLEXPORT
void
SessionGetRequestInfo(TSession * const sessionP,
const TRequestInfo ** const requestInfoPP);
+XMLRPC_DLLEXPORT
void
SessionGetChannelInfo(TSession * const sessionP,
void ** const channelInfoPP);
+XMLRPC_DLLEXPORT
void *
SessionGetDefaultHandlerCtx(TSession * const sessionP);
+XMLRPC_DLLEXPORT
char *
RequestHeaderValue(TSession * const sessionP,
const char * const name);
+XMLRPC_DLLEXPORT
abyss_bool
ResponseAddField(TSession * const sessionP,
const char * const name,
const char * const value);
-void
+XMLRPC_DLLEXPORT
+abyss_bool
ResponseWriteStart(TSession * const sessionP);
/* For backward compatibility: */
#define ResponseWrite ResponseWriteStart
+XMLRPC_DLLEXPORT
abyss_bool
ResponseWriteBody(TSession * const sessionP,
const char * const data,
xmlrpc_uint32_t const len);
+XMLRPC_DLLEXPORT
abyss_bool
ResponseWriteEnd(TSession * const sessionP);
+XMLRPC_DLLEXPORT
abyss_bool
ResponseChunked(TSession * const sessionP);
+XMLRPC_DLLEXPORT
xmlrpc_uint16_t
ResponseStatusFromErrno(int const errnoArg);
+XMLRPC_DLLEXPORT
void
ResponseStatus(TSession * const sessionP,
xmlrpc_uint16_t const code);
+XMLRPC_DLLEXPORT
void
ResponseStatusErrno(TSession * const sessionP);
+XMLRPC_DLLEXPORT
abyss_bool
ResponseContentType(TSession * const serverP,
const char * const type);
+XMLRPC_DLLEXPORT
abyss_bool
ResponseContentLength(TSession * const sessionP,
xmlrpc_uint64_t const len);
+typedef struct {
+/*----------------------------------------------------------------------------
+ These are parameters to control the HTTP "Access Control functions. That's
+ where the client asks whether it is OK to send a request that some other
+ server asked the client to send (e.g. a person web browses a page at
+ a.example.com, and it sends a script that executes on the user's computer
+ and tries to perform an XML-RPC RPC on b.example.com. The user's browser
+ first asks b.example.com if it is OK to do an RPC that is really initiated
+ by a.example.com.
+-----------------------------------------------------------------------------*/
+ const char * allowOrigin;
+ /* This tells what original servers (a.example.com in the example
+ above) are allowed to submit RPCs indirectly to us. The value is a
+ verbatim value for an HTTP Access-Control-Allow-Origin header field
+ (just the value part of the field, not the whole field). "*"
+ therefore means everyone is allowed. "" means no one.
+
+ NULL means not to say anything about access control to the client.
+ */
+ abyss_bool expires;
+ /* The permissions herein expire after a certain period from now.
+ 'maxAge' is that period.
+ */
+ unsigned int maxAge;
+ /* Meaningful only when 'expires' is true. The expiration period
+ in seconds. Zero is valid.
+ */
+} ResponseAccessCtl;
+
+XMLRPC_DLLEXPORT
+void
+ResponseAccessControl(TSession * const abyssSessionP,
+ ResponseAccessCtl const accessControl);
+
+XMLRPC_DLLEXPORT
void
ResponseError2(TSession * const sessionP,
const char * const explanation);
+XMLRPC_DLLEXPORT
void
ResponseError(TSession * const sessionP);
+XMLRPC_DLLEXPORT
const char *
MIMETypeFromExt(const char * const ext);
+XMLRPC_DLLEXPORT
const char *
MIMETypeFromExt2(MIMEType * const MIMETypeP,
const char * const ext);
+XMLRPC_DLLEXPORT
const char *
MIMETypeFromFileName2(MIMEType * const MIMETypeP,
const char * const fileName);
+XMLRPC_DLLEXPORT
const char *
MIMETypeFromFileName(const char * const fileName);
+XMLRPC_DLLEXPORT
const char *
MIMETypeGuessFromFile2(MIMEType * const MIMETypeP,
const char * const fileName);
+XMLRPC_DLLEXPORT
const char *
MIMETypeGuessFromFile(const char * const filename);
@@ -460,7 +581,7 @@ MIMETypeGuessFromFile(const char * const filename);
** Maximum number of simultaneous connections
*********************************************************************/
-#define MAX_CONN 100000
+#define MAX_CONN 16
/*********************************************************************
** General purpose definitions
@@ -482,26 +603,21 @@ MIMETypeGuessFromFile(const char * const filename);
** Range
*********************************************************************/
+XMLRPC_DLLEXPORT
abyss_bool
RangeDecode(char * const str,
xmlrpc_uint64_t const filesize,
xmlrpc_uint64_t * const start,
xmlrpc_uint64_t * const end);
+XMLRPC_DLLEXPORT
abyss_bool DateInit(void);
-/*********************************************************************
-** Base64
-*********************************************************************/
-
-void
-Base64Encode(const char * const chars,
- char * const base64);
-
/*********************************************************************
** Session
*********************************************************************/
+XMLRPC_DLLEXPORT
abyss_bool SessionLog(TSession * const s);
diff --git a/libs/xmlrpc-c/include/xmlrpc-c/abyss_winsock.h b/libs/xmlrpc-c/include/xmlrpc-c/abyss_winsock.h
index f376446b8f..8aeb78203f 100644
--- a/libs/xmlrpc-c/include/xmlrpc-c/abyss_winsock.h
+++ b/libs/xmlrpc-c/include/xmlrpc-c/abyss_winsock.h
@@ -7,17 +7,19 @@ struct abyss_win_chaninfo {
struct sockaddr peerAddr;
};
-
+XMLRPC_DLLEXPORT
void
ChanSwitchWinCreate(unsigned short const portNumber,
TChanSwitch ** const chanSwitchPP,
const char ** const errorP);
+XMLRPC_DLLEXPORT
void
ChanSwitchWinCreateWinsock(SOCKET const winsock,
TChanSwitch ** const chanSwitchPP,
const char ** const errorP);
+XMLRPC_DLLEXPORT
void
ChannelWinCreateWinsock(SOCKET const fd,
TChannel ** const channelPP,
diff --git a/libs/xmlrpc-c/include/xmlrpc-c/base.h b/libs/xmlrpc-c/include/xmlrpc-c/base.h
index a68a4f1242..cdc9161db8 100644
--- a/libs/xmlrpc-c/include/xmlrpc-c/base.h
+++ b/libs/xmlrpc-c/include/xmlrpc-c/base.h
@@ -6,26 +6,40 @@
#include
#include
#include
+#include
#include
#include
- /* Defines XMLRPC_HAVE_WCHAR, XMLRPC_INT64 */
+ /* Defines XMLRPC_HAVE_WCHAR, XMLRPC_INT64, XMLRPC_HAVE_TIMEVAL */
#if XMLRPC_HAVE_WCHAR
#include
#endif
+#if XMLRPC_HAVE_TIMEVAL
+#include
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
-
/*=========================================================================
** Version of libxmlrpc
**=======================================================================*/
+
+/* These are for backward compatibility -- they can't be exported from a
+ Windows DLL. xmlrpc_server_version() is preferred.
+*/
extern unsigned int const xmlrpc_version_major;
extern unsigned int const xmlrpc_version_minor;
extern unsigned int const xmlrpc_version_point;
+XMLRPC_DLLEXPORT
+void
+xmlrpc_version(unsigned int * const majorP,
+ unsigned int * const minorP,
+ unsigned int * const pointP);
+
/*=========================================================================
** C types equivalent to XML-RPC types
**=======================================================================*/
@@ -50,6 +64,19 @@ typedef double xmlrpc_double;
so it's probably clearer just to use that. This typedef is here
for mathematical completeness.
*/
+typedef struct {
+ /* A datetime of the type defined by XML-RPC with
+ a few extensions. I.e. in the range 1-9999 AD with microsecond
+ resolution.
+ */
+ unsigned int Y; /* 1-? */
+ unsigned int M; /* 1-12 */
+ unsigned int D; /* 1-31 */
+ unsigned int h; /* 0-23 */
+ unsigned int m; /* 0-59 */
+ unsigned int s; /* 0-59 */
+ unsigned int u; /* 0-999999 */
+} xmlrpc_datetime;
/* xmlrpc_socket is just for backward compatibility, in case someone decided
to use this in user code. New code should use the native type for a
@@ -89,12 +116,13 @@ typedef enum {
#define XMLRPC_HAVE_I8 1
-/* These are *always* allocated on the heap. No exceptions. */
typedef struct _xmlrpc_value xmlrpc_value;
+XMLRPC_DLLEXPORT
const char *
xmlrpc_type_name(xmlrpc_type const type);
+XMLRPC_DLLEXPORT
void
xmlrpc_abort_if_array_bad(xmlrpc_value * const arrayP);
@@ -102,109 +130,193 @@ xmlrpc_abort_if_array_bad(xmlrpc_value * const arrayP);
xmlrpc_abort_if_array_bad(val)
/* Increment the reference count of an xmlrpc_value. */
-extern void xmlrpc_INCREF (xmlrpc_value* const value);
+XMLRPC_DLLEXPORT
+extern void xmlrpc_INCREF(xmlrpc_value* const value);
/* Decrement the reference count of an xmlrpc_value. If there
** are no more references, free it. */
-extern void xmlrpc_DECREF (xmlrpc_value* const value);
+XMLRPC_DLLEXPORT
+extern void xmlrpc_DECREF(xmlrpc_value* const value);
/* Get the type of an XML-RPC value. */
+XMLRPC_DLLEXPORT
extern xmlrpc_type xmlrpc_value_type (xmlrpc_value* const value);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_int_new(xmlrpc_env * const envP,
int const intValue);
-xmlrpc_value *
-xmlrpc_i8_new(xmlrpc_env * const envP,
- xmlrpc_int64 const value);
-
+XMLRPC_DLLEXPORT
void
xmlrpc_read_int(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
int * const intValueP);
+XMLRPC_DLLEXPORT
+xmlrpc_value *
+xmlrpc_i8_new(xmlrpc_env * const envP,
+ xmlrpc_int64 const value);
+
+XMLRPC_DLLEXPORT
+void
+xmlrpc_read_i8(xmlrpc_env * const envP,
+ const xmlrpc_value * const valueP,
+ xmlrpc_int64 * const intValueP);
+
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_bool_new(xmlrpc_env * const envP,
xmlrpc_bool const boolValue);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_bool(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
xmlrpc_bool * const boolValueP);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_double_new(xmlrpc_env * const envP,
double const doubleValue);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_double(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
xmlrpc_double * const doubleValueP);
+XMLRPC_DLLEXPORT
+xmlrpc_value *
+xmlrpc_datetime_new(xmlrpc_env * const envP,
+ xmlrpc_datetime const dt);
+
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_datetime_new_str(xmlrpc_env * const envP,
const char * const value);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_datetime_new_sec(xmlrpc_env * const envP,
time_t const value);
+XMLRPC_DLLEXPORT
+xmlrpc_value*
+xmlrpc_datetime_new_usec(xmlrpc_env * const envP,
+ time_t const secs,
+ unsigned int const usecs);
+
+#if XMLRPC_HAVE_TIMEVAL
+XMLRPC_DLLEXPORT
+xmlrpc_value *
+xmlrpc_datetime_new_timeval(xmlrpc_env * const envP,
+ struct timeval const value);
+#endif
+
+#if XMLRPC_HAVE_TIMESPEC
+XMLRPC_DLLEXPORT
+xmlrpc_value *
+xmlrpc_datetime_new_timespec(xmlrpc_env * const envP,
+ struct timespec const value);
+#endif
+
+void
+XMLRPC_DLLEXPORT
+xmlrpc_read_datetime(xmlrpc_env * const envP,
+ const xmlrpc_value * const valueP,
+ xmlrpc_datetime * const dtP);
+
+XMLRPC_DLLEXPORT
void
xmlrpc_read_datetime_str(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_datetime_sec(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
time_t * const timeValueP);
+XMLRPC_DLLEXPORT
+void
+xmlrpc_read_datetime_usec(xmlrpc_env * const envP,
+ const xmlrpc_value * const valueP,
+ time_t * const secsP,
+ unsigned int * const usecsP);
+
+#if XMLRPC_HAVE_TIMEVAL
+XMLRPC_DLLEXPORT
+void
+xmlrpc_read_datetime_timeval(xmlrpc_env * const envP,
+ const xmlrpc_value * const valueP,
+ struct timeval * const timeValueP);
+#endif
+
+#if XMLRPC_HAVE_TIMESPEC
+XMLRPC_DLLEXPORT
+void
+xmlrpc_read_datetime_timespec(xmlrpc_env * const envP,
+ const xmlrpc_value * const valueP,
+ struct timespec * const timeValueP);
+#endif
+
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_string_new(xmlrpc_env * const envP,
const char * const stringValue);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_string_new_lp(xmlrpc_env * const envP,
size_t const length,
const char * const stringValue);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_string_new_va(xmlrpc_env * const envP,
const char * const format,
va_list args);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_string_new_f(xmlrpc_env * const envP,
const char * const format,
...);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_string_new_lp_cr(xmlrpc_env * const envP,
size_t const length,
const char * const value);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_string_new_cr(xmlrpc_env * const envP,
const char * const value);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_string(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_string_crlf(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_string_lp_crlf(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP,
const char ** const stringValueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_string_lp(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
@@ -212,80 +324,93 @@ xmlrpc_read_string_lp(xmlrpc_env * const envP,
const char ** const stringValueP);
#if XMLRPC_HAVE_WCHAR
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_string_w_new(xmlrpc_env * const envP,
const wchar_t * const stringValue);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_string_w_new_lp(xmlrpc_env * const envP,
size_t const length,
const wchar_t * const stringValue);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_string_w(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
const wchar_t ** const stringValueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_string_w_crlf(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
const wchar_t ** const stringValueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_string_w_lp(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
size_t * const lengthP,
const wchar_t ** const stringValueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_string_w_lp_crlf(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
size_t * const lengthP,
const wchar_t ** const stringValueP);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_string_w_new_lp_cr(xmlrpc_env * const envP,
size_t const length,
const wchar_t * const value);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_string_w_new_cr(xmlrpc_env * const envP,
const wchar_t * const value);
#endif /* XMLRPC_HAVE_WCHAR */
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_base64_new(xmlrpc_env * const envP,
size_t const length,
const unsigned char * const value);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_base64(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP,
const unsigned char ** const bytestringValueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_base64_size(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP);
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_array_new(xmlrpc_env * const envP);
/* Return the number of elements in an XML-RPC array.
** Sets XMLRPC_TYPE_ERROR if 'array' is not an array. */
+XMLRPC_DLLEXPORT
int
xmlrpc_array_size(xmlrpc_env * const env,
const xmlrpc_value * const array);
-/* Append an item to an XML-RPC array.
-** Sets XMLRPC_TYPE_ERROR if 'array' is not an array. */
-extern void
-xmlrpc_array_append_item (xmlrpc_env * const envP,
- xmlrpc_value * const arrayP,
- xmlrpc_value * const valueP);
+XMLRPC_DLLEXPORT
+void
+xmlrpc_array_append_item(xmlrpc_env * const envP,
+ xmlrpc_value * const arrayP,
+ xmlrpc_value * const valueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_array_read_item(xmlrpc_env * const envP,
const xmlrpc_value * const arrayP,
@@ -299,30 +424,35 @@ xmlrpc_array_read_item(xmlrpc_env * const envP,
Sets XMLRPC_TYPE_ERROR if 'array' is not an array.
Sets XMLRPC_INDEX_ERROR if 'index' is out of bounds.
*/
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_array_get_item(xmlrpc_env * const envP,
const xmlrpc_value * const arrayP,
int const index);
/* Not implemented--we don't need it yet.
-extern
-int xmlrpc_array_set_item (xmlrpc_env* env,
-xmlrpc_value* array,
-int index,
- xmlrpc_value* value);
+XMLRPC_DLLEXPORT
+int
+xmlrpc_array_set_item(xmlrpc_env * const envP,
+ xmlrpc_value * const arrayP,
+ unsigned int const index,
+ xmlrpc_value * const valueP);
*/
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_struct_new(xmlrpc_env * const env);
/* Return the number of key/value pairs in a struct.
** Sets XMLRPC_TYPE_ERROR if 'strct' is not a struct. */
+XMLRPC_DLLEXPORT
int
-xmlrpc_struct_size (xmlrpc_env * env,
- xmlrpc_value * strct);
+xmlrpc_struct_size (xmlrpc_env * const env,
+ xmlrpc_value * const strct);
/* Returns true iff 'strct' contains 'key'.
** Sets XMLRPC_TYPE_ERROR if 'strct' is not a struct. */
+XMLRPC_DLLEXPORT
int
xmlrpc_struct_has_key(xmlrpc_env * const envP,
xmlrpc_value * const strctP,
@@ -332,6 +462,7 @@ xmlrpc_struct_has_key(xmlrpc_env * const envP,
Deprecated. xmlrpc_struct_get_value_v() is more general, and this
case is not common enough to warrant a shortcut.
*/
+XMLRPC_DLLEXPORT
int
xmlrpc_struct_has_key_n(xmlrpc_env * const envP,
xmlrpc_value * const strctP,
@@ -340,6 +471,7 @@ xmlrpc_struct_has_key_n(xmlrpc_env * const envP,
#if 0
/* Not implemented yet, but needed for completeness. */
+XMLRPC_DLLEXPORT
int
xmlrpc_struct_has_key_v(xmlrpc_env * env,
xmlrpc_value * strct,
@@ -347,6 +479,7 @@ xmlrpc_struct_has_key_v(xmlrpc_env * env,
#endif
+XMLRPC_DLLEXPORT
void
xmlrpc_struct_find_value(xmlrpc_env * const envP,
xmlrpc_value * const structP,
@@ -354,18 +487,21 @@ xmlrpc_struct_find_value(xmlrpc_env * const envP,
xmlrpc_value ** const valuePP);
+XMLRPC_DLLEXPORT
void
xmlrpc_struct_find_value_v(xmlrpc_env * const envP,
xmlrpc_value * const structP,
xmlrpc_value * const keyP,
xmlrpc_value ** const valuePP);
+XMLRPC_DLLEXPORT
void
xmlrpc_struct_read_value(xmlrpc_env * const envP,
xmlrpc_value * const structP,
const char * const key,
xmlrpc_value ** const valuePP);
+XMLRPC_DLLEXPORT
void
xmlrpc_struct_read_value_v(xmlrpc_env * const envP,
xmlrpc_value * const structP,
@@ -375,6 +511,7 @@ xmlrpc_struct_read_value_v(xmlrpc_env * const envP,
/* The "get_value" functions are deprecated. Use the "find_value"
and "read_value" functions instead.
*/
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_struct_get_value(xmlrpc_env * const envP,
xmlrpc_value * const strctP,
@@ -384,6 +521,7 @@ xmlrpc_struct_get_value(xmlrpc_env * const envP,
Deprecated. xmlrpc_struct_get_value_v() is more general, and this
case is not common enough to warrant a shortcut.
*/
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_struct_get_value_n(xmlrpc_env * const envP,
xmlrpc_value * const strctP,
@@ -393,6 +531,7 @@ xmlrpc_struct_get_value_n(xmlrpc_env * const envP,
/* Set the value associated with 'key' in 'strct' to 'value'.
Sets XMLRPC_TYPE_ERROR if 'strct' is not a struct.
*/
+XMLRPC_DLLEXPORT
void
xmlrpc_struct_set_value(xmlrpc_env * const env,
xmlrpc_value * const strct,
@@ -403,6 +542,7 @@ xmlrpc_struct_set_value(xmlrpc_env * const env,
The general way to set a structure value is xmlrpc_struct_set_value_v(),
and this case is not common enough to deserve a shortcut.
*/
+XMLRPC_DLLEXPORT
void
xmlrpc_struct_set_value_n(xmlrpc_env * const env,
xmlrpc_value * const strct,
@@ -412,6 +552,7 @@ xmlrpc_struct_set_value_n(xmlrpc_env * const env,
/* The same as above, but the key must be an XML-RPC string.
** Fails with XMLRPC_TYPE_ERROR if 'keyval' is not a string. */
+XMLRPC_DLLEXPORT
void
xmlrpc_struct_set_value_v(xmlrpc_env * const env,
xmlrpc_value * const strct,
@@ -423,6 +564,7 @@ xmlrpc_struct_set_value_v(xmlrpc_env * const env,
** Fails with XMLRPC_TYPE_ERROR if 'struct' is not a struct.
** Fails with XMLRPC_INDEX_ERROR if 'index' is out of bounds. */
+XMLRPC_DLLEXPORT
void
xmlrpc_struct_read_member(xmlrpc_env * const envP,
xmlrpc_value * const structP,
@@ -436,6 +578,7 @@ xmlrpc_struct_read_member(xmlrpc_env * const envP,
Deprecated. Use xmlrpc_struct_read_member() instead.
*/
+XMLRPC_DLLEXPORT
void
xmlrpc_struct_get_key_and_value(xmlrpc_env * const env,
xmlrpc_value * const strct,
@@ -443,38 +586,55 @@ xmlrpc_struct_get_key_and_value(xmlrpc_env * const env,
xmlrpc_value ** const out_keyval,
xmlrpc_value ** const out_value);
+/* The "C pointer" type has no relation to XML-RPC. It is here for the
+ convenience of programs that use xmlrpc_value for XML-RPC purposes
+ and can benefit from using it for non-XML-RPC purposes as well.
+
+ Also, some people use libxmlrpc for xmlrpc_value alone, because sometimes
+ you need to work with basic data types in richer ways than the C types
+ (int, time_t, etc) allow.
+*/
+
+XMLRPC_DLLEXPORT
+xmlrpc_value *
+xmlrpc_cptr_new(xmlrpc_env * const envP,
+ void * const value);
+
+typedef void (*xmlrpc_cptr_dtor_fn)(void *, void *);
+
+XMLRPC_DLLEXPORT
+xmlrpc_value *
+xmlrpc_cptr_new_dtor(xmlrpc_env * const envP,
+ void * const value,
+ xmlrpc_cptr_dtor_fn const dtor,
+ void * const dtorContext);
+
+XMLRPC_DLLEXPORT
void
xmlrpc_read_cptr(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
void ** const ptrValueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_read_nil(xmlrpc_env * const envP,
xmlrpc_value * const valueP);
-
-void
-xmlrpc_read_i8(xmlrpc_env * const envP,
- const xmlrpc_value * const valueP,
- xmlrpc_int64 * const intValueP);
-
-
-xmlrpc_value *
-xmlrpc_cptr_new(xmlrpc_env * const envP,
- void * const value);
-
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_nil_new(xmlrpc_env * const envP);
/* Build an xmlrpc_value from a format string. */
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_build_value(xmlrpc_env * const env,
const char * const format,
...);
/* The same as the above, but using a va_list and more general */
+XMLRPC_DLLEXPORT
void
xmlrpc_build_value_va(xmlrpc_env * const env,
const char * const format,
@@ -482,12 +642,14 @@ xmlrpc_build_value_va(xmlrpc_env * const env,
xmlrpc_value ** const valPP,
const char ** const tailP);
+XMLRPC_DLLEXPORT
void
xmlrpc_decompose_value(xmlrpc_env * const envP,
xmlrpc_value * const value,
const char * const format,
...);
+XMLRPC_DLLEXPORT
void
xmlrpc_decompose_value_va(xmlrpc_env * const envP,
xmlrpc_value * const value,
@@ -501,6 +663,7 @@ xmlrpc_decompose_value_va(xmlrpc_env * const envP,
These are deprecated. Use xmlrpc_decompose_value... instead.
*/
+XMLRPC_DLLEXPORT
void
xmlrpc_parse_value(xmlrpc_env * const envP,
xmlrpc_value * const value,
@@ -508,6 +671,7 @@ xmlrpc_parse_value(xmlrpc_env * const envP,
...);
/* The same as the above, but using a va_list. */
+XMLRPC_DLLEXPORT
void
xmlrpc_parse_value_va(xmlrpc_env * const envP,
xmlrpc_value * const value,
@@ -523,28 +687,33 @@ typedef enum xmlrpc_dialect {
xmlrpc_dialect_apache
} xmlrpc_dialect;
+XMLRPC_DLLEXPORT
void
xmlrpc_serialize_value2(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const valueP,
xmlrpc_dialect const dialect);
+XMLRPC_DLLEXPORT
void
xmlrpc_serialize_value(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const valueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_serialize_params2(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const paramArrayP,
xmlrpc_dialect const dialect);
+XMLRPC_DLLEXPORT
void
xmlrpc_serialize_params(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const paramArrayP);
+XMLRPC_DLLEXPORT
void
xmlrpc_serialize_call2(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
@@ -552,23 +721,27 @@ xmlrpc_serialize_call2(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
xmlrpc_dialect const dialect);
+XMLRPC_DLLEXPORT
void
xmlrpc_serialize_call(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
const char * const methodName,
xmlrpc_value * const paramArrayP);
+XMLRPC_DLLEXPORT
void
xmlrpc_serialize_response2(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const valueP,
xmlrpc_dialect const dialect);
+XMLRPC_DLLEXPORT
void
xmlrpc_serialize_response(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const valueP);
+XMLRPC_DLLEXPORT
void
xmlrpc_serialize_fault(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
@@ -579,17 +752,22 @@ xmlrpc_serialize_fault(xmlrpc_env * const envP,
** Decoding XML
**=======================================================================*/
-/* Parse an XML-RPC call. If an error occurs, set a fault and set
-** the output variables to NULL.
-** The caller is responsible for calling free(*out_method_name) and
-** xmlrpc_DECREF(*out_param_array). */
+XMLRPC_DLLEXPORT
+void
+xmlrpc_parse_value_xml(xmlrpc_env * const envP,
+ const char * const xmlData,
+ size_t const xmlDataLen,
+ xmlrpc_value ** const valuePP);
+
+XMLRPC_DLLEXPORT
void
xmlrpc_parse_call(xmlrpc_env * const envP,
- const char * const xml_data,
- size_t const xml_len,
- const char ** const out_method_name,
- xmlrpc_value ** const out_param_array);
+ const char * const xmlData,
+ size_t const xmlDataLen,
+ const char ** const methodNameP,
+ xmlrpc_value ** const paramArrayP);
+XMLRPC_DLLEXPORT
void
xmlrpc_parse_response2(xmlrpc_env * const envP,
const char * const xmlData,
@@ -601,6 +779,7 @@ xmlrpc_parse_response2(xmlrpc_env * const envP,
/* xmlrpc_parse_response() is for backward compatibility */
+XMLRPC_DLLEXPORT
xmlrpc_value *
xmlrpc_parse_response(xmlrpc_env * const envP,
const char * const xmlData,
@@ -616,23 +795,26 @@ xmlrpc_parse_response(xmlrpc_env * const envP,
/* This routine inserts newlines every 76 characters, as required by the
** Base64 specification. */
+XMLRPC_DLLEXPORT
xmlrpc_mem_block *
-xmlrpc_base64_encode(xmlrpc_env * env,
- unsigned char * bin_data,
- size_t bin_len);
+xmlrpc_base64_encode(xmlrpc_env * const envP,
+ const unsigned char * const binData,
+ size_t const binLen);
/* This routine encodes everything in one line. This is needed for HTTP
** authentication and similar tasks. */
+XMLRPC_DLLEXPORT
xmlrpc_mem_block *
-xmlrpc_base64_encode_without_newlines(xmlrpc_env * env,
- unsigned char * bin_data,
- size_t bin_len);
+xmlrpc_base64_encode_without_newlines(xmlrpc_env * const envP,
+ const unsigned char * const binData,
+ size_t const binLen);
/* This decodes Base64 data with or without newlines. */
+XMLRPC_DLLEXPORT
extern xmlrpc_mem_block *
xmlrpc_base64_decode(xmlrpc_env * const envP,
- const char * const ascii_data,
- size_t const ascii_len);
+ const char * const asciiData,
+ size_t const asciiLen);
/*=========================================================================
@@ -645,10 +827,12 @@ xmlrpc_base64_decode(xmlrpc_env * const envP,
** a cookie replacement of basic authentication.)
**/
+XMLRPC_DLLEXPORT
extern void xmlrpc_authcookie_set(xmlrpc_env * const env,
const char * const username,
const char * const password);
+XMLRPC_DLLEXPORT
char *xmlrpc_authcookie(void);
/*=========================================================================
@@ -677,9 +861,11 @@ char *xmlrpc_authcookie(void);
#define XMLRPC_XML_SIZE_LIMIT_DEFAULT (512*1024)
/* Set a specific limit to the specified value. */
+XMLRPC_DLLEXPORT
extern void xmlrpc_limit_set (int const limit_id, size_t const value);
/* Get the value of a specified limit. */
+XMLRPC_DLLEXPORT
extern size_t xmlrpc_limit_get (int const limit_id);
diff --git a/libs/xmlrpc-c/include/xmlrpc-c/base.hpp b/libs/xmlrpc-c/include/xmlrpc-c/base.hpp
index ab6fe3e4c6..6f93e38532 100644
--- a/libs/xmlrpc-c/include/xmlrpc-c/base.hpp
+++ b/libs/xmlrpc-c/include/xmlrpc-c/base.hpp
@@ -1,19 +1,24 @@
#ifndef XMLRPC_BASE_HPP_INCLUDED
#define XMLRPC_BASE_HPP_INCLUDED
+#include
+
#include
#include
#include
#include
#include