Several small changes, like freeing pixmaps which won't be needed later, reducing the default Imlib2 cache size to 0 bytes (we don't really use it well), and an image path bugfix spotted by Teodor Zlatanov <tzz@iglou.com>. The big change, of course, is the disappearance of libmej and the new dependency on libast, which is now distributed separately. SVN revision: 3793eterm-0.10
parent
536efe1a48
commit
8138d895fa
27 changed files with 206 additions and 2148 deletions
@ -1,7 +0,0 @@ |
||||
Makefile |
||||
Makefile.in |
||||
.deps |
||||
.libs |
||||
libmej.la |
||||
*.da |
||||
*.lo |
@ -1,10 +0,0 @@ |
||||
# $Id$
|
||||
|
||||
lib_LTLIBRARIES = libmej.la
|
||||
include_HEADERS = libmej.h
|
||||
|
||||
libmej_la_SOURCES = debug.c mem.c msgs.c strings.c snprintf.c libmej.h
|
||||
|
||||
LIBS = -lm
|
||||
|
||||
libmej_la_LDFLAGS = -release $(VERSION)
|
@ -1,36 +0,0 @@ |
||||
/*
|
||||
* 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. |
||||
*/ |
||||
|
||||
static const char cvs_ident[] = "$Id$"; |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
# include <config.h> |
||||
#endif |
||||
|
||||
#include "libmej.h" |
||||
|
||||
/* 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; |
||||
|
@ -1,400 +0,0 @@ |
||||
/*
|
||||
* 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 |
||||
|
||||
#include <X11/Xatom.h> |
||||
#include <X11/X.h> |
||||
#include <X11/Intrinsic.h> |
||||
#ifdef HAVE_LIBIMLIB2 |
||||
# include <Imlib2.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 |
||||
|
||||
/* An "unused block" marker similar to the above. */ |
||||
#define UNUSED_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(); libmej_dprintf("Moo.\n");} while (0) |
||||
|
||||
/* Assertion/abort macros which are quite a bit more useful than assert() and abort(). */ |
||||
#if DEBUG >= 1 |
||||
# 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) |
||||
#else |
||||
# define ASSERT(x) NOP |
||||
# define ASSERT_RVAL(x, val) NOP |
||||
# define ASSERT_NOTREACHED() return |
||||
# define ASSERT_NOTREACHED_RVAL(val) return (val) |
||||
# define ABORT() fatal_error("Aborting.\n") |
||||
# define REQUIRE(x) do {if (!(x)) return;} while (0) |
||||
# define REQUIRE_RVAL(x, v) do {if (!(x)) return (v);} while (0) |
||||
#endif |
||||
|
||||
#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 ***********************************/ |
||||
#define LIBMEJ_FNAME_LEN 20 |
||||
|
||||
typedef struct ptr_struct { |
||||
void *ptr; |
||||
size_t size; |
||||
char file[LIBMEJ_FNAME_LEN + 1]; |
||||
unsigned long line; |
||||
} ptr_t; |
||||
typedef struct memrec_struct { |
||||
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_DUMP() libmej_dump_mem_tables() |
||||
# define X_CREATE_PIXMAP(d, win, w, h, depth) libmej_x_create_pixmap(__FILE__, __LINE__, (d), (win), (w), (h), (depth)) |
||||
# define X_FREE_PIXMAP(d, p) libmej_x_free_pixmap(#p, __FILE__, __LINE__, (d), (p)) |
||||
# ifdef HAVE_LIBIMLIB2 |
||||
# define IMLIB_REGISTER_PIXMAP(p) libmej_imlib_register_pixmap(#p, __FILE__, __LINE__, (p)) |
||||
# define IMLIB_FREE_PIXMAP(p) libmej_imlib_free_pixmap(#p, __FILE__, __LINE__, (p)) |
||||
# else |
||||
# define IMLIB_REGISTER_PIXMAP(p) NOP |
||||
# define IMLIB_FREE_PIXMAP(p) NOP |
||||
# endif |
||||
# define PIXMAP_DUMP() libmej_dump_pixmap_tables() |
||||
# define X_CREATE_GC(d, win, f, gcv) libmej_x_create_gc(__FILE__, __LINE__, (d), (win), (f), (gcv)) |
||||
# define X_FREE_GC(d, gc) libmej_x_free_gc(#gc, __FILE__, __LINE__, (d), (gc)) |
||||
# define GC_DUMP() libmej_dump_gc_tables() |
||||
# 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) |
||||
# define MALLOC_DUMP() NOP |
||||
# define X_CREATE_PIXMAP(d, win, w, h, depth) XCreatePixmap((d), (win), (w), (h), (depth)) |
||||
# define X_FREE_PIXMAP(d, p) XFreePixmap((d), (p)) |
||||
# ifdef HAVE_LIBIMLIB2 |
||||
# define IMLIB_REGISTER_PIXMAP(p) NOP |
||||
# define IMLIB_FREE_PIXMAP(p) imlib_free_pixmap_and_mask(p) |
||||
# else |
||||
# define IMLIB_REGISTER_PIXMAP(p) NOP |
||||
# define IMLIB_FREE_PIXMAP(p) NOP |
||||
# endif |
||||
# define PIXMAP_DUMP() NOP |
||||
# define X_CREATE_GC(d, win, f, gcv) XCreateGC((d), (win), (f), (gcv)) |
||||
# define X_FREE_GC(d, gc) XFreeGC((d), (gc)) |
||||
# define GC_DUMP() NOP |
||||
#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 *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_dump_mem_tables(void); |
||||
extern Pixmap libmej_x_create_pixmap(const char *, unsigned long, Display *, Drawable, unsigned int, unsigned int, unsigned int); |
||||
extern void libmej_x_free_pixmap(const char *, const char *, unsigned long, Display *, Pixmap); |
||||
extern void libmej_dump_pixmap_tables(void); |
||||
extern GC libmej_x_create_gc(const char *, unsigned long, Display *, Drawable, unsigned long, XGCValues *); |
||||
extern void libmej_x_free_gc(const char *, const char *, unsigned long, Display *, GC); |
||||
extern void libmej_dump_gc_tables(void); |
||||
|
||||
/* 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_ */ |
@ -1,446 +0,0 @@ |
||||
|
||||
/*
|
||||
* 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. |
||||
*/ |
||||
|
||||
static const char cvs_ident[] = "$Id$"; |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
# include <config.h> |
||||
#endif |
||||
|
||||
#include "libmej.h" |
||||
|
||||
static void memrec_add_var(memrec_t *, const char *, unsigned long, void *, size_t); |
||||
static ptr_t *memrec_find_var(memrec_t *, const void *); |
||||
static void memrec_rem_var(memrec_t *, const char *, const char *, unsigned long, const void *); |
||||
static void memrec_chg_var(memrec_t *, const char *, const char *, unsigned long, const void *, void *, size_t); |
||||
static void memrec_dump_pointers(memrec_t *); |
||||
static void memrec_dump_resources(memrec_t *); |
||||
|
||||
/*
|
||||
* These're added for a pretty obvious reason -- they're implemented towards |
||||
* The beginning of each one's respective function. (The ones with capitalized |
||||
* letters. I'm not sure that they'll be useful outside of gdb. Maybe.
|
||||
*/ |
||||
#ifdef MALLOC_CALL_DEBUG |
||||
static int malloc_count = 0; |
||||
static int calloc_count = 0; |
||||
static int realloc_count = 0; |
||||
static int free_count = 0; |
||||
#endif |
||||
|
||||
static memrec_t malloc_rec, pixmap_rec, gc_rec; |
||||
|
||||
void |
||||
memrec_init(void) |
||||
{ |
||||
D_MEM(("Constructing memory allocation records\n")); |
||||
malloc_rec.ptrs = (ptr_t *) malloc(sizeof(ptr_t)); |
||||
pixmap_rec.ptrs = (ptr_t *) malloc(sizeof(ptr_t)); |
||||
gc_rec.ptrs = (ptr_t *) malloc(sizeof(ptr_t)); |
||||
} |
||||
|
||||
static void |
||||
memrec_add_var(memrec_t *memrec, const char *filename, unsigned long line, void *ptr, size_t size) |
||||
{ |
||||
register ptr_t *p; |
||||
|
||||
ASSERT(memrec != NULL); |
||||
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))); |
||||
} |
||||
p = memrec->ptrs + memrec->cnt - 1; |
||||
D_MEM(("Adding variable (%8p, %lu bytes) from %s:%lu.\n", ptr, size, filename, line)); |
||||
D_MEM(("Storing as pointer #%lu at %8p (from %8p).\n", memrec->cnt, p, memrec->ptrs)); |
||||
p->ptr = ptr; |
||||
p->size = size; |
||||
strncpy(p->file, filename, LIBMEJ_FNAME_LEN); |
||||
p->file[LIBMEJ_FNAME_LEN] = 0; |
||||
p->line = line; |
||||
} |
||||
|
||||
static ptr_t * |
||||
memrec_find_var(memrec_t *memrec, const void *ptr) |
||||
{ |
||||
register ptr_t *p; |
||||
register unsigned long i; |
||||
|
||||
ASSERT(memrec != NULL); |
||||
REQUIRE_RVAL(ptr != NULL, NULL); |
||||
|
||||
for (i = 0, p = memrec->ptrs; i < memrec->cnt; i++, p++) { |
||||
if (p->ptr == ptr) { |
||||
D_MEM(("Found pointer #%lu stored at %8p (from %8p)\n", i + 1, p, memrec->ptrs)); |
||||
return p; |
||||
} |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
static void |
||||
memrec_rem_var(memrec_t *memrec, const char *var, const char *filename, unsigned long line, const void *ptr) |
||||
{ |
||||
register ptr_t *p; |
||||
|
||||
ASSERT(memrec != NULL); |
||||
|
||||
if ((p = memrec_find_var(memrec, ptr)) == NULL) { |
||||
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->cnt--; |
||||
D_MEM(("Removing variable %s (%8p) of size %lu\n", var, ptr, p->size)); |
||||
memmove(p, p + 1, sizeof(ptr_t) * (memrec->cnt - (p - memrec->ptrs))); |
||||
memrec->ptrs = (ptr_t *) realloc(memrec->ptrs, sizeof(ptr_t) * memrec->cnt); |
||||
} |
||||
|
||||
static void |
||||
memrec_chg_var(memrec_t *memrec, const char *var, const char *filename, unsigned long line, const void *oldp, void *newp, size_t size) |
||||
{ |
||||
register ptr_t *p; |
||||
|
||||
ASSERT(memrec != NULL); |
||||
|
||||
if ((p = memrec_find_var(memrec, oldp)) == NULL) { |
||||
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_MEM(("Changing variable %s (%8p, %lu -> %8p, %lu)\n", var, oldp, p->size, newp, size)); |
||||
p->ptr = newp; |
||||
p->size = size; |
||||
strncpy(p->file, filename, LIBMEJ_FNAME_LEN); |
||||
p->line = line; |
||||
} |
||||
|
||||
static void |
||||
memrec_dump_pointers(memrec_t *memrec) |
||||
{ |
||||
register ptr_t *p; |
||||
unsigned long i, j, k, l, total = 0; |
||||
unsigned long len; |
||||
unsigned char buff[9]; |
||||
|
||||
ASSERT(memrec != NULL); |
||||
fprintf(LIBMEJ_DEBUG_FD, "PTR: %lu pointers stored.\n", memrec->cnt); |
||||
fprintf(LIBMEJ_DEBUG_FD, "PTR: Pointer | Filename | Line | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n"); |
||||
fprintf(LIBMEJ_DEBUG_FD, "PTR: ---------+----------------------+--------+----------+--------+---------+-------------------------+---------\n"); |
||||
fflush(LIBMEJ_DEBUG_FD); |
||||
len = sizeof(ptr_t) * memrec->cnt; |
||||
memset(buff, 0, sizeof(buff)); |
||||
|
||||
/* First, dump the contents of the memrec->ptrs[] array. */ |
||||
for (p = memrec->ptrs, j = 0; j < len; j += 8) { |
||||
fprintf(LIBMEJ_DEBUG_FD, "PTR: %07lu | %20s | %6lu | %8p | %06lu | %07x | ", (unsigned long) 0, "", (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, ((char *) p) + j, l); |
||||
buff[l] = 0; |
||||
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); |
||||
} |
||||
|
||||
/* Now print out each pointer and its contents. */ |
||||
for (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, "PTR: %07lu | %20s | %6lu | %8p | %06lu | %07x | ", i + 1, NONULL(p->file), p->line, 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, ((char *) p->ptr) + j, l); |
||||
buff[l] = 0; |
||||
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); |
||||
} |
||||
} |
||||
fprintf(LIBMEJ_DEBUG_FD, "PTR: Total allocated memory: %10lu bytes\n", total); |
||||
fflush(LIBMEJ_DEBUG_FD); |
||||
} |
||||
|
||||
static void |
||||
memrec_dump_resources(memrec_t *memrec) |
||||
{ |
||||
register ptr_t *p; |
||||
unsigned long i, total; |
||||
unsigned long len; |
||||
|
||||
ASSERT(memrec != NULL); |
||||
len = memrec->cnt; |
||||
fprintf(LIBMEJ_DEBUG_FD, "RES: %lu resources stored.\n", memrec->cnt); |
||||
fprintf(LIBMEJ_DEBUG_FD, "RES: Index | Resource ID | Filename | Line | Size \n"); |
||||
fprintf(LIBMEJ_DEBUG_FD, "RES: -------+-------------+----------------------+--------+--------\n"); |
||||
fflush(LIBMEJ_DEBUG_FD); |
||||
|
||||
for (p = memrec->ptrs, i = 0, total = 0; i < len; i++, p++) { |
||||
total += p->size; |
||||
fprintf(LIBMEJ_DEBUG_FD, "RES: %5lu | 0x%08x | %20s | %6lu | %6lu\n", i, (unsigned) p->ptr, NONULL(p->file), p->line, (unsigned long) p->size); |
||||
/* Flush after every line in case we crash */ |
||||
fflush(LIBMEJ_DEBUG_FD); |
||||
} |
||||
fprintf(LIBMEJ_DEBUG_FD, "RES: Total size: %lu bytes\n", total); |
||||
fflush(LIBMEJ_DEBUG_FD); |
||||
} |
||||
|
||||
/******************** MEMORY ALLOCATION INTERFACE ********************/ |
||||
void * |
||||
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(LIBMEJ_DEBUG_FD, "Calls to malloc(): %d\n", malloc_count); |
||||
} |
||||
#endif |
||||
|
||||
D_MEM(("%lu bytes requested at %s:%lu\n", size, filename, line)); |
||||
|
||||
temp = (void *) malloc(size); |
||||
ASSERT_RVAL(temp != NULL, NULL); |
||||
if (DEBUG_LEVEL >= DEBUG_MEM) { |
||||
memrec_add_var(&malloc_rec, filename, line, temp, size); |
||||
} |
||||
return (temp); |
||||
} |
||||
|
||||
void * |
||||
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)) { |
||||
D_MEM(("Calls to realloc(): %d\n", realloc_count)); |
||||
} |
||||
#endif |
||||
|
||||
D_MEM(("Variable %s (%8p -> %lu) at %s:%lu\n", var, ptr, (unsigned long) size, filename, line)); |
||||
if (ptr == NULL) { |
||||
temp = (void *) libmej_malloc(__FILE__, __LINE__, size); |
||||
} else { |
||||
temp = (void *) realloc(ptr, size); |
||||
ASSERT_RVAL(temp != NULL, ptr); |
||||
if (DEBUG_LEVEL >= DEBUG_MEM) { |
||||
memrec_chg_var(&malloc_rec, var, filename, line, ptr, temp, size); |
||||
} |
||||
} |
||||
return (temp); |
||||
} |
||||
|
||||
void * |
||||
libmej_calloc(const char *filename, unsigned long line, size_t count, size_t size) |
||||
{ |
||||
void *temp; |
||||
|
||||
#ifdef MALLOC_CALL_DEBUG |
||||
++calloc_count; |
||||
if (!(calloc_count % CALLOC_MOD)) { |
||||
fprintf(LIBMEJ_DEBUG_FD, "Calls to calloc(): %d\n", calloc_count); |
||||
} |
||||
#endif |
||||
|
||||
D_MEM(("%lu units of %lu bytes each requested 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(&malloc_rec, filename, line, temp, size * count); |
||||
} |
||||
return (temp); |
||||
} |
||||
|
||||
void |
||||
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(LIBMEJ_DEBUG_FD, "Calls to free(): %d\n", free_count); |
||||
} |
||||
#endif |
||||
|
||||
D_MEM(("Variable %s (%8p) at %s:%lu\n", var, ptr, filename, line)); |
||||
if (ptr) { |
||||
if (DEBUG_LEVEL >= DEBUG_MEM) { |
||||
memrec_rem_var(&malloc_rec, var, filename, line, ptr); |
||||
} |
||||
free(ptr); |
||||
} else { |
||||
D_MEM(("ERROR: Caught attempt to free NULL pointer\n")); |
||||
} |
||||
} |
||||
|
||||
char * |
||||
libmej_strdup(const char *var, const char *filename, unsigned long line, const char *str) |
||||
{ |
||||
register char *newstr; |
||||
register size_t len; |
||||
|
||||
D_MEM(("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_dump_mem_tables(void) |
||||
{ |
||||
fprintf(LIBMEJ_DEBUG_FD, "Dumping memory allocation table:\n"); |
||||
memrec_dump_pointers(&malloc_rec); |
||||
} |
||||
|
||||
|
||||
|
||||
/******************** PIXMAP ALLOCATION INTERFACE ********************/ |
||||
|
||||
Pixmap |
||||
libmej_x_create_pixmap(const char *filename, unsigned long line, Display *d, Drawable win, unsigned int w, unsigned int h, unsigned int depth) |
||||
{ |
||||
Pixmap p; |
||||
|
||||
D_MEM(("Creating %ux%u pixmap of depth %u for window 0x%08x at %s:%lu\n", w, h, depth, win, filename, line)); |
||||
|
||||
p = XCreatePixmap(d, win, w, h, depth); |
||||
ASSERT_RVAL(p != None, None); |
||||
if (DEBUG_LEVEL >= DEBUG_MEM) { |
||||
memrec_add_var(&pixmap_rec, filename, line, (void *) p, w * h * (depth / 8)); |
||||
} |
||||
return (p); |
||||
} |
||||
|
||||
void |
||||
libmej_x_free_pixmap(const char *var, const char *filename, unsigned long line, Display *d, Pixmap p) |
||||
{ |
||||
D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu\n", var, p, filename, line)); |
||||
if (p) { |
||||
if (DEBUG_LEVEL >= DEBUG_MEM) { |
||||
memrec_rem_var(&pixmap_rec, var, filename, line, (void *) p); |
||||
} |
||||
XFreePixmap(d, p); |
||||
} else { |
||||
D_MEM(("ERROR: Caught attempt to free NULL pixmap\n")); |
||||
} |
||||
} |
||||
|
||||
void |
||||
libmej_imlib_register_pixmap(const char *var, const char *filename, unsigned long line, Pixmap p) |
||||
{ |
||||
D_MEM(("Registering pixmap %s (0x%08x) created by Imlib2 at %s:%lu\n", var, p, filename, line)); |
||||
if (p) { |
||||
if (DEBUG_LEVEL >= DEBUG_MEM) { |
||||
if (!memrec_find_var(&pixmap_rec, (void *) p)) { |
||||
memrec_add_var(&pixmap_rec, filename, line, (void *) p, 1); |
||||
} else { |
||||
D_MEM(("Pixmap 0x%08x already registered.\n")); |
||||
} |
||||
} |
||||
} else { |
||||
D_MEM(("ERROR: Refusing to register a NULL pixmap\n")); |
||||
} |
||||
} |
||||
|
||||
void |
||||
libmej_imlib_free_pixmap(const char *var, const char *filename, unsigned long line, Pixmap p) |
||||
{ |
||||
D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu using Imlib2\n", var, p, filename, line)); |
||||
if (p) { |
||||
if (DEBUG_LEVEL >= DEBUG_MEM) { |
||||
memrec_rem_var(&pixmap_rec, var, filename, line, (void *) p); |
||||
} |
||||
imlib_free_pixmap_and_mask(p); |
||||
} else { |
||||
D_MEM(("ERROR: Caught attempt to free NULL pixmap\n")); |
||||
} |
||||
} |
||||
|
||||
void |
||||
libmej_dump_pixmap_tables(void) |
||||
{ |
||||
fprintf(LIBMEJ_DEBUG_FD, "Dumping X11 Pixmap allocation table:\n"); |
||||
memrec_dump_resources(&pixmap_rec); |
||||
} |
||||
|
||||
|
||||
|
||||
/********************** GC ALLOCATION INTERFACE **********************/ |
||||
|
||||
GC |
||||
libmej_x_create_gc(const char *filename, unsigned long line, Display *d, Drawable win, unsigned long mask, XGCValues *gcv) |
||||
{ |
||||
GC gc; |
||||
|
||||
D_MEM(("Creating gc for window 0x%08x at %s:%lu\n", win, filename, line)); |
||||
|
||||
gc = XCreateGC(d, win, mask, gcv); |
||||
ASSERT_RVAL(gc != None, None); |
||||
if (DEBUG_LEVEL >= DEBUG_MEM) { |
||||
memrec_add_var(&gc_rec, filename, line, (void *) gc, sizeof(XGCValues)); |
||||
} |
||||
return (gc); |
||||
} |
||||
|
||||
void |
||||
libmej_x_free_gc(const char *var, const char *filename, unsigned long line, Display *d, GC gc) |
||||
{ |
||||
D_MEM(("libmej_x_free_gc() called for variable %s (0x%08x) at %s:%lu\n", var, gc, filename, line)); |
||||
if (gc) { |
||||
if (DEBUG_LEVEL >= DEBUG_MEM) { |
||||
memrec_rem_var(&gc_rec, var, filename, line, (void *) gc); |
||||
} |
||||
XFreeGC(d, gc); |
||||
} else { |
||||
D_MEM(("ERROR: Caught attempt to free NULL GC\n")); |
||||
} |
||||
} |
||||
|
||||
void |
||||
libmej_dump_gc_tables(void) |
||||
{ |
||||
fprintf(LIBMEJ_DEBUG_FD, "Dumping X11 GC allocation table:\n"); |
||||
memrec_dump_resources(&gc_rec); |
||||
} |
@ -1,81 +0,0 @@ |
||||
/*
|
||||
* 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. |
||||
*/ |
||||
|
||||
static const char cvs_ident[] = "$Id$"; |
||||
|
||||
#ifdef HAVE_CONFIG_H |
||||
# include <config.h> |
||||
#endif |
||||
|
||||
#include "libmej.h" |
||||
|
||||
int |
||||
libmej_dprintf(const char *format, ...) |
||||
{ |
||||
va_list args; |
||||
int n; |
||||
|
||||
va_start(args, format); |
||||
n = vfprintf(LIBMEJ_DEBUG_FD, format, args); |
||||
va_end(args); |
||||
fflush(LIBMEJ_DEBUG_FD); |
||||
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); |
||||
} |
||||
|
@ -1,521 +0,0 @@ |
||||
#ifdef HAVE_CONFIG_H |
||||
# include <config.h> |
||||
#endif |
||||
|
||||
#include <errno.h> |
||||
#ifdef HAVE_STDARG_H |
||||
# include <stdarg.h> |
||||
#endif |
||||
|
||||
static const char cvs_ident[] = "$Id$"; |
||||
|
||||
/*
|
||||
* Shamelessly snarfed from Enlightenment... |
||||
* which shamelessly snarfed from sane...
|
||||
* which shamelessly snarfed from LPR
|
||||
* which probably shamelessly snarfed from.... |
||||
*
|
||||
* Moved comments to end so I can actually read the code.. cleaned out useless |
||||
* junk.... |
||||
*/ |
||||
|
||||
#if !defined(HAVE_SNPRINTF) || (HAVE_SNPRINTF_BUG == 1) |
||||
|
||||
#define VA_LOCAL_DECL va_list ap |
||||
#define VA_START(f) va_start(ap, f) |
||||
#define VA_SHIFT(v,t) ; /* no-op for ANSI */ |
||||
#define VA_END va_end(ap) |
||||
|
||||
/*
|
||||
* dopr(): poor man's version of doprintf |
||||
*/ |
||||
|
||||
static void dopr(char *buffer, const char *format, va_list args); |
||||
static void fmtstr(char *value, int ljust, int len, int zpad, int precision); |
||||
static void fmtnum(long value, int base, int dosign, |
||||
int ljust, int len, int zpad, int precision); |
||||
static void fmtdouble(int fmt, double value, |
||||
int ljust, int len, int zpad, int precision); |
||||
static void dostr(char *); |
||||
static char *output; |
||||
static void dopr_outch(int c); |
||||
static char *end; |
||||
int visible_control = 1; |
||||
|
||||
int |
||||
vsnprintf(char *str, size_t count, const char *fmt, va_list args) |
||||
{ |
||||
str[0] = 0; |
||||
end = str + count - 1; |
||||
dopr(str, fmt, args); |
||||
if (count > 0) { |
||||
end[0] = 0; |
||||
} |
||||
return (strlen(str)); |
||||
} |
||||
|
||||
#ifdef HAVE_STDARG_H |
||||
int |
||||
snprintf(char *str, size_t count, const char *fmt,...) |
||||
#else |
||||
int |
||||
snprintf(va_alist) |
||||
va_dcl |
||||
|
||||
#endif |
||||
{ |
||||
#ifndef HAVE_STDARG_H |
||||
char *str; |
||||
size_t count; |
||||
char *fmt; |
||||
|
||||
#endif |
||||
VA_LOCAL_DECL; |
||||
|
||||
VA_START(fmt); |
||||
VA_SHIFT(str, char *); |
||||
|
||||
VA_SHIFT(count, size_t); |
||||
VA_SHIFT(fmt, char *); |
||||
|
||||
(void) vsnprintf(str, count, fmt, ap); |
||||
VA_END; |
||||
return (strlen(str)); |
||||
} |
||||
|
||||
static void |
||||
dopr(char *buffer, const char *format, va_list args) |
||||
{ |
||||
int ch; |
||||
long value; |
||||
int longflag = 0; |
||||
char *strvalue; |
||||
int ljust; |
||||
int len; |
||||
int zpad; |
||||
int precision; |
||||
int set_precision; |
||||
double dval; |
||||
|
||||
output = buffer; |
||||
while ((ch = *format++)) { |
||||
switch (ch) { |
||||
case '%': |
||||
ljust = len = zpad = 0; |
||||
precision = -1; |
||||
set_precision = 0; |
||||
nextch: |
||||
ch = *format++; |
||||
switch (ch) { |
||||
case 0: |
||||
dostr("**end of format**"); |
||||
return; |
||||
case '-': |
||||
ljust = 1; |
||||
goto nextch; |
||||
case '.': |
||||
set_precision = 1; |
||||
precision = 0; |
||||
goto nextch; |
||||
case '*': |
||||
len = va_arg(args, int); |
||||
|
||||
goto nextch; |
||||
case '0': /* set zero padding if len not set */ |
||||
if (len == 0 && set_precision == 0) |
||||
zpad = '0'; |
||||
case '1': |
||||
case '2': |
||||
case '3': |
||||
case '4': |
||||
case '5': |
||||
case '6': |
||||
case '7': |
||||
case '8': |
||||
case '9': |
||||
if (set_precision) { |
||||
precision = precision * 10 + ch - '0'; |
||||
} else { |
||||
len = len * 10 + ch - '0'; |
||||
} |
||||
goto nextch; |
||||
case 'l': |
||||
longflag = 1; |
||||
goto nextch; |
||||
case 'u': |
||||
case 'U': |
||||
/*fmtnum(value,base,dosign,ljust,len, zpad, precision) */ |
||||
if (longflag) { |
||||
value = va_arg(args, long); |
||||
} else { |
||||
value = va_arg(args, int); |
||||
} |
||||
fmtnum(value, 10, 0, ljust, len, zpad, precision); |
||||
break; |
||||
case 'o': |
||||
case 'O': |
||||
/*fmtnum(value,base,dosign,ljust,len, zpad, precision) */ |
||||
if (longflag) { |
||||
value = va_arg(args, long); |
||||
} else { |
||||
value = va_arg(args, int); |
||||
} |
||||
fmtnum(value, 8, 0, ljust, len, zpad, precision); |
||||
break; |
||||
case 'd': |
||||
case 'i': |
||||
case 'D': |
||||
if (longflag) { |
||||
value = va_arg(args, long); |
||||
} else { |
||||
value = va_arg(args, int); |
||||
} |
||||
fmtnum(value, 10, 1, ljust, len, zpad, precision); |
||||
break; |
||||
case 'x': |
||||
if (longflag) { |
||||
value = va_arg(args, long); |
||||
} else { |
||||
value = va_arg(args, int); |
||||
} |
||||
fmtnum(value, 16, 0, ljust, len, zpad, precision); |
||||
break; |
||||
case 'X': |
||||
if (longflag) { |
||||
value = va_arg(args, long); |
||||
} else { |
||||
value = va_arg(args, int); |
||||
} |
||||
fmtnum(value, -16, 0, ljust, len, zpad, precision); |
||||
break; |
||||
case 's': |
||||
strvalue = va_arg(args, char *); |
||||
|
||||
fmtstr(strvalue, ljust, len, zpad, precision); |
||||
break; |
||||
case 'c': |
||||
ch = va_arg(args, int); |
||||
|
||||
{ |
||||
char b[2]; |
||||
int vsb = visible_control; |
||||
|
||||
b[0] = ch; |
||||
b[1] = 0; |
||||
visible_control = 0; |
||||
fmtstr(b, ljust, len, zpad, precision); |
||||
visible_control = vsb; |
||||
} |
||||
break; |
||||
case 'f': |
||||
case 'g': |
||||