/*
   MESSAGE.H
   Version 2.0
   November 1994
*/

/*
 * Copyright (C) 1994  Johannes Plass
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *   Author: Johannes Plass
 *           Department of Physics
 *           Johannes Gutenberg University, Mainz, Germany
 *
 * Internet: plass@dipmza.physik.uni-mainz.de
 *
*/


#ifndef _MESSAGE_LOADED_

#if defined(MESSAGES) || defined(MESSAGES1)

#ifdef MESSAGE_NO_ESC
#   define MESSAGE_B_ESC ""
#   define MESSAGE_E_ESC ""
#else
#   define MESSAGE_B_ESC "\033[1m"
#   define MESSAGE_E_ESC "\033[m"
#endif

#include<stdlib.h>
#include<string.h>
#include<time.h>

#if __STDC__
#   define MESSAGE_STRING(x) #x
#else
#   define MESSAGE_STRING(x) "x"
#endif

/*#####################################################################*/
/*                               VMS                                   */

#ifdef VMS

#   include<descrip.h>
#   include<libclidef.h>
#   include<lib$routines.h>
#   include<unixlib.h>

#   define MESSAGE_FILE (strrchr(__FILE__,']')+1)
   
#   define MESSAGE_dsc(name,string,length)				\
      name.dsc$w_length  = (unsigned short) (length);			\
      name.dsc$b_dtype   = (unsigned char)  DSC$K_DTYPE_T;		\
      name.dsc$b_class   = (unsigned char)  DSC$K_CLASS_S;		\
      name.dsc$a_pointer = (char*) (string)

#   define MESSAGE_SAVEINDENT(indent) {					\
      long table = LIB$K_CLI_LOCAL_SYM;					\
      struct dsc$descriptor symbol;					\
      struct dsc$descriptor value;					\
      MESSAGE_dsc(symbol,"MESSAGE_INDENT",14);				\
      MESSAGE_dsc(value,indent,strlen(indent));				\
      lib$set_symbol(&symbol,&value,&table);				\
    }

#   define MESSAGE_GETINDENT(indent,len) {				\
      struct dsc$descriptor symbol;					\
      struct dsc$descriptor result;					\
      MESSAGE_dsc(symbol,"MESSAGE_INDENT",14);				\
      MESSAGE_dsc(result,indent,99);					\
      len = 0;								\
      if (lib$get_symbol(&symbol,&result,&len,NULL) != 1) len = 0;	\
      indent[len] = '\0';						\
    }

#endif /* VMS */

/*                          end of VMS                                 */

#define MESSAGE_PRINTF(format,value) {	\
   char indent[100]; unsigned short len;\
   MESSAGE_GETINDENT(indent,len);	\
   printf(indent);			\
   printf(format,value);		\
}

#define MESSAGE2_PRINTF(format,value1,value2) {	\
   char indent[100]; unsigned short len;	\
   MESSAGE_GETINDENT(indent,len);		\
   printf(indent);				\
   printf(format,value1,value2);		\
}

#define BEGIN_MESSAGE(txt)	{			\
   char indent[100]; unsigned short len;		\
   MESSAGE_GETINDENT(indent,len)			\
   printf("%s\273\273\273 %s%s%s <%s>\n",		\
	indent,						\
	MESSAGE_B_ESC,MESSAGE_STRING(txt),MESSAGE_E_ESC,\
	MESSAGE_FILE					\
   );							\
   if (len <= 56) strcat(indent,"    ");		\
   MESSAGE_SAVEINDENT(indent)				\
}

#define END_MESSAGE(txt)	{			\
   char indent[100]; unsigned short len;		\
   MESSAGE_GETINDENT(indent,len)			\
   if (len>= 4) indent[len-4] = '\0';			\
   printf("%s\253\253\253 %s%s%s <%s>\n",		\
	indent,						\
	MESSAGE_B_ESC,MESSAGE_STRING(txt),MESSAGE_E_ESC,\
	MESSAGE_FILE					\
   );							\
   MESSAGE_SAVEINDENT(indent)				\
}

#define MAIN_BEGIN_MESSAGE(txt) {	\
   char *indent = "";			\
   MESSAGE_SAVEINDENT(indent)		\
   BEGINMESSAGE(txt)			\
}

#define MAIN_END_MESSAGE(txt) {		\
   char *indent = "";			\
   MESSAGE_SAVEINDENT(indent)		\
   ENDMESSAGE(txt)			\
}

#endif /* MESSAGES || MESSAGES1 */

#ifdef MESSAGES

