/* File: simrtl.h
 *
 * Contains definitions needed to compile the C level of the SIMSCRIPT
 * runtime lib. (formerly internal.h).
 * This file is included im simc.h for the whole SIMSCRIPT runtime (C AND
 * SIMSCRIPT level!). THis is because we need prototypes for all C routines
 * called from the SIMSCRIPT layer of the RTL.
 *
 * Defined platform macros (for C level code; same as in OSI):
 *
 *   	OS_SUNOS	Sun OS (not solaris!)
 *   	OS_SOLARIS	Sun Solaris
 *   	OS_IRIX		SGI with Irix
 *	OS_VMS		VMS
 *	OS_ULTRIX	Dec Ultrix
 *	OS_HPUNIX	HP/UX 
 *	OS_AIX		RS/6000 with AIX
 *	OS_NEXT		NextStep
 *	OS_WIN16	Windows (16 bit)
 *	OS_OS2		OS/2 2.0 or greater
 *	OS_NT		Windows NT
 *
 */


/*----- 0. General macros --------------------------------------*/

/*-- check for internal errors */
#include <stdio.h>

/*-- ALWAYS_ASSERT is always there --*/
#define ALWAYS_ASSERT(n)	if (!(n)) {fprintf(stderr, "Internal SIMSCRIPT error in %s, line %d.\n", __FILE__, __LINE__); exit(1); } else

/*-- macros for case DEBUG (during development) --*/
#ifdef DEBUG

#define ASSERT(cond)	if (!(cond)) {fprintf(stderr, "Assertion failed in %s, line %d.\n", __FILE__, __LINE__); exit(1); } else
#define CLIB_ERR_IF(cond)	if (cond) {fprintf(stderr, "C low level error in %s, line %d.\n", __FILE__, __LINE__); perror(""); exit(1); } else

#else

#define ASSERT(cond)
#define CLIB_ERR_IF(cond)

#endif


/*----- 1. Derive machine/OS -----------------------------------*/



/*-----------------------------*/
#if defined(OS_WIN16) || defined(OS_NT)
#include "limits.h"
#define SIMMAXINT LONG_MAX

#endif


/*-----------------------------*/
#ifdef unix
#include "values.h"
#define SIMMAXINT MAXINT

#endif



/*-------- setjmp -----*/
#if defined(OS_HPUNIX)

/* formerly in "simjmp.h" */
#ifndef _JBLEN
#define _JBLEN 15
typedef double jmp_buf[_JBLEN];
#endif _JBLEN
extern int  _setjmp();
extern void _longjmp();

/* we MUST use our own _setjmp/_longjmp !!! */
#define setjmp 		_setjmp
#define longjmp 	_longjmp


#else
#include <setjmp.h>
#endif


/*------- 2. C routines of the runtime ---------------------------*/

S_P STDCALL zcalloctype PROTO(());
S_T STDCALL zcerrtxt PROTO(());
S_VOID STDCALL zexit  PROTO((S_I Status));
S_P STDCALL zfopen  PROTO((S_T Filename, S_T OpenFlag));
S_I STDCALL zfclose  PROTO((S_P FILEDES));
S_VOID STDCALL zfflush  PROTO((S_P FILEDES));
S_P STDCALL zfgets  PROTO((S_P Buffer, S_I RecSize, S_P FILEDES));
S_I STDCALL zfputs  PROTO((S_P Buffer, S_P FILEDES));
S_I STDCALL zfread  PROTO((S_P Buffer, S_I RecSize, S_I Count, S_P FILEDES));
S_I STDCALL zfwrite  PROTO((S_P Buffer, S_I RecSize, S_I Count, S_P FILEDES));
/*VOID STDCALL zfree  PROTO((S_P pBlock)); */
S_VOID STDCALL zfree  PROTO((char *));
S_T STDCALL zprogdir  PROTO((char **argv));
S_T STDCALL zprogname  PROTO((char **argv));
S_VOID STDCALL zrterror PROTO((S_T Title, S_I errnum, S_T msg));
S_I STDCALL zsleep  PROTO((S_I Seconds));

#ifdef ANSI
void (STDCALL * STDCALL zsignal (int signum, void (STDCALL *func)()) )();
#else
void (STDCALL * STDCALL zsignal ()) ();
#endif


/*--- headers when we use our own malloc routines -----*/

char * SIMCALL sim_calloc   PROTO((unsigned, int)) ;
char * SIMCALL sim_malloc   PROTO((unsigned)) ;
char * SIMCALL sim_realloc  PROTO((char *, unsigned)) ;
/*void   SIMCALL sim_free     PROTO((char *)) ; */
S_VOID   SIMCALL sim_free     PROTO((char *)) ;


/*--------- 3. CMR stuff --------------------------------------------*/

/* There is the main routine "cmr_op" in cmr.c. Each other C module that
 * needs to save/store local statics needs its own cmr_op_<modname>
 * routine. 
 */


#define CMR_OP_SAVE	1
#define CMR_OP_LOAD	2

#define CMR_OP_ERROR	-1
#define CMR_OP_OK	0

/*-- top level routine and proto for module --*/
S_I cmr_top_op PROTO((int fno, int oper));


