//genMethods "-g" "-t" "Testobj*" "-I" "LINK/userobj/Testobj.h" "-d" "userobj" "-y" "display_testobjptr" "-m" "mark_testobjptr" "-w" "free_testobjptr" 
#include <stk.h>
#include <LINK/stkWrapper/LINK_STk.h>
#include <LINK/userobj/Testobj.h>
#include <LINK/stkWrapper/Wrapper.h>
#include <LINK/stkWrapper/Register.h>
void display_testobjptr(SCM, SCM, int);
void mark_testobjptr(SCM);
void free_testobjptr(SCM);
typedef Testobj* _Testobj_;
#define _Testobj_DATA(x) ((Testobj**) (EXTDATA(x)))
#define _Testobj_IS_DATA(x) (TYPEP(x, tc_CXXwrapper) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<Testobj* >::type))
#define _Testobj_ISNT_DATA(x) (!_Testobj_IS_DATA(x))
#define _Testobj_CXX_DATA(x) (*(Testobj**) (EXTDATA(VAL(x))))
#define _Testobj_CXX_IS_DATA(x) (INSTANCEP(x) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<Testobj* >::type))
#define _Testobj_CXX_ISNT_DATA(x) (!_Testobj_CXX_IS_DATA(x))
#include<strstream.h>
void display_testobjptr(SCM c, SCM port, int mode)
{
        ostrstream oss;
        if (*_Testobj_DATA(c))
        	oss << **_Testobj_DATA(c);
        oss << ends;
        char *buffer = oss.str();
        Puts(buffer, (port));
        delete buffer;
}
void mark_testobjptr(SCM p)
{
        //cout << "mark_testobjptr" << endl;
        Register<Testobj>::markEntry(*_Testobj_DATA(p));
}
void free_testobjptr(SCM p)
{
        //cout << "free_testobjptr" << endl;
        if (!EXTSTATICP(p)) {
                delete _Testobj_DATA(p);
        }
}
static PRIMITIVE MakeTestobjCmd(SCM num)
{
        Tcl_HashEntry *p;
        SCM objptr;
        Testobj *ap, **app;
        int not_found;
        if (NINTEGERP(num))
                Err("usage:  make-testobj <integer>", NIL);
        ap = new Testobj(INTEGER(num));
        //Register<Testobj>::createEntry(ap);
        Register<Testobj>::createEntry(Wrapper<Testobj>::type, 
				       Wrapper<Testobj>::name, ap);
        app = new Testobj *(ap);
        return STk_make_CXXwrapper(Wrapper<Testobj*>::type,
                        Wrapper<Testobj*>::name, (void *) app, LINK_DYNAMIC);
}
static PRIMITIVE eqvTestobj(SCM a, SCM b)
{
  if (Wrapper<Testobj*>::compareItems(a, b) == 0)
        return Truth;
  return Ntruth;
}
static PRIMITIVE lthTestobj(SCM a, SCM b)
{
  if (Wrapper<Testobj*>::compareItems(a, b) < 0)
        return Truth;
  return Ntruth;
}
static PRIMITIVE leTestobj(SCM a, SCM b)
{
  if (Wrapper<Testobj*>::compareItems(a, b) <= 0)
        return Truth;
  return Ntruth;
}
static PRIMITIVE grTestobj(SCM a, SCM b)
{
  if (Wrapper<Testobj*>::compareItems(a, b) > 0)
        return Truth;
  return Ntruth;
}
static PRIMITIVE geTestobj(SCM a, SCM b)
{
  if (Wrapper<Testobj*>::compareItems(a, b) >= 0)
        return Truth;
  return Ntruth;
}
static PRIMITIVE GetTestobjSize(SCM a)
{
  SCM z;
  struct stat *info;
  if (_Testobj_CXX_ISNT_DATA(a))
    Err("testobj-size: bad structure ", a);
  NEWCELL(z, tc_integer);
  SET_INTEGER(z, _Testobj_CXX_DATA(a)->current_size);
  return z;
}
static SCM TestobjpCmd(SCM ctr)
{
        return _Testobj_CXX_IS_DATA(ctr) ? Truth : Ntruth;
}
// define methods above, register below
void genExtra_Testobj_Methods() 
{
        STk_add_new_cpp_primitive("make-testobj", tc_subr_1,
                                        (PRIMITIVE (*)(...))MakeTestobjCmd);
        STk_add_new_cpp_primitive("testobj-eqv?", tc_subr_2,
                                        (PRIMITIVE (*)(...))eqvTestobj);
        STk_add_new_cpp_primitive("testobj-<", tc_subr_2,
                                        (PRIMITIVE (*)(...))lthTestobj);
        STk_add_new_cpp_primitive("testobj-<=", tc_subr_2,
                                        (PRIMITIVE (*)(...))leTestobj);
        STk_add_new_cpp_primitive("testobj->", tc_subr_2,
                                        (PRIMITIVE (*)(...))grTestobj);
        STk_add_new_cpp_primitive("testobj->=", tc_subr_2,
                                        (PRIMITIVE (*)(...))geTestobj);
        STk_add_new_cpp_primitive("testobj?", tc_subr_1,
                                        (PRIMITIVE (*)(...))TestobjpCmd);
        STk_add_new_cpp_primitive("size-testobj", tc_subr_1,
                                        (PRIMITIVE (*)(...))GetTestobjSize);
        addTwoArgMethod("eqv?", Wrapper<Testobj*>::name,
                        Wrapper<Testobj*>::name, "testobj-eqv?", LINK_OVL);
        addBooleanMethod("<",
                        Wrapper<Testobj*>::name, "testobj-<", LINK_OVL);
        addBooleanMethod("<=",
                        Wrapper<Testobj*>::name, "testobj-<=", LINK_OVL);
        addBooleanMethod(">",
                        Wrapper<Testobj*>::name, "testobj->", LINK_OVL);
        addBooleanMethod(">=",
                        Wrapper<Testobj*>::name, "testobj->=", LINK_OVL);
}
