diff options
Diffstat (limited to 'common/compat.c')
| -rw-r--r-- | common/compat.c | 458 | 
1 files changed, 458 insertions, 0 deletions
| diff --git a/common/compat.c b/common/compat.c new file mode 100644 index 0000000..ff8d527 --- /dev/null +++ b/common/compat.c @@ -0,0 +1,458 @@ +/* + * AUTHOR + * N. Nielsen + * + * LICENSE + * This software is in the public domain. + * + * 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 author(s) 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. + * + * SUPPORT + * Send bug reports to: <nielsen@memberwebs.com> + */ + +#include <sys/types.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include "compat.h" + +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#ifndef HAVE_TOLOWER +int tolower(int c) +{ +	if('A' <= c && c <= 'Z') +		c += 'a' - 'A'; +	return c; +} +#define HAVE_TOLOWER +#endif + + +#ifndef HAVE_STRDUP + +#ifndef HAVE_MALLOC +#error Need a working malloc. +#endif + +char* strdup(const char* str) +{ +	char* dup = (char*)malloc((strlen(str) + 1) * sizeof(char)); +	if(dup) +		strcpy(dup, str); +	return dup; +} +#define HAVE_STRDUP +#endif + + +#ifndef HAVE_STRNDUP +#ifdef HAVE_MEMORY_H +#include <memory.h> +#endif +char* strndup(const char* str, size_t cnt) +{ +	char* buff = malloc(sizeof(char) * (cnt + 1)); +	if(buff) +	{ +		memcpy(buff, str, sizeof(char) * cnt); +		buff[cnt] = 0; +	} +	return buff; +} +#endif + + +#ifndef HAVE_STRCASESTR +char* strcasestr(const char* buff, const char* str) +{ +	const char* ptr = buff; + +    while (*ptr != 0x00) +	{ +        const char* one = ptr; +        const char* two = str; + +        while (tolower(*one) == tolower(*two)) +		{ +            one++; +            two++; +            if (*two == 0x00) +				return (char*) ptr; +        } +        ptr++; +    } +    return NULL; +} +#endif + +#ifndef HAVE_STRLCPY + +#ifndef HAVE_STRNCPY +#error neither strncpy or strlcpy found +#endif + +void strlcpy(char* dest, const char* src, size_t count) +{ +	strncpy(dest, src, count); +	dest[count - 1] = 0; +} +#endif + +#ifndef HAVE_STRLCAT + +#ifndef HAVE_STRNCAT +#error neither strncat or strlcat found +#endif + +void strlcat(char* dest, const char* src, size_t count) +{ +	strncat(dest, src, count); +	dest[count - 1] = 0; +} +#endif + + +#ifndef HAVE_VASPRINTF + +#ifndef HAVE_VSNPRINTF +#error neither vasprintf or vsnprintf found +#endif + +int vasprintf(char** ret, const char* format, va_list vl) +{ +	size_t size = 32; +	int c; +	*ret = NULL; + +	do +	{ +		// Double the buffer size for next time around +		size += size; + +		if(*ret) +			free(*ret); + +		*ret = (char*)malloc(sizeof(char) * size); + +		if(!(*ret)) +		{ +			errno = ENOMEM; +			return -1; +		} + +		c = vsnprintf(*ret, size, format, vl); +	} +	while(c < 0); + +	return c; +} + +#endif + + +/* + * We need to get a better check for this one. + * Basically have to make a variable __progname if none + * exist + */ + +#ifndef HAVE_UNISTD_H + +char* __progname = 0; +char prognamebuf[256]; + +void fixprogname() +{ +	if(__progname == 0) +	{ +		const char* beg = strrchr(_pgmptr, '\\'); +		const char* temp = strrchr(_pgmptr, '/'); +		beg = (beg > temp) ? beg : temp; +		beg = (beg) ? beg + 1 : _pgmptr; + +		temp = strrchr(_pgmptr, '.'); +		temp = (temp > beg) ? temp : _pgmptr + strlen(_pgmptr); + +		if((temp - beg) > 255) +			temp = beg + 255; + +		strncpy(prognamebuf, beg, temp - beg); +		prognamebuf[temp - beg] = 0; +		__progname = prognamebuf; +	} +} +#endif + + + +#ifndef HAVE_GETOPT + +int		opterr = 1,             /* if error message should be printed */ +        optind = 1,             /* index into parent argv vector */ +        optopt,                 /* character checked for validity */ +        optreset;               /* reset getopt */ +char*	optarg; + +#define BADCH   (int)'?' +#define BADARG  (int)':' +#define EMSG    "" + +/* + * getopt -- + *      Parse argc/argv argument vector. + */ +int getopt(int nargc, char* const* nargv, const char* ostr) +{ +    static char* place = EMSG;              /* option letter processing */ +    char *oli;                              /* option letter list index */ + +	fixprogname(); + +	if(optreset || !*place)					/* update scanning pointer */ +	{ +		optreset = 0; +		if(optind >= nargc || *(place = nargv[optind]) != '-') +		{ +			place = EMSG; +            return (-1); +        } + +		if (place[1] && *++place == '-')       /* found "--" */ +		{ +			++optind; +            place = EMSG; +            return (-1); +        } +	}											/* option letter okay? */ + +    if ((optopt = (int)*place++) == (int)':' || +		!(oli = strchr(ostr, optopt))) +	{ +		/* +         * if the user didn't specify '-' as an option, +		 * assume it means -1. +		 */ +		if(optopt == (int)'-') +			return (-1); +		if(!*place) +			++optind; +		if(opterr && *ostr != ':' && optopt != BADCH) +			(void)fprintf(stderr, "%s: illegal option -- %c\n", __progname, optopt); +				return(BADCH); +	} +	if (*++oli != ':')                  /* don't need argument */ +	{ +		optarg = NULL; +		if(!*place) +			++optind; +	} +	else                                /* need an argument */ +	{ +		if (*place)                     /* no white space */ +			optarg = place; +		else if (nargc <= ++optind)		/* no arg */ +		{ +			place = EMSG; +			if (*ostr == ':') +				return (BADARG); +			if(opterr) +				(void)fprintf(stderr, "%s: option requires an argument -- %c\n", __progname, optopt); +					return(BADCH); +		} +		else                            /* white space */ +			optarg = nargv[optind]; + +		place = EMSG; +		++optind; +	} +	return (optopt);                        /* dump back option letter */ +} +#endif + + +#ifndef HAVE_ERR_H + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +static FILE *err_file; /* file to use for error output */ +static void (*err_exit)(int); + +/* + * This is declared to take a `void *' so that the caller is not required + * to include <stdio.h> first.  However, it is really a `FILE *', and the + * manual page documents it as such. + */ +void err_set_file(void *fp) +{ +	if (fp) +		err_file = fp; +	else +		err_file = stderr; +} + +void err_set_exit(void (*ef)(int)) +{ +	err_exit = ef; +} + +void err(int eval, const char *fmt, ...) +{ +	va_list ap; +	va_start(ap, fmt); +	verrc(eval, errno, fmt, ap); +	va_end(ap); +} + +void verr(int eval, const char *fmt, va_list ap) +{ +	verrc(eval, errno, fmt, ap); +} + +void errc(int eval, int code, const char *fmt, ...) +{ +	va_list ap; +	va_start(ap, fmt); +	verrc(eval, code, fmt, ap); +	va_end(ap); +} + +void verrc(int eval, int code, const char *fmt, va_list ap) +{ +	fixprogname(); +	if (err_file == 0) +		err_set_file((FILE *)0); +	fprintf(err_file, "%s: ", __progname); +	if (fmt != NULL) { +		vfprintf(err_file, fmt, ap); +		fprintf(err_file, ": "); +	} +	fprintf(err_file, "%s\n", strerror(code)); +	if (err_exit) +		err_exit(eval); +	exit(eval); +} + +void errx(int eval, const char *fmt, ...) +{ +	va_list ap; +	va_start(ap, fmt); +	verrx(eval, fmt, ap); +	va_end(ap); +} + +void verrx(int eval, const char *fmt, va_list ap) +{ +	fixprogname(); +	if (err_file == 0) +		err_set_file((FILE *)0); +	fprintf(err_file, "%s: ", __progname); +	if (fmt != NULL) +		vfprintf(err_file, fmt, ap); +	fprintf(err_file, "\n"); +	if (err_exit) +		err_exit(eval); +	exit(eval); +} + +void warn(const char *fmt, ...) +{ +	va_list ap; +	va_start(ap, fmt); +	vwarnc(errno, fmt, ap); +	va_end(ap); +} + +void vwarn(const char *fmt, va_list ap) +{ +	vwarnc(errno, fmt, ap); +} + +void warnc(int code, const char *fmt, ...) +{ +	va_list ap; +	va_start(ap, fmt); +	vwarnc(code, fmt, ap); +	va_end(ap); +} + +void vwarnc(int code, const char *fmt, va_list ap) +{ +	fixprogname(); +	if (err_file == 0) +		err_set_file((FILE *)0); +	fprintf(err_file, "%s: ", __progname); +	if (fmt != NULL) +	{ +		vfprintf(err_file, fmt, ap); +		fprintf(err_file, ": "); +	} +	fprintf(err_file, "%s\n", strerror(code)); +} + +void warnx(const char *fmt, ...) +{ +	va_list ap; +	va_start(ap, fmt); +	vwarnx(fmt, ap); +	va_end(ap); +} + +void vwarnx(const char *fmt, va_list ap) +{ +	fixprogname(); +	if(err_file == 0) +		err_set_file((FILE*)0); +	fprintf(err_file, "%s: ", __progname); +	if(fmt != NULL) +		vfprintf(err_file, fmt, ap); +	fprintf(err_file, "\n"); +} + +#endif + + + +#ifndef HAVE_STRLWR + +char* strlwr(char *string) +{ +	char * cp; +	for (cp=string; *cp; ++cp) +    { +		if('A' <= *cp && *cp <= 'Z') +            *cp += 'a' - 'A'; +    } +    return(string); +} + +#endif + + + +#ifndef HAVE_REALLOCF + +void* reallocf(void* ptr, size_t size) +{ +	void* ret = realloc(ptr, size); + +	if(!ret && size) +		free(ptr); + +	return ret; +} + +#endif + | 
