/*
 * SCORE.H - include file for PACT standard core package
 *
 * Source Version: 2.0
 * Software Release #92-0043
 *
 */

#ifndef PCK_SCORE

#define PCK_SCORE                                 /* SCORE package resident */

#include "cpyright.h"

#include "scstd.h"

/* name of the program using the package */
#ifndef CODE
# define CODE   ""
#endif

/* version designation of CODE */
#ifndef VERSION
# define VERSION   SC_version_string
#endif

# define REAL double
# define HUGE_REAL 1.0e100
FUNCTION_POINTER(double, *(*PFPREAL));

/*--------------------------------------------------------------------------*/

/*                           DEFINED CONSTANTS                              */

/*--------------------------------------------------------------------------*/

#define UNCOLLECT       SHRT_MAX
#define MAX_LEX_BUFFER  4096

#define ERRDEV  stderr                /* device to dump diagnostic messages */
#define ERR_FREE   2                 /* error free return flag for longjmps */
#define ABORT      3                      /* error return flag for longjmps */
#define RETURN_OK  4                     /* simple return flag for longjmps */

#define DESTROY 5
#define APPEND  6
#define FAIL    7

#define NO_FILE  9
#define ASCII   10
#define BINARY  11
#define PDB     12

#define HSZSMALL  31              /* small table size */
#define HSZSMINT  67              /* small intermediate table size */
#define HSZLRINT 127              /* table size for variables*/
#define HSZLARGE 521              /* large table size */
#define DOC        1              /* indicate the presence of documentation */
#define NODOC      0              /* indicate no documentation */

/* IO Hooks */
#define io_open    (*io_open_hook)
#define io_setvbuf (*io_setvbuf_hook)
#define io_tell    (*io_tell_hook)
#define io_read    (*io_read_hook)
#define io_write   (*io_write_hook)
#define io_close   (*io_close_hook)
#define io_seek    (*io_seek_hook)
#define io_printf  (*io_printf_hook)
#define io_puts    (*io_puts_hook)
#define io_getc    (*io_getc_hook)
#define io_ungetc  (*io_ungetc_hook)
#define io_flush   (*io_flush_hook)
#define io_gets    (*io_gets_hook)

#undef PRINT
#define PRINT (*putln)

#undef STDOUT
#define STDOUT ((SC_comm_rank == 0) ? stdout : NULL)

#undef GETLN
#define GETLN (*getln)

#undef CONVERT
#define CONVERT (*SC_convert_hook)

#undef SIZEOF
#define SIZEOF (*SC_sizeof_hook)

#undef CONTAINER
#define CONTAINER (*SC_container_hook)

#define OTOL   (*SC_otol_hook)
#define HTOL   (*SC_htol_hook)
#define ATOL   (*SC_atol_hook)
#define ATOF   (*SC_atof_hook)
#define STRTOD (*SC_strtod_hook)
#define STRTOL (*SC_strtol_hook)

#ifndef SYSTEM
# define SYSTEM system
#endif

#ifndef ALARM
# define ALARM alarm
#endif

#ifndef SIGNAL_FUNCTION
# define SIGNAL_FUNCTION signal
#endif

#define SIGNAL(sig, fnc)  SIGNAL_FUNCTION(sig, (PFSignal_handler) fnc)


/* relevant languages require/support these token types */

#define SC_WSPC_TOK    0    /* whitespace token */
#define SC_DELIM_TOK   1    /* delimiter token */
#define SC_IDENT_TOK   2    /* identifier token */
#define SC_DINT_TOK    3    /* decimal integer number token */
#define SC_REAL_TOK    4    /* decimal real number token */
#define SC_OINT_TOK    5    /* octal integer number token */
#define SC_HINT_TOK    6    /* hexidecimal integer number token */
#define SC_OPER_TOK    7    /* operator token */
#define SC_STRING_TOK  8    /* string token */
#define SC_KEY_TOK     9    /* keyword token */
#define SC_PRED_TOK   10    /* predicate token */
#define SC_CMMNT_TOK  11    /* comment token */

/* FORTRAN derivatives require these tokens */

#define SC_HOLLER_TOK  1000    /* hollerith token */

#ifndef REMOVE
#define REMOVE remove
#endif

#undef MAKE
#undef MAKE_N
#undef REMAKE
#undef REMAKE_N
#undef SFREE
#undef SFREE_N

/*--------------------------------------------------------------------------*/

/*                           PROCEDURAL MACROS                              */

/*--------------------------------------------------------------------------*/

/* NMAKE - memory allocation and bookkeeping macro */

#define NMAKE(x, name)                                                       \
    ((x *) SC_alloc_na(1L, (long) sizeof(x), name, TRUE))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* NMAKE_N - allocate a block of type x and return a pointer to it */

#define NMAKE_N(x, n, name)                                                  \
    ((x *) SC_alloc_na((long) n, (long) sizeof(x), name, TRUE))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* NREMAKE - memory reallocation and bookkeeping macro */

#define NREMAKE(p, x)                                                        \
   (p = (x *) SC_realloc_na((byte *) p, 1L, (long) sizeof(x), TRUE))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* NREMAKE_N - reallocate a block of type x and return a pointer to it */

