// $Id: bruby.cpp,v 1.11 2003/03/06 03:39:00 yuya Exp $

#include "BRbBase.h"
#include "BRb.h"

////////////////////////////////////////////////////////////////////////////////

#ifdef BRB_WRITER
static VALUE rb_brb_s_dump(int argc, VALUE *argv, VALUE obj);
static VALUE rb_brb_s_dumpfile(VALUE obj, VALUE filename);
//static VALUE rb_brb_s_dumpproc(VALUE obj, VALUE proc);
#endif
#ifdef BRB_READER
static VALUE rb_brb_s_load(int argc, VALUE *argv, VALUE obj);
static VALUE rb_brb_s_loadfile(VALUE obj, VALUE filename);
//static VALUE rb_brb_s_loadproc(VALUE obj, VALUE code);
#endif
#if defined(BRB_WRITER) && defined(BRB_READER)
static VALUE rb_brb_s_verify(VALUE obj, VALUE source, VALUE filename);
static VALUE rb_brb_s_verifyfile(VALUE obj, VALUE filename);
#endif
static VALUE rb_brb_s_debug_get(VALUE obj);
static VALUE rb_brb_s_debug_set(VALUE obj, VALUE debug);

extern "C" void Init_bruby();

////////////////////////////////////////////////////////////////////////////////

VALUE rb_mBRb          = 0;
VALUE rb_eBRbException = 0;

static bool g_debug = false;

////////////////////////////////////////////////////////////////////////////////

#ifdef BRB_WRITER

static VALUE
rb_brb_s_dump(int argc, VALUE *argv, VALUE obj)
{
	VALUE source, filename;
	if ( ::rb_scan_args(argc, argv, "11", &source, &filename) == 1 ) {
		filename = ::rb_str_new2("(bruby)");
	}

	Check_Type(source,   T_STRING);
	Check_Type(filename, T_STRING);

	return BRb::dumpcode(source, filename, g_debug, rb_eBRbException);
}

static VALUE
rb_brb_s_dumpfile(VALUE obj, VALUE filename)
{
	Check_Type(filename, T_STRING);
	return BRb::dumpfile(filename, g_debug, rb_eBRbException);
}

/*
static VALUE
rb_brb_s_dumpproc(VALUE obj, VALUE proc)
{
	Check_Type(proc, T_DATA);

	struct BLOCK *data;
	Data_Get_Struct(proc, struct BLOCK, data);

	return Qnil;
}
*/

#endif

#ifdef BRB_READER

static VALUE
rb_brb_s_load(int argc, VALUE *argv, VALUE obj)
{
	VALUE code, filename;
	if ( ::rb_scan_args(argc, argv, "11", &code, &filename) == 1 ) {
		filename = ::rb_str_new2("(bruby)");
	}

	Check_Type(code, T_STRING);
	Check_Type(filename, T_STRING);

	return BRb::loadcode(code, filename, g_debug, rb_eBRbException);
}

static VALUE
rb_brb_s_loadfile(VALUE obj, VALUE filename)
{
	Check_Type(filename, T_STRING);
	return BRb::loadfile(filename, g_debug, rb_eBRbException);
}

/*
static VALUE
rb_brb_s_loadproc(VALUE obj, VALUE code)
{
	return Qnil;
}
*/

#endif

#if defined(BRB_WRITER) && defined(BRB_READER)

static VALUE
rb_brb_s_verify(VALUE obj, VALUE source, VALUE filename)
{
	Check_Type(source,   T_STRING);
	Check_Type(filename, T_STRING);
	return (BRb::verifycode(source, filename, g_debug, rb_eBRbException) ? Qtrue : Qfalse);
}

static VALUE
rb_brb_s_verifyfile(VALUE obj, VALUE filename)
{
	Check_Type(filename, T_STRING);
	return (BRb::verifyfile(filename, g_debug, rb_eBRbException) ? Qtrue : Qfalse);
}

#endif

static VALUE
rb_brb_s_debug_get(VALUE obj)
{
	return (g_debug ? Qtrue : Qfalse);
}

static VALUE
rb_brb_s_debug_set(VALUE obj, VALUE debug)
{
	g_debug = (RTEST(debug) ? true : false);
	return debug;
}

////////////////////////////////////////////////////////////////////////////////

extern "C" void
Init_bruby()
{
	rb_mBRb = ::rb_define_module("BRb");
	::rb_define_const(rb_mBRb, "VERSION", ::rb_str_new2(BRB_VERSION));
#ifdef BRB_WRITER
	::rb_define_singleton_method(rb_mBRb, "dump",       (VALUE(*)(...))rb_brb_s_dump,       -1);
	::rb_define_singleton_method(rb_mBRb, "dumpfile",   (VALUE(*)(...))rb_brb_s_dumpfile,   1);
//	::rb_define_singleton_method(rb_mBRb, "dumpproc",   (VALUE(*)(...))rb_brb_s_dumpproc,   1);
#endif
#ifdef BRB_READER
	::rb_define_singleton_method(rb_mBRb, "load",       (VALUE(*)(...))rb_brb_s_load,       -1);
	::rb_define_singleton_method(rb_mBRb, "loadfile",   (VALUE(*)(...))rb_brb_s_loadfile,   1);
//	::rb_define_singleton_method(rb_mBRb, "loadproc",   (VALUE(*)(...))rb_brb_s_loadproc,   1);
#endif
#if defined(BRB_WRITER) && defined(BRB_READER)
	::rb_define_singleton_method(rb_mBRb, "verify",     (VALUE(*)(...))rb_brb_s_verify,     2);
	::rb_define_singleton_method(rb_mBRb, "verifyfile", (VALUE(*)(...))rb_brb_s_verifyfile, 1);
#endif
	::rb_define_singleton_method(rb_mBRb, "debug",      (VALUE(*)(...))rb_brb_s_debug_get,  0);
	::rb_define_singleton_method(rb_mBRb, "debug=",     (VALUE(*)(...))rb_brb_s_debug_set,  1);

	rb_eBRbException = ::rb_define_class("BRbException", rb_eException);
}

////////////////////////////////////////////////////////////////////////////////
