/*
 *	mcfktns.h
 */

#define sigreturntype	void

#include <stdio.h>
#include <math.h>

#define	P_INFO	1
#define	P_WARN	2
#define	P_EXCEPTION256	3
#define	P_INTERN	4



/*
 * The following objects are declared
 * in the libraries libmc...
 */

extern	char	*processtype;


/*
 * Modula-P Types and Constants
 */

#include <mctypes.h>


/*
 * Signal-Steuerung
 */
extern	sigreturntype	((*(sig_save[])) ());
extern	sigreturntype	((*(sig_exception)) ());
extern	void	sig_init();
extern	void	sig_ign();
extern	void	sig_neu();
extern	void	m0_raise();


/*
 * Prozess-Identifikation und -Steuerung
 */

typedef	struct	PROCESSES {
			char	*processname;
			int	maxnumber;
			sigreturntype	(*exception) ();
			struct	PROCESSES	*next;
		} PROCESSES;


extern	int	m0_processid;
extern	int	m0_processno;

extern	int	inc_processno_activ_exception ();
extern	void	define_exception ();


/*
 * MODULO with positive result
 */
#define modulo(a, b)	(((a % b) + b) % b)


/*
 * Typumwandlungsfunktionen
 */
#define m0_float(i)	((m0_longreal) (i))
#define m0_trunc(r)	((r) < 0.0 ? ((m0_longint) (r)) : ((m0_longcard) (r)))
#define m0_ord(c)	((m0_byte) (c))
#define m0_chr(b)	((m0_char) (b))

#define m0_0_integer(arg)	((m0_integer) (arg))
#define m0_0_shortint(arg)	((m0_shortint) (arg))
#define m0_0_longint(arg)	((m0_longint) (arg))
#define m0_0_real(arg)		((m0_real) (arg))
#define m0_0_shortreal(arg)	((m0_shortreal) (arg))
#define m0_0_longreal(arg)	((m0_longreal) (arg))
#define m0_0_cardinal(arg)	((m0_cardinal) (arg))
#define m0_0_shortcard(arg)	((m0_shortcard) (arg))
#define m0_0_longcard(arg)	((m0_longcard) (arg))
#define m0_0_byte(arg)		((m0_byte) (arg))


/*
 * Standardfunktionen
 */
#define m0_dec(e, typ)	(e = (typ) (((m0_longint) e) - 1))
#define m0_inc(e, typ)	(e = (typ) (((m0_longint) e) + 1))

#define m0_new(p, s)	{\
	if ((p = (void *) get_shared_memory_client (s)) == NULL) {\
		runtime_error (P_INTERN, "m0_new: No more memory for NEW-Operation");\
	}\
}
#define m0_dispose(p)	{\
	shfree ((char *) p);\
	p = m0_nil;\
}



/*
 * Ein-Ausgabe-Funktionen
 */
extern	FILE	*IN_FILE;
extern	FILE	*OUT_FILE;
extern	int	done;

extern	unsigned long	read_longunsigned;
extern	long	read_long;
extern	double	read_double;
extern	char	read_stringbuf[];

#define	EOL	'\n'
#define	CR	'\n'
#define	FF	'\f'

extern	char	*get_filename();

#define setlinebuf(file)	setvbuf (file, 0, _IOLBF, BUFSIZ)

#define close_file(fp1, fp2)	{\
	if ((fp1 != stdin) && (fp1 != stdout))\
		fclose (fp1);\
	fp1 = fp2;\
			/* Der Puffer wird auf Non-Buffered gesetzt */\
	setbuf (fp1, NULL);\
	done = m0_true;\
}

#define open_file(fp, name, mode, std)	{\
	done = m0_true;\
	if (strlen (name)) {\
		if ((fp = fopen (name, mode)) == NULL) {\
			fp = std;\
			done = m0_false;\
		}\
	} else {\
		if ((fp = fopen (get_filename (mode), mode)) == NULL) {\
			fp = std;\
			done = m0_false;\
		}\
	}\
			/* Der Puffer wird auf Line-Buffered gesetzt */\
	setlinebuf (fp);\
}

#define	m0_closeinput()		{close_file (IN_FILE, stdin);}
#define	m0_closeoutput()	{close_file (OUT_FILE, stdout);}
#define	m0_openinput(str, len)	{close_file (IN_FILE, stdin); open_file (IN_FILE, str, "r", stdin);}
#define	m0_openoutput(str, len)	{close_file (OUT_FILE, stdout); open_file (OUT_FILE, str, "w", stdout);}