#define NREMAKE_N(p, x, n)                                                   \
   (p = (x *) SC_realloc_na((byte *) p, (long) (n), (long) sizeof(x), TRUE))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* FMAKE - memory allocation and bookkeeping macro */

#define FMAKE(x, name)                                                       \
    ((x *) SC_alloc_na(1L, (long) sizeof(x), name, FALSE))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* FMAKE_N - allocate a block of type x and return a pointer to it */

#define FMAKE_N(x, n, name)                                                  \
    ((x *) SC_alloc_na((long) n, (long) sizeof(x), name, FALSE))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* MAKE - memory allocation and bookkeeping macro */

#define MAKE(x)                                                              \
    ((x *) SC_alloc_na(1L, (long) sizeof(x), NULL, FALSE))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* MAKE_N - allocate a block of type x and return a pointer to it */

#define MAKE_N(x, n)                                                         \
    ((x *) SC_alloc_na((long) n, (long) sizeof(x), NULL, FALSE))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* REMAKE - memory reallocation and bookkeeping macro */

#define REMAKE(p, x)                                                         \
   (p = (x *) SC_realloc_na((byte *) p, 1L, (long) sizeof(x), FALSE))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* REMAKE_N - reallocate a block of type x and return a pointer to it */

#define REMAKE_N(p, x, n)                                                    \
   (p = (x *) SC_realloc_na((byte *) p, (long) (n), (long) sizeof(x), FALSE))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* SFREE - release memory and do bookkeeping */

