mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-08-13 01:26:58 +00:00
add xmlrpc-c 1.03.14 to in tree libs
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3772 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
32
libs/xmlrpc-c/lib/util/Makefile
Normal file
32
libs/xmlrpc-c/lib/util/Makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
ifeq ($(SRCDIR)x,x)
|
||||
SRCDIR = $(CURDIR)/../..
|
||||
BUILDDIR = $(SRCDIR)
|
||||
endif
|
||||
|
||||
default: all
|
||||
|
||||
include $(BUILDDIR)/Makefile.config
|
||||
|
||||
include $(SRCDIR)/Makefile.common
|
||||
|
||||
.PHONY: all
|
||||
all: casprintf.lo cmdline_parser.lo getoptx.lo
|
||||
|
||||
INCLUDES = -Iinclude -I$(BUILDDIR)
|
||||
|
||||
CFLAGS = $(CFLAGS_COMMON) $(INCLUDES) $(CFLAGS_PERSONAL) $(CADD)
|
||||
|
||||
%.lo:%.c
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CFLAGS) $<
|
||||
|
||||
include Makefile.depend
|
||||
|
||||
.PHONY: clean distclean
|
||||
clean: clean-common
|
||||
|
||||
distclean: clean distclean-common
|
||||
|
||||
.PHONY: dep
|
||||
dep: dep-common
|
||||
|
||||
install:
|
0
libs/xmlrpc-c/lib/util/Makefile.depend
Normal file
0
libs/xmlrpc-c/lib/util/Makefile.depend
Normal file
83
libs/xmlrpc-c/lib/util/casprintf.c
Normal file
83
libs/xmlrpc-c/lib/util/casprintf.c
Normal file
@@ -0,0 +1,83 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "xmlrpc_config.h" /* For HAVE_ASPRINTF, __inline__ */
|
||||
#include "casprintf.h"
|
||||
|
||||
|
||||
|
||||
static __inline__ void
|
||||
simpleVasprintf(char ** const retvalP,
|
||||
const char * const fmt,
|
||||
va_list varargs) {
|
||||
/*----------------------------------------------------------------------------
|
||||
This is a poor man's implementation of vasprintf(), of GNU fame.
|
||||
-----------------------------------------------------------------------------*/
|
||||
size_t const initialSize = 4096;
|
||||
char * result;
|
||||
|
||||
result = malloc(initialSize);
|
||||
if (result != NULL) {
|
||||
size_t bytesNeeded;
|
||||
bytesNeeded = vsnprintf(result, initialSize, fmt, varargs);
|
||||
if (bytesNeeded > initialSize) {
|
||||
free(result);
|
||||
result = malloc(bytesNeeded);
|
||||
if (result != NULL)
|
||||
vsnprintf(result, bytesNeeded, fmt, varargs);
|
||||
} else if (bytesNeeded == initialSize) {
|
||||
if (result[initialSize-1] != '\0') {
|
||||
/* This is one of those old systems where vsnprintf()
|
||||
returns the number of bytes it used, instead of the
|
||||
number that it needed, and it in fact needed more than
|
||||
we gave it. Rather than mess with this highly unlikely
|
||||
case (old system and string > 4095 characters), we just
|
||||
treat this like an out of memory failure.
|
||||
*/
|
||||
free(result);
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
*retvalP = result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
cvasprintf(const char ** const retvalP,
|
||||
const char * const fmt,
|
||||
va_list varargs) {
|
||||
|
||||
char * retval;
|
||||
|
||||
#if HAVE_ASPRINTF
|
||||
vasprintf(&retval, fmt, varargs);
|
||||
#else
|
||||
simpleVasprintf(&retval, fmt, varargs);
|
||||
#endif
|
||||
|
||||
*retvalP = retval;
|
||||
}
|
||||
|
||||
|
||||
void GNU_PRINTF_ATTR(2,3)
|
||||
casprintf(const char ** const retvalP, const char * const fmt, ...) {
|
||||
|
||||
va_list varargs; /* mysterious structure used by variable arg facility */
|
||||
|
||||
va_start(varargs, fmt); /* start up the mysterious variable arg facility */
|
||||
|
||||
cvasprintf(retvalP, fmt, varargs);
|
||||
|
||||
va_end(varargs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
strfree(const char * const string) {
|
||||
free((void *)string);
|
||||
}
|
449
libs/xmlrpc-c/lib/util/cmdline_parser.c
Normal file
449
libs/xmlrpc-c/lib/util/cmdline_parser.c
Normal file
@@ -0,0 +1,449 @@
|
||||
#include "xmlrpc_config.h" /* prereq for mallocvar.h -- defines __inline__ */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "mallocvar.h"
|
||||
#include "bool.h"
|
||||
#include "casprintf.h"
|
||||
#include "getoptx.h"
|
||||
|
||||
#include "cmdline_parser.h"
|
||||
|
||||
#define MAXOPTS 100
|
||||
|
||||
struct optionDesc {
|
||||
const char * name;
|
||||
enum optiontype type;
|
||||
bool present;
|
||||
union {
|
||||
unsigned int u;
|
||||
int i;
|
||||
const char * s;
|
||||
} value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct cmdlineParserCtl {
|
||||
struct optionDesc * optionDescArray;
|
||||
unsigned int numOptions;
|
||||
const char ** argumentArray;
|
||||
unsigned int numArguments;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct optionx *
|
||||
createLongOptsArray(struct optionDesc * const optionDescArray,
|
||||
unsigned int const numOptions) {
|
||||
|
||||
struct optionx * longopts;
|
||||
|
||||
MALLOCARRAY(longopts, numOptions+1);
|
||||
if (longopts != NULL) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < numOptions; ++i) {
|
||||
longopts[i].name = optionDescArray[i].name;
|
||||
/* If the option takes a value, we say it is optional even
|
||||
though it never is. That's because if we say it is
|
||||
mandatory, getopt_long_only() pretends it doesn't even
|
||||
recognize the option if the user doesn't give a value.
|
||||
We prefer to generate a meaningful error message when
|
||||
the user omits a required option value.
|
||||
*/
|
||||
longopts[i].has_arg =
|
||||
optionDescArray[i].type == OPTTYPE_FLAG ?
|
||||
no_argument : optional_argument;
|
||||
longopts[i].flag = NULL;
|
||||
longopts[i].val = i;
|
||||
}
|
||||
longopts[numOptions].name = 0;
|
||||
longopts[numOptions].has_arg = 0;
|
||||
longopts[numOptions].flag = 0;
|
||||
longopts[numOptions].val = 0;
|
||||
}
|
||||
return longopts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
parseOptionValue(const char * const optarg,
|
||||
struct optionDesc * const optionP,
|
||||
const char ** const errorP) {
|
||||
|
||||
switch (optionP->type) {
|
||||
case OPTTYPE_UINT:
|
||||
case OPTTYPE_INT: {
|
||||
if (optarg == NULL)
|
||||
casprintf(errorP, "Option requires a value");
|
||||
else if (strlen(optarg) == 0)
|
||||
casprintf(errorP, "Numeric option value is null string");
|
||||
else {
|
||||
char * tailptr;
|
||||
long const longvalue = strtol(optarg, &tailptr, 10);
|
||||
if (*tailptr != '\0')
|
||||
casprintf(errorP, "Non-numeric value "
|
||||
"for numeric option value: '%s'", optarg);
|
||||
else if (errno == ERANGE || longvalue > INT_MAX)
|
||||
casprintf(errorP, "Numeric value out of range: %s", optarg);
|
||||
else {
|
||||
if (optionP->type == OPTTYPE_UINT) {
|
||||
if (longvalue < 0)
|
||||
casprintf(errorP, "Unsigned numeric value is "
|
||||
"negative: %ld", longvalue);
|
||||
else {
|
||||
*errorP = NULL;
|
||||
optionP->value.u = (unsigned int) longvalue;
|
||||
}
|
||||
} else {
|
||||
*errorP = NULL;
|
||||
optionP->value.u = (int) longvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OPTTYPE_STRING:
|
||||
if (optarg == NULL)
|
||||
casprintf(errorP, "Option requires a value");
|
||||
else {
|
||||
*errorP = NULL;
|
||||
optionP->value.s = strdup(optarg);
|
||||
}
|
||||
break;
|
||||
case OPTTYPE_FLAG:
|
||||
*errorP = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
processOption(struct optionDesc * const optionP,
|
||||
const char * const optarg,
|
||||
const char ** const errorP) {
|
||||
|
||||
const char * error;
|
||||
|
||||
parseOptionValue(optarg, optionP, &error);
|
||||
if (error)
|
||||
casprintf(errorP, "Error in '%s' option: %s", optionP->name, error);
|
||||
else
|
||||
optionP->present = TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
extractArguments(struct cmdlineParserCtl * const cpP,
|
||||
unsigned int const argc,
|
||||
const char ** const argv) {
|
||||
|
||||
cpP->numArguments = argc - getopt_argstart();
|
||||
MALLOCARRAY(cpP->argumentArray, cpP->numArguments);
|
||||
|
||||
if (cpP->argumentArray == NULL) {
|
||||
fprintf(stderr, "Unable to allocate memory for argument array\n");
|
||||
abort();
|
||||
} else {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < cpP->numArguments; ++i) {
|
||||
cpP->argumentArray[i] = strdup(argv[getopt_argstart() + i]);
|
||||
if (cpP->argumentArray[i] == NULL) {
|
||||
fprintf(stderr, "Unable to allocate memory for Argument %u\n",
|
||||
i);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
cmd_processOptions(cmdlineParser const cpP,
|
||||
int const argc,
|
||||
const char ** const argv,
|
||||
const char ** const errorP) {
|
||||
|
||||
struct optionx * longopts;
|
||||
|
||||
longopts = createLongOptsArray(cpP->optionDescArray, cpP->numOptions);
|
||||
|
||||
if (longopts == NULL)
|
||||
casprintf(errorP, "Unable to get memory for longopts array");
|
||||
else {
|
||||
int endOfOptions;
|
||||
unsigned int i;
|
||||
|
||||
*errorP = NULL;
|
||||
|
||||
/* Set up initial assumption: No options present */
|
||||
|
||||
for (i = 0; i < cpP->numOptions; ++i)
|
||||
cpP->optionDescArray[i].present = FALSE;
|
||||
|
||||
endOfOptions = FALSE; /* initial value */
|
||||
|
||||
while (!endOfOptions && !*errorP) {
|
||||
int const opterr0 = 0;
|
||||
/* Don't let getopt_long_only() print an error message */
|
||||
unsigned int longoptsIndex;
|
||||
const char * unrecognizedOption;
|
||||
const char * optarg;
|
||||
|
||||
getopt_long_onlyx(argc, (char**) argv, "", longopts,
|
||||
&longoptsIndex, opterr0,
|
||||
&endOfOptions, &optarg, &unrecognizedOption);
|
||||
|
||||
if (unrecognizedOption)
|
||||
casprintf(errorP, "Unrecognized option: '%s'",
|
||||
unrecognizedOption);
|
||||
else {
|
||||
if (!endOfOptions)
|
||||
processOption(&cpP->optionDescArray[longoptsIndex], optarg,
|
||||
errorP);
|
||||
}
|
||||
}
|
||||
if (!*errorP)
|
||||
extractArguments(cpP, argc, argv);
|
||||
|
||||
free(longopts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
cmdlineParser
|
||||
cmd_createOptionParser(void) {
|
||||
|
||||
struct cmdlineParserCtl * cpP;
|
||||
|
||||
MALLOCVAR(cpP);
|
||||
|
||||
if (cpP != NULL) {
|
||||
struct optionDesc * optionDescArray;
|
||||
|
||||
cpP->numOptions = 0;
|
||||
MALLOCARRAY(optionDescArray, MAXOPTS);
|
||||
if (optionDescArray == NULL) {
|
||||
free(cpP);
|
||||
cpP = NULL;
|
||||
} else
|
||||
cpP->optionDescArray = optionDescArray;
|
||||
}
|
||||
return cpP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
cmd_destroyOptionParser(cmdlineParser const cpP) {
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < cpP->numOptions; ++i) {
|
||||
struct optionDesc const option = cpP->optionDescArray[i];
|
||||
if (option.type == OPTTYPE_STRING && option.present)
|
||||
strfree(option.value.s);
|
||||
strfree(option.name);
|
||||
}
|
||||
|
||||
for (i = 0; i < cpP->numArguments; ++i)
|
||||
strfree(cpP->argumentArray[i]);
|
||||
|
||||
free(cpP->optionDescArray);
|
||||
free(cpP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
cmd_defineOption(cmdlineParser const cpP,
|
||||
const char * const name,
|
||||
enum optiontype const type) {
|
||||
|
||||
if (cpP->numOptions < MAXOPTS) {
|
||||
cpP->optionDescArray[cpP->numOptions].name = strdup(name);
|
||||
cpP->optionDescArray[cpP->numOptions].type = type;
|
||||
|
||||
++cpP->numOptions;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct optionDesc *
|
||||
findOptionDesc(struct cmdlineParserCtl * const cpP,
|
||||
const char * const name) {
|
||||
|
||||
struct optionDesc * retval;
|
||||
unsigned int i;
|
||||
|
||||
retval = NULL;
|
||||
|
||||
for (i = 0; i < cpP->numOptions && !retval; ++i)
|
||||
if (strcmp(cpP->optionDescArray[i].name, name) == 0)
|
||||
retval = &cpP->optionDescArray[i];
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
cmd_optionIsPresent(cmdlineParser const cpP,
|
||||
const char * const name) {
|
||||
|
||||
struct optionDesc * const optionDescP = findOptionDesc(cpP, name);
|
||||
|
||||
bool present;
|
||||
|
||||
if (!optionDescP) {
|
||||
fprintf(stderr, "cmdlineParser called incorrectly. "
|
||||
"optionIsPresent() called for undefined option '%s'\n",
|
||||
name);
|
||||
abort();
|
||||
} else
|
||||
present = optionDescP->present;
|
||||
|
||||
return present;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned int
|
||||
cmd_getOptionValueUint(cmdlineParser const cpP,
|
||||
const char * const name) {
|
||||
|
||||
struct optionDesc * const optionDescP = findOptionDesc(cpP, name);
|
||||
|
||||
unsigned int retval;
|
||||
|
||||
if (!optionDescP) {
|
||||
fprintf(stderr, "cmdlineParser called incorrectly. "
|
||||
"cmd_getOptionValueUint() called for undefined option '%s'\n",
|
||||
name);
|
||||
abort();
|
||||
} else {
|
||||
if (optionDescP->type != OPTTYPE_UINT) {
|
||||
fprintf(stderr, "cmdlineParser called incorrectly. "
|
||||
"cmd_getOptionValueUint() called for non-unsigned integer "
|
||||
"option '%s'\n", optionDescP->name);
|
||||
abort();
|
||||
} else {
|
||||
if (optionDescP->present)
|
||||
retval = optionDescP->value.u;
|
||||
else
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
cmd_getOptionValueInt(cmdlineParser const cpP,
|
||||
const char * const name) {
|
||||
|
||||
struct optionDesc * const optionDescP = findOptionDesc(cpP, name);
|
||||
|
||||
int retval;
|
||||
|
||||
if (!optionDescP) {
|
||||
fprintf(stderr, "cmdlineParser called incorrectly. "
|
||||
"cmd_getOptionValueInt() called for undefined option '%s'\n",
|
||||
name);
|
||||
abort();
|
||||
} else {
|
||||
if (optionDescP->type != OPTTYPE_INT) {
|
||||
fprintf(stderr, "cmdlineParser called incorrectly. "
|
||||
"cmd_getOptionValueInt() called for non-integer "
|
||||
"option '%s'\n", optionDescP->name);
|
||||
abort();
|
||||
} else {
|
||||
if (optionDescP->present)
|
||||
retval = optionDescP->value.i;
|
||||
else
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
cmd_getOptionValueString(cmdlineParser const cpP,
|
||||
const char * const name) {
|
||||
|
||||
struct optionDesc * const optionDescP = findOptionDesc(cpP, name);
|
||||
|
||||
const char * retval;
|
||||
|
||||
if (!optionDescP) {
|
||||
fprintf(stderr, "cmdlineParser called incorrectly. "
|
||||
"cmd_getOptionValueString() called for "
|
||||
"undefined option '%s'\n",
|
||||
name);
|
||||
abort();
|
||||
} else {
|
||||
if (optionDescP->type != OPTTYPE_STRING) {
|
||||
fprintf(stderr, "cmdlineParser called incorrectly. "
|
||||
"getOptionValueString() called for non-string "
|
||||
"option '%s'\n", optionDescP->name);
|
||||
abort();
|
||||
} else {
|
||||
if (optionDescP->present) {
|
||||
retval = strdup(optionDescP->value.s);
|
||||
if (retval == NULL) {
|
||||
fprintf(stderr,
|
||||
"out of memory in cmd_getOptionValueString()\n");
|
||||
abort();
|
||||
}
|
||||
} else
|
||||
retval = NULL;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned int
|
||||
cmd_argumentCount(cmdlineParser const cpP) {
|
||||
|
||||
return cpP->numArguments;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
cmd_getArgument(cmdlineParser const cpP,
|
||||
unsigned int const argNumber) {
|
||||
|
||||
const char * retval;
|
||||
|
||||
if (argNumber >= cpP->numArguments)
|
||||
retval = NULL;
|
||||
else {
|
||||
retval = strdup(cpP->argumentArray[argNumber]);
|
||||
|
||||
if (retval == NULL) {
|
||||
fprintf(stderr,
|
||||
"out of memory in cmd_getArgument()\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
462
libs/xmlrpc-c/lib/util/getoptx.c
Normal file
462
libs/xmlrpc-c/lib/util/getoptx.c
Normal file
@@ -0,0 +1,462 @@
|
||||
/* This version of `getopt' appears to the caller like standard Unix getopt()
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As getopt() works, it permutes the elements of `argv' so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "getoptx.h"
|
||||
|
||||
#ifdef _AIX
|
||||
#pragma alloca
|
||||
#endif
|
||||
|
||||
/* Note that on some systems, the header files above declare variables
|
||||
for use with their native getopt facilities, and those variables have
|
||||
the same names as we'd like to use. So we use things like optargx
|
||||
instead of optarg to avoid the collision.
|
||||
*/
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
*/
|
||||
static char *optargx = 0;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to getoptx().
|
||||
|
||||
On entry to getoptx(), zero means this is the first call; initialize.
|
||||
|
||||
When getoptx() returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optindx' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far.
|
||||
*/
|
||||
|
||||
static int optindx = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options.
|
||||
*/
|
||||
|
||||
static int opterrx;
|
||||
|
||||
/* Index in _GETOPT_LONG_OPTIONS of the long-named option actually found.
|
||||
Only valid when a long-named option was found. */
|
||||
|
||||
static int option_index;
|
||||
|
||||
struct optionx * _getopt_long_options;
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optindx), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange(char ** const argv) {
|
||||
unsigned int const nonopts_size =
|
||||
(last_nonopt - first_nonopt) * sizeof (char *);
|
||||
char **temp = (char **) alloca (nonopts_size);
|
||||
|
||||
/* Interchange the two blocks of data in argv. */
|
||||
|
||||
bcopy (&argv[first_nonopt], temp, nonopts_size);
|
||||
bcopy (&argv[last_nonopt], &argv[first_nonopt],
|
||||
(optindx - last_nonopt) * sizeof (char *));
|
||||
bcopy (temp, &argv[first_nonopt + optindx - last_nonopt],
|
||||
nonopts_size);
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (optindx - last_nonopt);
|
||||
last_nonopt = optindx;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If getoptx()
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If getoptx() finds another option character, it returns that character,
|
||||
updating `optindx' and `nextchar' so that the next call to getoptx() can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, getoptx() returns `EOF'.
|
||||
Then `optindx' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set `opterrx' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optargx'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optargx', otherwise `optargx' is set to zero.
|
||||
|
||||
If OPTSTRING starts with `-', it requests a different method of handling the
|
||||
non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above.
|
||||
|
||||
Long-named options begin with `+' instead of `-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a `=', or else the in next ARGV-element.
|
||||
getoptx() returns 0 when it finds a long-named option. */
|
||||
|
||||
static int
|
||||
getoptx(int const argc,
|
||||
char ** const argv,
|
||||
const char * const optstring) {
|
||||
|
||||
optargx = 0;
|
||||
|
||||
/* Initialize the internal data when the first call is made.
|
||||
Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
if (optindx == 0)
|
||||
{
|
||||
first_nonopt = last_nonopt = optindx = 1;
|
||||
|
||||
nextchar = 0;
|
||||
|
||||
}
|
||||
|
||||
if (nextchar == 0 || *nextchar == 0)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optindx)
|
||||
exchange (argv);
|
||||
else if (last_nonopt != optindx)
|
||||
first_nonopt = optindx;
|
||||
|
||||
/* Now skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optindx < argc
|
||||
&& (argv[optindx][0] != '-'|| argv[optindx][1] == 0)
|
||||
&& (argv[optindx][0] != '+'|| argv[optindx][1] == 0))
|
||||
optindx++;
|
||||
last_nonopt = optindx;
|
||||
|
||||
/* Special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optindx != argc && !strcmp (argv[optindx], "--"))
|
||||
{
|
||||
optindx++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optindx)
|
||||
exchange (argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optindx;
|
||||
last_nonopt = argc;
|
||||
|
||||
optindx = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optindx == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optindx = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass
|
||||
it by.
|
||||
*/
|
||||
|
||||
if ((argv[optindx][0] != '-' || argv[optindx][1] == 0)
|
||||
&& (argv[optindx][0] != '+' || argv[optindx][1] == 0))
|
||||
{
|
||||
optargx = argv[optindx++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Start decoding its characters. */
|
||||
|
||||
nextchar = argv[optindx] + 1;
|
||||
}
|
||||
|
||||
if ((argv[optindx][0] == '+' || (argv[optindx][0] == '-'))
|
||||
)
|
||||
{
|
||||
struct optionx *p;
|
||||
char *s = nextchar;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
struct optionx *pfound = 0;
|
||||
int indfound;
|
||||
|
||||
while (*s && *s != '=') s++;
|
||||
|
||||
/* Test all options for either exact match or abbreviated matches. */
|
||||
for (p = _getopt_long_options, option_index = 0; p->name;
|
||||
p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, s - nextchar))
|
||||
{
|
||||
if ((unsigned int)(s - nextchar) == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == 0)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||
argv[0], argv[optindx]);
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != 0)
|
||||
{
|
||||
option_index = indfound;
|
||||
optindx++;
|
||||
if (*s)
|
||||
{
|
||||
if (pfound->has_arg > 0)
|
||||
optargx = s + 1;
|
||||
else
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s: option `%c%s' doesn't allow an argument\n",
|
||||
argv[0], argv[optindx - 1][0], pfound->name);
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg)
|
||||
{
|
||||
if (optindx < argc)
|
||||
optargx = argv[optindx++];
|
||||
else if (pfound->has_arg != 2)
|
||||
{
|
||||
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
||||
argv[0], argv[optindx - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (pfound->flag)
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
if (argv[optindx][0] == '+' || index (optstring, *nextchar) == 0)
|
||||
{
|
||||
if (opterrx != 0)
|
||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||
argv[0], argv[optindx][0], nextchar);
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = index (optstring, c);
|
||||
|
||||
/* Increment `optindx' when we start to process its last character. */
|
||||
if (*nextchar == 0)
|
||||
optindx++;
|
||||
|
||||
if (temp == 0 || c == ':')
|
||||
{
|
||||
if (opterrx != 0)
|
||||
{
|
||||
if (c < 040 || c >= 0177)
|
||||
fprintf (stderr, "%s: unrecognized option, "
|
||||
"character code 0%o\n",
|
||||
argv[0], c);
|
||||
else
|
||||
fprintf (stderr, "%s: unrecognized option `-%c'\n",
|
||||
argv[0], c);
|
||||
}
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != 0)
|
||||
{
|
||||
optargx = nextchar;
|
||||
optindx++;
|
||||
}
|
||||
else
|
||||
optargx = 0;
|
||||
nextchar = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != 0)
|
||||
{
|
||||
optargx = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest
|
||||
as an arg, we must advance to the next element
|
||||
now.
|
||||
*/
|
||||
optindx++;
|
||||
}
|
||||
else if (optindx == argc)
|
||||
{
|
||||
if (opterrx != 0)
|
||||
fprintf (stderr,
|
||||
"%s: option `-%c' requires an argument\n",
|
||||
argv[0], c);
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optindx' once;
|
||||
increment it again when taking next ARGV-elt as
|
||||
argument.
|
||||
*/
|
||||
optargx = argv[optindx++];
|
||||
nextchar = 0;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
getopt_long_onlyx(int const argc,
|
||||
char ** const argv,
|
||||
const char * const options,
|
||||
struct optionx * const long_options,
|
||||
unsigned int * const opt_index,
|
||||
int const opterrArg,
|
||||
int * const end_of_options,
|
||||
const char ** const optarg_arg,
|
||||
const char ** const unrecognized_option) {
|
||||
|
||||
int rc;
|
||||
|
||||
opterrx = opterrArg;
|
||||
_getopt_long_options = long_options;
|
||||
rc = getoptx(argc, argv, options);
|
||||
if (rc == 0)
|
||||
*opt_index = option_index;
|
||||
|
||||
if (rc == '?')
|
||||
*unrecognized_option = argv[optindx];
|
||||
else
|
||||
*unrecognized_option = NULL;
|
||||
|
||||
if (rc < 0)
|
||||
*end_of_options = 1;
|
||||
else
|
||||
*end_of_options = 0;
|
||||
|
||||
*optarg_arg = optargx;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
getopt_argstart(void) {
|
||||
/*----------------------------------------------------------------------------
|
||||
This is a replacement for what traditional getopt does with global
|
||||
variables.
|
||||
|
||||
You call this after getopt_long_onlyx() has returned "end of
|
||||
options"
|
||||
-----------------------------------------------------------------------------*/
|
||||
return optindx;
|
||||
}
|
||||
|
||||
|
||||
/* Getopt for GNU.
|
||||
Copyright (C) 1987, 1989 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
51
libs/xmlrpc-c/lib/util/getoptx.h
Normal file
51
libs/xmlrpc-c/lib/util/getoptx.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* Interface to getopt_long_onlyx() */
|
||||
|
||||
|
||||
enum argreq {no_argument, required_argument, optional_argument};
|
||||
|
||||
struct optionx {
|
||||
/* This describes an option. If the field `flag' is nonzero, it
|
||||
points to a variable that is to be set to the value given in
|
||||
the field `val' when the option is found, but left unchanged if
|
||||
the option is not found.
|
||||
*/
|
||||
const char * name;
|
||||
enum argreq has_arg;
|
||||
int * flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* long_options[] is a list terminated by an element that contains
|
||||
a NULL 'name' member.
|
||||
*/
|
||||
void
|
||||
getopt_long_onlyx(int const argc,
|
||||
char ** const argv,
|
||||
const char * const options,
|
||||
struct optionx * const long_options,
|
||||
unsigned int * const opt_index,
|
||||
int const opterrArg,
|
||||
int * const end_of_options,
|
||||
const char ** const optarg_arg,
|
||||
const char ** const unrecognized_option);
|
||||
|
||||
unsigned int
|
||||
getopt_argstart(void);
|
||||
|
||||
/*
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
18
libs/xmlrpc-c/lib/util/include/bool.h
Normal file
18
libs/xmlrpc-c/lib/util/include/bool.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef BOOL_H_INCLUDED
|
||||
#define BOOL_H_INCLUDED
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1)
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE (0)
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#ifndef HAVE_BOOL
|
||||
#define HAVE_BOOL
|
||||
typedef int bool;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
27
libs/xmlrpc-c/lib/util/include/casprintf.h
Normal file
27
libs/xmlrpc-c/lib/util/include/casprintf.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef CASPRINTF_H_INCLUDED
|
||||
#define CASPRINTF_H_INCLUDED
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/* GNU_PRINTF_ATTR lets the GNU compiler check printf-type
|
||||
calls to be sure the arguments match the format string, thus preventing
|
||||
runtime segmentation faults and incorrect messages.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
#define GNU_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b)))
|
||||
#else
|
||||
#define GNU_PRINTF_ATTR(a,b)
|
||||
#endif
|
||||
|
||||
void
|
||||
cvasprintf(const char ** const retvalP,
|
||||
const char * const fmt,
|
||||
va_list varargs);
|
||||
|
||||
void GNU_PRINTF_ATTR(2,3)
|
||||
casprintf(const char ** const retvalP, const char * const fmt, ...);
|
||||
|
||||
void
|
||||
strfree(const char * const string);
|
||||
|
||||
#endif
|
59
libs/xmlrpc-c/lib/util/include/cmdline_parser.h
Normal file
59
libs/xmlrpc-c/lib/util/include/cmdline_parser.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef CMDLINE_PARSER_H
|
||||
#define CMDLINE_PARSER_H
|
||||
|
||||
|
||||
/*
|
||||
|
||||
NOTE NOTE NOTE: cmd_getOptionValueString() and
|
||||
cmd_getArgument() return malloc'ed memory (and abort the program if
|
||||
out of memory). You must free it.
|
||||
|
||||
*/
|
||||
|
||||
enum optiontype {OPTTYPE_FLAG, OPTTYPE_INT, OPTTYPE_UINT, OPTTYPE_STRING};
|
||||
|
||||
struct cmdlineParserCtl;
|
||||
|
||||
typedef struct cmdlineParserCtl * cmdlineParser;
|
||||
|
||||
void
|
||||
cmd_processOptions(cmdlineParser const cpP,
|
||||
int const argc,
|
||||
const char ** const argv,
|
||||
const char ** const errorP);
|
||||
|
||||
cmdlineParser
|
||||
cmd_createOptionParser(void);
|
||||
|
||||
void
|
||||
cmd_destroyOptionParser(cmdlineParser const cpP);
|
||||
|
||||
void
|
||||
cmd_defineOption(cmdlineParser const cpP,
|
||||
const char * const name,
|
||||
enum optiontype const type);
|
||||
|
||||
int
|
||||
cmd_optionIsPresent(cmdlineParser const cpP,
|
||||
const char * const name);
|
||||
|
||||
unsigned int
|
||||
cmd_getOptionValueUint(cmdlineParser const cpP,
|
||||
const char * const name);
|
||||
|
||||
int
|
||||
cmd_getOptionValueInt(cmdlineParser const cpP,
|
||||
const char * const name);
|
||||
|
||||
const char *
|
||||
cmd_getOptionValueString(cmdlineParser const cpP,
|
||||
const char * const name);
|
||||
|
||||
unsigned int
|
||||
cmd_argumentCount(cmdlineParser const cpP);
|
||||
|
||||
const char *
|
||||
cmd_getArgument(cmdlineParser const cpP,
|
||||
unsigned int const argNumber);
|
||||
|
||||
#endif
|
19
libs/xmlrpc-c/lib/util/include/inline.h
Normal file
19
libs/xmlrpc-c/lib/util/include/inline.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef XMLRPC_INLINE_H_INCLUDED
|
||||
#define XMLRPC_INLINE_H_INCLUDED
|
||||
|
||||
/* Xmlrpc-c uses __inline__ to declare functions that should be
|
||||
compiled as inline code. Some compilers, e.g. GNU, recognize the
|
||||
__inline__ keyword.
|
||||
*/
|
||||
#ifndef __GNUC__
|
||||
#ifndef __inline__
|
||||
#ifdef __sgi
|
||||
#define __inline__ __inline
|
||||
#else
|
||||
#define __inline__
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
193
libs/xmlrpc-c/lib/util/include/linklist.h
Normal file
193
libs/xmlrpc-c/lib/util/include/linklist.h
Normal file
@@ -0,0 +1,193 @@
|
||||
#ifndef LINKLIST_H_INCLUDED
|
||||
#define LINKLIST_H_INCLUDED
|
||||
|
||||
#include "inline.h"
|
||||
|
||||
struct list_head {
|
||||
/*----------------------------------------------------------------------------
|
||||
This is a header for an element of a doubly linked list, or an anchor
|
||||
for such a list.
|
||||
|
||||
itemP == NULL means it's an anchor; otherwise it's a header.
|
||||
|
||||
Initialize a list header with list_init_header(). You don't have to
|
||||
do anything to terminate a list header.
|
||||
|
||||
Initialize an anchor with list_make_emtpy(). You don't have to do anything
|
||||
to terminate a list header.
|
||||
-----------------------------------------------------------------------------*/
|
||||
struct list_head * nextP;
|
||||
/* For a header, this is the address of the list header for
|
||||
the next element in the list. If there is no next element,
|
||||
it points to the anchor. If the header is not in a list at
|
||||
all, it is NULL.
|
||||
|
||||
For an anchor, it is the address of the list header of the
|
||||
first element. If the list is empty, it points to the
|
||||
anchor itself.
|
||||
*/
|
||||
struct list_head * prevP;
|
||||
/* For a header, this is the address of the list header for
|
||||
the previous element in the list. If there is no previous element,
|
||||
it points to the anchor. If the header is not in a list at
|
||||
all, it is NULL.
|
||||
|
||||
For an anchor, it is the address of the list header of the
|
||||
last element. If the list is empty, it points to the
|
||||
anchor itself.
|
||||
*/
|
||||
void * itemP;
|
||||
/* For a header, this is the address of the list element to which it
|
||||
belongs. For an anchor, this is NULL.
|
||||
*/
|
||||
};
|
||||
|
||||
static __inline__ void
|
||||
list_init_header(struct list_head * const headerP,
|
||||
void * const itemP) {
|
||||
|
||||
headerP->prevP = NULL;
|
||||
headerP->nextP = NULL;
|
||||
headerP->itemP = itemP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ int
|
||||
list_is_linked(struct list_head * headerP) {
|
||||
return headerP->prevP != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ int
|
||||
list_is_empty(struct list_head * const anchorP) {
|
||||
return anchorP->nextP == anchorP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ unsigned int
|
||||
list_count(struct list_head * const anchorP) {
|
||||
unsigned int count;
|
||||
|
||||
struct list_head * p;
|
||||
|
||||
for (p = anchorP->nextP, count = 0;
|
||||
p != anchorP;
|
||||
p = p->nextP, ++count);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ void
|
||||
list_make_empty(struct list_head * const anchorP) {
|
||||
anchorP->prevP = anchorP;
|
||||
anchorP->nextP = anchorP;
|
||||
anchorP->itemP = NULL;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
list_insert_after(struct list_head * const beforeHeaderP,
|
||||
struct list_head * const newHeaderP) {
|
||||
newHeaderP->prevP = beforeHeaderP;
|
||||
newHeaderP->nextP = beforeHeaderP->nextP;
|
||||
|
||||
beforeHeaderP->nextP = newHeaderP;
|
||||
newHeaderP->nextP->prevP = newHeaderP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ void
|
||||
list_add_tail(struct list_head * const anchorP,
|
||||
struct list_head * const headerP) {
|
||||
list_insert_after(anchorP->prevP, headerP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ void
|
||||
list_add_head(struct list_head * const anchorP,
|
||||
struct list_head * const headerP) {
|
||||
list_insert_after(anchorP, headerP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ void
|
||||
list_remove(struct list_head * const headerP) {
|
||||
headerP->prevP->nextP = headerP->nextP;
|
||||
headerP->nextP->prevP = headerP->prevP;
|
||||
headerP->prevP = NULL;
|
||||
headerP->nextP = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ struct list_head *
|
||||
list_remove_head(struct list_head * const anchorP) {
|
||||
struct list_head * retval;
|
||||
|
||||
if (list_is_empty(anchorP))
|
||||
retval = NULL;
|
||||
else {
|
||||
retval = anchorP->nextP;
|
||||
list_remove(retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ struct list_head *
|
||||
list_remove_tail(struct list_head * const anchorP) {
|
||||
struct list_head * retval;
|
||||
|
||||
if (list_is_empty(anchorP))
|
||||
retval = NULL;
|
||||
else {
|
||||
retval = anchorP->prevP;
|
||||
list_remove(retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ void *
|
||||
list_foreach(struct list_head * const anchorP,
|
||||
void * functionP(struct list_head *, void *),
|
||||
void * const context) {
|
||||
|
||||
struct list_head * p;
|
||||
struct list_head * nextP;
|
||||
void * result;
|
||||
|
||||
for (p = anchorP->nextP, nextP = p->nextP, result=NULL;
|
||||
p != anchorP && result == NULL;
|
||||
p = nextP, nextP = p->nextP)
|
||||
result = (*functionP)(p, context);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ void
|
||||
list_append(struct list_head * const newAnchorP,
|
||||
struct list_head * const baseAnchorP) {
|
||||
|
||||
if (!list_is_empty(newAnchorP)) {
|
||||
baseAnchorP->prevP->nextP = newAnchorP->nextP;
|
||||
newAnchorP->nextP->prevP = baseAnchorP->prevP;
|
||||
newAnchorP->prevP->nextP = baseAnchorP;
|
||||
baseAnchorP->prevP = newAnchorP->prevP;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
94
libs/xmlrpc-c/lib/util/include/mallocvar.h
Normal file
94
libs/xmlrpc-c/lib/util/include/mallocvar.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/* These are some dynamic memory allocation facilities. They are essentially
|
||||
an extension to C, as they do allocations with a cognizance of C
|
||||
variables. You can use them to make C read more like a high level
|
||||
language.
|
||||
|
||||
Before including this, you must define an __inline__ macro if your
|
||||
compiler doesn't recognize it as a keyword.
|
||||
*/
|
||||
|
||||
#ifndef MALLOCVAR_INCLUDED
|
||||
#define MALLOCVAR_INCLUDED
|
||||
|
||||
#include "xmlrpc_config.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static __inline__ void
|
||||
mallocProduct(void ** const resultP,
|
||||
unsigned int const factor1,
|
||||
unsigned int const factor2) {
|
||||
/*----------------------------------------------------------------------------
|
||||
malloc a space whose size in bytes is the product of 'factor1' and
|
||||
'factor2'. But if that size cannot be represented as an unsigned int,
|
||||
return NULL without allocating anything. Also return NULL if the malloc
|
||||
fails.
|
||||
|
||||
If either factor is zero, malloc a single byte.
|
||||
|
||||
Note that malloc() actually takes a size_t size argument, so the
|
||||
proper test would be whether the size can be represented by size_t,
|
||||
not unsigned int. But there is no reliable indication available to
|
||||
us, like UINT_MAX, of what the limitations of size_t are. We
|
||||
assume size_t is at least as expressive as unsigned int and that
|
||||
nobody really needs to allocate more than 4GB of memory.
|
||||
-----------------------------------------------------------------------------*/
|
||||
if (factor1 == 0 || factor2 == 0)
|
||||
*resultP = malloc(1);
|
||||
else {
|
||||
if (UINT_MAX / factor2 < factor1)
|
||||
*resultP = NULL;
|
||||
else
|
||||
*resultP = malloc(factor1 * factor2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ void
|
||||
reallocProduct(void ** const blockP,
|
||||
unsigned int const factor1,
|
||||
unsigned int const factor2) {
|
||||
|
||||
if (UINT_MAX / factor2 < factor1)
|
||||
*blockP = NULL;
|
||||
else
|
||||
*blockP = realloc(*blockP, factor1 * factor2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define MALLOCARRAY(arrayName, nElements) do { \
|
||||
void * array; \
|
||||
mallocProduct(&array, nElements, sizeof(arrayName[0])); \
|
||||
arrayName = array; \
|
||||
} while (0)
|
||||
|
||||
#define REALLOCARRAY(arrayName, nElements) \
|
||||
reallocProduct((void **)&arrayName, nElements, sizeof(arrayName[0]))
|
||||
|
||||
|
||||
#define MALLOCARRAY_NOFAIL(arrayName, nElements) \
|
||||
do { \
|
||||
MALLOCARRAY(arrayName, nElements); \
|
||||
if ((arrayName) == NULL) \
|
||||
abort(); \
|
||||
} while(0)
|
||||
|
||||
#define REALLOCARRAY_NOFAIL(arrayName, nElements) \
|
||||
do { \
|
||||
REALLOCARRAY(arrayName, nElements); \
|
||||
if ((arrayName) == NULL) \
|
||||
abort(); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define MALLOCVAR(varName) \
|
||||
varName = malloc(sizeof(*varName))
|
||||
|
||||
#define MALLOCVAR_NOFAIL(varName) \
|
||||
do {if ((varName = malloc(sizeof(*varName))) == NULL) abort();} while(0)
|
||||
|
||||
#endif
|
||||
|
68
libs/xmlrpc-c/lib/util/include/pthreadx.h
Normal file
68
libs/xmlrpc-c/lib/util/include/pthreadx.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* Copyright (C) 2001 by First Peer, Inc. 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. */
|
||||
|
||||
#ifndef PTHREADX_H_INCLUDED
|
||||
#define PTHREADX_H_INCLUDED
|
||||
|
||||
#ifndef WIN32
|
||||
# define _REENTRANT
|
||||
# include <pthread.h>
|
||||
#elif defined (WIN32)
|
||||
|
||||
typedef HANDLE pthread_t;
|
||||
typedef CRITICAL_SECTION pthread_mutex_t;
|
||||
|
||||
#define PTHREAD_MUTEX_INITIALIZER NULL
|
||||
//usage: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
typedef
|
||||
struct {
|
||||
int attrs; //currently unused. placeholder.
|
||||
} pthread_attr_t;
|
||||
|
||||
typedef
|
||||
struct {
|
||||
int attrs; //currently unused. placeholder.
|
||||
} pthread_mutexattr_t;
|
||||
|
||||
//typedef void * (*pthread_func)(void *);
|
||||
typedef unsigned ( __stdcall *pthread_func )( void * );
|
||||
|
||||
extern int pthread_create(pthread_t *new_thread_ID,
|
||||
const pthread_attr_t *attr,
|
||||
pthread_func start_func, void *arg);
|
||||
extern int pthread_cancel(pthread_t target_thread);
|
||||
extern int pthread_join(pthread_t target_thread, void **status);
|
||||
extern int pthread_detach(pthread_t target_thread);
|
||||
|
||||
extern int pthread_mutex_init(pthread_mutex_t *mp,
|
||||
const pthread_mutexattr_t *attr);
|
||||
extern int pthread_mutex_lock(pthread_mutex_t *mp);
|
||||
extern int pthread_mutex_unlock(pthread_mutex_t *mp);
|
||||
extern int pthread_mutex_destroy(pthread_mutex_t *mp);
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#endif
|
15
libs/xmlrpc-c/lib/util/include/sstring.h
Normal file
15
libs/xmlrpc-c/lib/util/include/sstring.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef SSTRING_H_INCLUDED
|
||||
#define SSTRING_H_INCLUDED
|
||||
|
||||
/* This file contains string functions that are cognizant of the
|
||||
declared size of the destination data structure.
|
||||
*/
|
||||
|
||||
|
||||
/* Copy string pointed by B to array A with size checking. */
|
||||
#define SSTRCPY(A,B) \
|
||||
(strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0')
|
||||
#define SSTRCMP(A,B) \
|
||||
(strncmp((A), (B), sizeof(A)))
|
||||
|
||||
#endif
|
101
libs/xmlrpc-c/lib/util/pthreadx_win32.c
Normal file
101
libs/xmlrpc-c/lib/util/pthreadx_win32.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/* Copyright (C) 2001 by First Peer, Inc. 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. */
|
||||
|
||||
#include "xmlrpc_config.h"
|
||||
|
||||
#if WIN32
|
||||
|
||||
#include "pthreadx.h"
|
||||
|
||||
#include <process.h>
|
||||
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
|
||||
int pthread_create(pthread_t *new_thread_ID,
|
||||
const pthread_attr_t * attr,
|
||||
pthread_func start_func, void *arg)
|
||||
{
|
||||
HANDLE hThread;
|
||||
DWORD dwThreadID;
|
||||
|
||||
hThread = (HANDLE) _beginthreadex (
|
||||
NULL, 0, start_func, (LPVOID)arg, CREATE_SUSPENDED, &dwThreadID);
|
||||
|
||||
SetThreadPriority (hThread, THREAD_PRIORITY_NORMAL);
|
||||
ResumeThread (hThread);
|
||||
|
||||
*new_thread_ID = hThread;
|
||||
|
||||
return hThread ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Just kill it. */
|
||||
int pthread_cancel(pthread_t target_thread)
|
||||
{
|
||||
CloseHandle (target_thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Waits for the thread to exit before continuing. */
|
||||
int pthread_join(pthread_t target_thread, void **status)
|
||||
{
|
||||
DWORD dwResult = WaitForSingleObject(target_thread, INFINITE);
|
||||
(*status) = (void *)dwResult;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Stubbed. Do nothing. */
|
||||
int pthread_detach(pthread_t target_thread)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_init(pthread_mutex_t *mp,
|
||||
const pthread_mutexattr_t * attr)
|
||||
{
|
||||
InitializeCriticalSection(mp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_lock(pthread_mutex_t *mp)
|
||||
{
|
||||
EnterCriticalSection(mp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_unlock(pthread_mutex_t *mp)
|
||||
{
|
||||
LeaveCriticalSection(mp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_destroy(pthread_mutex_t *mp)
|
||||
{
|
||||
DeleteCriticalSection(mp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user