From b49d8ebefe9b10c53a6a09ad564e22111b7b25c6 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sat, 20 Sep 2003 07:12:49 +0000 Subject: Initial Import --- common/Makefile.am | 2 + common/binfile.c | 334 ++++++++++++++++++++++++++++++++++++++ common/binfile.h | 110 +++++++++++++ common/compat.c | 458 +++++++++++++++++++++++++++++++++++++++++++++++++++++ common/compat.h | 177 +++++++++++++++++++++ common/repfile.c | 113 +++++++++++++ common/repfile.h | 52 ++++++ common/usuals.h | 61 +++++++ common/xstring.c | 104 ++++++++++++ common/xstring.h | 70 ++++++++ 10 files changed, 1481 insertions(+) create mode 100644 common/Makefile.am create mode 100644 common/binfile.c create mode 100644 common/binfile.h create mode 100644 common/compat.c create mode 100644 common/compat.h create mode 100644 common/repfile.c create mode 100644 common/repfile.h create mode 100644 common/usuals.h create mode 100644 common/xstring.c create mode 100644 common/xstring.h (limited to 'common') diff --git a/common/Makefile.am b/common/Makefile.am new file mode 100644 index 0000000..0686d9d --- /dev/null +++ b/common/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = compat.c compat.h xstring.c xstring.h usuals.h binfile.h binfile.c repfile.h repfile.c + diff --git a/common/binfile.c b/common/binfile.c new file mode 100644 index 0000000..fa0a120 --- /dev/null +++ b/common/binfile.c @@ -0,0 +1,334 @@ + /* + * 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: + */ +#include +#include +#include +#include "binfile.h" + +#define BF_FILE 0x00000010 +#define BF_ERROR 0x00000040 + +/* bfctx: --------------------------------------------------- + * This is the structure that becomes a BFILE + * to the outside world + */ +typedef struct _bfctx +{ + union + { + FILE* file; /* Valid when working with a FILE */ + void* data; /* Valid when working with memory */ + } d; + size_t cur; /* Current position */ + size_t len; /* Size of the memory buffer */ + int flags; +} +bfctx; + + +/* bfWriteRaw: ----------------------------------------------- + * Write data to appropriate buffer/file + */ +int bfWriteRaw(BFILE h, const void* data, size_t len) +{ + bfctx* ctx = (bfctx*)h; + + /* file */ + if(ctx->flags & BF_FILE) + { + len = fwrite(data, len, 1, ctx->d.file); + ctx->cur += len; + return len; + } + + /* memory */ + else + { + /* Check if enough space */ + if((ctx->cur + len) > ctx->len) + { + /* If we ran out of space try and reallocate */ + if(ctx->flags & BF_REALLOC) + { + void* old = ctx->d.data; + + ctx->len = ctx->len + (((len / 1024) + 1) * 1024); + ctx->d.data = realloc(ctx->d.data, ctx->len); + + if(!ctx->d.data) + free(old); + } + + /* + * If there's no more space and we can't + * reallocate then it's an error + */ + if(!ctx->d.data || !(ctx->flags & BF_REALLOC)) + { + ctx->flags |= BF_ERROR; + return 0; + } + + } + + /* write the data in */ + memcpy(((unsigned char*)ctx->d.data) + ctx->cur, data, len); + ctx->cur += len; + return len; + } +} + + +/* bfReadRaw: ------------------------------------------------------ + * Read data from either buffer or file + */ +int bfReadRaw(BFILE h, void* data, size_t len) +{ + bfctx* ctx = (bfctx*)h; + + /* file */ + if(ctx->flags & BF_FILE) + { + len = fread(data, 1, len, ctx->d.file); + ctx->cur += len; + return len; + } + + /* memory */ + else + { + if((ctx->len - ctx->cur) < len) + len = ctx->len - ctx->cur; + + memcpy(data, ((unsigned char*)ctx->d.data) + ctx->cur, len); + ctx->cur += len; + return len; + } +} + + +/* bfSeek: --------------------------------------------------------- + * Seek forward in either buffer or file + */ +int bfSeek(bfctx* ctx, long offset) +{ + /* file */ + if(ctx->flags & BF_FILE) + { + int ret = fseek(ctx->d.file, offset, SEEK_CUR); + if(ret == 0) + ctx->cur += offset; + return ret; + } + + /* memory */ + else + { + if((long)(ctx->len - ctx->cur) < offset) + return 1; + ctx->cur += offset; + + return 0; + } +} + + +/* bfError: ------------------------------------------------- + * Check for errors on output + */ +int bfError(BFILE h) +{ + bfctx* ctx = (bfctx*)h; + if(ctx->flags & BF_FILE) + return ferror(ctx->d.file); + else + return ctx->flags & BF_ERROR; +} + + +/* bfStartFile: ----------------------------------------------- + * Get a BFILE based on a FILE output + * file should be opened for appropriate input or output + */ +BFILE bfStartFile(FILE* file) +{ + bfctx* ctx = (bfctx*)malloc(sizeof(bfctx)); + if(!ctx) return 0; + memset(ctx, 0, sizeof(bfctx)); + + ctx->d.file = file; + ctx->flags = BF_FILE; + return ctx; +} + +/* bfStartMem: ------------------------------------------------- + * Get a BFILE based on memory + * If flags have BF_REALLOC set then NULL can be passed + * and/or we can reallocate the buffer + */ +BFILE bfStartMem(void* mem, size_t len, int flags) +{ + bfctx* ctx = (bfctx*)malloc(sizeof(bfctx)); + if(!ctx) return 0; + memset(ctx, 0, sizeof(bfctx)); + + ctx->len = len; + ctx->flags = flags; + ctx->flags &= ~(BF_FILE | BF_ERROR); + ctx->d.data = mem; + + return ctx; +} + +/* bfClose: ----------------------------------------------------- + * Close a BFILE + * Returns either the file or memory buffer, and returns size + * in the len argument + */ +void bfClose(BFILE h) +{ + if(h) + free(h); +} + +/* bfInternal: -------------------------------------------------- + * Get the internal file handle or memory pointer for this + * binfile + */ +void* bfInternal(BFILE h) +{ + bfctx* ctx = (bfctx*)h; + if(ctx->flags & BF_FILE) + return ctx->d.file; + else + return ctx->d.data; +} + +/* bfCount: ---------------------------------------------------- + * Returns the number of bytes written or read to this binfile + */ +size_t bfCount(BFILE h) +{ + bfctx* ctx = (bfctx*)h; + return ctx->cur; +} + +/* bfWriteEnd: ------------------------------------------------- + * Puts down an end of tags marker in the binfile + */ +int bfWriteEnd(BFILE h) +{ + bfval opt; + int c; + + opt.id = BINTYPE_END; + opt.len = 0; + opt.type = BINTYPE_END; + c = bfWriteRaw(h, &opt, sizeof(opt)); + + return bfError(h) ? 0 : c; +} + +/* bfWriteValue: ----------------------------------------------- + * Writes a tagged value to the binfile + */ +int bfWriteValue(BFILE h, const bfval* val, const void* data) +{ + int c = bfWriteRaw(h, val, sizeof(bfval)); + c += bfWriteRaw(h, data, val->len); + return bfError(h) ? 0 : c; +} + +/* bfReadValueInfo: -------------------------------------------- + * Gets the next tag (without data) and returns the length + * of the memory required to hold it. + */ +int bfReadValueInfo(BFILE h, bfval* val) +{ + int c = bfReadRaw(h, val, sizeof(bfval)); + return c == sizeof(bfval) && !bfError(h); +} + +/* bfReadValueData: --------------------------------------------- + * Gets the data for a value. val should be same one returned + * from bfReadValueInfo + */ +int bfReadValueData(BFILE h, const bfval* val, void* data) +{ + size_t c; + if((c = bfReadRaw(h, data, val->len)) != val->len || + bfError(h)) + return 0; + + /* Special handling for these guys */ + switch(val->type) + { + case BINTYPE_ASCII: + { + char* str = (char*)data; + str[val->len] = 0; + } + break; + + case BINTYPE_INT32: + case BINTYPE_INT16: + /* TODO: do endianness here */ + break; + }; + + return c; +} + +/* bfSkipValueData: ------------------------------------------------ + * Skips the data for a tagged value + */ +int bfSkipValueData(BFILE h, const bfval* val) +{ + bfctx* ctx = (bfctx*)h; + return bfSeek(ctx, val->len) == 0; +} + + +/* bfWriteString: -------------------------------------------------- + * Convenience function for writing out strings to file + */ +int bfWriteString(BFILE h, short id, const char* data) +{ + bfval val; + val.id = id; + val.type = BINTYPE_ASCII; + val.len = strlen(data); + + return bfWriteValue(h, &val, (void*)data); +} + +/* bfWriteInt: ----------------------------------------------------- + * Convenience function for writing out 4 byte integers to file + */ +int bfWriteInt(BFILE h, short id, int data) +{ + bfval val; + val.id = id; + val.type = BINTYPE_INT32; + val.len = BINSIZE_INT32; + + /* TODO: take care of endianess here */ + return bfWriteValue(h, &val, &data); +} + diff --git a/common/binfile.h b/common/binfile.h new file mode 100644 index 0000000..3b86b8f --- /dev/null +++ b/common/binfile.h @@ -0,0 +1,110 @@ +/* + * 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: + */ + +#ifndef __BINFILE_H__ +#define __BINFILE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 +#pragma pack(push, ops) +#endif + +#pragma pack(1) + +/* bfval: ---------------------------------------------------------- + * A tagged value to be written/read from a binfile + */ +typedef struct _bfval +{ + short id; /* The tag id */ + short type; /* The data type */ + size_t len; /* The length in bytes */ +} +bfval; + +#pragma pack() + +#ifdef _WIN32 +#pragma pack(pop, ops) +#endif + + +/* BFILE: -------------------------------------------------------- + * The binfile open handle + */ +typedef void* BFILE; + + + +#define BINTYPE_NONE (short)0x0000 +#define BINTYPE_INT16 (short)0x0001 +#define BINTYPE_INT32 (short)0x0002 +#define BINTYPE_ASCII (short)0x0005 +#define BINTYPE_DATA (short)0x0010 +#define BINTYPE_END (short)0xFFFF + +#define BINSIZE_INT32 4 /* sizeof(int) */ +#define BINSIZE_INT16 2 /* sizeof(short) */ + +#define BF_REALLOC 0x00000001 + +/* Open a binfile based on a disk FILE */ +BFILE bfStartFile(FILE* file); +/* Open a binfile based on memory */ +BFILE bfStartMem(void* mem, size_t len, int flags); + + +/* Write raw data to a binfile at current position */ +int bfWriteRaw(BFILE h, const void* data, size_t len); +/* Read raw data from a binfile at the current position */ +int bfReadRaw(BFILE h, void* data, size_t len); + +/* Check if an error occured during reading/writing */ +int bfError(BFILE h); + +/* Write a bfval to binfile */ +int bfWriteValue(BFILE h, const bfval* opt, const void* data); +/* Write a string to a binfile */ +int bfWriteString(BFILE h, short id, const char* data); +/* Write a 4 byte integer to a binfile */ +int bfWriteInt(BFILE h, short id, int data); +/* Write the end tag marker */ +int bfWriteEnd(BFILE h); + +/* Read the tag information for a value */ +int bfReadValueInfo(BFILE h, bfval* opt); +/* Read the data for a value */ +int bfReadValueData(BFILE h, const bfval* opt, void* data); +/* Skip the data for the current value */ +int bfSkipValueData(BFILE h, const bfval* opt); + +size_t bfCount(BFILE h); +void* bfInternal(BFILE h); + +/* Close a binfile */ +void bfClose(BFILE h); + +#ifdef __cplusplus +} +#endif + +#endif /* __BINFILE_H__ */ 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: + */ + +#include +#include +#include +#include +#include "compat.h" + +#ifdef HAVE_STRING_H +#include +#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 +#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 +#include +#include +#include + +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 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 + diff --git a/common/compat.h b/common/compat.h new file mode 100644 index 0000000..09934db --- /dev/null +++ b/common/compat.h @@ -0,0 +1,177 @@ +/* + * 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: + */ + +#ifndef _COMPAT_H_ +#define _COMPAT_H_ + +/* Force use of win32 configuration if compiling there */ +#ifdef _WIN32 +#include "../config.win32.h" +#else +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif +#endif + +#ifndef HAVE_STDARG_H +#error ERROR: Must have a working header +#else +#include +#endif + + +#ifndef HAVE_STAT +#ifdef _WIN32 +#define S_IFDIR _S_IFDIR +#define HAVE_STAT +#else +#error ERROR: Must have a working 'stat' function +#endif +#endif + +#ifndef HAVE_GETCWD +#ifdef _WIN32 +#include +#define getcwd _getcwd +#define HAVE_GETCWD +#else +#error ERROR: Must have a working 'getcwd' function +#endif +#endif + +#ifndef HAVE_CHDIR +#ifdef _WIN32 +#include +#define chdir _chdir +#define HAVE_CHDIR +#else +#error ERROR: Must have a working 'chdir' function +#endif +#endif + +#ifndef HAVE_TOLOWER +int tolower(int c); +#endif + +#ifndef HAVE_STRDUP +char* strdup(const char* str); +#endif + +#ifndef HAVE_STRNDUP +char* strndup(const char* str, size_t cnt); +#endif + +#ifndef HAVE_STRCASESTR +char* strcasestr(const char* big, const char* little); +#endif + +#ifndef HAVE_STRCASECMP +#ifdef HAVE_STRICMP +#define strcasecmp stricmp +#else +#error ERROR: Must have either 'strcasecmp' or 'stricmp' +#endif +#endif + +#ifndef HAVE_STRCASECMP +#ifdef HAVE_STRICMP +#define strncasecmp strnicmp +#else +#error ERROR: Must have either 'strncasecmp' or 'strnicmp' +#endif +#endif + + +#ifndef NULL +#define NULL (void*)0 +#endif + +#ifndef __cplusplus +typedef unsigned char bool; +#define false 0x00 +#define true 0x01 +#endif + +#ifndef HAVE_BYTE +typedef unsigned char byte; +#define HAVE_BYTE +#endif + +#ifndef HAVE_UINT +typedef unsigned int uint; +#define HAVE_UINT +#endif + +#ifndef HAVE_STRLCPY +void strlcpy(char* dest, const char* src, size_t count); +#endif + +#ifndef HAVE_STRLCAT +void strlcat(char* dest, const char* src, size_t count); +#endif + +#ifndef HAVE_VSNPRINTF + +#ifdef _WIN32 +#define vsnprintf _vsnprintf +#define HAVE_VSNPRINTF +#else +#ifndef HAVE_VASPRINTF +#error ERROR: Must have a working 'vsnprintf' or 'vasprintf' function +#endif +#endif +#endif + +#ifndef HAVE_VASPRINTF +int vasprintf(char** ret, const char* format, va_list vl); +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifndef HAVE_GETOPT +extern char* optarg; +extern int optind, opterr, optopt; +int getopt(int nargc, char* const* nargv, const char* ostr); +#endif + +#ifndef HAVE_ERR_H +#include +void err_set_file(void *fp); +void err_set_exit(void (*ef)(int)); +void err(int eval, const char *fmt, ...); +void verr(int eval, const char *fmt, va_list ap); +void errc(int eval, int code, const char *fmt, ...); +void verrc(int eval, int code, const char *fmt, va_list ap); +void errx(int eval, const char *fmt, ...); +void verrx(int eval, const char *fmt, va_list ap); +void warn(const char *fmt, ...); +void vwarn(const char *fmt, va_list ap); +void warnc(int code, const char *fmt, ...); +void vwarnc(int code, const char *fmt, va_list ap); +void warnx(const char *fmt, ...); +void vwarnx(const char *fmt, va_list ap); +#endif + +#ifndef HAVE_REALLOCF +void* reallocf(void* ptr, size_t size); +#endif + +#endif \ No newline at end of file diff --git a/common/repfile.c b/common/repfile.c new file mode 100644 index 0000000..eec6ca2 --- /dev/null +++ b/common/repfile.c @@ -0,0 +1,113 @@ +/* + * 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: + */ + +#include +#include +#include "common/usuals.h" +#include "common/compat.h" +#include "common/binfile.h" +#include "common/repfile.h" + +/* errmsg: ----------------------------------------------------------- + * Display an rlib error on the console + */ +int errmsg(int ret, r_script* script) +{ + const char* msg; + + switch(ret) + { + case R_NOMEM: + msg = "out of memory"; + break; + case R_SYNTAX: + msg = "syntax error:"; + break; + case R_REGEXP: + msg = "reg expression error:"; + break; + case R_LOOP: + msg = "an endless loop was encountered "; + break; + case R_USER: + msg = "stop: "; + break; + case R_IOERR: + msg = "read or write error"; + break; + case R_INVARG: + ASSERT(0 && "This error should be taken care of by programmer"); + msg = "internal programmer error"; + break; + default: + msg = "unknown error"; + break; + } + + if(script && script->error) + { + if(script->errline > 0) + warnx("%s %s (at line %d)", msg, script->error, script->errline); + else + warnx("%s %s", msg, script->error); + } + else + { + warnx(msg); + } + + return ret; +} + +/* repscriptheader: ------------------------------------------------- + * The top of every compiled rep file has this signature + */ +typedef struct _repscriptheader +{ + uint sig; /* 'rep0' */ + uint version; /* Note this is the file version */ +} +repscriptheader; + +const uint kReplSig = '0per'; +const uint kReplVer = 0x00023100; + +/* repfWriteHeader: ------------------------------------------------- + * Write out a valid header + */ +bool repfWriteHeader(BFILE h) +{ + repscriptheader head; + head.sig = kReplSig; + head.version = kReplVer; + + bfWriteRaw(h, &head, sizeof(head)); + return !bfError(h); +} + +/* repfReadHeader: -------------------------------------------------- + * Read and validate rep file header + */ +bool repfReadHeader(BFILE h) +{ + repscriptheader head; + memset(&head, 0, sizeof(head)); + bfReadRaw(h, &head, sizeof(head)); + return head.sig == kReplSig && head.version == kReplVer; +} diff --git a/common/repfile.h b/common/repfile.h new file mode 100644 index 0000000..5d0ff95 --- /dev/null +++ b/common/repfile.h @@ -0,0 +1,52 @@ +/* + * 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: + */ + +#ifndef __REPL_H__ +#define __REPL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "lib/rlib.h" +#include "common/usuals.h" +#include "common/compat.h" +#include "common/binfile.h" + +/* Write rlib errors to console */ +int errmsg(int ret, r_script* script); + +/* Read and validate a rep compiled script header */ +bool repfReadHeader(BFILE h); +/* Write a valid rep compiled script header */ +bool repfWriteHeader(BFILE h); + +/* Some binfile tags */ +#define REPVAL_BUFSIZE 0x0008 +#define REPVAL_PARSEMODE 0x0009 +#define REPVAL_BINARYMODE 0x000A +#define REPVAL_SCRIPT 0x0020 +#define REPVAL_VERSION 0x0030 + +#ifdef __cplusplus +} +#endif + +#endif /* __REPL_H__ */ diff --git a/common/usuals.h b/common/usuals.h new file mode 100644 index 0000000..7317f99 --- /dev/null +++ b/common/usuals.h @@ -0,0 +1,61 @@ +/* + * 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: + */ + +#ifndef __USUALS_H__20000613 +#define __USUALS_H__20000613 + +#include +#include +#include +#include +#include +#include + +#define zero(v) (memset(&(v), 0, sizeof((v)))) +#define countof(a) (sizeof(a) / sizeof(a[0])) + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef ASSERT +#include +#define ASSERT assert +#endif + +#ifndef ASSERT_PTR + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#define ASSERT_PTR_LEN(p, len) ASSERT(!(IsBadReadPtr((p), len) || IsBadWritePtr((p), len))) +#else +#define ASSERT_PTR_LEN(p, len) ASSERT((p) != 0) +#endif + +#define ASSERT_PTR(p) ASSERT_PTR_LEN(p, sizeof(*(p))) + +#endif + + +#endif //__USUALS_H__20000613 \ No newline at end of file diff --git a/common/xstring.c b/common/xstring.c new file mode 100644 index 0000000..31a363f --- /dev/null +++ b/common/xstring.c @@ -0,0 +1,104 @@ +/* + * 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: + */ + +#include +#include +#include +#include "compat.h" +#include "xstring.h" + + +/* memins: ------------------------------------------------------------- + * Insert bytes at location + */ +void memins(void* buff, size_t cbuff, const void* ins, size_t cins) +{ + memmove((unsigned char*)buff + cins, buff, cbuff); + memcpy(buff, ins, cins); +} + + +/* memrep: ------------------------------------------------------------ + * Replace a number of bytes at a certain location with yet + * another number of bytes + */ +void* memrep(void* buff, size_t len, size_t cold, const void* ins, size_t cnew) +{ + memmove((unsigned char*)buff + cnew, (unsigned char*)buff + cold, len - cold); + memcpy(buff, ins, cnew); + return (unsigned char*)buff + cnew; +} + + +/* starlen: ----------------------------------------------------------- + * Returns the length of a null terminated string array + */ +size_t starlen(const char* array) +{ + size_t cnt = 0; + while(array[0] || array[1]) + { + array += strlen(array); + cnt++; + } + + return cnt; +} + + +/* starend: ----------------------------------------------------------- + * Gets the end of a string array + */ +char* starend(const char* array) +{ + while(array[0]) + array += strlen(array) + 1; + + return (char*)array; +} + + +/* starnadd: ---------------------------------------------------------- + * Add a value to a string array + */ +char* starnadd(char** parray, const char* str, size_t len) +{ + char* last = starend(*parray); + if(!strrsrv(*parray, (last - *parray) + len + 2)) + return NULL; + + // It's possible we were relocated + last = starend(*parray); + + strncpy(last, str, len); + last += len; + last[0] = last[1] = 0; + return last; +} + + +/* starnext: ---------------------------------------------------------- + * Get the next value in a string array + */ +const char* starnext(const char* prev) +{ + prev += strlen(prev) + 1; + return prev[0] ? prev : NULL; +} + diff --git a/common/xstring.h b/common/xstring.h new file mode 100644 index 0000000..3be4116 --- /dev/null +++ b/common/xstring.h @@ -0,0 +1,70 @@ +/* + * AUTHOR + * N. Nielsen + * + * VERSION + * 2.1.2b + * + * 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: + */ + +#ifndef __XSTRING_H__ +#define __XSTRING_H__ + +#include + +/* Insert bytes at a memory location */ +void memins(void* buff, size_t cbuff, const void* ins, size_t cins); + +/* Insert string into a string */ +#define strins(buff, ins) \ + memins((byte*)buff, strlen(buff) + 1, (byte*)ins, strlen(ins)) + +/* Replace a number of bytes with other bytes at a memory location */ +void* memrep(void* buff, size_t len, size_t cold, const void* ins, size_t cnew); + +/* Replace a number of chars with a string */ +#define strrep(s, cold, ins) \ + (char*)memrep(s, sizeof(char) * (strlen(s) + 1), cold, ins, strlen(ins)) +#define strnrep(s, cold, ins, cins) \ + (char*)memrep(s, sizeof(char) * (strlen(s) + 1), cold, ins, cins) + +/* Reserve memory in a string. (NOTE: buff must be allocated with malloc) */ +#define strrsrv(buff, cnt) \ + (buff = (char*)realloc(buff, sizeof(char) * ((cnt) + 1))) + + + +/* Get the length of a null terminated string array */ +size_t starlen(const char* array); + +/* Get the end of a null terminated string array */ +char* starend(const char* array); + +/* Add a string to the end of a null terminated string array */ +char* starnadd(char** parray, const char* str, size_t len); +#define staradd(parray, str) \ + starnadd(parray, str, strlen(str)) + +/* Get next value in a null terminated string array */ +const char* starnext(const char* prev); + +/* Clear a null terminated string array */ +#define starclr(arr) \ + (arr[0] = arr[1] = 0) + + + +#endif //__XSTRING_H__ \ No newline at end of file -- cgit v1.2.3