/*************************************************************************
** ^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 OS specific #defines for unix, SYSV, BSD, etc ...
**    - 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_

#if (defined(_unix) || defined(__unix) || defined(_unix_) || defined(__unix__))
# ifndef unix
#   define unix
# endif
#endif /* _unix */

#if (defined(_UNIX) || defined(__UNIX) || defined(_UNIX_) || defined(__UNIX__))
# ifndef unix
#   define unix
# endif
#endif /* _UNIX */

   /* give a stab at the dual Unix universe dilemma (UCB vs AT&T) */
#ifdef unix
# if ( defined(_BSD) && !defined(BSD) )
#  define BSD
# endif
# if ( defined(_SYSV) && !defined(SYSV) )
#  define SYSV
# endif

# ifndef BSD
#  ifdef sun
#   define BSD
#  endif
#  if ( defined(apollo) || defined(aegis) )
#   define BSD
#  endif
#  if ( defined(_CX_UX) && defined(ucb_universe) )
#   define BSD
#  endif
#  if ( defined(VAX_BSD) || defined(ULTRIX) || defined(ultrix) )
#   define BSD
#  endif
#  if ( defined(DYNIX) || defined(dynix) )
#   define BSD
#  endif
#  if ( defined(UTX) || defined(utx) )
#   define BSD
#  endif
# endif /* !BSD */

# ifndef SYSV
#  ifdef mips
#   define SYSV
#  endif
#  ifdef DGUX
#   define SYSV
#  endif
#  if ( defined(_CX_UX) && defined(att_universe) )
#   define SYSV
#  endif
#  if ( defined(hpux) || defined(HPUX) )
#   define SYSV
#  endif
#  if ( defined(irix) || defined(IRIX) )
#   define SYSV
#  endif
#  if ( defined(aix) || defined(AIX) )
#   define SYSV
#  endif
# endif /* !SYSV */
#endif /* unix */

#ifndef MSDOS
# if (defined(_MSDOS_)||defined(__MSDOS__)||defined(_MSDOS)||defined(__MSDOS))
#  define MSDOS
# endif
#endif

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

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


#ifdef __STDC__
# include <stddef.h>
# include <stdlib.h>
#endif

#if ( !defined(__STDC__) && defined(vms) )
# include <stdlib.h>
#endif

#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

#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

#if ( defined(__ANSI_C__)  ||  defined(vms) )
   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 *, 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 */
   
# ifndef 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 */

#if ( !defined(__ANSI_C__)  &&  !defined(_SIZE_T_DEFINED) )
# if (defined(sun) && defined(BSD))
#  include <sys/types.h>
#  if (!defined (__sys_stdtypes_h) && !defined(_TYPES_))
	/* size_t is also defined in <sys/stdtypes.h> in SunOS 4.1
    ** and int <types.h> in SunOS 4.0.3
    */
    typedef int size_t;
#  endif
#  define _SIZE_T_DEFINED 1
# endif /* sun */
# if (defined(vms) && defined(__STDDEF_LOADED))
#  define _SIZE_T_DEFINED 1
# endif /* vms */
# ifndef _SIZE_T_DEFINED
   typedef unsigned int size_t;
#  define _SIZE_T_DEFINED 1
# endif  /* !_SIZE_T_DEFINED */
#endif

#if ( !defined(__malloc_h) && !defined(__MALLOC_H) && !defined(vms) )
# include <malloc.h>
#else
  EXTERN  ARBPTR  malloc   ARGS(( size_t ));
  EXTERN  ARBPTR  realloc  ARGS(( ARBPTR, size_t ));
  EXTERN  VOID    free     ARGS(( ARBPTR ));
#endif /*__malloc_h*/

EXTERN  ARBPTR  ckalloc  ARGS(( size_t ));
EXTERN  VOID    exit     ARGS(( int ));

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

#endif /* _USEFUL_H_ */
