/* Copyright (C) 1991-99 Free Software Foundation, Inc.

   This file is part of GNU Pascal Library.

   Global run time system definitions.

The GNU Pascal Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.

The GNU Pascal Library 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
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with the GNU Pascal Library; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.  */

/*
 * Authors: Jukka Virtanen <jtv@hut.fi>
 *          J.J. van der Heijden <j.j.vanderheijden@student.utwente.nl>
 *          Frank Heckenbach <frank@pascal.gnu.de>
 */

/* edit history:
    15 6 85: First version for Pax compiler at HUT.FI.

    Later (89?) I converted this for Gnu Pascal compiler (GPC).

    The run time system is rewritten for GPC and it should support
    all features of the Extended Pascal Standard. If you find deviances,
    please report them to <jtv@hut.fi>

    July '96 : adapted for GNU autoconf <j.j.vanderheijde@student.utwente.nl>
 */

#ifndef __RTS_H
#define __RTS_H

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <dirent.h>

#ifndef errno
extern int errno;
#endif

#include "limits.h"

#include "tconfig.h" /* GCC xm-*.h configuration file for system type */

/* Created by autoconf */
#include "rts-config.h"

#ifdef STDC_HEADERS
#include <stdlib.h>
#include <string.h>
#else
#ifndef HAVE_STRCHR
#define strchr index
#define strrchr rindex
#endif
char *strchr(), *strrchr();
#ifndef HAVE_MEMCPY
#define memcpy(d, s, n) bcopy((s), (d), (n))
#endif
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef MACH
void *malloc();
#endif

#ifdef BSD_RTS
#undef USG_RTS
#include <sys/file.h>
#else
#define USG_RTS
#include <fcntl.h>
#endif

/* If you don't have this file, you can generate it with
   the `enquire -f > float.h' command. Enquire comes
   with GCC distribution, and should have been made when
   you compiled GCC */
#include "float.h" /* ANSI C float.h file */

#ifdef DEBUG
#define D(level, x) do if (_p_debug >= level) x; while (0)
#else
#define D(level, x)
#endif

/* A list of collected constructor addresses is built with these
 * Used in module initialization.
 */
typedef struct contype {
  void (*fun)();
  int  run_id;
  struct contype *next;
} CONSTRUCTOR;

#ifndef PROTO
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
#define PROTO(ARGS) ARGS
#else
#define PROTO(ARGS) ()
#endif
#endif

#include "types.h"

/* More stuff */

#define NEWPAGE '\f' /* Page writes this */
#define NEWLINE '\n' /* Writeln writes this */
#define TRUE    1
#define FALSE   0

#ifndef FALSE_str
#define FALSE_str "False" /* For Write (Boolean) */
#endif

#ifndef TRUE_str
#define TRUE_str "True"
#endif

#define EOT '\004' /* File name queries abort if first char is EOT */

/* Signal handling types */
#define NONE   (0)
#define UND    (-1)
#define FAST   (-2)

/* error message handling codes */
#define ABORT  (-1)
#define REPORT (-2)
#if 0
#define IGNORE (-3)
#endif

/* GPC uses this value to detect uninitialized integer variables.
   Should be the most negative integer you can use with your hardware.
   @@ Not used yet. */
#define ILLINT INT_MIN

/* General purpose macros */
#define isdigit(ch) ((ch) >= '0' && (ch) <= '9')
#define isspace(ch) ((ch) == ' ' || (ch) == '\t')
#define isspace_nl(ch) (isspace(ch) || (ch) == '\n')

typedef unsigned char Boolean;

typedef long long int longestint;

typedef enum { NoRangeCheck, SignedRangeCheck, UnsignedRangeCheck } TRangeCheck;

typedef struct
{
  longestint f_block_size, f_blocks_total, f_blocks_free;
  int        f_files_total, f_files_free;
} statfsbuf;

typedef struct
{
  int    count;
  char **result;
  void  *buf;
} globbuffer;

/* association table for internal and external file names
   set with the "-a Intname:extname" option (Intname is the
   file name in your program, first letter capitalized) */
typedef struct assoc
{
  char    *int_name;
  char    *ext_name;
} assoc;

/* write.c */
extern void   _p_internal_fwrite PROTO ((const void *,size_t,size_t *,FDR));

/* numtodec.pas */
extern char   *_p_card_to_decimal     PROTO((unsigned int, char *));
extern char   *_p_longcard_to_decimal PROTO((unsigned long long, char *));
extern char   *_p_longreal_to_decimal PROTO((long double, int, int, int, int, int, int *));

/* read.c */
extern void   _p_read_buffer PROTO ((FDR));
extern int    _p_internal_getc PROTO ((FDR));