#define	m0_write(c)		{\
	if (fputc (c, OUT_FILE) == EOF)\
		done = m0_false;\
	else\
		done = m0_true;\
}
#define	m0_writeboolean(b, len)		{\
	if (fprintf (OUT_FILE, "%-*.*s", len, len, (b?"TRUE":"FALSE")) < 0)\
		done = m0_false;\
	else\
		done = m0_true;\
}
#define	m0_writebool(b)		m0_writeboolean (b, 5)
#define	m0_writecard(ui,n)	{\
	if (fprintf (OUT_FILE, "%*lu", (int) n, (unsigned long) ui) < 0)\
		done = m0_false;\
	else\
		done = m0_true;\
}
#define	m0_writefixpt(r,n1,n2)	{\
	if (fprintf (OUT_FILE, "%*.*f", (int) n1+n2+1, (int) n2, r) < 0)\
		done = m0_false;\
	else\
		done = m0_true;\
}
#define	m0_writehex(i,n)	{\
	if (fprintf (OUT_FILE, "%*lX", (int) n, (long) i) < 0)\
		done = m0_false;\
	else\
		done = m0_true;\
}
#define	m0_writeint(i,n)	{\
	if (fprintf (OUT_FILE, "%*ld", (int) n, (long) i) < 0)\
		done = m0_false;\
	else\
		done = m0_true;\
}
#define	m0_writeln()		{\
	if (fputc (EOL, OUT_FILE) == EOF)\
		done = m0_false;\
	else\
		done = m0_true;\
}
#define	m0_writeoct(i,n)	{\
	if (fprintf (OUT_FILE, "%*lo", (int) n, (long) i) < 0)\
		done = m0_false;\
	else\
		done = m0_true;\
}
#define	m0_writestring(str, len)	{\
/*	if (fputs ((char *) str, OUT_FILE) == EOF)\
*/	if (fprintf (OUT_FILE, "%-*.*s", len, len, (char *) str) < 0)\
		done = m0_false;\
	else\
		done = m0_true;\
}
#define	m0_writereal(r,n)	{\
	if (fprintf (OUT_FILE, "%*f", (int) n, r) < 0)\
		done = m0_false;\
	else\
		done = m0_true;\
}

#define	m0_read(c)		{\
	char	in;\
	if ((in = fgetc (IN_FILE)) == (char) EOF)\
		if (feof (IN_FILE))\
			done = m0_false;\
		else\
			done = m0_true;\
	else\
		done = m0_true;\
	*(c) = in;\
}
#define m0_readcard(ui)		{\
	if (fscanf (IN_FILE, "%lu", &read_longunsigned) == EOF)\
		done = m0_false;\
	else {\
		done = m0_true;\
		*(ui) = read_longunsigned;\
	}\
}
#define m0_readint(i)		{\
	if (fscanf (IN_FILE, "%ld", &read_long) == EOF)\
		done = m0_false;\
	else {\
		done = m0_true;\
		*(i) = read_long;\
	}\
}
#define m0_readreal(r)		{\
	if (fscanf (IN_FILE, "%lf", &read_double) == EOF)\
		done = m0_false;\
	else {\
		done = m0_true;\
		*(r) = read_double;\
	}\
}
#define m0_readstring(str, len)	{\
	if (fscanf (IN_FILE, "%256s", read_stringbuf) == EOF)\
		done = m0_false;\
	else {\
		done = m0_true;\
		strncpy ((*str).a, read_stringbuf, len + 1);\
	}\
}

#define m0_done()		done

/*
 * mathematic functions
 */
#define m0_acos(a)	acos(a)
#define m0_asin(a)	asin(a)
#define m0_atan(a)	atan(a)
#define m0_atan2(a, b)	atan2(a, b)
#define m0_ceil(a)	ceil(a)
#define m0_cos(a)	cos(a)
#define m0_cosh(a)	cosh(a)
#define m0_exp(a)	exp(a)
#define m0_fabs(a)	fabs(a)
#define m0_floor(a)	floor(a)
#define m0_fmod(a, b)	fmod(a, b)
#define m0_log(a)	log(a)
#define m0_log10(a)	log10(a)
#define m0_pow(a, b)	pow(a, b)
#define m0_sin(a)	sin(a)
#define m0_sinh(a)	sinh(a)
#define m0_sqrt(a)	sqrt(a)
#define m0_tan(a)	tan(a)
#define m0_tanh(a)	tanh(a)


/*
 * Random-Funktionen
 */
/* the following extern declarations are
   needed on SUN and DEC workstations.
   They are obsolete on RS/6000, HP-900
   and SEQUENT. */
extern void srand48();
extern long mrand48();
extern long lrand48();
extern double drand48();

#define m0_brandom()	((m0_boolean) mrand48 () < 0L)
#define	m0_crandom()	((m0_char) lrand48 () % 256L)
#define m0_irandom()	((m0_integer) lrand48 ())
#define m0_rrandom()	((m0_real) drand48 ())


/*
 * Weitere Runtime-Funktionen
 */
extern	void	runtime_error();
extern	char	*mk_str();
extern	char	*mem_save();
extern	char	*str_save();
extern	long	range_check();

