/*
 * Copyright (C) 1999 Stanley J. Brooks
 */

/*
 * from slang-1.3.8.  Many header declarations are copied from J.E.D.'s
 * _slang.h file, since we need some of the hidden intrinsics in order
 * to deal with:
 *   (1) Char_Type arrays
 *   (2) reference types
 *   (3) SLang_Object_Type
 *
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>

#include <slang.h>

/* we need stripped-down version of SLang_Object_Type for cookies: */
typedef	struct {
	unsigned char data_type;	       /* SLANG_INT_TYPE, ... */
	union {
		void * p_val;
		double f_val;
	}v;
}
SLang_Object_Type;

#if 0
typedef struct _SLang_Name_Type
{
   char *name;
   struct _SLang_Name_Type *next;
   char name_type;
   /* These values must be less than 0x10 because they map directly
    * to byte codes.  See _slang.h.
    */
#define SLANG_LVARIABLE		0x01
#define SLANG_GVARIABLE 	0x02
#define SLANG_IVARIABLE 	0x03           /* intrinsic variables */
   /* Note!!! For Macro MAKE_VARIABLE below to work, SLANG_IVARIABLE Must
    be 1 less than SLANG_RVARIABLE!!! */
#define SLANG_RVARIABLE		0x04	       /* read only variable */
#define SLANG_INTRINSIC 	0x05
#define SLANG_FUNCTION  	0x06
#define SLANG_MATH_UNARY  	0x07
#define SLANG_APP_UNARY  	0x08
#define SLANG_ICONSTANT		0x09
#define SLANG_DCONSTANT		0x0A
#define SLANG_PVARIABLE		0x0B   /* private */
#define SLANG_PFUNCTION		0x0C   /* private */

   /* Rest of fields depend on name type */
}
SLang_Name_Type;
#endif

typedef struct
{
  char *name;
  SLang_Name_Type *next;
  char name_type;

  SLang_Object_Type obj;
}
SLang_Global_Var_Type;

/*
 * some extra internals we need, ripped out of _slang.h
 */

/* From: _slang.h */
struct _SLong_Ref_Type
{
   int is_global;
   union
   {
     SLang_Name_Type *nt;
     SLang_Object_Type *local_obj;
   }
   v;
};


extern int SLang_pop(SLang_Object_Type *);
extern void SLang_free_object (SLang_Object_Type *);
#if 0
extern int SLang_push(SLang_Object_Type *); /* doesn't handle ref-cts, etc */
#endif
extern int _SLpush_slang_obj (SLang_Object_Type *);

extern int _SLang_deref_assign (SLang_Ref_Type *);
extern int _SLstack_depth(void);

/* End: _slang.h */
extern SLang_Name_Type *_SLlocate_global_name (char *name);

static void cheats_info(char *s)
{
	SLang_Global_Var_Type *gt;
	
	gt = (SLang_Global_Var_Type *) _SLlocate_global_name (s);
	if (gt) {
		SLang_vmessage("%s %p vs %p",s,s,gt->name);
		SLang_vmessage("%s %p %.2x",s,gt,gt->name_type);
		SLang_vmessage("datatype=%.2x p=%p",(gt->obj).data_type, (gt->obj).v.p_val);
	}
	return;
}

/*
static void ref_info(char *s)
{
	SLang_Ref_Type *ref;
	
	if (-1 != SLang_pop_ref(&ref)) {
		SLang_vmessage("%s nt=%p obj=%p",s,ref->nt,ref->);
	}
	if (ref) SLang_free_ref(ref);
	return;
}
*/


#define I SLANG_INT_TYPE
#define S SLANG_STRING_TYPE
#define V SLANG_VOID_TYPE
static SLang_Intrin_Fun_Type Cheats_Fun_Table[] =
{
	MAKE_INTRINSIC_S("cheats_info", cheats_info, V),
# if 0
	MAKE_INTRINSIC_S("ref_info", ref_info, V),
	MAKE_INTRINSIC_S("getservbyname", VF_getservbyname, I),
	MAKE_INTRINSIC_S("inet_addr", VF_inet_addr, I),
	MAKE_INTRINSIC_I("inet_ntoa", VF_inet_ntoa, S),
	MAKE_INTRINSIC_S("gethostbyname", VF_gethostbyname, I),
	MAKE_INTRINSIC_I("gethostbyaddr", VF_gethostbyaddr, S),

	MAKE_INTRINSIC_0("array_get_string", ar_get_string, V),
	MAKE_INTRINSIC_0("array_get_u32", ar_get_u32, I),
	MAKE_INTRINSIC_0("array_put_u32", ar_put_u32, V),
# endif
	SLANG_END_TABLE
};
static int VFerrno = 13;

static SLang_Intrin_Var_Type Cheats_Var_Table[] =
{
	MAKE_VARIABLE("vf_errno", &VFerrno, I, 1),
#	if 0
	MAKE_VARIABLE("vf_errmsg", &VFerrmsg, S, 1),
# endif
	SLANG_END_TABLE
};
#undef I
#undef S
#undef V


int init_cheats_module(void) __attribute__((unused));
int init_cheats_module(void)
{
	if (SLdefine_for_ifdef("CHEATS")) {
		fprintf(stderr,"cheats: fail define_for_isdef(CHEATS)\n");
		return -1;
	}
	if (SLadd_intrin_fun_table(Cheats_Fun_Table, "_CHEATS") ||
			SLadd_intrin_var_table(Cheats_Var_Table, NULL))
		return -1;

	return 1;
}


syntax highlighted by Code2HTML, v. 0.9.1