/* vim: set shiftwidth=4 tabstop=8 softtabstop=4: */
/* $Id: cfuncs.h,v 1.5 2003/01/19 09:50:59 shinra Exp $ */

#ifndef CFUNCS_H
#define CFUNCS_H

#define PRIVATESYM(x) spt_p_##x
#define ALTSYM PRIVATESYM
#define DEBUGSYM(x) PRIVATESYM(debug_##x)

#define NEED_STRDUP
#define NEED_STRCSPN

#ifdef NEED_STRDUP
# ifdef HAVE_STRDUP
#  define NDEBUG_STRDUP(str) strdup(str)
# else /* !HAVE_STRDUP */
extern char *ALTSYM(strdup) (const char *str);
#  define NDEBUG_STRDUP(str) ALTSYM(strdup) (str)
# endif /* !HAVE_STRDUP */
#endif /* NEED_STRDUP */

#ifdef NEED_STRNDUP
# ifdef HAVE_STRNDUP
#  define NDEBUG_STRNDUP(str) strndup(str)
# else /* !HAVE_STRNDUP */
extern char *ALTSYM(strndup) (const char *str, size_t len);
#  define NDEBUG_STRNDUP(str, len) ALTSYM(strndup) (str, len)
# endif /* !HAVE_STRNDUP */
#endif /* NEED_STRNDUP */

#ifdef HAVE_MALLOC
# define NDEBUG_MALLOC(size) malloc(size)
# define NDEBUG_CALLOC(number, size) calloc(number, size)
#else /* !HAVE_MALLOC */
extern void *ALTSYM(malloc) (size_t size);
extern void *ALTSYM(calloc) (size_t number, size_t size);
# define NDEBUG_MALLOC(size) ALTSYM(malloc) (size)
# define NDEBUG_CALLOC(number, size) ALTSYM(calloc) (number, size)
#endif /* !HAVE_MALLOC */

#ifdef HAVE_REALLOCF
# define NDEBUG_REALLOCF(ptr, size) reallocf(ptr, size)
#else /* !HAVE_REALLOCF */
extern void *ALTSYM(reallocf) (void *ptr, size_t size);
# define NDEBUG_REALLOCF(ptr, size) ALTSYM(reallocf) (ptr, size)
#endif /* !HAVE_REALLOCF */

#ifdef USE_MEMORY_DEBUG
# define DEBUG_ARGS const char *file, unsigned int line
extern void *DEBUGSYM(malloc) (size_t size, DEBUG_ARGS);
extern void *DEBUGSYM(calloc) (size_t number, size_t size, DEBUG_ARGS);
extern void *DEBUGSYM(realloc) (void *ptr, size_t size, DEBUG_ARGS);
extern void *DEBUGSYM(reallocf) (void *ptr, size_t size, DEBUG_ARGS);
extern void DEBUGSYM(free) (void *ptr, DEBUG_ARGS);
extern void DEBUGSYM(safe_free) (void *ptr, DEBUG_ARGS);
extern char *DEBUGSYM(strdup) (const char *str, DEBUG_ARGS);
extern void DEBUGSYM(memory_report) (void);
# define FILELINE __FILE__, __LINE__
# define MALLOC(size) DEBUGSYM(malloc) (size, FILELINE)
# define CALLOC(number, size) DEBUGSYM(calloc) (number, size, FILELINE)
# define REALLOC(ptr, size) DEBUGSYM(realloc) (ptr, size, FILELINE)
# define REALLOCF(ptr, size) DEBUGSYM(reallocf) (ptr, size, FILELINE)
# define FREE(ptr) DEBUGSYM(free) (ptr, FILELINE)
# define SAFE_FREE(ptr) DEBUGSYM(safe_free) (ptr, FILELINE)
# define STRDUP(str) DEBUGSYM(strdup) (str, FILELINE)
# define STRNDUP(str, len) DEBUGSYM(strndup) (str, len, FILELINE)
# define MEMORY_REPORT() DEBUGSYM(memory_report) ()
#else /* !USE_MEMORY_DEBUG */
# define MALLOC(size) NDEBUG_MALLOC(size)
# define CALLOC(number, size) NDEBUG_CALLOC(number, size)
# define REALLOC(ptr, size) realloc(ptr, size)
# define REALLOCF(ptr, size) NDEBUG_REALLOCF(ptr, size)
# define FREE(ptr) free(ptr)
# define SAFE_FREE(ptr) free(ptr)
# define STRDUP(str) NDEBUG_STRDUP(str)
# define STRNDUP(str, len) NDEBUG_STRNDUP(str, len)
# define MEMORY_REPORT()
#endif /* !USE_MEMORY_DEBUG */

#ifdef HAVE_STRCHR
# define STRCHR strchr
# define STRRCHR strrchr
#else
# define STRCHR index
# define STRRCHR rindex
#endif
#ifdef HAVE_MEMCPY
# define MEMCPY memcpy
# define MEMMOVE memmove
#else
# define MEMCPY(dst, src, size) bcopy(src, dst, size)
# define MEMMOVE(dst, src, size) bcopy(src, dst, size)
#endif
#ifdef HAVE_BZERO
# define BZERO bzero
#else
# define BZERO(ptr, size) memset(ptr, 0, size)
#endif
#ifdef HAVE_STRCSPN
# ifdef NEED_STRSPN
#  define STRSPN strspn
# endif
# ifdef NEED_STRCSPN
#  define STRCSPN strcspn
# endif
#else /* !HAVE_STRCSPN */
# ifdef NEED_STRSPN
#  define STRSPN ALTSYM(strspn)
extern size_t ALTSYM(strspn) (const char *s, const char *cs);
# endif
# ifdef NEED_STRCSPN
#  define STRCSPN ALTSYM(strcspn)
extern size_t ALTSYM(strcspn) (const char *s, const char *cs);
# endif
#endif /* !HAVE_STRCSPN */

#define ARRAYLEN(x) (sizeof x / sizeof(x[0]))

#ifdef RETSIGTYPE_VOID
# define SIGNAL_RETURN
#else
# define SIGNAL_RETURN return 0
#endif

#ifdef HAVE_SIGACTION
typedef struct sigaction sighandler_type;
extern void PRIVATESYM(trap_signal) (
	int sig, RETSIGTYPE (*func) (int), sighandler_type *old);
# define TRAP_SIGNAL(sig, func, old) PRIVATESYM(trap_signal) (sig, func, old)
# define RESTORE_SIGNAL(sig, old) ((void)sigaction(sig, old, NULL))
#else
# define TRAP_SIGNAL(sig, func, old) ((void)(*(old) = signal(sig, func)))
# define RESTORE_SIGNAL(sig, old) ((void)signal(sig, *(old)))
typedef RETSIGTYPE (*sighandler_type) (int dummy);
#endif

#endif /* CFUNCS_H */
