/*************************************************************************
** ^FILE: useful.h - various definitions of general interest
**
** ^DESCRIPTION:
**    This file #defines several macros that are either of very general
**    use, or that assist in writing portable programs between various
**    systems and/or compilers.
**
** ^HISTORY:
**    --/--/--	Brad Appleton	<brad@ssd.csd.harris.com>	
**    - Added structured block comments
**    - Added varargs/stdarg macros
**    - Added BSET, BCLEAR, BTEST macros for handling bitmasks
**    - #defined EXTERN to be extern "C" for C++
**    - Added #defines for STDIN, STDOUT, and STDERR file descriptors
**
**    --/--/--	Peter da Silva	<peter@ferranti.com>	
**
**    --/--/--	Eric P. Allman	<eric@Berkeley.EDU> 	Created
***^^**********************************************************************/

/* $Header: useful.h,v 2.0 89/12/24 00:56:33 eric Exp $ */

#ifndef _USEFUL_H_
#define _USEFUL_H_

#ifndef unix
# if (defined(_unix) || defined(_unix_) || defined(__unix) || defined(__unix__) || defined(UNIX) || defined(_UNIX) || defined(_UNIX_) || defined(__UNIX) || defined(__UNIX__) || defined(Unix) || defined(_Unix) || defined(_Unix_) || defined(__Unix) || defined(__Unix__) || defined(sun))
#   define unix
# endif /* _UNIX */
#endif /* unix */

#ifndef BSD
# if (defined(ucb_universe) || defined(UCB) || defined(_BSD) || defined(_BSD_) || defined(__BSD) || defined(__BSD__) || defined(BSD_UNIX) || defined(_BSD_UNIX) || defined(_BSD_UNIX_) || defined(__BSD_UNIX) || defined(__BSD_UNIX__) || defined(sun))
#   define BSD
# endif /* _BSD */
#endif /* BSD */

#ifndef AmigaDOS
# if (defined(MANX) || defined(AZTEC))
#   define AmigaDOS
# endif
#endif /* AmigaDOS */

#ifndef vms
# if (defined(_vms) || defined(_vms_) || defined(__vms) || defined(__vms__) || defined(VMS) || defined(_VMS) || defined(_VMS_) || defined(__VMS) || defined(__VMS__))
#   define vms
# endif /* _VMS */
#endif /* vms */

#ifndef MSDOS
# if (defined(_MSDOS) || defined(_MSDOS_) || defined(__MSDOS) || defined(__MSDOS__) || defined(MS_DOS) || defined(_MS_DOS) || defined(_MS_DOS_) || defined(__MS_DOS) || defined(__MS_DOS__))
#   define MSDOS
# endif /* _MSDOS */
#endif /* MSDOS */

#ifndef OS2
# if (defined(_OS2) || defined(_OS2_) || defined(__OS2) || defined(__OS2__))
#   define OS2
# endif /* _OS2 */
#endif /* OS2 */


#ifndef FILE
# include <stdio.h>
#endif

#ifndef STDIN
# define STDIN   0
# define STDOUT  1
# define STDERR  2
#endif

   /* macros to portably convert character case */
#define TOUPPER(c)  ( islower(c) ) ? toupper(c) : (c)
#define TOLOWER(c)  ( isupper(c) ) ? tolower(c) : (c)

   /* give a stab at the multiple-language dilemma */
#ifdef __STDC__
#  define ARGS(x)		x
#  define NOARGS		( void )
#  define __ANSI_C__
#else
#  if defined(c_plusplus) || defined(__cplusplus)
#    define ARGS(x)		x
#    define NOARGS		()
#    define __ANSI_C__
#  else
#    define ARGS(x)	    ()
#    define NOARGS		()
#  endif
#endif

   /* give a stab at the variable arguments dilemma  --BDA */
#ifdef __STDC__
#  ifndef va_arg
#    include <stdarg.h>
#  endif
#  define  VA_START(ap,last)  va_start(ap, last)
#  define  VA_ARG(ap,type)    va_arg(ap, type)
#  define  VA_END(ap)         va_end(ap)
#else
#  ifndef va_arg
#    include  <varargs.h>
#  endif
#  define  VA_START(ap,last)  va_start(ap)
#  define  VA_ARG(ap,type)    va_arg(ap, type)
#  define  VA_END(ap)         va_end(ap)
#endif

#if ( !defined(__ANSI_C__)  &&  !defined(_SIZE_T_DEFINED) )
  typedef unsigned int size_t;
# define _SIZE_T_DEFINED 1
#endif

#ifndef VOID
#  if ( defined(__ANSI_C__)  ||  !defined(NOVOID) )
#    define VOID		void
#  else
#    define VOID		int
#  endif
#endif

#ifndef TRUE
#  define TRUE		1
#  define FALSE		0
#endif

#ifndef STATIC
#  ifndef NODEBUG
#    define STATIC
#  else
#    define STATIC		static
#  endif
#endif

