Wed Aug 30 22:58:18 PDT 2000 Michael Jennings <mej@eterm.org>

Massive reorganization/rewrite to libmej.  It should now be 100%
	independent of Eterm.  There still may be some gremlins in the memory
	debugging code, so don't use too high a number with --debug....


SVN revision: 3282
This commit is contained in:
Michael Jennings 2000-08-31 05:41:44 +00:00
parent eb4400feea
commit 9a6507f458
42 changed files with 1219 additions and 1775 deletions

View File

@ -3834,3 +3834,10 @@ Tue Aug 22 21:35:50 PDT 2000 Michael Jennings <mej@eterm.org>
This should fix the selection problems between Eterm and other apps.
-------------------------------------------------------------------------------
Wed Aug 30 22:58:18 PDT 2000 Michael Jennings <mej@eterm.org>
Massive reorganization/rewrite to libmej. It should now be 100%
independent of Eterm. There still may be some gremlins in the memory
debugging code, so don't use too high a number with --debug....
-------------------------------------------------------------------------------

View File

@ -128,7 +128,7 @@ dnl# Checks for header files.
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(fcntl.h termios.h \
sys/ioctl.h sys/select.h sys/time.h \
sys/sockio.h sys/byteorder.h \
sys/sockio.h sys/byteorder.h malloc.h \
utmpx.h unistd.h bsd/signal.h regex.h \
regexp.h stdarg.h X11/Xmu/Atoms.h)
AC_HEADER_TIME
@ -141,7 +141,10 @@ AC_TYPE_UID_T
dnl# Checks for library functions.
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(atexit _exit unsetenv setutent seteuid memmove putenv strsep setresuid setresgid memmem usleep snprintf)
AC_CHECK_FUNCS(atexit _exit unsetenv setutent \
seteuid memmove putenv strsep setresuid setresgid \
memmem usleep snprintf strcasestr strcasechr \
strcasepbrk strrev)
dps_snprintf_oflow()
AC_CHECK_LIB(m, pow, LIBS="$LIBS -lm", , $SUBLIBS)

View File

@ -1,12 +1,10 @@
# $Id$
lib_LTLIBRARIES = libmej.la
include_HEADERS = libmej.h
libmej_la_SOURCES = debug.c mem.c strings.c snprintf.c
libmej_la_SOURCES = debug.c mem.c msgs.c strings.c snprintf.c libmej.h
INCLUDES = -I. -I.. -I$(includedir) -I$(prefix)/include
libmej_la_LDFLAGS = -release $(VERSION)
EXTRA_DIST = debug.h global.h mem.h strings.h strptime.h strptime.c

View File

@ -1,8 +1,3 @@
/*********************************************************
* DEBUG.C -- Standardized debugging output *
* -- Michael Jennings *
* -- 20 December 1996 *
*********************************************************/
/*
* Copyright (C) 1997-2000, Michael Jennings
*
@ -28,31 +23,14 @@
static const char cvs_ident[] = "$Id$";
#include "config.h"
#include "../src/feature.h"
#include "global.h"
#include <stdio.h>
#include <stdlib.h>
#ifndef WITH_DMALLOC
# include <malloc.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include "debug.h"
int
real_dprintf(const char *format,...)
{
#include "libmej.h"
va_list args;
int n;
/* FIXME: Change this to an unsigned short once the
options parser can handle function pointers. */
unsigned int libmej_debug_level = 0;
unsigned long libmej_debug_flags = 0;
va_start(args, format);
n = vfprintf(stderr, format, args);
va_end(args);
fflush(stderr);
return (n);
}

View File

@ -1,36 +0,0 @@
/**********************************************************
* DEBUG.H -- Header file for DEBUG.C *
* -- Michael Jennings *
* -- 20 December 1996 *
**********************************************************/
/*
* Copyright (C) 1997-2000, Michael Jennings
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of the Software, its documentation and marketing & publicity
* materials, and acknowledgment shall be given in the documentation, materials
* and software packages that this Software was used.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS 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.
*/
#ifndef _LIBMEJ_DEBUG_H
# define _LIBMEJ_DEBUG_H
extern int real_dprintf(const char *, ...);
#include "../src/debug.h"
#endif /* _LIBMEJ_DEBUG_H */

347
libmej/libmej.h Normal file
View File