/* file.c */
extern void   _p_inittfdd PROTO((FDR));
extern void   _p_initfdr PROTO((FDR,char *,int,int));
extern void   _p_fdrchain PROTO((FDR,int));
extern void   _p_open PROTO ((FDR, TOpenMode));
extern int    _p_seek PROTO ((FDR, int, int, int));
extern void   _p_clearbuffer PROTO((FDR));
extern void   _p_f_flush PROTO((void *));
extern void   _p_flush PROTO((FDR));
extern FILE  *_p_getfile PROTO((FDR));
extern void   _p_rewrite PROTO((FDR,char *,int));
extern void   _p_extend  PROTO((FDR,char *,int));
extern void   _p_reset   PROTO((FDR,char *,int));
extern int    _p_ok_READ PROTO((FDR));
extern int    _p_ok_EOF PROTO((FDR));
extern int    _p_ok_WRITE PROTO((FDR));
extern size_t _p_f_read     PROTO((void *,char *,size_t));
extern size_t _p_f_read_tty PROTO((void *,char *,size_t));
extern size_t _p_f_write PROTO((void *,const char *,size_t));
extern void   _p_getbyte PROTO((FDR));
extern void   _p_get PROTO((FDR));
extern void   _p_got PROTO((FDR));
extern void   _p_lazytryget PROTO((FDR));
extern void   _p_lazyget PROTO((FDR));
extern void   _p_lazyunget PROTO((FDR));
extern Boolean _p_data_ready PROTO((FDR));
extern int    _p_eof PROTO((FDR));
extern int    _p_eoln PROTO((FDR));
extern void   _p_page PROTO((FDR));
extern void   _p_put PROTO((FDR));
extern char  *_p_filename PROTO((const FDR));
extern char  *_p_get_file_name PROTO((const FDR));
extern void   _p_erase   PROTO((FDR));
extern void   _p_rename  PROTO((FDR,char *));
extern void   _p_chdir   PROTO((char *));
extern void   _p_mkdir   PROTO((char *));
extern void   _p_rmdir   PROTO((char *));
extern char  *_p_readdir_c PROTO((DIR *));
extern int    _p_closedir PROTO((DIR *));
extern void   _p_set_file_time PROTO((FDR,UnixTimeType));
extern void   _p_statfs  PROTO((char *,statfsbuf *));
extern int    _p_fnmatch PROTO ((const char *, const char *));
extern void   _p_glob PROTO ((globbuffer *gbuf, char *pattern));
extern void   _p_globfree PROTO ((globbuffer *gbuf));
extern int    _p_execute PROTO ((char *));
extern void   _p_extend PROTO((FDR,char *,int));
extern void   _p_close PROTO((FDR));
extern void   _p_donefdr PROTO((FDR));

/* bind.c */
extern void   _p_bind    PROTO((FDR, const GPC_BINDING *));
extern void   _p_clearbinding PROTO ((GPC_BINDING *));
extern void   _p_binding PROTO((const FDR, GPC_BINDING *));
extern void   _p_unbind  PROTO((FDR));
extern void   _p_assign_tfdd PROTO ((FDR, TOpenProc, TReadFunc, TWriteFunc, TFlushProc, TCloseProc, TDoneProc, void *));
extern void   _p_get_tfdd PROTO ((FDR, TOpenProc *, TReadFunc *, TWriteFunc *, TFlushProc *, TCloseProc *, TDoneProc *, void **));

/* fassign.pas */
extern void   _p_internal_assign PROTO ((FDR,char *,int));

/* randfile.c */
extern void   _p_seekall PROTO((FDR,int));
extern void   _p_seekwrite PROTO((FDR,int));
extern void   _p_seekread PROTO((FDR,int));
extern void   _p_seekupdate PROTO((FDR,int));
extern int    _p_empty PROTO((const FDR));
extern void   _p_update PROTO((FDR));
extern int    _p_position PROTO((FDR));
extern int    _p_lastposition PROTO((FDR));
extern void   _p_definesize PROTO((FDR,int));
extern int    _p_getsize PROTO((FDR));
extern void   _p_truncate PROTO((FDR));
extern void   _p_blockread  PROTO ((FDR,       char *, unsigned int, unsigned int *));
extern void   _p_blockwrite PROTO ((FDR, const char *, unsigned int, unsigned int *));

/* times.c */
extern void         _p_unix_time_to_time PROTO ((UnixTimeType, int *, int *, int *, int *, int *, int *));
extern UnixTimeType _p_time_to_unix_time PROTO ((int, int, int, int, int, int));
extern UnixTimeType _p_get_unix_time PROTO((int *));

/* heap.pas */
extern void   _p_dispose PROTO((void *));
extern void  *_p_malloc PROTO((size_t));
extern void   _p_heap_init PROTO((void));