#ifndef EXTERN
#  if defined(c_plusplus) || defined(__cplusplus)
#    define EXTERN		extern "C"
#  else
#    define EXTERN		extern
#  endif
#endif

#ifndef CONST
#  ifdef __ANSI_C__
#    define CONST		const
#  else
#    define CONST
#  endif
#endif

#ifndef NULL
#  define NULL		0
#endif

#ifndef CHARNULL
#  define CHARNULL	((char *) NULL)
#endif

#ifndef FILENULL
#  define FILENULL	((FILE *) NULL)
#endif

#ifdef __ANSI_C__
   typedef   void *ARBPTR;
#else
   typedef   char *ARBPTR;
#endif

#define __		(ARBPTR)
#define ARBNULL		(__ NULL)

#ifndef BOOL
   typedef   char   BOOL;
#endif

#ifdef lint
#  define VERSIONID(v)
#else
#  define VERSIONID(v)	static char _Version[] = v
#endif

   /* keep BITSET for compatibilty
   ** but use BSET, BCLEAR, etc... instead   --BDA
   */
#define BITSET(bstr,mask)	( ((bstr) & (mask)) != 0 )

#define BTEST(bstr,mask)	( ((bstr) & (mask)) != 0 )
#define BSET(bstr,mask)     (bstr) |= (mask)
#define BCLEAR(bstr,mask)   (bstr) &= ~(mask)

#ifndef STRING_H
# define STRING_H
   EXTERN  char  *strcat    ARGS(( char *, const char * ));
   EXTERN  char  *strncat   ARGS(( char *, const char *, int ));
   EXTERN  int    strcmp    ARGS(( const char *, const char * ));
   EXTERN  int    strncmp   ARGS(( const char *, const char *, int ));
   EXTERN  char  *strcpy    ARGS(( char *, const char * ));
   EXTERN  char  *strncpy   ARGS(( char *, const char *, int ));
   EXTERN  int    strlen    ARGS(( const char * ));
   
# ifndef BSD
#  define index(s,c)   strchr(s,c)
#  define rindex(s,c)  strrchr(s,c)
   EXTERN  char  *strchr    ARGS(( const char *, int ));
   EXTERN  char  *strrchr   ARGS(( const char *, int ));
   EXTERN  char  *strpbrk   ARGS(( const char *, const char * ));
   EXTERN  int    strspn    ARGS(( const char *, const char * ));
   EXTERN  int    strcspn   ARGS(( const char *, const char * ));
   EXTERN  char  *strtok    ARGS(( char *, char * ));
   EXTERN  char  *strdup    ARGS(( const char * ));
   
# else
#  define strchr(s,c)   index(s,c)
#  define strrchr(s,c)  rindex(s,c)
   EXTERN  char  *index     ARGS(( const char *, int ));
   EXTERN  char  *rindex    ARGS(( const char *, int ));
# endif /* !BSD */
   
# ifdef BSD
#  define bcmp(b1,b2,n)   memcmp(b1,b2,n)
#  define bcopy(b1,b2,n)  memcpy(b2,b1,n)
#  define bzero(b,n)      memset(b,'\0',n)
#  ifndef MEMORY_H
#    define MEMORY_H
   EXTERN  ARBPTR  memccpy   ARGS(( ARBPTR, const ARBPTR, int, int ));
   EXTERN  ARBPTR  memchr    ARGS(( ARBPTR, int, int ));
   EXTERN  int     memcmp    ARGS(( const ARBPTR, const ARBPTR, int ));
   EXTERN  ARBPTR  memcpy    ARGS(( ARBPTR, const ARBPTR, int ));
   EXTERN  ARBPTR  memmove   ARGS(( ARBPTR, const ARBPTR, int ));
   EXTERN  ARBPTR  memset    ARGS(( ARBPTR, int, int ));
#  endif  /* MEMORY_H */
   
# else
#  define memcmp(b1,b2,n)  bcmp(b1,b2,n)
#  define memcpy(b1,b2,n)  bcopy(b2,b1,n)
#  ifndef BSTRING_H
#    define BSTRING_H
   EXTERN  VOID   bcopy     ARGS(( const ARBPTR, ARBPTR, int ));
   EXTERN  int    bcmp      ARGS(( const ARBPTR, const ARBPTR, int ));
   EXTERN  VOID   bzero     ARGS(( ARBPTR, int ));
   EXTERN  int    ffs       ARGS(( int ));
#  endif  /* BSTRING_H */
# endif /* !BSD */
#endif /* STRING_H */

EXTERN  ARBPTR  malloc   ARGS(( size_t ));
EXTERN  ARBPTR  ckalloc  ARGS(( size_t ));
EXTERN  ARBPTR  realloc  ARGS(( ARBPTR, size_t ));
EXTERN  ARBPTR  free     ARGS(( ARBPTR ));
EXTERN  VOID    exit     ARGS(( int ));

#define MAXINPUTLINE	200		/* maximum string input line */
#define MAXWORDLEN	100		/* maximum word (token) length */

#endif /* _USEFUL_H_ */