@ -0,0 +1,347 @@
/*
* Copyright (C) 1997-2000, Michael Jennings
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of the Software, its documentation and marketing & publicity
* materials, and acknowledgment shall be given in the documentation, materials
* and software packages that this Software was used.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS 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.
*/
#ifndef _LIBMEJ_H_
#define _LIBMEJ_H_
/* This GNU goop has to go before the system headers */
#ifdef __GNUC__
# ifndef __USE_GNU
# define __USE_GNU
# endif
# ifndef _GNU_SOURCE
# define _GNU_SOURCE
# endif
# ifndef _BSD_SOURCE
# define _BSD_SOURCE
# endif
# ifndef inline
# define inline __inline__
# endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#ifdef HAVE_REGEX_H
# include <regex.h>
#endif
#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif
#ifdef WITH_DMALLOC
# include <dmalloc.h>
#elif defined(HAVE_MALLOC_H)
# include <malloc.h>
#endif
/******************************* GENERIC GOOP *********************************/
#ifndef TRUE
# define TRUE ((unsigned char)(1))
# define FALSE ((unsigned char)(0))
#endif
#ifndef PACKAGE
# define PACKAGE "libmej"
#endif
/****************************** DEBUGGING GOOP ********************************/
#ifndef LIBMEJ_DEBUG_FD
# define LIBMEJ_DEBUG_FD (stderr)
#endif
#ifndef DEBUG
# define DEBUG 0
#endif
#define DEBUG_LEVEL (libmej_debug_level)
#define DEBUG_FLAGS (libmej_debug_flags)
/* A NOP. Does nothing. */
#define NOP ((void)0)
/* A macro and an #define to FIXME-ize individual calls or entire code blocks. */
#define FIXME_NOP(x)
#define FIXME_BLOCK 0
/* The basic debugging output leader. */
#if defined(__FILE__) && defined(__LINE__)
# ifdef __GNUC__
# define __DEBUG() fprintf(LIBMEJ_DEBUG_FD, "[%lu] %12s | %4d: %s(): ", (unsigned long) time(NULL), __FILE__, __LINE__, __FUNCTION__)
# else
# define __DEBUG() fprintf(LIBMEJ_DEBUG_FD, "[%lu] %12s | %4d: ", (unsigned long) time(NULL), __FILE__, __LINE__)
# endif
#else
# define __DEBUG() NOP
#endif
/* A quick and dirty macro to say, "Hi! I got here without crashing!" */
#define MOO() do { __DEBUG(); fprintf(LIBMEJ_DEBUG_FD, "Moo.\n"); fflush(LIBMEJ_DEBUG_FD); } while (0)
/* Assertion/abort macros which are quite a bit more useful than assert() and abort(). */
#if defined(__FILE__) && defined(__LINE__)
# ifdef __GNUC__
# define ASSERT(x) do {if (!(x)) {if (DEBUG_LEVEL>=1) {fatal_error("ASSERT failed in %s() at %s:%d: %s", __FUNCTION__, __FILE__, __LINE__, #x);} \
else {print_warning("ASSERT failed in %s() at %s:%d: %s", __FUNCTION__, __FILE__, __LINE__, #x);}}} while (0)
# define ASSERT_RVAL(x, val) do {if (!(x)) {if (DEBUG_LEVEL>=1) {fatal_error("ASSERT failed in %s() at %s:%d: %s", __FUNCTION__, __FILE__, __LINE__, #x);} \
else {print_warning("ASSERT failed in %s() at %s:%d: %s", __FUNCTION__, __FILE__, __LINE__, #x);} \
return (val);}} while (0)
# define ASSERT_NOTREACHED() do {if (DEBUG_LEVEL>=1) {fatal_error("ASSERT failed in %s() at %s:%d: This code should not be reached.", __FUNCTION__, __FILE__, __LINE__);} \
else {print_warning("ASSERT failed in %s() at %s:%d: This code should not be reached.", __FUNCTION__, __FILE__, __LINE__);} \
} while (0)
# define ASSERT_NOTREACHED_RVAL(val) do {if (DEBUG_LEVEL>=1) {fatal_error("ASSERT failed in %s() at %s:%d: This code should not be reached.", __FUNCTION__, __FILE__, __LINE__);} \
else {print_warning("ASSERT failed in %s() at %s:%d: This code should not be reached.", __FUNCTION__, __FILE__, __LINE__);} \
return (val);} while (0)
# define ABORT() fatal_error("Aborting in %s() at %s:%d.", __FUNCTION__, __FILE__, __LINE__)
# else
# define ASSERT(x) do {if (!(x)) {if (DEBUG_LEVEL>=1) {fatal_error("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \
else {print_warning("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);}}} while (0)
# define ASSERT_RVAL(x, val) do {if (!(x)) {if (DEBUG_LEVEL>=1) {fatal_error("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \
else {print_warning("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \
return (val);}} while (0)
# define ASSERT_NOTREACHED() do {if (DEBUG_LEVEL>=1) {fatal_error("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \
else {print_warning("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \
} while (0)
# define ASSERT_NOTREACHED_RVAL(val) do {if (DEBUG_LEVEL>=1) {fatal_error("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \
else {print_warning("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \
return (val);} while (0)
# define ABORT() fatal_error("Aborting at %s:%d.", __FILE__, __LINE__)
# endif
#else
# define ASSERT(x) do {if (!(x)) {if (DEBUG_LEVEL>=1) {fatal_error("ASSERT failed: %s", #x);} \
else {print_warning("ASSERT failed: %s", #x);}}} while (0)
# define ASSERT_RVAL(x, val) do {if (!(x)) {if (DEBUG_LEVEL>=1) {fatal_error("ASSERT failed: %s", #x);} \
else {print_warning("ASSERT failed: %s", #x);} return (val);}} while (0)
# define ASSERT_NOTREACHED() return
# define ASSERT_NOTREACHED_RVAL(x) return (x)
# define ABORT() fatal_error("Aborting.\n")
#endif
#define REQUIRE(x) do {if (!(x)) {if (DEBUG_LEVEL>=1) {__DEBUG(); libmej_dprintf("REQUIRE failed: %s\n", #x);} return;}} while (0)
#define REQUIRE_RVAL(x, v) do {if (!(x)) {if (DEBUG_LEVEL>=1) {__DEBUG(); libmej_dprintf("REQUIRE failed: %s\n", #x);} return (v);}} while (0)
#define NONULL(x) ((x) ? (x) : ("<null>"))
/* Macros for printing debugging messages */
#if DEBUG >= 1
# ifndef DPRINTF
# define DPRINTF(x) do { __DEBUG(); libmej_dprintf x; } while (0)
# endif
# define DPRINTF1(x) do { if (DEBUG_LEVEL >= 1) {__DEBUG(); libmej_dprintf x;} } while (0)
# define DPRINTF2(x) do { if (DEBUG_LEVEL >= 2) {__DEBUG(); libmej_dprintf x;} } while (0)
# define DPRINTF3(x) do { if (DEBUG_LEVEL >= 3) {__DEBUG(); libmej_dprintf x;} } while (0)
# define DPRINTF4(x) do { if (DEBUG_LEVEL >= 4) {__DEBUG(); libmej_dprintf x;} } while (0)
# define DPRINTF5(x) do { if (DEBUG_LEVEL >= 5) {__DEBUG(); libmej_dprintf x;} } while (0)
# define DPRINTF6(x) do { if (DEBUG_LEVEL >= 6) {__DEBUG(); libmej_dprintf x;} } while (0)
# define DPRINTF7(x) do { if (DEBUG_LEVEL >= 7) {__DEBUG(); libmej_dprintf x;} } while (0)
# define DPRINTF8(x) do { if (DEBUG_LEVEL >= 8) {__DEBUG(); libmej_dprintf x;} } while (0)
# define DPRINTF9(x) do { if (DEBUG_LEVEL >= 9) {__DEBUG(); libmej_dprintf x;} } while (0)
#else
# ifndef DPRINTF
# define DPRINTF(x) NOP
# endif
# define DPRINTF1(x) NOP
# define DPRINTF2(x) NOP
# define DPRINTF3(x) NOP
# define DPRINTF4(x) NOP
# define DPRINTF5(x) NOP
# define DPRINTF6(x) NOP
# define DPRINTF7(x) NOP
# define DPRINTF8(x) NOP
# define DPRINTF9(x) NOP
#endif
/* Use this for stuff that you only want turned on in dire situations */
#define D_NEVER(x) NOP
#define DEBUG_MEM 5
#define D_MEM(x) DPRINTF5(x)
#define DEBUG_STRINGS 9999
#define D_STRINGS(x) D_NEVER(x)
/********************************* MEM GOOP ***********************************/
typedef struct ptr_struct {
void *ptr;
size_t size;
} ptr_t;
typedef struct memrec_struct {
unsigned char init;
unsigned long cnt;
ptr_t *ptrs;
} memrec_t;
#if (DEBUG >= DEBUG_MEM)
# define MALLOC(sz) libmej_malloc(__FILE__, __LINE__, (sz))
# define CALLOC(type,n) libmej_calloc(__FILE__, __LINE__, (n), (sizeof(type)))
# define REALLOC(mem,sz) libmej_realloc(#mem, __FILE__, __LINE__, (mem), (sz))
# define FREE(ptr) do { libmej_free(#ptr, __FILE__, __LINE__, (ptr)); (ptr) = NULL; } while (0)
# define STRDUP(s) libmej_strdup(#s, __FILE__, __LINE__, (s))
# define MALLOC_MOD 25
# define REALLOC_MOD 25
# define CALLOC_MOD 25
# define FREE_MOD 25
#else
# define MALLOC(sz) malloc(sz)
# define CALLOC(type,n) calloc((n),(sizeof(type)))
# define REALLOC(mem,sz) ((sz) ? ((mem) ? (realloc((mem), (sz))) : (malloc(sz))) : ((mem) ? (free(mem), NULL) : (NULL)))
# define FREE(ptr) do { free(ptr); (ptr) = NULL; } while (0)
# define STRDUP(s) strdup(s)
#endif
/* Fast memset() macro contributed by vendu */
#if (SIZEOF_LONG == 8)
# define MEMSET_LONG() l |= l<<32
#else
# define MEMSET_LONG() ((void)0)
#endif
#define MEMSET(s, c, count) do { \
char *end = (char *)(s) + (count); \
long l; \
long *l_dest = (long *)(s); \
char *c_dest; \
\
/* areas of less than 4 * sizeof(long) are set in 1-byte chunks. */ \
if (((unsigned long) count) >= 4 * sizeof(long)) { \
/* fill l with c. */ \
l = (c) | (c)<<8; \
l |= l<<16; \
MEMSET_LONG(); \
\
/* fill in 1-byte chunks until boundary of long is reached. */ \
if ((unsigned long)l_dest & (unsigned long)(sizeof(long) -1)) { \
c_dest = (char *)l_dest; \
while ((unsigned long)c_dest & (unsigned long)(sizeof(long) -1)) { \
*(c_dest++) = (c); \
} \
l_dest = (long *)c_dest; \
} \
\
/* fill in long-size chunks as long as possible. */ \
while (((unsigned long) (end - (char *)l_dest)) >= sizeof(long)) { \
*(l_dest++) = l; \
} \
} \
\
/* fill the tail in 1-byte chunks. */ \
if ((char *)l_dest < end) { \
c_dest = (char *)l_dest; \
*(c_dest++) = (c); \
while (c_dest < end) { \
*(c_dest++) = (c); \
} \
} \
} while (0)
/******************************* STRINGS GOOP *********************************/
#ifdef __GNUC__
# define SWAP(a, b) __extension__ ({__typeof__(a) tmp = (a); (a) = (b); (b) = tmp;})
#else
# define SWAP(a, b) do {void *tmp = ((void *)(a)); (a) = (b); (b) = tmp;} while (0)
#endif
#define CONST_STRLEN(x) (sizeof(x) - 1)
#define BEG_STRCASECMP(s, constr) (strncasecmp(s, constr, CONST_STRLEN(constr)))
/******************************** PROTOTYPES **********************************/
/* msgs.c */
extern int libmej_dprintf(const char *, ...);
extern void print_error(const char *fmt, ...);
extern void print_warning(const char *fmt, ...);
extern void fatal_error(const char *fmt, ...);
/* debug.c */
extern unsigned int DEBUG_LEVEL;
/* mem.c */
extern void memrec_init(void);
extern void memrec_add_var(void *, size_t);
extern void memrec_rem_var(const char *, const char *, unsigned long, void *);
extern void memrec_chg_var(const char *, const char *, unsigned long, void *, void *, size_t);
extern void memrec_dump(void);
extern void *libmej_malloc(const char *, unsigned long, size_t);
extern void *libmej_realloc(const char *, const char *, unsigned long, void *, size_t);
extern void *libmej_calloc(const char *, unsigned long, size_t, size_t);
extern void libmej_free(const char *, const char *, unsigned long, void *);
extern char *libmej_strdup(const char *, const char *, unsigned long, const char *);
extern void libmej_handle_sigsegv(int);
/* strings.c */
extern char *left_str(const char *, unsigned long);
extern char *mid_str(const char *, unsigned long, unsigned long);
extern char *right_str(const char *, unsigned long);
#ifdef HAVE_REGEX_H
extern unsigned char regexp_match(const char *, const char *);
#endif
extern char *get_word(unsigned long, const char *);
extern char *get_pword(unsigned long, const char *);
extern unsigned long num_words(const char *);
extern char *strip_whitespace(char *);
extern char *downcase_str(char *);
extern char *upcase_str(char *);
#ifndef HAVE_STRCASESTR
extern char *strcasestr(char *, const char *);
#endif
#ifndef HAVE_STRCASECHR
extern char *strcasechr(char *, char);
#endif
#ifndef HAVE_STRCASEPBRK
extern char *strcasepbrk(char *, char *);
#endif
#ifndef HAVE_STRREV
extern char *strrev(char *);
#endif
#if !(HAVE_STRSEP)
extern char *strsep(char **, char *);
#endif
extern char *safe_str(char *, unsigned short);
extern char *garbage_collect(char *, size_t);
extern char *file_garbage_collect(char *, size_t);
extern char *condense_whitespace(char *);
extern void hex_dump(void *, size_t);
#ifndef HAVE_MEMMEM
extern void *memmem(void *, size_t, void *, size_t);
#endif
#ifndef HAVE_USLEEP
extern void usleep(unsigned long);
#endif
#ifndef HAVE_SNPRINTF
extern int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
extern int snprintf(char *str, size_t count, const char *fmt, ...);
#endif
#endif /* _LIBMEJ_H_ */

View File

@ -1,9 +1,4 @@
/***************************************************************
* MEM.C -- Memory allocation handlers *
* -- Michael Jennings *
* -- 07 January 1997 *
***************************************************************/
/*
* Copyright (C) 1997-2000, Michael Jennings
*
@ -29,20 +24,11 @@
static const char cvs_ident[] = "$Id$";
#include "config.h"
#include "../src/feature.h"
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "global.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include "debug.h"
#include "mem.h"
#include "libmej.h"
/*
* These're added for a pretty obvious reason -- they're implemented towards
@ -56,276 +42,244 @@ static int realloc_count = 0;
static int free_count = 0;
#endif
MemRec memrec =
{0, 0, 0, (void **) NULL, (size_t *) NULL};
char *
SafeStr(register char *str, unsigned short len)
{
register unsigned short i;
for (i = 0; i < len; i++) {
if (iscntrl(str[i])) {
str[i] = '.';
}
}
return (str);
}
static memrec_t memrec;
void
memrec_init(void)
{
memrec.Count = 0;
D_MALLOC(("Constructing memrec\n"));
memrec.Ptrs = (void **) malloc(sizeof(void *));
memrec.Size = (size_t *) malloc(sizeof(size_t));
D_MEM(("Constructing memrec\n"));
memrec.ptrs = (ptr_t *) malloc(sizeof(ptr_t));
memrec.init = 1;
}
void
memrec_add_var(void *ptr, size_t size)
{
memrec.Count++;
if ((memrec.Ptrs = (void **) realloc(memrec.Ptrs, sizeof(void *) * memrec.Count)) == NULL) {
D_MALLOC(("Unable to reallocate pointer list -- %s\n", strerror(errno)));
register ptr_t *p;
memrec.cnt++;
if ((memrec.ptrs = (ptr_t *) realloc(memrec.ptrs, sizeof(ptr_t) * memrec.cnt)) == NULL) {
D_MEM(("Unable to reallocate pointer list -- %s\n", strerror(errno)));
}
if ((memrec.Size = (size_t *) realloc(memrec.Size, sizeof(size_t) * memrec.Count)) == NULL) {
D_MALLOC(("Unable to reallocate pointer size list -- %s\n", strerror(errno)));
}
D_MALLOC(("Adding variable of size %lu at %8p\n", size, ptr));
memrec.Ptrs[memrec.Count - 1] = ptr;
memrec.Size[memrec.Count - 1] = size;
D_MEM(("Adding variable of size %lu at %8p\n", size, ptr));
p = memrec.ptrs + memrec.cnt - 1;
p->ptr = ptr;
p->size = size;
}
void
memrec_rem_var(const char *filename, unsigned long line, void *ptr)
memrec_rem_var(const char *var, const char *filename, unsigned long line, void *ptr)
{
register ptr_t *p = NULL;
register unsigned long i;
unsigned long i;
for (i = 0; i < memrec.Count; i++)
if (memrec.Ptrs[i] == ptr)
for (i = 0; i < memrec.cnt; i++) {
if (memrec.ptrs[i].ptr == ptr) {
p = memrec.ptrs + i;
break;
if (i == memrec.Count && memrec.Ptrs[i] != ptr) {
D_MALLOC(("ERROR: File %s, line %d attempted to free a pointer not allocated with Malloc/Realloc: %8p\n", filename, line, ptr));
}
}
if (!p) {
D_MEM(("ERROR: File %s, line %d attempted to free variable %s (%8p) which was not allocated with MALLOC/REALLOC\n", filename, line, var, ptr));
return;
}
memrec.Count--;
D_MALLOC(("Removing variable of size %lu at %8p\n", memrec.Size[i], memrec.Ptrs[i]));
memmove(memrec.Ptrs + i, memrec.Ptrs + i + 1, sizeof(void *) * (memrec.Count - i));
memmove(memrec.Size + i, memrec.Size + i + 1, sizeof(size_t) * (memrec.Count - i));
memrec.Ptrs = (void **) realloc(memrec.Ptrs, sizeof(void *) * memrec.Count);
memrec.Size = (size_t *) realloc(memrec.Size, sizeof(size_t) * memrec.Count);
memrec.cnt--;
D_MEM(("Removing variable of size %lu at %8p\n", p->size, p->ptr));
memmove(p, p + 1, sizeof(ptr_t) * (memrec.cnt - i));
memrec.ptrs = (ptr_t *) realloc(memrec.ptrs, sizeof(ptr_t) * memrec.cnt);
}
void
memrec_chg_var(const char *filename, unsigned long line, void *oldp, void *newp, size_t size)
memrec_chg_var(const char *var, const char *filename, unsigned long line, void *oldp, void *newp, size_t size)
{
register ptr_t *p = NULL;
register unsigned long i;
unsigned long i;
for (i = 0; i < memrec.Count; i++)
if (memrec.Ptrs[i] == oldp)
for (i = 0; i < memrec.cnt; i++) {
if (memrec.ptrs[i].ptr == oldp) {
p = memrec.ptrs + i;
break;
if (i == memrec.Count && memrec.Ptrs[i] != oldp) {
D_MALLOC(("ERROR: File %s, line %d attempted to realloc a pointer not allocated with Malloc/Realloc: %8p\n", filename, line, oldp));
}
}
if (i == memrec.cnt) {
D_MEM(("ERROR: File %s, line %d attempted to realloc variable %s (%8p) which was not allocated with MALLOC/REALLOC\n", filename, line, var, oldp));
return;
}
D_MALLOC(("Changing variable of %lu bytes at %8p to one of %lu bytes at %8p\n", memrec.Size[i], memrec.Ptrs[i], size, newp));
memrec.Ptrs[i] = newp;
memrec.Size[i] = size;
D_MEM(("Changing variable of %lu bytes at %8p to one of %lu bytes at %8p\n", p->size, p->ptr, size, newp));
p->ptr = newp;
p->size = size;
}
void
memrec_dump(void)
{
register ptr_t *p;
unsigned long i, j, k, l, total = 0;
unsigned long len1, len2;
unsigned char *ptr;
unsigned long len;
unsigned char buff[9];
fprintf(stderr, "DUMP :: %lu pointers stored.\n", memrec.Count);
fprintf(stderr, "DUMP :: Pointer | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n");
fflush(stderr);
fprintf(stderr, "DUMP :: ---------+----------+--------+---------+-------------------------+---------\n");
fflush(stderr);
len1 = sizeof(void *) * memrec.Count;
fprintf(LIBMEJ_DEBUG_FD, "DUMP :: %lu pointers stored.\n", memrec.cnt);
fprintf(LIBMEJ_DEBUG_FD, "DUMP :: Pointer | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n");
fprintf(LIBMEJ_DEBUG_FD, "DUMP :: ---------+----------+--------+---------+-------------------------+---------\n");
fflush(LIBMEJ_DEBUG_FD);
len = sizeof(ptr_t) * memrec.cnt;
memset(buff, 0, sizeof(buff));
len2 = sizeof(size_t) * memrec.Count;
for (ptr = (unsigned char *) memrec.Ptrs, j = 0; j < len1; j += 8) {
fprintf(stderr, "DUMP :: %07lu | %8p | %06lu | %07x | ", (unsigned long) 0, memrec.Ptrs, (unsigned long) (sizeof(void *) * memrec.Count), (unsigned int) j);
/* First, dump the contents of the memrec.ptrs[] array. */
for (p = memrec.ptrs, j = 0; j < len; p++, j += 8) {
fprintf(LIBMEJ_DEBUG_FD, "DUMP :: %07lu | %8p | %06lu | %07x | ", (unsigned long) 0, memrec.ptrs, (unsigned long) (sizeof(ptr_t) * memrec.cnt), (unsigned int) j);
/* l is the number of characters we're going to output */
l = ((len - j < 8) ? (len - j) : (8));
/* Copy l bytes (up to 8) from memrec.ptrs[] (p) to buffer */
memcpy(buff, p + j, l);
for (k = 0; k < l; k++) {
fprintf(LIBMEJ_DEBUG_FD, "%02x ", buff[k]);
}
/* If we printed less than 8 bytes worth, pad with 3 spaces per byte */
for (; k < 8; k++) {
fprintf(LIBMEJ_DEBUG_FD, " ");
}
/* Finally, print the printable ASCII string for those l bytes */
fprintf(LIBMEJ_DEBUG_FD, "| %-8s\n", safe_str((char *) buff, l));
/* Flush after every line in case we crash */
fflush(LIBMEJ_DEBUG_FD);
}
l = ((len1 - j < 8) ? (len1 - j) : (8));
memset(buff, 0, 9);
memcpy(buff, ptr + j, l);
for (k = 0; k < l; k++) {
fprintf(stderr, "%02x ", buff[k]);
}
for (; k < 8; k++) {
fprintf(stderr, " ");
}
fprintf(stderr, "| %-8s\n", SafeStr((char *) buff, l));
fflush(stderr);
}
for (ptr = (unsigned char *) memrec.Size, j = 0; j < len2; j += 8) {
fprintf(stderr, "DUMP :: %07lu | %8p | %06lu | %07x | ", (unsigned long) 0, memrec.Size, sizeof(size_t) * memrec.Count, (unsigned int) j);
l = ((len2 - j < 8) ? (len2 - j) : (8));
memset(buff, 0, 9);
memcpy(buff, ptr + j, l);
for (k = 0; k < l; k++) {
fprintf(stderr, "%02x ", buff[k]);
}
for (; k < 8; k++) {
fprintf(stderr, " ");
}
fprintf(stderr, "| %-8s\n", SafeStr((char *) buff, l));
fflush(stderr);
}
for (i = 0; i < memrec.Count; i++) {
total += memrec.Size[i];
for (ptr = (unsigned char *) memrec.Ptrs[i], j = 0; j < memrec.Size[i]; j += 8) {
fprintf(stderr, "DUMP :: %07lu | %8p | %06lu | %07x | ", i + 1, memrec.Ptrs[i], (unsigned long) memrec.Size[i], (unsigned int) j);
l = ((memrec.Size[i] - j < 8) ? (memrec.Size[i] - j) : (8));
memset(buff, 0, 9);
memcpy(buff, ptr + j, l);
/* Now print out each pointer and its contents. */
for (p = memrec.ptrs, i = 0; i < memrec.cnt; p++, i++) {
/* Add this pointer's size to our total */
total += p->size;
for (j = 0; j < p->size; j += 8) {
fprintf(LIBMEJ_DEBUG_FD, "DUMP :: %07lu | %8p | %06lu | %07x | ", i + 1, p->ptr, (unsigned long) p->size, (unsigned int) j);
/* l is the number of characters we're going to output */
l = ((p->size - j < 8) ? (p->size - j) : (8));
/* Copy l bytes (up to 8) from p->ptr to buffer */
memcpy(buff, p->ptr + j, l);
for (k = 0; k < l; k++) {
fprintf(stderr, "%02x ", buff[k]);
fprintf(LIBMEJ_DEBUG_FD, "%02x ", buff[k]);
}
/* If we printed less than 8 bytes worth, pad with 3 spaces per byte */
for (; k < 8; k++) {
fprintf(stderr, " ");
fprintf(LIBMEJ_DEBUG_FD, " ");
}
fprintf(stderr, "| %-8s\n", SafeStr((char *) buff, l));
fflush(stderr);
/* Finally, print the printable ASCII string for those l bytes */
fprintf(LIBMEJ_DEBUG_FD, "| %-8s\n", safe_str((char *) buff, l));
/* Flush after every line in case we crash */
fflush(LIBMEJ_DEBUG_FD);
}
}
fprintf(stderr, "DUMP :: Total allocated memory: %10lu bytes\n\n", total);
fflush(stderr);
fprintf(LIBMEJ_DEBUG_FD, "DUMP :: Total allocated memory: %10lu bytes\n\n", total);
fflush(LIBMEJ_DEBUG_FD);
}
/************* Function prototypes ****************/
void *
Malloc(const char *filename, unsigned long line, size_t size)
libmej_malloc(const char *filename, unsigned long line, size_t size)
{
void *temp;
#ifdef MALLOC_CALL_DEBUG
++malloc_count;
if (!(malloc_count % MALLOC_MOD)) {
fprintf(stderr, "Calls to malloc(): %d\n", malloc_count);
fprintf(LIBMEJ_DEBUG_FD, "Calls to malloc(): %d\n", malloc_count);
}
#endif
D_MALLOC(("Malloc(%lu) called at %s:%lu\n", size, filename, line));
if (!memrec.init) {
D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n"));
memrec_init();
}
D_MEM(("libmej_malloc(%lu) called at %s:%lu\n", size, filename, line));
temp = (void *) malloc(size);
if (!temp)
return NULL;
if (debug_level >= DEBUG_MALLOC) {
ASSERT_RVAL(temp != NULL, NULL);
if (DEBUG_LEVEL >= DEBUG_MEM) {
memrec_add_var(temp, size);
}
return (temp);
}
void *
Realloc(const char *var, const char *filename, unsigned long line, void *ptr, size_t size)
libmej_realloc(const char *var, const char *filename, unsigned long line, void *ptr, size_t size)
{
void *temp;
#ifdef MALLOC_CALL_DEBUG
++realloc_count;
if (!(realloc_count % REALLOC_MOD)) {
fprintf(stderr, "Calls to realloc(): %d\n", realloc_count);
D_MEM(("Calls to realloc(): %d\n", realloc_count));
}
#endif
if (!memrec.init) {
D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n"));
memrec_init();
}
D_MALLOC(("Realloc(%lu) called for variable %s (%8p) at %s:%lu\n", size, var, ptr, filename, line));
D_MEM(("libmej_realloc(%lu) called for variable %s (%8p) at %s:%lu\n", size, var, ptr, filename, line));
if (ptr == NULL) {
temp = (void *) Malloc(__FILE__, __LINE__, size);
temp = (void *) libmej_malloc(__FILE__, __LINE__, size);
} else {
temp = (void *) realloc(ptr, size);
if (debug_level >= DEBUG_MALLOC) {
memrec_chg_var(filename, line, ptr, temp, size);
ASSERT_RVAL(temp != NULL, ptr);
if (DEBUG_LEVEL >= DEBUG_MEM) {
memrec_chg_var(var, filename, line, ptr, temp, size);
}
}
return (temp);
}
void *
Calloc(const char *filename, unsigned long line, size_t count, size_t size)
libmej_calloc(const char *filename, unsigned long line, size_t count, size_t size)
{
char *temp;
void *temp;
#ifdef MALLOC_CALL_DEBUG
++calloc_count;
if (!(calloc_count % CALLOC_MOD)) {
fprintf(stderr, "Calls to calloc(): %d\n", calloc_count);
fprintf(LIBMEJ_DEBUG_FD, "Calls to calloc(): %d\n", calloc_count);
}
#endif
if (!memrec.init) {
D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n"));
memrec_init();
}
D_MALLOC(("Calloc(%lu, %lu) called at %s:%lu\n", count, size, filename, line));
temp = (char *) calloc(count, size);
if (debug_level >= DEBUG_MALLOC) {
D_MEM(("libmej_calloc(%lu, %lu) called at %s:%lu\n", count, size, filename, line));
temp = (void *) calloc(count, size);
ASSERT_RVAL(temp != NULL, NULL);
if (DEBUG_LEVEL >= DEBUG_MEM) {
memrec_add_var(temp, size * count);
}
return (temp);
}
void
Free(const char *var, const char *filename, unsigned long line, void *ptr)
libmej_free(const char *var, const char *filename, unsigned long line, void *ptr)
{
#ifdef MALLOC_CALL_DEBUG
++free_count;
if (!(free_count % FREE_MOD)) {
fprintf(stderr, "Calls to free(): %d\n", free_count);
fprintf(LIBMEJ_DEBUG_FD, "Calls to free(): %d\n", free_count);
}
#endif
if (!memrec.init) {
D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n"));
memrec_init();
}
D_MALLOC(("Free() called for variable %s (%8p) at %s:%lu\n", var, ptr, filename, line));
D_MEM(("libmej_free() called for variable %s (%8p) at %s:%lu\n", var, ptr, filename, line));
if (ptr) {
if (debug_level >= DEBUG_MALLOC) {
memrec_rem_var(filename, line, ptr);
if (DEBUG_LEVEL >= DEBUG_MEM) {
memrec_rem_var(var, filename, line, ptr);
}
free(ptr);
} else {
D_MALLOC(("ERROR: Caught attempt to free NULL pointer\n"));
D_MEM(("ERROR: Caught attempt to free NULL pointer\n"));
}
}
void
HandleSigSegv(int sig)
char *
libmej_strdup(const char *var, const char *filename, unsigned long line, const char *str)
{
register char *newstr;
register size_t len;
#if DEBUG >= DEBUG_MALLOC
fprintf(stderr, "Fatal memory fault (%d)! Dumping memory table.\n", sig);
D_MEM(("libmej_strdup() called for variable %s (%8p) at %s:%lu\n", var, str, filename, line));
len = strlen(str) + 1; /* Copy NUL byte also */
newstr = (char *) libmej_malloc(filename, line, len);
strcpy(newstr, str);
return (newstr);
}
void
libmej_handle_sigsegv(int sig)
{
#if DEBUG >= DEBUG_MEM
fprintf(LIBMEJ_DEBUG_FD, "Fatal memory fault (%d)! Dumping memory table.\n", sig);
memrec_dump();
#endif
exit(EXIT_FAILURE);

View File

@ -1,73 +0,0 @@
/***************************************************************
* MEM.H -- Header file for mem.c *
* -- Michael Jennings *
* -- 07 January 1997 *
***************************************************************/
/*
* Copyright (C) 1997-2000, Michael Jennings
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of the Software, its documentation and marketing & publicity
* materials, and acknowledgment shall be given in the documentation, materials
* and software packages that this Software was used.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS 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.
*/
#ifndef _MEM_H_
#define _MEM_H_
typedef struct memrec_struct {
unsigned char init;
unsigned long Count, TotalSize;
void **Ptrs;
size_t *Size;
} MemRec;
#ifdef WITH_DMALLOC
# include <dmalloc.h>
#endif
#if (DEBUG >= DEBUG_MALLOC)
# define MALLOC(sz) Malloc(__FILE__, __LINE__, (sz))
# define CALLOC(type,n) Calloc(__FILE__, __LINE__, (n),(sizeof(type)))
# define REALLOC(mem,sz) Realloc(#mem, __FILE__, __LINE__, (mem),(sz))
# define FREE(ptr) do { Free(#ptr, __FILE__, __LINE__, (ptr)); (ptr) = NULL; } while (0)
# define MALLOC_MOD 25
# define REALLOC_MOD 25
# define CALLOC_MOD 25
# define FREE_MOD 25
#else
# define MALLOC(sz) malloc(sz)
# define CALLOC(type,n) calloc((n),(sizeof(type)))
# define REALLOC(mem,sz) ((sz) ? ((mem) ? (realloc((mem), (sz))) : (malloc(sz))) : ((mem) ? (free(mem), NULL) : (NULL)))
# define FREE(ptr) do { free(ptr); (ptr) = NULL; } while (0)
#endif
extern char *SafeStr(char *, unsigned short);
extern MemRec memrec;
extern void memrec_init(void);
extern void memrec_add_var(void *, size_t);
extern void memrec_rem_var(const char *, unsigned long, void *);
extern void memrec_chg_var(const char *, unsigned long, void *, void *, size_t);
extern void memrec_dump(void);
extern void *Malloc(const char *, unsigned long, size_t);
extern void *Realloc(const char *, const char *, unsigned long, void *, size_t);
extern void *Calloc(const char *, unsigned long, size_t, size_t);
extern void Free(const char *, const char *, unsigned long, void *);
extern void HandleSigSegv(int);
#endif /* _MEM_H_ */

View File

@ -1,8 +1,3 @@
/***************************************************************
* GLOBAL.H -- Compile-time options header file *
* -- Michael Jennings *
* -- 16 January 1997 *
***************************************************************/
/*
* Copyright (C) 1997-2000, Michael Jennings
*
@ -26,21 +21,61 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _GLOBAL_H_
#define _GLOBAL_H_
/* Other compile-time defines */
#ifdef LINUX
# define _GNU_SOURCE
# define __USE_GNU
# define _BSD_SOURCE
#elif defined(IRIX)
# define _MODERN_C_
# define _BSD_TYPES
# define _SGI_SOURCE
#elif defined(HP_UX)
static const char cvs_ident[] = "$Id$";
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#endif /* _GLOBAL_H_ */
#include "libmej.h"
int
libmej_dprintf(const char *format, ...)
{
va_list args;
int n;
va_start(args, format);
n = vfprintf(stderr, format, args);
va_end(args);
fflush(stderr);
return (n);
}
/* Print a non-terminal error message */
void
print_error(const char *fmt, ...)
{
va_list arg_ptr;
va_start(arg_ptr, fmt);
fprintf(stderr, PACKAGE ": Error: ");
vfprintf(stderr, fmt, arg_ptr);
va_end(arg_ptr);
}
/* Print a simple warning */
void
print_warning(const char *fmt, ...)
{
va_list arg_ptr;
va_start(arg_ptr, fmt);
fprintf(stderr, PACKAGE ": Warning: ");
vfprintf(stderr, fmt, arg_ptr);
va_end(arg_ptr);
}
/* Print a fatal error message and terminate */
void
fatal_error(const char *fmt, ...)
{
va_list arg_ptr;
va_start(arg_ptr, fmt);
fprintf(stderr, PACKAGE ": FATAL: ");
vfprintf(stderr, fmt, arg_ptr);
va_end(arg_ptr);
exit(-1);
}

View File

@ -1,8 +1,11 @@
#include "config.h"
#include "../src/feature.h"
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "global.h"
#include <errno.h>
#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif
static const char cvs_ident[] = "$Id$";
@ -18,10 +21,6 @@ static const char cvs_ident[] = "$Id$";
#if !defined(HAVE_SNPRINTF) || (HAVE_SNPRINTF_BUG == 1)
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#define VA_LOCAL_DECL va_list ap
#define VA_START(f) va_start(ap, f)
#define VA_SHIFT(v,t) ; /* no-op for ANSI */
@ -452,7 +451,7 @@ dopr_outch(int c)
* Copyright Holder, but only to the computing community at large
* as a market that must bear the fee.)
*
* "Freely Available" means that no fee is charged for the item
* "libmej_freely Available" means that no fee is charged for the item
* itself, though there may be fees involved in handling the item.
* It also means that recipients of the item may redistribute it
* under the same conditions they received it.
@ -471,7 +470,7 @@ dopr_outch(int c)
* following:
*
* a) place your modifications in the Public Domain or otherwise make them
* Freely Available, such as by posting said modifications to Usenet or
* libmej_freely Available, such as by posting said modifications to Usenet or
* an equivalent medium, or placing the modifications on a major archive
* site such as uunet.uu.net, or by allowing the Copyright Holder to include
* your modifications in the Standard Version of the Package.

View File

@ -1,8 +1,3 @@
/***************************************************************
* STRINGS.C -- String manipulation routines *
* -- Michael Jennings *
* -- 08 January 1997 *
***************************************************************/
/*
* Copyright (C) 1997-2000, Michael Jennings
*
@ -28,22 +23,11 @@
static const char cvs_ident[] = "$Id$";
#include "config.h"
#include "../src/feature.h"
#include "global.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#ifndef WITH_DMALLOC
# include <malloc.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <ctype.h>
#include "debug.h"
#include "mem.h"
#include "strings.h"
#include <libmej.h>
#ifndef HAVE_MEMMEM
/* Find first occurance of bytestring needle of size needlelen in memory region
@ -51,7 +35,6 @@ static const char cvs_ident[] = "$Id$";
void *
memmem(void *haystack, register size_t haystacklen, void *needle, register size_t needlelen)
{
register char *hs = (char *) haystack;
register char *n = (char *) needle;
register unsigned long i;
@ -70,7 +53,6 @@ memmem(void *haystack, register size_t haystacklen, void *needle, register size_
void
usleep(unsigned long usec)
{
struct timeval delay;
delay.tv_sec = 0;
@ -92,9 +74,8 @@ nanosleep(unsigned long nsec) {
/* Return the leftmost cnt characters of str */
char *
LeftStr(const char *str, unsigned long cnt)
left_str(const char *str, unsigned long cnt)
{
char *tmpstr;
tmpstr = (char *) MALLOC(cnt + 1);
@ -105,9 +86,8 @@ LeftStr(const char *str, unsigned long cnt)
/* Return cnt characters from str, starting at position index (from 0) */
char *
MidStr(const char *str, unsigned long index, unsigned long cnt)
mid_str(const char *str, unsigned long index, unsigned long cnt)
{
char *tmpstr;
const char *pstr = str;
@ -120,9 +100,8 @@ MidStr(const char *str, unsigned long index, unsigned long cnt)
/* Return the rightmost characters of str */
char *
RightStr(const char *str, unsigned long cnt)
right_str(const char *str, unsigned long cnt)
{
char *tmpstr;
const char *pstr = str;
@ -136,37 +115,21 @@ RightStr(const char *str, unsigned long cnt)
/* Returns TRUE if str matches regular expression pattern, FALSE otherwise */
#if defined(HAVE_REGEX_H) || defined(IRIX)
unsigned char
Match(register const char *str, register const char *pattern)
regexp_match(register const char *str, register const char *pattern)
{
register regex_t *rexp;
register int result;
#ifndef IRIX
char errbuf[256];
rexp = (regex_t *) MALLOC(sizeof(regex_t));
#endif
#ifdef IRIX
if ((rexp = compile((const char *) pattern, (char *) NULL, (char *) NULL)) == NULL) {
fprintf(stderr, "Unable to compile regexp %s\n", pattern);
return (FALSE);
}
#else
if ((result = regcomp(rexp, pattern, REG_EXTENDED)) != 0) {
regerror(result, rexp, errbuf, 256);
fprintf(stderr, "Unable to compile regexp %s -- %s.\n", pattern, errbuf);
FREE(rexp);
return (FALSE);
}
#endif
#ifdef IRIX
result = step((const char *) str, rexp);
FREE(rexp);
return (result);
#else
if (((result = regexec(rexp, str, (size_t) 0, (regmatch_t *) NULL, 0))
!= 0) && (result != REG_NOMATCH)) {
regerror(result, rexp, errbuf, 256);
@ -176,22 +139,22 @@ Match(register const char *str, register const char *pattern)
}
FREE(rexp);
return (!result);
#endif
}
#endif
/* Return malloc'd pointer to index-th word in str. "..." counts as 1 word. */
char *
Word(unsigned long index, const char *str)
{
#define IS_DELIM(c) (delim ? ((c) == delim) : (isspace(c)))
char *
get_word(unsigned long index, const char *str)
{
char *tmpstr;
char *delim = DEFAULT_DELIM;
char delim = 0;
register unsigned long i, j, k;
k = strlen(str) + 1;
if ((tmpstr = (char *) MALLOC(k)) == NULL) {
fprintf(stderr, "Word(%lu, %s): Unable to allocate memory -- %s.\n",
fprintf(stderr, "get_word(%lu, %s): Unable to allocate memory -- %s.\n",
index, str, strerror(errno));
return ((char *) NULL);
}
@ -200,17 +163,17 @@ Word(unsigned long index, const char *str)
for (; isspace(str[i]); i++);
switch (str[i]) {
case '\"':
delim = "\"";
delim = '\"';
i++;
break;
case '\'':
delim = "\'";
delim = '\'';
i++;
break;
default:
delim = DEFAULT_DELIM;
delim = 0;
}
for (k = 0; str[i] && !strchr(delim, str[i]);) {
for (k = 0; str[i] && !IS_DELIM(str[i]);) {
if (str[i] == '\\') {
if (str[i + 1] == '\'' || str[i + 1] == '\"') {
i++;
@ -229,20 +192,19 @@ Word(unsigned long index, const char *str)
if (j != index) {
FREE(tmpstr);
D_STRINGS(("Word(%lu, %s) returning NULL.\n", index, str));
D_STRINGS(("get_word(%lu, %s) returning NULL.\n", index, str));
return ((char *) NULL);
} else {
tmpstr = (char *) REALLOC(tmpstr, strlen(tmpstr) + 1);
D_STRINGS(("Word(%lu, %s) returning \"%s\".\n", index, str, tmpstr));
D_STRINGS(("get_word(%lu, %s) returning \"%s\".\n", index, str, tmpstr));
return (tmpstr);
}
}
/* Return pointer into str to index-th word in str. "..." counts as 1 word. */
char *
PWord(unsigned long index, const char *str)
get_pword(unsigned long index, const char *str)
{
register const char *tmpstr = str;
register unsigned long j;
@ -258,38 +220,37 @@ PWord(unsigned long index, const char *str)
tmpstr++;
}
if (*tmpstr == '\0') {
D_STRINGS(("PWord(%lu, %s) returning NULL.\n", index, str));
D_STRINGS(("get_pword(%lu, %s) returning NULL.\n", index, str));
return ((char *) NULL);
} else {
D_STRINGS(("PWord(%lu, %s) returning \"%s\"\n", index, str, tmpstr));
D_STRINGS(("get_pword(%lu, %s) returning \"%s\"\n", index, str, tmpstr));
return (char *) tmpstr;
}
}
/* Returns the number of words in str, for use with Word() and PWord(). "..." counts as 1 word. */
/* Returns the number of words in str, for use with get_word() and get_pword(). "..." counts as 1 word. */
unsigned long
NumWords(const char *str)
num_words(const char *str)
{
register unsigned long cnt = 0;
char *delim = DEFAULT_DELIM;
char delim = 0;
register unsigned long i;
for (i = 0; str[i] && strchr(delim, str[i]); i++);
for (i = 0; str[i] && IS_DELIM(str[i]); i++);
for (; str[i]; cnt++) {
switch (str[i]) {
case '\"':
delim = "\"";
delim = '\"';
i++;
break;
case '\'':
delim = "\'";
delim = '\'';
i++;
break;
default:
delim = DEFAULT_DELIM;
delim = 0;
}
for (; str[i] && !strchr(delim, str[i]); i