#define SFREE(x)                                                             \
   {SC_free(x);                                                              \
    x = NULL;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* SFREE_N - release memory and do bookkeeping on arrays */

#define SFREE_N(x, n)                                                        \
   {SC_free(x);                                                              \
    x = NULL;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* SC_REMEMBER - add an item to an array of items */

#define SC_REMEMBER(type, item, lst, n, nx, delta)                           \
    {if (lst == NULL)                                                        \
        {nx = delta;                                                         \
         n  = 0;                                                             \
         lst = FMAKE_N(type, nx, "SC_REMEMBER:lst");};                       \
     lst[n++] = item;                                                        \
     if (n >= nx)                                                            \
        {nx += delta;                                                        \
         REMAKE_N(lst, type, nx);};}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* SC_ADD_VALUE_ALIST - add a scalar value to an alist */

#define SC_ADD_VALUE_ALIST(lst, t, str, name, val)                           \
   {t *pt;                                                                   \
    pt  = FMAKE(t, "SC_ADD_VALUE_ALIST:pt");                                 \
    *pt = val;                                                               \
    lst = SC_add_alist(lst, name, str, pt);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* SC_CHANGE_VALUE_ALIST - change a scalar value in an alist */

#define SC_CHANGE_VALUE_ALIST(lst, t, str, name, val)                        \
   {t *pt;                                                                   \
    pt  = FMAKE(t, "SC_CHANGE_VALUE_ALIST:pt");                              \
    *pt = val;                                                               \
    lst = SC_change_alist(lst, name, str, (byte *) pt);}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

#ifdef F77_INT_SIZE_PTR_DIFFER

#define SC_GET_POINTER(type, n)      ((type *) _SC_ptr_list_[n-1])
#define SC_ADD_POINTER(p)            SC_stash_pointer(p)
#define SC_DEL_POINTER(type, n)      ((type *) SC_del_pointer(n))
#define SC_GET_INDEX(p)              SC_pointer_index(p)
#define SC_T_GET_POINTER(t, type, n) SC_GET_POINTER(type, n)
#define SC_T_ADD_POINTER(t, p)       SC_ADD_POINTER(p)
#define SC_T_DEL_POINTER(t, type, n) SC_DEL_POINTER(type, n)
#define SC_T_GET_INDEX(t, p)         SC_GET_INDEX(p)

#else
/* F77 INT SIZE and PTR SAME */

#ifdef HAVE_THREADS

#define SC_T_GET_POINTER(t, type, n) SC_T_TO_ADDRESS(t, type, n)
#define SC_T_ADD_POINTER(t, p)       SC_T_TO_NUMBER(t, p)
#define SC_T_DEL_POINTER(t, type, n) SC_T_TO_ADDRESS(t, type, n)
#define SC_T_GET_INDEX(t, p)         SC_T_TO_NUMBER(t, p)

#else

#define SC_T_GET_POINTER(t, type, n) SC_GET_POINTER(type, n)
#define SC_T_ADD_POINTER(t, p)       SC_ADD_POINTER(p)
#define SC_T_DEL_POINTER(t, type, n) SC_DEL_POINTER(type, n)
#define SC_T_GET_INDEX(t, p)         SC_GET_INDEX(p)

#endif

#define SC_GET_POINTER(type, n) SC_TO_ADDRESS(type, n)
#define SC_ADD_POINTER(p)       SC_TO_NUMBER(p)
#define SC_DEL_POINTER(type, n) SC_TO_ADDRESS(type, n)
#define SC_GET_INDEX(p)         SC_TO_NUMBER(p)

#endif

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* SC_INIT - setup certain universal things for applications, i.e.
 *         - interrupt handler
 *         - top level longjump
 *         - output buffering
 *         - this must be a macro to circumvent implementations that
 *         - won't let you longjmp back into function from which a
 *         - return has been done
 *         - Prototype arguments would be:
 *         -   char *msg;
 *         -   byte (*fnc)(int err);
 *         -   int sighand;
 *         -   PFByte sigfnc;
 *         -   int bfhand;
 *         -   char *bf;
 *         -   int bfsize;
 */

#define SC_init(msg, fnc, sighand, sigfnc, bfhand, bf, bfsize)               \
   {static DECLFPTR(byte, lfnc, (int err)) = NULL;                           \
    switch (setjmp(SC_top_lev))                                              \
       {case ABORT :                                                         \
             PRINT(STDOUT, "\n%s\n\n", msg);                                 \
             if (lfnc != NULL)                                               \
                (*lfnc)(ABORT);                                              \
             exit(1);                                                        \
        case ERR_FREE :                                                      \
             if (lfnc != NULL)                                               \
                (*lfnc)(ERR_FREE);                                           \
             exit(0);                                                        \
        default :                                                            \
             lfnc = fnc;                                                     \
             break;};                                                        \
    if (sighand)                                                             \
       {if (sigfnc != NULL)                                                  \
           SIGNAL(SIGINT, sigfnc);                                           \
        else                                                                 \
           SIGNAL(SIGINT, SC_interrupt_handler);};                           \
    if (bfhand)                                                              \
       {if ((bf == NULL) || (bfsize <= 0))                                   \
           {SC_setbuf(stdout, NULL);}                                        \
        else                                                                 \
           {io_setvbuf(stdout, bf, _IOFBF, bfsize);};};}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* SC_ITEMLEN - return the length of an array in items */

#define SC_ITEMLEN(array, type)                                              \
    ((array == NULL) ? 0 : SC_arrlen(array) / sizeof(type))

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* SC_SWAP_VALUE - exchange two values */

#define SC_SWAP_VALUE(type, v1, v2)                                         \
   {type t;                                                                 \
    t    = (v1);                                                            \
    (v1) = (v2);                                                            \
    (v2) = t;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* SC_REVERSE_LIST - generic linked list reverser macro */

#define SC_REVERSE_LIST(type, var, member)                                  \
   {type *ths, *nxt, *prv;                                                  \
    for (ths = NULL, nxt = var; nxt != NULL; )                              \
        {prv = ths;                                                         \
         ths = nxt;                                                         \
         nxt = ths->member;                                                 \
         ths->member = prv;};                                               \
    var = ths;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* POP - pop a stack */

#define pop(p, pend) ((p) < (pend)) ? (p)++ : (pend)

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

/* PUSH - push onto a stack */

#define push(p, pfirst) ((p) > (pfirst)) ? (p)-- : (pfirst)

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

#define SC_SET_FUNC_ADDR(x)                                                  \
   (_SC_addr_.funcaddr = (PFInt) (x), _SC_addr_)

#define SC_SET_MEM_ADDR(x)                                                   \
   (_SC_addr_.memaddr = (char *) (x), _SC_addr_)

#define SC_SET_DISK_ADDR(x)                                                  \
   (_SC_addr_.diskaddr = (off_t) (x), _SC_addr_)

#define SC_LOOKUP_FUNCTION(typ, nm, tab)                                     \
   (_SC_addr_.memaddr = SC_def_lookup(nm, tab), (typ) _SC_addr_.funcaddr)

#ifdef HAVE_THREADS

#define SC_T_SET_FUNC_ADDR(t, x)                                             \
   (_SC_ADDR_(t).funcaddr = (PFInt) (x), _SC_ADDR_(t))

#define SC_T_SET_MEM_ADDR(t, x)                                              \
   (_SC_ADDR_(t).memaddr = (char *) (x), _SC_ADDR_(t))

#define SC_T_SET_DISK_ADDR(t, x)                                             \
   (_SC_ADDR_(t).diskaddr = (off_t) (x), _SC_ADDR_(t))

#define SC_T_LOOKUP_FUNCTION(t, typ, nm, tab)                                \
   (_SC_ADDR_(t).memaddr = SC_def_lookup(nm, tab), (typ) _SC_ADDR_(t).funcaddr)

#else

#define SC_T_SET_FUNC_ADDR(t, x)   SC_SET_FUNC_ADDR(x)
#define SC_T_SET_MEM_ADDR(t, x)    SC_SET_MEM_ADDR(x)
#define SC_T_SET_DISK_ADDR(t, x)   SC_SET_DISK_ADDR(x)
#define SC_T_LOOKUP_FUNCTION(t, typ, nm, tab) SC_LOOKUP_FUNCTION(typ, nm, tab)

#endif

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

#define SC_GET_FUNC_ADDR(type, a)   ((type) a.funcaddr)
#define SC_GET_MEM_ADDR(type, a)    ((type) a.memaddr)
#define SC_GET_DISK_ADDR(type, a)   ((type) a.diskaddr)

#define SC_TO_NUMBER(a)                                                      \
   (_SC_addr_.memaddr = (char *) (a), _SC_addr_.mdiskaddr)

#define SC_TO_ADDRESS(type, a)                                               \
   (_SC_addr_.mdiskaddr = (a), (type *) _SC_addr_.memaddr)

#ifdef HAVE_THREADS

#define SC_T_TO_NUMBER(t, a)                                                 \
   (_SC_ADDR_(t).memaddr = (char *) (a), _SC_ADDR_(t).mdiskaddr)

#define SC_T_TO_ADDRESS(t, type, a)                                          \
   (_SC_ADDR_(t).mdiskaddr = (a), (type *) _SC_ADDR_(t).memaddr)

#else

#define SC_T_TO_NUMBER(t, a) SC_TO_NUMBER(a)
#define SC_T_TO_ADDRESS(t, type, a) SC_TO_ADDRESS(type, a)

#endif

#define SC_TOKEN_TYPE(x, i)         ((x)->tokens[i].type)
#define SC_TOKEN_INTEGER(x, i)      ((x)->tokens[i].val.l)
#define SC_TOKEN_REAL(x, i)         ((x)->tokens[i].val.d)
#define SC_TOKEN_STRING(x, i)       ((x)->tokens[i].val.s)
#define SC_LEX_SCAN(x)              (*((x)->scan))()

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

#define SC_INIT_DYNAMIC(arr, d)                                              \
    {arr.delta = (d);                                                        \
     arr.nx    = 0;                                                          \
     arr.type  = NULL;                                                       \
     arr.array = NULL;}

#define SC_INIT_DYNAMIC_ARRAY(_arr, _type, _t, _d)                           \
    {int _n;                                                                 \
     char *_s;                                                               \
     _n = strlen(_t) + 4;                                                    \
     _s = FMAKE_N(char, _n, "SC_INIT_DYNAMIC_ARRAY:_s");                     \
     sprintf(_s, "%s *", (char *) (_t));                                     \
     _n = (_d);                                                              \
     (_arr).delta = _n;                                                      \
     (_arr).type  = _s;                                                      \
     (_arr).nx    = _n;                                                      \
     (_arr).n     = 0;                                                       \
     (_arr).array = FMAKE_N(_type, _n, "SC_INIT_DYNAMIC_ARRAY:array");       \
     if ((_SC_zero_space != 1) && (_SC_zero_space != 2))                     \
        memset((_arr).array, 0, _n*sizeof(_type));}

#define SC_ARRAY_DYNAMIC(type, arr)          ((type *) (arr).array)
#define SC_GET_NTH_DYNAMIC(type, arr, n)     (((type *) (arr).array)[n])
#define SC_SET_NTH_DYNAMIC(type, arr, n, v)  ((type *) (arr).array)[(n)] = (v)
#define SC_N_DYNAMIC(arr)                    (arr.n)

#define SC_REMEMBER_DYNAMIC(type, item, arr)                                 \
    SC_REMEMBER_DYNAMIC_F(type, item, arr, "SC_REMEMBER_DYNAMIC")

#define SC_RELEASE_DYNAMIC(arr)                                              \
    {SFREE(arr.type);                                                        \
     SFREE(arr.array);                                                       \
     SC_INIT_DYNAMIC(arr, 0);}

#define SC_REMEMBER_DYNAMIC_F(type, item, arr, name)                         \
    {int n, nx, d;                                                           \
     type *lst;                                                              \
     lst = (type *) (arr).array;                                             \
     n   = (arr).n;                                                          \
     nx  = (arr).nx;                                                         \
     if (lst == NULL)                                                        \
        {d   = (arr).delta;                                                  \
         nx  = d;                                                            \
         n   = 0;                                                            \
         lst = FMAKE_N(type, nx, name);                                      \
         if ((_SC_zero_space != 1) && (_SC_zero_space != 2))                 \
	    memset(lst, 0, nx*sizeof(type));                                 \
         (arr).array = lst;                                                  \
         (arr).nx    = nx;};                                                 \
     lst[n++] = item;                                                        \
     (arr).n    = n;                                                         \
     if (n >= nx)                                                            \
        {d   = (arr).delta;                                                  \
         nx += d;                                                            \
         REMAKE_N(lst, type, nx);                                            \
         if ((_SC_zero_space != 1) && (_SC_zero_space != 2))                 \
   	    memset(lst+nx-d, 0, d*sizeof(type));                             \
         (arr).array = lst;                                                  \
         (arr).nx    = nx;};}

#define SC_SIZE_DYNAMIC(type, arr, m)                                        \
    SC_SIZE_DYNAMIC_F(type, arr, m, "SC_SIZE_DYNAMIC:lst")

#define SC_SIZE_DYNAMIC_F(type, arr, m, name)                                \
    {int n, nx, na, d;                                                       \
     type *lst;                                                              \
     lst = (type *) (arr).array;                                             \
     n   = (arr).n;                                                          \
     nx  = (arr).nx;                                                         \
     d   = (arr).delta;                                                      \
     na  = d*((m + d - 1)/d);                                                \
     if (lst == NULL)                                                        \
        {lst = FMAKE_N(type, nx, name);                                      \
         if ((_SC_zero_space != 1) && (_SC_zero_space != 2))                 \
	    memset(lst, 0, na*sizeof(type));                                 \
         n   = 0;                                                            \
         nx = na;};                                                          \
     if (na >= nx)                                                           \
        {REMAKE_N(lst, type, na);                                            \
         if ((_SC_zero_space != 1) && (_SC_zero_space != 2))                 \
   	    memset(lst+nx, 0, (na-nx)*sizeof(type));                         \
         nx = na;};                                                          \
     (arr).array = lst;                                                      \
     (arr).n     = n;                                                        \
     (arr).nx    = nx;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

#define SC_SET_N_THREADS(_t, _arr, _n)                                       \
   {int _nt;                                                                 \
    _t *_lst;                                                                \
    _lst = (_t *) (_arr).array;                                              \
    _nt  = (_n);                                                             \
    if (_lst == NULL)                                                        \
       {_lst = FMAKE_N(_t, _nt+1, "SC_SET_N_THREADS:lst");                   \
        if ((_SC_zero_space != 1) && (_SC_zero_space != 2))                  \
	   memset(_lst, 0, (_nt+1)*sizeof(_t));}                             \
    else                                                                     \
       {REMAKE_N(_lst, _t, _nt+1);                                           \
        if ((_SC_zero_space != 1) && (_SC_zero_space != 2))                  \
   	   memset(_lst+_nt, 0, sizeof(_t));};                                \
    (_arr).array       = (void *) _lst;                                      \
    (_arr).n_threads = _nt;}

#define SC_GET_NTH_THREAD(type, _arr)                                        \
   (((type *) (_arr).array)[SC_current_thread()])

#define SC_TID(x)                                                            \
   {if (SC_tid_hook != NULL)                                                 \
       (*SC_tid_hook)(&x);                                                   \
    else                                                                     \
       x = 0;}

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

#ifdef IBMMP

# define FLUSH_ON(_f, _x)   SC_fflush(_f)

#else

# define FLUSH_ON(_f, _x)

#endif

/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

#ifdef HAVE_THREADS

#define SC_THREAD_ID(t)       int t = SC_current_thread()
#define _SC_ADDR_(t)                                                         \
   ((SC_n_threads > 0) ? (_SC_tsa[t]._SC_addr_) :                            \
                         (SC_init_threads(1, NULL),                          \
			  _SC_tsa[t]._SC_addr_))

#else

#define SC_THREAD_ID(t)
#define _SC_ADDR_(t)        _SC_addr_

#endif
/*--------------------------------------------------------------------------*/

/*                         TYPEDEFS AND STRUCTS                             */

/*--------------------------------------------------------------------------*/

FUNCTION_POINTER(FILE,  *(*PFPFILE));
FUNCTION_POINTER(size_t, (*PFSize_t));

/* Pcons definition
 *    - useful for linked lists, association lists and whatnot
 *    - the type fields are for bookkeeping that may be crucial to
 *    - other packages
 */

struct s_pcons
   {char *car_type;
    byte *car;
    char *cdr_type;
    byte *cdr;};

typedef struct s_pcons pcons;

FUNCTION_POINTER(pcons, *(*PFPPcons));

/* Hashel definition
 *          - hashel have four members, the name, type, def, and free
 *          - the name is a string on which the function hash operates
 *          - type is a string which names the type of object associated
 *          - with the name and type checking on the object can be used
 *          - to determine appropriate casts for accessing the object
 *          - def is a pointer to an object, usually a struct with
 *          - the necessary members for the specific application
 *          - free specifies whether or not def was marked when installed
 */

struct s_hashel                 
   {char *name;
    char *type;
    byte *def;
    int free;
    struct s_hashel *next;};                         /* next entry in chain */

typedef struct s_hashel hashel;

/* Hash table type */

struct s_hashtab
   {int size;
    int nelements;
    int docp;
    hashel **table;};

typedef struct s_hashtab HASHTAB;

union u_SC_address
   {long mdiskaddr;
    off_t diskaddr;
    PFInt funcaddr;
    char *memaddr;};

typedef union u_SC_address SC_address;

typedef char char_8[8];

union u_SC_token_value
   {long l;
    double d;
    char *s;
    PFInt f;};

typedef union u_SC_token_value SC_token_value;

struct s_SC_lexical_token
   {int type;
    SC_token_value val;};

typedef struct s_SC_lexical_token SC_lexical_token;

struct s_SC_lexical_stream
   {char *name;
    FILE *file;
    int i_token;
    int n_tokens;
    int n_tokens_max;
    SC_lexical_token *tokens;
    char *in_bf;
    char *in_ptr;
    char *out_bf;
    char *out_ptr;
    char *str_bf;
    char *str_ptr;
    PFInt scan;
    PFInt inp;
    PFInt out;
    PFInt unp;
    PFInt wrap;
    PFInt more;
    PFInt less;};

typedef struct s_SC_lexical_stream SC_lexical_stream;


/* Dynamic arrays and MP arrays */

typedef struct s_SC_dynamic_array SC_dynamic_array;

struct s_SC_dynamic_array
  {char *type;
   void *array;
   int n;
   int nx;
   int delta;};

typedef struct s_SC_thread_array SC_thread_array;

struct s_SC_thread_array
  {void *array;
   int n_threads;};

typedef FILE
 *SC_DECLARE((*PFfopen), (char *name, char *mode));

typedef off_t
 SC_DECLARE((*PFftell), (void *stream));

typedef size_t
 SC_DECLARE((*PFfread), (byte *ptr, size_t sz, size_t ni, void *stream));

typedef size_t
 SC_DECLARE((*PFfwrite), (void *ptr, size_t sz, size_t ni, void *stream));

typedef int
 SC_DECLARE((*PFsetvbuf), (void *stream, char *bf, int type, size_t sz));

typedef int
 SC_DECLARE((*PFfclose), (void *stream));

typedef int
 SC_DECLARE((*PFfseek), (void *stream, off_t offs, int whence));

typedef int
 SC_DECLARE((*PFfprintf), (void *stream, char *fmt, ...));

typedef int
 SC_DECLARE((*PFfputs), (char *s, void *stream));

typedef int
 SC_DECLARE((*PFfgetc), (void *stream));

typedef int
 SC_DECLARE((*PFungetc), (int c, void *stream));

typedef int
 SC_DECLARE((*PFfflush), (void *stream));

typedef char
 *SC_DECLARE((*PFfgets), (char *s, int n, void *stream));

typedef struct s_SC_thread_state SC_thread_state;

struct s_SC_thread_state
   {SC_address _SC_addr_;};

#ifdef __cplusplus
extern "C" {
#endif

/*--------------------------------------------------------------------------*/

/*                         VARIABLE DECLARATIONS                            */

/*--------------------------------------------------------------------------*/

extern SC_thread_state
 *_SC_tsa;

extern SC_address
 _SC_addr_;

extern SC_lexical_stream
 *SC_current_lexical_stream;

extern jmp_buf
 SC_top_lev;             /* top level environment - mainly for error return */

extern PFfgets
 getln;                                      /* line input function pointer */

extern PFfprintf
 putln;                                           /* print function pointer */

extern PFInt
 SC_convert_hook,                         /* data type conversion in memory */
 SC_sizeof_hook;                                 /* string driven size hook */

extern PFDouble
 SC_atof_hook,
 SC_strtod_hook;

extern PFLong
 SC_otol_hook,
 SC_htol_hook,
 SC_atol_hook,
 SC_strtol_hook;

extern PFVoid
 SC_container_hook,
 SC_tid_hook,
 _SC_free_hook;

extern PFPByte
 _SC_alloc_hook,
 _SC_realloc_hook;


/* IO hooks */

extern PFfopen io_open_hook;
extern PFftell io_tell_hook;
extern PFfread io_read_hook;
extern PFfwrite io_write_hook;
extern PFsetvbuf io_setvbuf_hook;
extern PFfclose io_close_hook;
extern PFfseek io_seek_hook;
extern PFfprintf io_printf_hook;
extern PFfputs io_puts_hook;
extern PFfgetc io_getc_hook;
extern PFungetc io_ungetc_hook;
extern PFfflush io_flush_hook;
extern PFfgets io_gets_hook;

extern byte
 **_SC_ptr_list_;

extern int
 SC_unary_plus,
 SC_full_mm,
 _SC_zero_space,
 SC_n_threads,
 SC_comm_rank,
 SC_comm_size,
 SC_mm_debug,
 Zero_I,
 One_I,
 Two_I,
 Three_I,
 Four_I,
 Radix;

extern double
 Zero_D,
 One_D,
 Two_D,
 Three_D,
 Four_D;

extern char
 SC_version_string[],
 CV_Banner[],
 SC_line[],             /* global copy of latest command line */
 pbuffer[],             /* print buffer */
 **SC_path,
 *SC_CHAR_8_S,
 *SC_CHAR_S,
 *SC_SHORT_S,
 *SC_INTEGER_S,
 *SC_LONG_S,
 *SC_FLOAT_S,
 *SC_REAL_S,
 *SC_DOUBLE_S,
 *SC_STRING_S,
 *SC_POINTER_S,
 *SC_PCONS_P_S,
 *SC_VOID_S,
 *SC_SHORT_P_S,
 *SC_INTEGER_P_S,
 *SC_LONG_P_S,
 *SC_FLOAT_P_S,
 *SC_REAL_P_S,
 *SC_DOUBLE_P_S,
 *SC_PCONS_S,
 *SC_STRUCT_S,
 *SC_UNKNOWN_S;

/*--------------------------------------------------------------------------*/

/*                          FUNCTION DECLARATIONS                           */

/*--------------------------------------------------------------------------*/

/* SCCTL.C declarations */

extern void
 SC_DECLARE(SC_banner, (char *s)),
 SC_DECLARE(SC_pause, (byte)),
 SC_DECLARE(SC_init_path, (int nd, ...)),
 SC_DECLARE(SC_advance_name, (char *s)),
 SC_DECLARE(SC_interrupt_handler, (int sig)),
 SC_DECLARE(SC_rl_pcons, (pcons *cp, int level)),
 SC_DECLARE(SC_free_alist, (pcons *alst, int level)),
 SC_DECLARE(SC_da_reset, (SC_dynamic_array *daa, int elem)),
 SC_DECLARE(SC_da_clean, (SC_dynamic_array *daa, int elem)),
 SC_DECLARE(SC_da_release, (SC_dynamic_array *daa)),
 SC_DECLARE(SC_da_release_pointees, (SC_dynamic_array *daa, int elem)),
 SC_DECLARE(SC_da_release_all, (SC_dynamic_array *daa)),
 SC_DECLARE(SC_dada_reset, (SC_dynamic_array *dada, int elem)),
 SC_DECLARE(SC_dada_clean, (SC_dynamic_array *dada, int elem)),
 SC_DECLARE(SC_dada_release, (SC_dynamic_array *dada));

extern long
 SC_DECLARE(SC_bit_count, (long c, int n));

extern off_t
 SC_DECLARE(SC_filelen, (FILE *fp));

extern unsigned int
 SC_DECLARE(SC_alarm, (unsigned int i)),
 SC_DECLARE(SC_bit_reverse, (unsigned int i, int n));

extern int
 SC_DECLARE(_SC_query_file, (char *name, char *mode, char *type)),
 SC_DECLARE(SC_isfile, (char *name)),
 SC_DECLARE(SC_isfile_ascii, (char *name)),
 SC_DECLARE(SC_numstrp, (char *s)),
 SC_DECLARE(SC_intstrp, (char *s, int base)),
 SC_DECLARE(SC_fltstrp, (char *s)),
 SC_DECLARE(SC_chrstrp, (char *s)),
 SC_DECLARE(SC_regx_match, (char *s, char *patt)),
 SC_DECLARE(SC_char_count, (char *s, int c)),
 SC_DECLARE(SC_str_icmp, (char *s, char *t)),
 SC_DECLARE(SC_system, (char *s)),
 SC_DECLARE(SC_remove, (char *s)),
 SC_DECLARE(SC_assoc_info, (pcons *alst, ...)),
 SC_DECLARE(SC_assoc_info_alt, (pcons *alst, ...));

extern double
 SC_DECLARE(SC_cpu_time, (byte)),
 SC_DECLARE(SC_wall_clock_time, (byte));

extern char
 *SC_DECLARE(SC_date, (byte)),
 *SC_DECLARE(SC_itoa, (int n, int radix, int nc)),
 *SC_DECLARE(SC_search_file, (char **path, char *name)),
 *SC_DECLARE(_SC_search_file, (char **path, char *name, char *mode, char *type)),
 *SC_DECLARE(SC_squeeze_blanks, (char *s)),
 *SC_DECLARE(SC_str_upper, (char *s)),
 *SC_DECLARE(SC_str_lower, (char *s));

extern byte
 *SC_DECLARE(SC_assoc, (pcons *alist, char *s));

extern pcons
 *SC_DECLARE(SC_assoc_entry, (pcons *alist, char *s)),
 *SC_DECLARE(SC_make_pcons, (char *cat, int ma, byte *ca,
			     char *cdt, int md, byte *cd)),
 *SC_DECLARE(SC_mk_pcons, (char *cat, byte *ca, char *cdt, byte *cd)),
 *SC_DECLARE(SC_add_alist, (pcons *alist, char *name, char *type, byte *val)),
 *SC_DECLARE(SC_change_alist, (pcons *alist, char *name, char *type, byte *val)),
 *SC_DECLARE(SC_rem_alist, (pcons *alist, char *name)),
 *SC_DECLARE(SC_copy_alist, (pcons *alist)),
 *SC_DECLARE(SC_append_alist, (pcons *alist1, pcons *alist2));

extern PFSignal_handler
 SC_DECLARE(SC_signal, (int sig, PFSignal_handler fnc));


/* SCCTLA.C declarations */

extern byte
 *SC_DECLARE(SC_alloc_na, (long nitems, long bytepitem, char *name, int na)),
 *SC_DECLARE(SC_alloc, (long nitems, long bytepitem, char *name)),
 *SC_DECLARE(SC_realloc_na, (byte *p, long nitems, long bytepitem, int na)),
 *SC_DECLARE(SC_realloc, (byte *p, long nitems, long bytepitem)),
 *SC_DECLARE(SC_copy_item, (byte *in));

extern int
 SC_DECLARE(SC_free, (byte *p)),
 SC_DECLARE(SC_mark, (byte *p, int n)),
 SC_DECLARE(SC_set_count, (byte *p, int n)),
 SC_DECLARE(SC_ref_count, (byte *p)),
 SC_DECLARE(SC_arrtype, (byte *p, int type)),
 SC_DECLARE(SC_permanent, (byte *p)),
 SC_DECLARE(SC_mem_trace, (byte)),
 SC_DECLARE(SC_mem_map, (FILE *fp, int flag)),
 SC_DECLARE(SC_zero_space, (int flag));

extern long
 SC_DECLARE(SC_mem_monitor, (int old, int lev, char *id, char *msg)),
 SC_DECLARE(SC_mem_chk, (int typ)),
 SC_DECLARE(SC_arrlen, (byte *p));

extern void
 SC_DECLARE(SC_configure_mm, (long mxl, long mxm, long bsz, double r)),
 SC_DECLARE(SC_mem_stats, (long *al, long *fr, long *df, long *mx)),
 SC_DECLARE(SC_mem_stats_acc, (long a, long f)),
 SC_DECLARE(SC_mem_stats_set, (long a, long f));


/* SCFIA.C declarations */

extern int
 SC_DECLARE(SC_stash_pointer, (byte *p)),
 SC_DECLARE(SC_pointer_index, (byte *p)),
 SC_DECLARE(SC_free_hash_dump, (byte)),
 SC_DECLARE(SC_set_hash_dump, (HASHTAB *tab, PFInt fun)),
 SC_DECLARE(SC_free_stash, (byte));

extern char
 *SC_DECLARE(SC_get_entry, (int n));

extern byte
 *SC_DECLARE(SC_del_pointer, (int n)),
 **SC_DECLARE(SC_hash_to_list, (HASHTAB *table));


/* SCFIS.C declarations */

extern int
 SC_DECLARE(_SC_strlen, (char *s, int nx));


/* SCHASH.C declarations */

extern void
 SC_DECLARE(SC_hash_clr, (HASHTAB *tab)),
 SC_DECLARE(SC_rl_hash_table, (HASHTAB *tab));

extern byte
 *SC_DECLARE(SC_def_lookup, (char *s, HASHTAB *tab));

extern hashel
 *SC_DECLARE(SC_lookup, (char *s, HASHTAB *tab)),
 *SC_DECLARE(SC_install, (char *name, byte *obj, char *type, HASHTAB *tab)),
 *SC_DECLARE(_SC_install, (char *name, byte *obj, char *type, HASHTAB *tab, int mark, int lookup));

extern HASHTAB
 *SC_DECLARE(SC_make_hash_table, (int sz, int docflag));

extern int
 SC_DECLARE(SC_hash, (char *s, int size)),
 SC_DECLARE(SC_hash_rem, (char *name, HASHTAB *tab));

extern char
 **SC_DECLARE(SC_hash_dump, (HASHTAB *tab, char *patt)),
 **SC_DECLARE(SC_dump_hash, (HASHTAB *tab, char *patt, int sort)),
 **SC_DECLARE(_SC_dump_hash, (HASHTAB *tab, char *patt, char *type, int sort));


/* SCSTR.C declarations */

extern char
 *SC_DECLARE(SC_strsave, (char *s)),
 *SC_DECLARE(SC_strsavef, (char *s, char *name)),
 *SC_DECLARE(SC_strstr, (char *string1, char *string2)),
 *SC_DECLARE(SC_strstri, (char *string1, char *string2)),
 *SC_DECLARE(SC_strrev, (char *s)),
 *SC_DECLARE(SC_str_replace, (char *s, char *po, char *pn)),
 *SC_DECLARE(SC_firsttok, (char *s, char *delim)),
 *SC_DECLARE(_SC_pr_tok, (char *s, char *delim)),
 *SC_DECLARE(SC_lasttok, (char *s, char *delim)),
 *SC_DECLARE(_SC_quoted_tok, (char *s, char *qdelim)),
 *SC_DECLARE(SC_firsttokq, (char *s, char *delim, char *qdelim));

extern double
 SC_DECLARE(SC_stof, (char *s)),
 SC_DECLARE(_SC_atof, (char *ps)),
 SC_DECLARE(_SC_strtod, (char *nptr, char **endptr));

extern int
 SC_DECLARE(SC_blankp, (char *s, char *chr)),
 SC_DECLARE(SC_stoi, (char *s)),
 SC_DECLARE(SC_scan, (SC_lexical_stream *str, int rd));

extern long
 SC_DECLARE(_SC_otol, (char *str)),
 SC_DECLARE(_SC_htol, (char *str)),
 SC_DECLARE(SC_stol, (char *s)),
 SC_DECLARE(_SC_strtol, (char *str, char **ptr, int base));

#ifdef _LARGE_FILES
extern long long
 SC_DECLARE(SC_stoll, (char *s));
#endif

extern void
 SC_DECLARE(SC_string_sort, (char **v, int n)),
 SC_DECLARE(SC_close_lexical_stream, (SC_lexical_stream *str)),
 SC_DECLARE(SC_lex_push_token, (int type, ...));

extern SC_lexical_stream
 *SC_DECLARE(SC_open_lexical_stream,
	 (char *name, int inbfsz, int strbfsz,
	  PFInt scan, PFInt input, PFInt output,
	  PFInt unput, PFInt wrap, PFInt more, PFInt less));

extern SC_lexical_token
 *SC_DECLARE(SC_get_next_lexical_token, (SC_lexical_stream *str));


/* SCFNCA.C declarations */

extern void
 SC_DECLARE(SC_container, (char *dtype, char *stype)),
 SC_DECLARE(SC_setbuf, (FILE *fp, char *bf));

extern int
 SC_DECLARE(SC_convert,
	    (char *dtype, byte **pd, char *stype, byte *s, int n, int flag)),
 SC_DECLARE(SC_fprintf, (FILE *fp, char *fmt, ...)),
 SC_DECLARE(SC_sizeof, (char *s)),
 SC_DECLARE(SC_setvbuf, (FILE *stream, char *buf, int type, size_t size)),
 SC_DECLARE(SC_fflush, (FILE *fp));

extern double
 SC_DECLARE(SC_machine_precision, (byte));


/* SCPAR.C declarations */

extern void
 SC_DECLARE(SC_init_threads, (int np, PFVoid tid)), 
 SC_DECLARE(SC_init_tpool, (int np, PFVoid tid)),
 SC_DECLARE(SC_do_threads, (int n, int *np, void *(*fnc[])(), void **arg,
			    void **ret)),
 SC_DECLARE(SC_chunk_loop, (PFPByte fnc, int mn, int mx,
			    int serial, byte *argl)),
 SC_DECLARE(SC_chunk_split, (int *pmn, int *pmx, void **prv)),
 SC_DECLARE(SC_queue_work, (PFPVoid fnc, int serial, byte *argl));


extern int
 SC_DECLARE(SC_current_thread, (byte)),
 SC_DECLARE(SC_queue_next_item, (int ng));

#ifdef __cplusplus
}
#endif

#endif