/* maths.c */
extern double   _p_arctan   PROTO((double));
extern double   _p_arctan2  PROTO((double, double));
extern double   _p_sqrt     PROTO((double));
extern double   _p_ln       PROTO((double));
extern double   _p_exp      PROTO((double));
extern double   _p_sin      PROTO((double));
extern double   _p_sinh     PROTO((double));
extern double   _p_cos      PROTO((double));
extern double   _p_cosh     PROTO((double));
extern double   _p_expon    PROTO((double,double));
extern double   _p_pow      PROTO((double,int));
extern long double   _pp_arctan   PROTO((long double));
extern long double   _pp_sqrt     PROTO((long double));
extern long double   _pp_ln       PROTO((long double));
extern long double   _pp_exp      PROTO((long double));
extern long double   _pp_sin      PROTO((long double));
extern long double   _pp_cos      PROTO((long double));
extern long double   _pp_expon    PROTO((long double,long double));
extern long double   _pp_pow      PROTO((long double,int));

/* rt0.c */
extern int    _p_signal, _p_sigcause, _p_debug, _p_warn, _p_argc, _p_pid;
extern char **_p_argv, **_p_envp;
extern int    _p_eoln_reset_hack;
extern int    _p_force_direct_files;
extern struct Fdr _p_stdin;
extern struct Fdr _p_stdout;
extern struct Fdr _p_stderr;
extern FILE  *_p_current_stdin;
extern assoc *_p_assoc;
extern void  *_p_default_malloc PROTO((size_t));
extern void   _p_initialize PROTO((int, char **, char **));
extern void   _p_init_heap PROTO((void));
extern void   _p_init_env PROTO((char **));
extern void   _p_init_arguments PROTO((int, char **));
extern void   _p_init_locale PROTO((void));
extern void   _p_init_signals PROTO((void));
extern void   _p_initialize_std_files PROTO ((void));
extern void   _p_init_std_files PROTO ((void));
extern void   _p_init_files_atexit PROTO((void));
extern void   _p_run_constructors PROTO((void));
extern void   _p_exit PROTO((int));
extern void   _p_done_files PROTO((void));
extern void   _p_fflush PROTO((Boolean));
extern int    _p_restore_stdin PROTO((FDR));

/* filename.pas */
extern char  *_p_get_temp_file_name_cstring PROTO((void));
extern char  *_p_osdirseparator2slash_cstring PROTO ((char *));

/* gstrings.pas */
extern size_t  _p_strlen PROTO((char *));
extern char   *_p_strdup PROTO((char *));
extern int     _p_strcasecmp PROTO ((char *,char *));
extern int     _p_strcmp     PROTO ((char *,char *));
extern Boolean _p_str_eq PROTO((char *, int, char *, int));
extern Boolean _p_str_lt PROTO((char *, int, char *, int));
extern Boolean _p_eq     PROTO((char *, int, char *, int));
extern Boolean _p_lt     PROTO((char *, int, char *, int));
extern int     _p_index  PROTO((char *, int, char *, int));
extern int     _p_trim   PROTO((char *, int, char *));
extern int     _p_substr PROTO((char *, int, int, int, char *, Boolean));

/* misc.c */
extern int          _p_no_constructors;
extern int          _p_collect_flag;
extern CONSTRUCTOR *_p_c_list;
extern void         _p_collect PROTO((void (*)(),int));

/* error.pas */
extern int _p_inoutres;
extern void   _p_heap_warning PROTO((char *));
extern char  *_p_errmsg PROTO((int));
extern char  *_p_check_errmsg PROTO((int,char *));
extern void   _p_prmessage PROTO((char *,int,Boolean));
extern void   _p_error PROTO((int));
extern void   _p_error_integer PROTO((int,long int));
extern void   _p_error_string PROTO((int,char *));
extern void   _p_internal_error PROTO((int));
extern void   _p_internal_error_integer PROTO((int,long int));
extern void   _p_io_error PROTO((int));
extern void   _p_io_error_string PROTO((int,char *));
extern void   _p_check_inoutres PROTO((void));
extern void   _p_warning PROTO((char *));
extern void   _p_warning_integer PROTO((char *,long int));
extern void   _p_warning_string PROTO((char *,char *));
extern void   _p_start_temp_io_error PROTO((void));
extern int    _p_end_temp_io_error PROTO((void));

#define IOERROR(err,retval) do {_p_io_error(err); return retval;} while (0)
#define IOERROR_STRING(err,str,retval) do {_p_io_error_string(err,str); return retval;} while (0)
#define IOERROR_FILE(err,file,retval) IOERROR_STRING(err,_p_get_file_name(file),retval)

#endif /* __RTS_H */