#ifdef __STDC__
#   define MAINBEGINMESSAGE(txt)	MAIN_BEGIN_MESSAGE(txt)
#   define MAINENDMESSAGE(txt)		MAIN_END_MESSAGE(txt)
#   define BEGINMESSAGE(txt)		BEGIN_MESSAGE(txt)
#   define ENDMESSAGE(txt)		END_MESSAGE(txt)
#   define INFMESSAGE(txt)		MESSAGE_PRINTF(#txt "%s\n","")
#   define CMESSAGE(cr)			MESSAGE_PRINTF(#cr "=%c\n",cr)
#   define INFCMESSAGE(txt,cr)		MESSAGE_PRINTF(#txt " " #cr "=%c\n",cr)
#   define IMESSAGE(it)			MESSAGE_PRINTF(#it "=%d\n",it)
#   define INFIMESSAGE(txt,it)		MESSAGE_PRINTF(#txt " " #it "=%d\n",it)
#   define IIMESSAGE(it1,it2)		MESSAGE2_PRINTF(#it1 "=%d, " #it2 "=%d\n",it1,it2)
#   define INFIIMESSAGE(txt,it1,it2)	MESSAGE2_PRINTF(#txt " " #it1 "=%d, " #it2 "=%d\n",it1,it2)
#   define FMESSAGE(ft)			MESSAGE_PRINTF(#ft "=%f\n",ft)
#   define INFFMESSAGE(txt,ft)		MESSAGE_PRINTF(#txt " " #ft "=%f\n",ft)
#   define SMESSAGE(st)			MESSAGE_PRINTF(#st "=%s\n",st)
#   define INFSMESSAGE(txt,st)		MESSAGE_PRINTF(#txt " " #st "=%s\n",st)
#else /*__STDC__*/
#   define MAINBEGINMESSAGE(txt)	MAIN_BEGIN_MESSAGE(txt)
#   define MAINENDMESSAGE(txt)		MAIN_END_MESSAGE(txt)
#   define BEGINMESSAGE(txt)		BEGIN_MESSAGE(txt)
#   define ENDMESSAGE(txt)		END_MESSAGE(txt)
#   define INFMESSAGE(txt)		MESSAGE_PRINTF("txt %s\n","")
#   define CMESSAGE(cr)			MESSAGE_PRINTF("cr=%c\n",cr)
#   define INFCMESSAGE(txt,cr)		MESSAGE_PRINTF("txt cr=%c\n",cr)
#   define IMESSAGE(it)			MESSAGE_PRINTF("it=%d\n",it)
#   define INFIMESSAGE(txt,it)		MESSAGE_PRINTF("txt it=%d\n",it)
#   define IIMESSAGE(it1,it2)		MESSAGE2_PRINTF("it1=%d, it2=%d\n",it1,it2)
#   define INFIIMESSAGE(txt,it1,it2)	MESSAGE2_PRINTF("txt it1=%d, it2=%d\n",it1,it2)
#   define FMESSAGE(ft)			MESSAGE_PRINTF("ft=%f\n",ft)
#   define INFFMESSAGE(txt,ft)		MESSAGE_PRINTF("txt ft=%f\n",ft)
#   define SMESSAGE(st)			MESSAGE_PRINTF("st=%s\n",st)
#   define INFSMESSAGE(txt,st)		MESSAGE_PRINTF("txt st=%s\n",st)
#endif  /* __STDC__ */

#else	/* MESSAGES */
#   define MAINBEGINMESSAGE(txt)
#   define MAINENDMESSAGE(txt)
#   define BEGINMESSAGE(txt)
#   define ENDMESSAGE(txt)
#   define INFMESSAGE(txt)
#   define CMESSAGE(cr)
#   define INFCMESSAGE(txt,cr)
#   define IMESSAGE(it)
#   define INFIMESSAGE(txt,it)
#   define IIMESSAGE(it1,it2)
#   define INFIIMESSAGE(txt,it1,it2)
#   define FMESSAGE(ft)
#   define INFFMESSAGE(txt,ft)
#   define SMESSAGE(st)
#   define INFSMESSAGE(txt,st)
#endif /* MESSAGES */

#ifdef MESSAGES1

#ifdef __STDC__
#   define BEGINMESSAGE1(txt)		BEGIN_MESSAGE(txt)
#   define ENDMESSAGE1(txt)		END_MESSAGE(txt)
#   define INFMESSAGE1(txt)		MESSAGE_PRINTF(#txt "%s\n","")
#   define IMESSAGE1(it)		MESSAGE_PRINTF(#it "=%d\n",it)
#   define INFIMESSAGE1(txt,it)		MESSAGE_PRINTF(#txt " " #it "=%d\n",it)
#   define FMESSAGE1(ft)		MESSAGE_PRINTF(#ft "=%f\n",ft)
#   define INFFMESSAGE1(txt,ft)		MESSAGE_PRINTF(#txt " " #ft "=%f\n",ft)
#   define SMESSAGE1(st)		MESSAGE_PRINTF(#st "=%s\n",st)
#   define INFSMESSAGE1(txt,st)		MESSAGE_PRINTF(#txt " " #st "=%s\n",st)
#   define IIMESSAGE1(it1,it2)		MESSAGE2_PRINTF(#it1 "=%d, " #it2 "=%d\n",it1,it2)
#else /*__STDC__*/
#   define BEGINMESSAGE1(txt)		BEGIN_MESSAGE(txt)
#   define ENDMESSAGE1(txt)		END_MESSAGE(txt)
#   define INFMESSAGE1(txt)		MESSAGE_PRINTF("txt %s\n","")
#   define IMESSAGE1(it)		MESSAGE_PRINTF("it=%d\n",it)
#   define INFIMESSAGE1(txt,it)		MESSAGE_PRINTF("txt it=%d\n",it)
#   define FMESSAGE1(ft)		MESSAGE_PRINTF("ft=%f\n",ft)
#   define INFFMESSAGE1(txt,ft)		MESSAGE_PRINTF("txt ft=%f\n",ft)
#   define SMESSAGE1(st)		MESSAGE_PRINTF("st=%s\n",st)
#   define INFSMESSAGE1(txt,st)		MESSAGE_PRINTF("txt st=%s\n",st)
#   define IIMESSAGE1(it1,it2)		MESSAGE2_PRINTF("it1=%d, it2=%d\n",it1,it2)
#endif  /* __STDC__  */

#else	/* MESSAGES1 */

#   define BEGINMESSAGE1(txt)
#   define ENDMESSAGE1(txt)
#   define INFMESSAGE1(txt)
#   define IMESSAGE1(it)
#   define INFIMESSAGE1(txt,it)
#   define FMESSAGE1(ft)
#   define INFFMESSAGE1(txt,ft)
#   define SMESSAGE1(st)
#   define INFSMESSAGE1(txt,st)
#   define IIMESSAGE1(it1,it2)

#endif	/* MESSAGES1 */


#define _MESSAGE_LOADED_
#endif /* _MESSAGE_LOADED_ */
