[seed] Importer supports native modules



commit 85a1bf4bddd2ca04c18b885cea3b9d9d1e379d66
Author: Robert Carr <racarr mireia (none)>
Date:   Sun Apr 12 09:27:28 2009 -0400

    Importer supports native modules
---
 libseed/seed-engine.c            |    5 +-
 libseed/seed-engine.h            |    2 +-
 libseed/seed-importer.c          |   60 ++++++++
 libseed/seed.h                   |    2 +-
 modules/Multiprocessing/multi.c  |  253 +++++++++++++++++-----------------
 modules/canvas/seed-canvas.c     |    8 +-
 modules/example/example.c        |    6 +-
 modules/readline/seed-readline.c |  208 ++++++++++++++--------------
 modules/sqlite/seed-sqlite.c     |  278 +++++++++++++++++++-------------------
 9 files changed, 442 insertions(+), 380 deletions(-)

diff --git a/libseed/seed-engine.c b/libseed/seed-engine.c
index a7e5cf7..328732d 100644
--- a/libseed/seed-engine.c
+++ b/libseed/seed-engine.c
@@ -909,11 +909,14 @@ seed_gi_import_namespace (JSContextRef ctx,
   extension = seed_try_load_extension (namespace);
   if (extension)
     {
+      JSObjectRef module_object;
       SeedModuleInitCallback init;
 
       g_module_symbol (extension, "seed_module_init", (gpointer *) & init);
 
-      (*init) (eng);
+      module_object = (*init) (eng);
+      
+      seed_object_set_property (ctx, eng->global, namespace, module_object);
 
       g_free (namespace);
       return JSValueMakeNull (ctx);
diff --git a/libseed/seed-engine.h b/libseed/seed-engine.h
index ed10ece..5dae7c7 100644
--- a/libseed/seed-engine.h
+++ b/libseed/seed-engine.h
@@ -57,6 +57,6 @@ void seed_create_function (JSContextRef ctx, gchar * name,
 
 void seed_repl_expose (JSContextRef ctx, ...);
 
-typedef void (*SeedModuleInitCallback) (SeedEngine * eng);
+typedef JSObjectRef (*SeedModuleInitCallback) (SeedEngine * eng);
 
 #endif
diff --git a/libseed/seed-importer.c b/libseed/seed-importer.c
index 7aafcef..584446d 100644
--- a/libseed/seed-importer.c
+++ b/libseed/seed-importer.c
@@ -408,6 +408,48 @@ seed_importer_get_search_path (JSContextRef ctx,
 }
 
 static JSObjectRef
+seed_importer_handle_native_module (JSContextRef ctx,
+				    const gchar *dir,
+				    const gchar *file,
+				    JSValueRef *exception)
+
+{
+  GModule *module;
+  JSObjectRef module_obj;
+  SeedModuleInitCallback init;
+  gchar *file_path = g_strconcat (dir, "/", file, NULL);
+
+  if (module_obj = g_hash_table_lookup (file_imports, file_path))
+    {
+      g_free (file_path);
+      return module_obj;
+    }
+  
+  module = g_module_open (file_path, G_MODULE_BIND_LAZY);
+  
+  if (!module)
+    {
+      gchar *mes = g_strdup_printf ("Error loading native module at %s: %s",
+				    file_path,
+				    g_module_error());
+      // Could be a better exception
+      seed_make_exception (ctx, exception, "ModuleError",
+			   mes);
+      g_free (file_path);
+      g_free (mes);
+      
+      return NULL;
+    }
+  g_module_symbol (module, "seed_module_init", (gpointer *) &init);
+  module_obj = (*init) (eng);
+  g_hash_table_insert (file_imports, file_path, module_obj);
+  
+  g_free (file_path);
+      
+  return module_obj;
+}
+
+static JSObjectRef
 seed_importer_handle_file (JSContextRef ctx,
 			   const gchar *dir,
 			   const gchar *file,
@@ -471,6 +513,7 @@ seed_importer_search (JSContextRef ctx,
 		      JSValueRef *exception)
 {
   GSList *path, *walk;
+  gchar *prop_as_lib = g_strconcat ("lib", prop, NULL);
   
   path = seed_importer_get_search_path (ctx, exception);
   
@@ -486,6 +529,8 @@ seed_importer_search (JSContextRef ctx,
 	{
 	  seed_make_exception_from_gerror (ctx, exception, e);
 	  g_error_free (e);
+	  g_free (prop_as_lib);
+	  seed_importer_free_search_path (path);
 	  
 	  return NULL;
 	}
@@ -493,6 +538,7 @@ seed_importer_search (JSContextRef ctx,
 	{
 	  guint i;
 	  gchar *mentry = g_strdup (entry);
+
 	  for (i = 0; i < strlen (mentry); i++)
 	    {
 	      if (mentry[i] == '.')
@@ -506,6 +552,19 @@ seed_importer_search (JSContextRef ctx,
 
 	      g_dir_close (dir);
 	      g_free (mentry);
+	      g_free (prop_as_lib);
+	      seed_importer_free_search_path (path);
+
+	      return ret;
+	    }
+	  else if (g_str_has_prefix (mentry, prop_as_lib) && g_str_has_suffix (entry, G_MODULE_SUFFIX))
+	    {
+	      JSObjectRef ret;
+	      
+	      ret = seed_importer_handle_native_module (ctx, walk->data, entry, exception);
+	      g_dir_close (dir);
+	      g_free (mentry);
+	      g_free (prop_as_lib);
 	      seed_importer_free_search_path (path);
 
 	      return ret;
@@ -519,6 +578,7 @@ seed_importer_search (JSContextRef ctx,
     }
   
   seed_importer_free_search_path (path);
+  g_free (prop_as_lib);
   return NULL;
 }
 
diff --git a/libseed/seed.h b/libseed/seed.h
index 40521f2..cdff2a9 100644
--- a/libseed/seed.h
+++ b/libseed/seed.h
@@ -237,7 +237,7 @@ void seed_create_function (SeedContext ctx,
 			   gchar * name, SeedFunctionCallback callback,
 			   SeedObject object);
 
-typedef void (*SeedModuleInitCallback) (SeedEngine * eng);
+typedef SeedObject (*SeedModuleInitCallback) (SeedEngine * eng);
 
 typedef void (*SeedObjectInitializeCallback) (SeedContext ctx,
 					      SeedObject object);
diff --git a/modules/Multiprocessing/multi.c b/modules/Multiprocessing/multi.c
index 12d3d90..5585ee5 100644
--- a/modules/Multiprocessing/multi.c
+++ b/modules/Multiprocessing/multi.c
@@ -7,182 +7,181 @@ SeedObject namespace_ref;
 SeedClass pipe_class;
 
 typedef struct _pipe_priv {
-	GIOChannel *read;
-	GIOChannel *write;
+  GIOChannel *read;
+  GIOChannel *write;
 } pipe_priv;
 
 void pipe_finalize(SeedObject pipeobj)
 {
-	pipe_priv *priv = seed_object_get_private(pipeobj);
-	g_io_channel_unref(priv->read);
-	g_io_channel_unref(priv->write);
-	g_free(priv);
+  pipe_priv *priv = seed_object_get_private(pipeobj);
+  g_io_channel_unref(priv->read);
+  g_io_channel_unref(priv->write);
+  g_free(priv);
 }
 
 SeedObject seed_construct_pipe(SeedContext ctx,
-							   SeedObject constructor,
-							   size_t argument_count,
-							   const SeedValue arguments[],
-							   SeedException * exception)
+			       SeedObject constructor,
+			       size_t argument_count,
+			       const SeedValue arguments[],
+			       SeedException * exception)
 {
-	GIOChannel *oner, *onew, twor, twow;
-	SeedObject jsone, jstwo, jsret;
-	int fd1[2], fd2[2];
-	pipe_priv *priv_one, *priv_two;
-
-	if (pipe(fd1) < 0)
-	{
-		perror("Pipe failed. Make me a javascript exception");
-		return seed_make_null(ctx);
-	}
-	if (pipe(fd2) < 0)
-	{
-		perror("Pipe failed. Make me a javascript exception");
-		return seed_make_null(ctx);
-	}
-
-	priv_one = g_new0(pipe_priv, 1);
-	priv_two = g_new0(pipe_priv, 1);
-
-	priv_one->read = g_io_channel_unix_new(fd1[0]);
-	priv_one->write = g_io_channel_unix_new(fd2[1]);
-	priv_two->read = g_io_channel_unix_new(fd2[0]);
-	priv_two->write = g_io_channel_unix_new(fd1[1]);
-
-	g_io_channel_set_close_on_unref(priv_one->read, TRUE);
-	g_io_channel_set_close_on_unref(priv_one->write, TRUE);
-	g_io_channel_set_close_on_unref(priv_two->read, TRUE);
-	g_io_channel_set_close_on_unref(priv_two->write, TRUE);
-
-	jsret = seed_make_object(ctx, 0, 0);
-	jsone = seed_make_object(ctx, pipe_class, priv_one);
-	jstwo = seed_make_object(ctx, pipe_class, priv_two);
-
-	seed_object_set_property_at_index(ctx, jsret, 0, jsone, exception);
-	seed_object_set_property_at_index(ctx, jsret, 1, jstwo, exception);
-
-	return jsret;
+  GIOChannel *oner, *onew, twor, twow;
+  SeedObject jsone, jstwo, jsret;
+  int fd1[2], fd2[2];
+  pipe_priv *priv_one, *priv_two;
+
+  if (pipe(fd1) < 0)
+    {
+      perror("Pipe failed. Make me a javascript exception");
+      return seed_make_null(ctx);
+    }
+  if (pipe(fd2) < 0)
+    {
+      perror("Pipe failed. Make me a javascript exception");
+      return seed_make_null(ctx);
+    }
+
+  priv_one = g_new0(pipe_priv, 1);
+  priv_two = g_new0(pipe_priv, 1);
+
+  priv_one->read = g_io_channel_unix_new(fd1[0]);
+  priv_one->write = g_io_channel_unix_new(fd2[1]);
+  priv_two->read = g_io_channel_unix_new(fd2[0]);
+  priv_two->write = g_io_channel_unix_new(fd1[1]);
+
+  g_io_channel_set_close_on_unref(priv_one->read, TRUE);
+  g_io_channel_set_close_on_unref(priv_one->write, TRUE);
+  g_io_channel_set_close_on_unref(priv_two->read, TRUE);
+  g_io_channel_set_close_on_unref(priv_two->write, TRUE);
+
+  jsret = seed_make_object(ctx, 0, 0);
+  jsone = seed_make_object(ctx, pipe_class, priv_one);
+  jstwo = seed_make_object(ctx, pipe_class, priv_two);
+
+  seed_object_set_property_at_index(ctx, jsret, 0, jsone, exception);
+  seed_object_set_property_at_index(ctx, jsret, 1, jstwo, exception);
+
+  return jsret;
 }
 
-#define GET_CHANNEL pipe_priv * priv =  \
-		seed_object_get_private(this_object)
+#define GET_CHANNEL pipe_priv * priv =		\
+    seed_object_get_private(this_object)
 
 SeedValue seed_pipe_read(SeedContext ctx,
-						 SeedObject function,
-						 SeedObject this_object,
-						 size_t argument_count,
-						 const SeedValue arguments[], SeedException * exception)
+			 SeedObject function,
+			 SeedObject this_object,
+			 size_t argument_count,
+			 const SeedValue arguments[], SeedException * exception)
 {
-	SeedValue ret;
-	gchar *read;
-	GET_CHANNEL;
+  SeedValue ret;
+  gchar *read;
+  GET_CHANNEL;
 
-	g_io_channel_read_line(priv->read, &read, 0, 0, 0);
-	ret = seed_value_from_string(ctx, read, exception);
-	g_free(read);
+  g_io_channel_read_line(priv->read, &read, 0, 0, 0);
+  ret = seed_value_from_string(ctx, read, exception);
+  g_free(read);
 
-	return ret;
+  return ret;
 }
 
 typedef struct _marshal_privates {
-	SeedObject function;
-	SeedObject source;
-	SeedValue user_data;
+  SeedObject function;
+  SeedObject source;
+  SeedValue user_data;
 } marshal_privates;
 
 static gboolean gio_marshal_func(GIOChannel * source,
-								 GIOCondition condition, gpointer data)
+				 GIOCondition condition, gpointer data)
 {
-	SeedGlobalContext ctx = seed_context_create(eng->group, 0);
-	SeedValue jscondition = seed_value_from_long(ctx, (glong) condition, 0);
-	SeedValue args[3], ret;
-	marshal_privates *priv = (marshal_privates *) data;
-	gboolean bret;
+  SeedGlobalContext ctx = seed_context_create(eng->group, 0);
+  SeedValue jscondition = seed_value_from_long(ctx, (glong) condition, 0);
+  SeedValue args[3], ret;
+  marshal_privates *priv = (marshal_privates *) data;
+  gboolean bret;
 
-	args[0] = priv->source;
-	args[1] = jscondition;
-	args[2] = priv->user_data;
+  args[0] = priv->source;
+  args[1] = jscondition;
+  args[2] = priv->user_data;
 
-	ret = seed_object_call(ctx, priv->function, 0, 3, args, 0);
+  ret = seed_object_call(ctx, priv->function, 0, 3, args, 0);
 
-	bret = seed_value_to_boolean(ctx, ret, 0);
-	seed_context_unref(ctx);
+  bret = seed_value_to_boolean(ctx, ret, 0);
+  seed_context_unref(ctx);
 
-	if (!bret)
-		g_free(priv);
+  if (!bret)
+    g_free(priv);
 
-	return bret;
+  return bret;
 }
 
 SeedValue seed_pipe_write(SeedContext ctx,
-						  SeedObject function,
-						  SeedObject this_object,
-						  size_t argument_count,
-						  const SeedValue arguments[],
-						  SeedException * exception)
+			  SeedObject function,
+			  SeedObject this_object,
+			  size_t argument_count,
+			  const SeedValue arguments[],
+			  SeedException * exception)
 {
-	gchar *data;
-	gsize written;
-	gchar eol = '\n';
-	GET_CHANNEL;
+  gchar *data;
+  gsize written;
+  gchar eol = '\n';
+  GET_CHANNEL;
 
-	data = seed_value_to_string(ctx, arguments[0], exception);
-	g_io_channel_write_chars(priv->write, data, -1, &written, 0);
-	g_io_channel_write_chars(priv->write, &eol, 1, 0, 0);
-	g_io_channel_flush(priv->write, 0);
+  data = seed_value_to_string(ctx, arguments[0], exception);
+  g_io_channel_write_chars(priv->write, data, -1, &written, 0);
+  g_io_channel_write_chars(priv->write, &eol, 1, 0, 0);
+  g_io_channel_flush(priv->write, 0);
 
-	return seed_value_from_int(ctx, written, exception);
+  return seed_value_from_int(ctx, written, exception);
 }
 
 SeedValue seed_pipe_add_watch(SeedContext ctx,
-							  SeedObject function,
-							  SeedObject this_object,
-							  size_t argument_count,
-							  const SeedValue arguments[],
-							  SeedException * exception)
+			      SeedObject function,
+			      SeedObject this_object,
+			      size_t argument_count,
+			      const SeedValue arguments[],
+			      SeedException * exception)
 {
-	GET_CHANNEL;
-	marshal_privates *mpriv = g_malloc0(sizeof(marshal_privates));
-	glong condition = seed_value_to_long(ctx, arguments[0], exception);
+  GET_CHANNEL;
+  marshal_privates *mpriv = g_malloc0(sizeof(marshal_privates));
+  glong condition = seed_value_to_long(ctx, arguments[0], exception);
 
-	mpriv->function = arguments[1];
-	mpriv->source = this_object;
-	mpriv->user_data = argument_count == 3 ? arguments[2] : seed_make_null(ctx);
+  mpriv->function = arguments[1];
+  mpriv->source = this_object;
+  mpriv->user_data = argument_count == 3 ? arguments[2] : seed_make_null(ctx);
 
-	g_io_add_watch(priv->read, condition, gio_marshal_func, mpriv);
+  g_io_add_watch(priv->read, condition, gio_marshal_func, mpriv);
 
-	return seed_value_from_boolean(ctx, TRUE, exception);
+  return seed_value_from_boolean(ctx, TRUE, exception);
 }
 
 seed_static_function pipe_funcs[] = {
-	{"read", seed_pipe_read, 0}
-	,
-	{"write", seed_pipe_write, 0}
-	,
-	{"add_watch", seed_pipe_add_watch, 0}
+  {"read", seed_pipe_read, 0}
+  ,
+  {"write", seed_pipe_write, 0}
+  ,
+  {"add_watch", seed_pipe_add_watch, 0}
 };
 
-void seed_module_init(SeedEngine * local_eng)
+SeedObject
+seed_module_init(SeedEngine * local_eng)
 {
-	SeedObject pipe_constructor;
-	seed_class_definition pipe_class_def = seed_empty_class;
-	eng = local_eng;
+  SeedObject pipe_constructor;
+  seed_class_definition pipe_class_def = seed_empty_class;
+  eng = local_eng;
 
-	namespace_ref = seed_make_object(eng->context, 0, 0);
+  namespace_ref = seed_make_object(eng->context, 0, 0);
 
-	pipe_class_def.class_name = "Pipe";
-	pipe_class_def.static_functions = pipe_funcs;
-	pipe_class_def.finalize = pipe_finalize;
+  pipe_class_def.class_name = "Pipe";
+  pipe_class_def.static_functions = pipe_funcs;
+  pipe_class_def.finalize = pipe_finalize;
 
-	pipe_class = seed_create_class(&pipe_class_def);
+  pipe_class = seed_create_class(&pipe_class_def);
 
-	seed_object_set_property(eng->context,
-							 eng->global, "Multiprocessing", namespace_ref);
-
-	pipe_constructor = seed_make_constructor(eng->context,
-											 0, seed_construct_pipe);
-
-	seed_object_set_property(eng->context,
-							 namespace_ref, "Pipe", pipe_constructor);
+  pipe_constructor = seed_make_constructor(eng->context,
+					   0, seed_construct_pipe);
 
+  seed_object_set_property(eng->context,
+			   namespace_ref, "Pipe", pipe_constructor);
+  
+  return namespace_ref;
 }
diff --git a/modules/canvas/seed-canvas.c b/modules/canvas/seed-canvas.c
index c9d9de4..f6d82b4 100644
--- a/modules/canvas/seed-canvas.c
+++ b/modules/canvas/seed-canvas.c
@@ -962,7 +962,7 @@ seed_static_value canvas_properties[] = {
   {0, 0, 0, 0}
 };
 
-void
+SeedObject
 seed_module_init (SeedEngine * local_eng)
 {
   SeedObject canvas_constructor, pdf_constructor,
@@ -973,9 +973,6 @@ seed_module_init (SeedEngine * local_eng)
 
   namespace_ref = seed_make_object (eng->context, 0, 0);
 
-  seed_object_set_property (eng->context, eng->global, "Canvas",
-			    namespace_ref);
-
   canvas_class_def.class_name = "CairoCanvas";
   canvas_class_def.static_functions = canvas_funcs;
   canvas_class_def.finalize = canvas_finalize;
@@ -1007,5 +1004,6 @@ seed_module_init (SeedEngine * local_eng)
 			    svg_constructor);
   seed_object_set_property (eng->context, namespace_ref, "ImageCanvas",
 			    svg_constructor);
-
+  
+  return namespace_ref;
 }
diff --git a/modules/example/example.c b/modules/example/example.c
index 0888f34..97c2d36 100644
--- a/modules/example/example.c
+++ b/modules/example/example.c
@@ -1,6 +1,8 @@
 #include <seed.h>
 
-void seed_module_init(SeedEngine * eng)
+SeedObject
+seed_module_init(SeedEngine * eng)
 {
-	g_printf("Hello Seed Module World \n");
+  g_printf("Hello Seed Module World \n");
+  return seed_make_object (eng->context, NULL, NULL);
 }
diff --git a/modules/readline/seed-readline.c b/modules/readline/seed-readline.c
index d8f9daf..884e956 100644
--- a/modules/readline/seed-readline.c
+++ b/modules/readline/seed-readline.c
@@ -12,138 +12,138 @@ gboolean readline_has_initialized = FALSE;
 static void
 seed_handle_rl_closure(ffi_cif * cif, void *result, void **args, void *userdata)
 {
-	SeedContext ctx = seed_context_create(eng->group, NULL);
-	SeedValue exception = 0;
-	SeedObject function = (SeedObject) userdata;
-
-	seed_object_call(ctx, function, 0, 0, 0, &exception);
-	if (exception)
-	{
-		gchar *mes = seed_exception_to_string(ctx,
-											  exception);
-		g_warning("Exception in readline bind key closure. %s \n", mes, 0);
-	}
-	seed_context_unref((SeedContext) ctx);
+  SeedContext ctx = seed_context_create(eng->group, NULL);
+  SeedValue exception = 0;
+  SeedObject function = (SeedObject) userdata;
+
+  seed_object_call(ctx, function, 0, 0, 0, &exception);
+  if (exception)
+    {
+      gchar *mes = seed_exception_to_string(ctx,
+					    exception);
+      g_warning("Exception in readline bind key closure. %s \n", mes, 0);
+    }
+  seed_context_unref((SeedContext) ctx);
 }
 
 // "Leaky" in that it exists for lifetime of program,
 // kind of unavoidable though.
 static ffi_closure *seed_make_rl_closure(SeedObject function)
 {
-	ffi_cif *cif;
-	ffi_closure *closure;
-	ffi_arg result;
-	ffi_status status;
-
-	cif = g_new0(ffi_cif, 1);
-	closure = mmap(0, sizeof(ffi_closure), PROT_READ | PROT_WRITE |
-				   PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
-	ffi_prep_cif(cif, FFI_DEFAULT_ABI, 0, &ffi_type_sint, 0);
-	ffi_prep_closure(closure, cif, seed_handle_rl_closure, function);
-
-	return closure;
+  ffi_cif *cif;
+  ffi_closure *closure;
+  ffi_arg result;
+  ffi_status status;
+
+  cif = g_new0(ffi_cif, 1);
+  closure = mmap(0, sizeof(ffi_closure), PROT_READ | PROT_WRITE |
+		 PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
+  ffi_prep_cif(cif, FFI_DEFAULT_ABI, 0, &ffi_type_sint, 0);
+  ffi_prep_closure(closure, cif, seed_handle_rl_closure, function);
+
+  return closure;
 }
 
 static SeedValue
 seed_readline_bind(SeedContext ctx,
-				   SeedObject function,
-				   SeedObject this_object,
-				   size_t argumentCount,
-				   const SeedValue arguments[], SeedValue * exception)
+		   SeedObject function,
+		   SeedObject this_object,
+		   size_t argumentCount,
+		   const SeedValue arguments[], SeedValue * exception)
 {
-	gchar *key;
-	ffi_closure *c;
+  gchar *key;
+  ffi_closure *c;
 
-	if (argumentCount != 2)
-	{
-		gchar *mes =
-			g_strdup_printf("Seed.readline_bind expected 2 arguments, "
-							"got %Zd", argumentCount);
-		seed_make_exception(ctx, exception, "ArgumentError", mes);
-		g_free(mes);
-		return seed_make_null(ctx);
-	}
+  if (argumentCount != 2)
+    {
+      gchar *mes =
+	g_strdup_printf("Seed.readline_bind expected 2 arguments, "
+			"got %Zd", argumentCount);
+      seed_make_exception(ctx, exception, "ArgumentError", mes);
+      g_free(mes);
+      return seed_make_null(ctx);
+    }
 
-	key = seed_value_to_string(ctx, arguments[0], exception);
-	c = seed_make_rl_closure((SeedObject) arguments[1]);
+  key = seed_value_to_string(ctx, arguments[0], exception);
+  c = seed_make_rl_closure((SeedObject) arguments[1]);
 
-	rl_bind_key(*key, (Function *) c);
+  rl_bind_key(*key, (Function *) c);
 
-	g_free(key);
+  g_free(key);
 
-	return seed_make_null(ctx);
+  return seed_make_null(ctx);
 }
 
 static SeedValue
 seed_readline(SeedContext ctx,
-			  SeedObject function,
-			  SeedObject this_object,
-			  size_t argumentCount,
-			  const SeedValue arguments[], SeedValue * exception)
+	      SeedObject function,
+	      SeedObject this_object,
+	      size_t argumentCount,
+	      const SeedValue arguments[], SeedValue * exception)
 {
-	SeedValue valstr = 0;
-	gchar *str = NULL;
-	gchar *buf;
-	const gchar *histfname = g_get_home_dir();
-	gchar *path = g_build_filename(histfname, ".seed_history", NULL);
-
-	if (!readline_has_initialized)
-	{
-		read_history(path);
-		readline_has_initialized = TRUE;
-	}
-
-	if (argumentCount != 1)
-	{
-		gchar *mes =
-			g_strdup_printf("Seed.readline expected 1 argument, "
-							"got %Zd", argumentCount);
-		seed_make_exception(ctx, exception, "ArgumentError", mes);
-		g_free(mes);
-		return seed_make_null(ctx);
-	}
-
-	buf = seed_value_to_string(ctx, arguments[0], exception);
-
-	str = readline(buf);
-	if (str && *str)
-	{
-		add_history(str);
-		valstr = seed_value_from_string(ctx, str, exception);
-		g_free(str);
-	}
-
-	write_history(path);
-	history_truncate_file(path, 1000);
-
-	g_free(buf);
-	g_free(path);
-
-	if (valstr == 0)
-		valstr = seed_make_null(ctx);
-
-	return valstr;
+  SeedValue valstr = 0;
+  gchar *str = NULL;
+  gchar *buf;
+  const gchar *histfname = g_get_home_dir();
+  gchar *path = g_build_filename(histfname, ".seed_history", NULL);
+
+  if (!readline_has_initialized)
+    {
+      read_history(path);
+      readline_has_initialized = TRUE;
+    }
+
+  if (argumentCount != 1)
+    {
+      gchar *mes =
+	g_strdup_printf("Seed.readline expected 1 argument, "
+			"got %Zd", argumentCount);
+      seed_make_exception(ctx, exception, "ArgumentError", mes);
+      g_free(mes);
+      return seed_make_null(ctx);
+    }
+
+  buf = seed_value_to_string(ctx, arguments[0], exception);
+
+  str = readline(buf);
+  if (str && *str)
+    {
+      add_history(str);
+      valstr = seed_value_from_string(ctx, str, exception);
+      g_free(str);
+    }
+
+  write_history(path);
+  history_truncate_file(path, 1000);
+
+  g_free(buf);
+  g_free(path);
+
+  if (valstr == 0)
+    valstr = seed_make_null(ctx);
+
+  return valstr;
 }
 
-void seed_module_init(SeedEngine * local_eng)
+SeedObject
+seed_module_init(SeedEngine * local_eng)
 {
-	seed_class_definition readline_class_def = seed_empty_class;
+  seed_class_definition readline_class_def = seed_empty_class;
 
-	eng = local_eng;
+  eng = local_eng;
 
-	namespace_ref = seed_make_object(eng->context, 0, 0);
+  namespace_ref = seed_make_object(eng->context, 0, 0);
 
-	seed_create_function(eng->context,
-						 "readline",
-						 (SeedFunctionCallback) seed_readline,
-						 (SeedObject) namespace_ref);
+  seed_create_function(eng->context,
+		       "readline",
+		       (SeedFunctionCallback) seed_readline,
+		       (SeedObject) namespace_ref);
 
-	seed_create_function(eng->context,
-						 "bind",
-						 (SeedFunctionCallback) seed_readline_bind,
-						 (SeedObject) namespace_ref);
+  seed_create_function(eng->context,
+		       "bind",
+		       (SeedFunctionCallback) seed_readline_bind,
+		       (SeedObject) namespace_ref);
 
-	seed_object_set_property(eng->context,
-							 eng->global, "readline", namespace_ref);
+  return namespace_ref;
 }
 
diff --git a/modules/sqlite/seed-sqlite.c b/modules/sqlite/seed-sqlite.c
index c9826d4..3287c02 100644
--- a/modules/sqlite/seed-sqlite.c
+++ b/modules/sqlite/seed-sqlite.c
@@ -5,193 +5,193 @@ SeedObject namespace_ref;
 SeedClass sqlite_class;
 SeedEngine *eng;
 
-#define MAKE_ERROR_ENUM(name)											\
-	seed_object_set_property(eng->context, namespace_ref, #name,			\
-							 seed_value_from_int(eng->context, SQLITE_##name, 0))
+#define MAKE_ERROR_ENUM(name)						\
+  seed_object_set_property(eng->context, namespace_ref, #name,		\
+			   seed_value_from_int(eng->context, SQLITE_##name, 0))
 
 void define_errors(SeedEngine * eng)
 {
-	MAKE_ERROR_ENUM(OK);
-	MAKE_ERROR_ENUM(ERROR);
-	MAKE_ERROR_ENUM(INTERNAL);
-	MAKE_ERROR_ENUM(PERM);
-	MAKE_ERROR_ENUM(ABORT);
-	MAKE_ERROR_ENUM(BUSY);
-	MAKE_ERROR_ENUM(LOCKED);
-	MAKE_ERROR_ENUM(NOMEM);
-	MAKE_ERROR_ENUM(READONLY);
-	MAKE_ERROR_ENUM(INTERRUPT);
-	MAKE_ERROR_ENUM(CORRUPT);
-	MAKE_ERROR_ENUM(NOTFOUND);
-	MAKE_ERROR_ENUM(FULL);
-	MAKE_ERROR_ENUM(CANTOPEN);
-	MAKE_ERROR_ENUM(PROTOCOL);
-	MAKE_ERROR_ENUM(EMPTY);
-	MAKE_ERROR_ENUM(SCHEMA);
-	MAKE_ERROR_ENUM(TOOBIG);
-	MAKE_ERROR_ENUM(CONSTRAINT);
-	MAKE_ERROR_ENUM(MISMATCH);
-	MAKE_ERROR_ENUM(MISUSE);
-	MAKE_ERROR_ENUM(NOLFS);
-	MAKE_ERROR_ENUM(AUTH);
-	MAKE_ERROR_ENUM(FORMAT);
-	MAKE_ERROR_ENUM(RANGE);
-	MAKE_ERROR_ENUM(NOTADB);
-	MAKE_ERROR_ENUM(ROW);
-	MAKE_ERROR_ENUM(DONE);
+  MAKE_ERROR_ENUM(OK);
+  MAKE_ERROR_ENUM(ERROR);
+  MAKE_ERROR_ENUM(INTERNAL);
+  MAKE_ERROR_ENUM(PERM);
+  MAKE_ERROR_ENUM(ABORT);
+  MAKE_ERROR_ENUM(BUSY);
+  MAKE_ERROR_ENUM(LOCKED);
+  MAKE_ERROR_ENUM(NOMEM);
+  MAKE_ERROR_ENUM(READONLY);
+  MAKE_ERROR_ENUM(INTERRUPT);
+  MAKE_ERROR_ENUM(CORRUPT);
+  MAKE_ERROR_ENUM(NOTFOUND);
+  MAKE_ERROR_ENUM(FULL);
+  MAKE_ERROR_ENUM(CANTOPEN);
+  MAKE_ERROR_ENUM(PROTOCOL);
+  MAKE_ERROR_ENUM(EMPTY);
+  MAKE_ERROR_ENUM(SCHEMA);
+  MAKE_ERROR_ENUM(TOOBIG);
+  MAKE_ERROR_ENUM(CONSTRAINT);
+  MAKE_ERROR_ENUM(MISMATCH);
+  MAKE_ERROR_ENUM(MISUSE);
+  MAKE_ERROR_ENUM(NOLFS);
+  MAKE_ERROR_ENUM(AUTH);
+  MAKE_ERROR_ENUM(FORMAT);
+  MAKE_ERROR_ENUM(RANGE);
+  MAKE_ERROR_ENUM(NOTADB);
+  MAKE_ERROR_ENUM(ROW);
+  MAKE_ERROR_ENUM(DONE);
 }
 
 void sqlite_database_finalize(SeedObject object)
 {
-	sqlite3 *db = seed_object_get_private(object);
-	if (db)
-		sqlite3_close(db);
+  sqlite3 *db = seed_object_get_private(object);
+  if (db)
+    sqlite3_close(db);
 }
 
 SeedObject sqlite_construct_database(SeedContext ctx,
-									 SeedObject constructor,
-									 size_t argument_count,
-									 const SeedValue arguments[],
-									 SeedException * exception)
+				     SeedObject constructor,
+				     size_t argument_count,
+				     const SeedValue arguments[],
+				     SeedException * exception)
 {
-	SeedObject ret;
-	gchar *file;
-	sqlite3 *db;
-	int rc;
+  SeedObject ret;
+  gchar *file;
+  sqlite3 *db;
+  int rc;
 
-	if (argument_count != 1)
-	{
-		seed_make_exception(ctx, exception, "ArgumentError",
-							"sqlite.Database constructor expected 1 argument");
-		return (SeedObject) seed_make_null(ctx);
-	}
-	file = seed_value_to_string(ctx, arguments[0], exception);
+  if (argument_count != 1)
+    {
+      seed_make_exception(ctx, exception, "ArgumentError",
+			  "sqlite.Database constructor expected 1 argument");
+      return (SeedObject) seed_make_null(ctx);
+    }
+  file = seed_value_to_string(ctx, arguments[0], exception);
 
-	rc = sqlite3_open(file, &db);
+  rc = sqlite3_open(file, &db);
 
-	g_free(file);
+  g_free(file);
 
-	ret = seed_make_object(ctx, sqlite_class, db);
-	seed_object_set_property(ctx, ret, "status",
-							 seed_value_from_int(ctx, rc, exception));
+  ret = seed_make_object(ctx, sqlite_class, db);
+  seed_object_set_property(ctx, ret, "status",
+			   seed_value_from_int(ctx, rc, exception));
 
-	return ret;
+  return ret;
 }
 
 static int seed_sqlite_exec_callback(SeedObject function,
-									 int argc,
-									 gchar ** argv, gchar ** azColName)
+				     int argc,
+				     gchar ** argv, gchar ** azColName)
 {
-	SeedGlobalContext ctx;
-	SeedObject hash;
-	int i;
+  SeedGlobalContext ctx;
+  SeedObject hash;
+  int i;
 
-	if (!function)
-		return 0;
+  if (!function)
+    return 0;
 
-	ctx = seed_context_create(eng->group, NULL);
+  ctx = seed_context_create(eng->group, NULL);
 
-	hash = seed_make_object(ctx, 0, 0);
-	for (i = 0; i < argc; i++)
-	{
-		seed_object_set_property(ctx, hash,
-								 azColName[i],
-								 seed_value_from_string(ctx, argv[i], 0));
-	}
+  hash = seed_make_object(ctx, 0, 0);
+  for (i = 0; i < argc; i++)
+    {
+      seed_object_set_property(ctx, hash,
+			       azColName[i],
+			       seed_value_from_string(ctx, argv[i], 0));
+    }
 
-	seed_object_call(ctx, function, 0, 1, &hash, 0);
+  seed_object_call(ctx, function, 0, 1, &hash, 0);
 
-	seed_context_unref(ctx);
+  seed_context_unref(ctx);
 
-	return 0;
+  return 0;
 }
 
 SeedValue seed_sqlite_exec(SeedContext ctx,
-						   SeedObject function,
-						   SeedObject this_object,
-						   size_t argument_count,
-						   const SeedValue arguments[],
-						   SeedException * exception)
+			   SeedObject function,
+			   SeedObject this_object,
+			   size_t argument_count,
+			   const SeedValue arguments[],
+			   SeedException * exception)
 {
-	gchar *statement;
-	gchar *sqlite_error = 0;
-	sqlite3 *db;
-	int rc;
-
-	if (argument_count < 1)
-	{
-		seed_make_exception(ctx, exception, "ArgumentError",
-							"sqlite.Database.exec expected 1 or 2 arguments");
-		return seed_make_null(ctx);
-	}
-
-	statement = seed_value_to_string(ctx, arguments[0], exception);
-	db = seed_object_get_private(this_object);
-
-	g_assert(db);
-
-	rc = sqlite3_exec(db, statement,
-					  seed_sqlite_exec_callback,
-					  argument_count == 2 ? arguments[1] : 0, &sqlite_error);
-	g_free(statement);
-
-	if (rc != SQLITE_OK)
+  gchar *statement;
+  gchar *sqlite_error = 0;
+  sqlite3 *db;
+  int rc;
+
+  if (argument_count < 1)
+    {
+      seed_make_exception(ctx, exception, "ArgumentError",
+			  "sqlite.Database.exec expected 1 or 2 arguments");
+      return seed_make_null(ctx);
+    }
+
+  statement = seed_value_to_string(ctx, arguments[0], exception);
+  db = seed_object_get_private(this_object);
+
+  g_assert(db);
+
+  rc = sqlite3_exec(db, statement,
+		    seed_sqlite_exec_callback,
+		    argument_count == 2 ? arguments[1] : 0, &sqlite_error);
+  g_free(statement);
+
+  if (rc != SQLITE_OK)
+    {
+      if (sqlite_error)
 	{
-		if (sqlite_error)
-		{
-			seed_make_exception(ctx, exception, "SqliteError", sqlite_error);
-			sqlite3_free(sqlite_error);
-		}
-		return seed_make_null(ctx);
+	  seed_make_exception(ctx, exception, "SqliteError", sqlite_error);
+	  sqlite3_free(sqlite_error);
 	}
+      return seed_make_null(ctx);
+    }
 
-	return seed_value_from_int(ctx, rc, exception);
+  return seed_value_from_int(ctx, rc, exception);
 
 }
 
 SeedValue seed_sqlite_close(SeedContext ctx,
-							SeedObject function,
-							SeedObject this_object,
-							size_t argument_count,
-							const SeedValue arguments[],
-							SeedException * exception)
+			    SeedObject function,
+			    SeedObject this_object,
+			    size_t argument_count,
+			    const SeedValue arguments[],
+			    SeedException * exception)
 {
-	sqlite3 *db = seed_object_get_private(this_object);
-	sqlite3_close(db);
-	return seed_value_from_boolean(ctx, TRUE, exception);
+  sqlite3 *db = seed_object_get_private(this_object);
+  sqlite3_close(db);
+  return seed_value_from_boolean(ctx, TRUE, exception);
 }
 
 seed_static_function database_funcs[] = {
-	{"close", seed_sqlite_close, 0}
-	,
-	{"exec", seed_sqlite_exec, 0}
-	,
-	{0, 0, 0}
+  {"close", seed_sqlite_close, 0}
+  ,
+  {"exec", seed_sqlite_exec, 0}
+  ,
+  {0, 0, 0}
 };
 
-void seed_module_init(SeedEngine * local_eng)
+SeedObject
+seed_module_init(SeedEngine * local_eng)
 {
-	SeedObject db_constructor;
-	seed_class_definition sqlite_class_def = seed_empty_class;
-
-	eng = local_eng;
+  SeedObject db_constructor;
+  seed_class_definition sqlite_class_def = seed_empty_class;
 
-	namespace_ref = seed_make_object(eng->context, 0, 0);
+  eng = local_eng;
 
-	seed_object_set_property(eng->context,
-							 eng->global, "sqlite", namespace_ref);
+  namespace_ref = seed_make_object(eng->context, 0, 0);
 
-	define_errors(eng);
+  define_errors(eng);
 
-	sqlite_class_def.class_name = "Database";
-	sqlite_class_def.finalize = sqlite_database_finalize;
-	sqlite_class_def.static_functions = database_funcs;
+  sqlite_class_def.class_name = "Database";
+  sqlite_class_def.finalize = sqlite_database_finalize;
+  sqlite_class_def.static_functions = database_funcs;
 
-	sqlite_class = seed_create_class(&sqlite_class_def);
+  sqlite_class = seed_create_class(&sqlite_class_def);
 
-	db_constructor = seed_make_constructor(eng->context,
-										   sqlite_class,
-										   sqlite_construct_database);
-	seed_object_set_property(eng->context,
-							 namespace_ref, "Database", db_constructor);
+  db_constructor = seed_make_constructor(eng->context,
+					 sqlite_class,
+					 sqlite_construct_database);
+  seed_object_set_property(eng->context,
+			   namespace_ref, "Database", db_constructor);
+  
+  return namespace_ref;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]