Ejemplo n.º 1
0
static void Terrain_new (LIScrArgs* args)
{
	int chunk_size;
	float grid_size;
	LIExtTerrain* self;
	LIExtTerrainModule* module;
	LIScrData* data;

	/* Get the arguments. */
	if (!liscr_args_geti_int (args, 0, &chunk_size) || chunk_size < 1)
		return;
	if (!liscr_args_geti_float (args, 1, &grid_size) || grid_size <= 0.0f)
		return;
	module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_TERRAIN);

	/* Allocate the object. */
	self = liext_terrain_new (module, chunk_size, grid_size);
	if (self == NULL)
		return;

	/* Allocate the userdata. */
	data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_TERRAIN, liext_terrain_free);
	if (data == NULL)
	{
		liext_terrain_free (self);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 2
0
static void Animation_new (LIScrArgs* args)
{
	const char* name;
	LIMdlAnimation* self;
	LIScrData* data;

	/* Get arguments. */
	if (!liscr_args_geti_string (args, 0, &name))
		return;

	/* Allocate the animation. */
	self = limdl_animation_new ();
	if (self == NULL)
		return;
	self->name = lisys_string_dup (name);
	if (self->name == NULL)
	{
		lisys_free (self);
		return;
	}

	/* Allocate the userdata. */
	data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_ANIMATION, limdl_animation_free);
	if (data == NULL)
	{
		limdl_animation_free (self);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 3
0
static void Animation_copy (LIScrArgs* args)
{
	LIMdlAnimation* self;
	LIMdlAnimation* copy;
	LIScrData* data;

	/* Get arguments. */
	if (!liscr_args_geti_data (args, 0, LIEXT_SCRIPT_ANIMATION, &data))
		return;
	copy = liscr_data_get_data (data);

	/* Allocate the animation. */
	self = limdl_animation_new_copy (copy);
	if (self == NULL)
		return;

	/* Allocate the userdata. */
	data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_ANIMATION, limdl_animation_free);
	if (data == NULL)
	{
		limdl_animation_free (self);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 4
0
static void Camera_new (LIScrArgs* args)
{
	LIExtCamera* self;
	LIExtCameraModule* module;
	LIScrData* data;
	LIRenRender* render;
	LIRenVideomode mode;

	/* Allocate self. */
	module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_CAMERA);
	self = liext_camera_new (module);
	if (self == NULL)
		return;
	liext_camera_set_driver (self, LIALG_CAMERA_THIRDPERSON);

	/* Initialize the viewport. */
	render = limai_program_find_component (module->program, "render");
	if (render)
	{
		liren_render_get_videomode (render, &mode);
		liext_camera_set_viewport (self, 0, 0, mode.width, mode.height);
	}

	/* Allocate userdata. */
	data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_CAMERA, liext_camera_free);
	if (data == NULL)
	{
		liext_camera_free (self);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 5
0
static void Heightmap_new (LIScrArgs* args)
{
	int i;
	int size;
	float spacing;
	float scaling;
	LIExtHeightmap* heightmap;
	LIExtHeightmapModule* module;
	LIImgImage* image;
	LIMatVector position;
	LIScrData* data;

	/* Get arguments. */
	module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_HEIGHTMAP);
	if (!liscr_args_geti_vector (args, 0, &position))
		position = limat_vector_init (0.0f, 0.0f, 0.0f);
	if (!liscr_args_geti_int (args, 1, &size))
		size = 33;
	else if (size < 0)
		size = 0;
	if (!liscr_args_geti_float (args, 2, &spacing))
		spacing = 1.0f;
	else if (spacing <= 0.0f)
		spacing = 1.0f;
	if (!liscr_args_geti_float (args, 3, &scaling))
		scaling = 1.0f;
	else if (scaling <= 0.0f)
		scaling = 1.0f;
	if (liscr_args_geti_data (args, 4, LIEXT_SCRIPT_IMAGE, &data))
		image = liscr_data_get_data (data);
	else
		image = NULL;

	/* Ensure that the size is valid. */
	for (i = 32 ; i < 65536 ; i *= 2)
	{
		if (size == i + 1)
			break;
	}
	if (size != i + 1)
	{
		lisys_error_set (EINVAL, "invalid heightmap size");
		lisys_error_report ();
		return;
	}

	/* Allocate the heightmap. */
	heightmap = liext_heightmap_new (module, image, &position, size, spacing, scaling);
	if (heightmap == NULL)
		return;

	/* Allocate the userdata. */
	data = liscr_data_new (args->script, args->lua, heightmap, LIEXT_SCRIPT_HEIGHTMAP, liext_heightmap_free);
	if (data == NULL)
	{
		liext_heightmap_free (heightmap);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 6
0
static void Model_copy (LIScrArgs* args)
{
	int shape_keys = 1;
	LIMaiProgram* program;
	LIMdlModel* self;
	LIScrData* data;

	/* Get arguments. */
	program = liscr_script_get_userdata (args->script, LISCR_SCRIPT_PROGRAM);
	liscr_args_geti_bool (args, 0, &shape_keys);

	/* Allocate the model. */
	self = limdl_model_new_copy (args->self, shape_keys);
	if (self == NULL)
		return;

	/* Allocate the unique ID. */
	if (!limdl_manager_add_model (program->models, self))
	{
		limdl_model_free (self);
		return;
	}

	/* Allocate userdata. */
	data = liscr_data_new (args->script, args->lua, self, LISCR_SCRIPT_MODEL, limdl_manager_free_model);
	if (data == NULL)
	{
		limdl_model_free (self);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 7
0
static void FirFilter_new (LIScrArgs* args)
{
	int i;
	int length;
	float* coeffs;
	LIExtFirFilter* fir;
	LIScrData* data;

	/* Get the number of coefficients. */
	if (!liscr_args_geti_int (args, 0, &length))
		return;
	if (length <= 0)
		return;

	/* Allocate the coefficients. */
	coeffs = lisys_calloc (length, sizeof (float));
	if (!coeffs)
		return;

	/* Read the coefficients. */
	if (liscr_args_geti_table (args, 1))
	{
		for (i = 0 ; i < length ; i++)
		{
			lua_pushnumber (args->lua, i + 1);
			lua_gettable (args->lua, -2);
			if (lua_type (args->lua, -1) == LUA_TNUMBER)
				coeffs[i] = lua_tonumber (args->lua, -1);
			lua_pop (args->lua, 1);
		}
		lua_pop (args->lua, 1);
	}

	/* Create the filter. */
	fir = liext_fir_filter_new (length, coeffs);
	lisys_free (coeffs);
	if (fir == NULL)
		return;

	/* Allocate userdata. */
	data = liscr_data_new (args->script, args->lua, fir, LIEXT_SCRIPT_FIR_FILTER, liext_fir_filter_free);
	if (data == NULL)
	{
		liext_fir_filter_free (fir);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 8
0
static void Terrain_build_chunk_model (LIScrArgs* args)
{
	int grid_x;
	int grid_z;
	LIExtTerrain* self;
	LIExtTerrainModule* module;
	LIMatVector offset;
	LIMdlModel* model;
	LIScrData* data;

	/* Get the arguments. */
	self = args->self;
	module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_TERRAIN);
	if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0)
		return;
	if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0)
		return;
	if (!liscr_args_geti_vector (args, 2, &offset))
		offset = limat_vector_init (grid_x * self->grid_size, 0.0f, grid_z * self->grid_size);

	/* Build the model. */
	model = liext_terrain_build_chunk_model (self, grid_x, grid_z, &offset);
	if (model == NULL)
		return;

	/* Copy the model. */
	model = limdl_model_new_copy (model, 0);
	if (model == NULL)
		return;

	/* Allocate the unique ID. */
	if (!limdl_manager_add_model (module->program->models, model))
	{
		limdl_model_free (model);
		return;
	}

	/* Allocate the userdata. */
	data = liscr_data_new (args->script, args->lua, model, LISCR_SCRIPT_MODEL, limdl_manager_free_model);
	if (data == NULL)
	{
		limdl_model_free (model);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 9
0
static void ImageMerger_new (LIScrArgs* args)
{
	LIImgAsyncMerger* self;
	LIScrData* data;

	/* Allocate the merger. */
	self = liimg_async_merger_new ();
	if (self == NULL)
		return;

	/* Allocate the userdata. */
	data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_IMAGE_MERGER, liimg_async_merger_free);
	if (data == NULL)
	{
		liimg_async_merger_free (self);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 10
0
static void Thread_pop_message (LIScrArgs* args)
{
	LIMaiMessage* message;
	LIExtThread* self;
	LIEngModel* model;

	/* Pop the name. */
	self = args->self;
	message = limai_program_pop_message (self->program, LIMAI_MESSAGE_QUEUE_PROGRAM);
	if (message == NULL)
		return;

	/* Return the message. */
	liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE);
	liscr_args_sets_string (args, "name", message->name);
	switch (message->type)
	{
		case LIMAI_MESSAGE_TYPE_EMPTY:
			liscr_args_sets_string (args, "type", "empty");
			break;
		case LIMAI_MESSAGE_TYPE_MODEL:
			liscr_args_sets_string (args, "type", "model");
			model = lieng_model_new_model (self->program->parent->engine, message->model);
			if (model != NULL)
			{
				message->model = NULL;
				model->script = liscr_data_new (args->script, args->lua, model, LISCR_SCRIPT_MODEL, lieng_model_free);
				if (model->script != NULL)
					liscr_args_sets_stack (args, "model");
				else
					lieng_model_free (model);
			}
			break;
		case LIMAI_MESSAGE_TYPE_STRING:
			liscr_args_sets_string (args, "type", "string");
			liscr_args_sets_string (args, "string", message->string);
			break;
	}

	/* Free the message. */
	limai_message_free (message);
}
Ejemplo n.º 11
0
static void Animation_load (LIScrArgs* args)
{
	char* file;
	const char* path;
	const char* name;
	LIMdlAnimation* self;
	LIExtAnimationModule* module;
	LIScrData* data;

	/* Get arguments. */
	module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_ANIMATION);
	if (!liscr_args_geti_string (args, 0, &name))
		return;

	/* Create the path. */
	file = lisys_string_concat (name, ".lani");
	if (file == NULL)
		return;
	path = lipth_paths_find_file (module->program->paths, file);
	lisys_free (file);
	if (path == NULL)
		return;

	/* Allocate the animation. */
	self = limdl_animation_new_from_file (path);
	if (self == NULL)
	{
		lisys_error_report ();
		return;
	}

	/* Allocate the userdata. */
	data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_ANIMATION, limdl_animation_free);
	if (data == NULL)
	{
		limdl_animation_free (self);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 12
0
static void Widget_new (LIScrArgs* args)
{
	LIExtModule* module;
	LIScrData* data;
	LIWdgWidget* self;

	/* Allocate userdata. */
	module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_WIDGET);
	self = liwdg_widget_new (module->widgets);
	if (self == NULL)
		return;

	/* Allocate userdata. */
	data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_WIDGET, liwdg_widget_free);
	if (data == NULL)
	{
		liwdg_widget_free (self);
		return;
	}
	liwdg_widget_set_script (self, data);
	liscr_args_seti_stack (args);
}
Ejemplo n.º 13
0
static void ImageMerger_pop_image (LIScrArgs* args)
{
	LIImgAsyncMerger* self;
	LIImgImage* image;
	LIScrData* data;

	/* Get arguments. */
	self = args->self;

	/* Get the image. */
	image = liimg_async_merger_pop_image (self);
	if (image == NULL)
		return;

	/* Create the script image. */
	data = liscr_data_new (args->script, args->lua, image, LIEXT_SCRIPT_IMAGE, liimg_image_free);
	if (data == NULL)
	{
		liimg_image_free (image);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 14
0
static void Database_query (LIScrArgs* args)
{
	int i;
	int col;
	int row;
	int ret;
	int size;
	const char* query;
	const char* str;
	sqlite3* self;
	LIArcPacket* packet;
	LIScrData* data;
	sqlite3_stmt* statement;

	self = args->self;
	if (!liscr_args_geti_string (args, 0, &query) &&
	    !liscr_args_gets_string (args, "query", &query))
		return;

	/* Create a statement. */
	if (sqlite3_prepare_v2 (self, query, -1, &statement, NULL) != SQLITE_OK)
	{
		lisys_error_set (EINVAL, "SQL prepare: %s", sqlite3_errmsg (self));
		lisys_error_report ();
		return;
	}

	/* Bind variables. */
	if (liscr_args_geti_table (args, 1) || liscr_args_gets_table (args, "bind"))
	{
		for (i = 1 ; i < sqlite3_bind_parameter_count (statement) + 1 ; i++)
		{
			/* We got a table that has the bound variables in fields matching
			   the indices of the bound variables. We can simply loop through
			   the table and use the binding index as the key. */
			lua_pushnumber (args->lua, i);
			lua_gettable (args->lua, -2);
			switch (lua_type (args->lua, -1))
			{
				/* Bind numbers as doubles. */
				case LUA_TNUMBER:
					if (sqlite3_bind_double (statement, i, lua_tonumber (args->lua, -1)) != SQLITE_OK)
					{
						lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self));
						lisys_error_report ();
						sqlite3_finalize (statement);
						return;
					}
					break;

				/* Bind strings as text. */
				case LUA_TSTRING:
					if (sqlite3_bind_text (statement, i, lua_tostring (args->lua, -1), -1, SQLITE_TRANSIENT) != SQLITE_OK)
					{
						lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self));
						lisys_error_report ();
						sqlite3_finalize (statement);
						return;
					}
					break;

				/* Bind packets as blobs. */
				case LUA_TUSERDATA:
					data = liscr_isdata (args->lua, -1, LISCR_SCRIPT_PACKET);
					if (data == NULL)
						break;
					packet = liscr_data_get_data (data);
					if (packet->writer != NULL)
					{
						if (sqlite3_bind_blob (statement, i, packet->writer->memory.buffer,
							packet->writer->memory.length, SQLITE_TRANSIENT) != SQLITE_OK)
						{
							lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self));
							lisys_error_report ();
							sqlite3_finalize (statement);
							return;
						}
					}
					else
					{
						if (sqlite3_bind_blob (statement, i, packet->reader->buffer,
							packet->reader->length, SQLITE_TRANSIENT) != SQLITE_OK)
						{
							lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self));
							lisys_error_report ();
							sqlite3_finalize (statement);
							return;
						}
					}
					break;

				/* Bind any other values as NULL. */
				default:
					if (sqlite3_bind_null (statement, i) != SQLITE_OK)
					{
						lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self));
						lisys_error_report ();
						sqlite3_finalize (statement);
						return;
					}
					break;
			}
			lua_pop (args->lua, 1);
		}
		lua_pop (args->lua, 1);
	}

	/* Execute the statement and process results. */
	for (row = 0, ret = sqlite3_step (statement) ; ret != SQLITE_DONE ; ret = sqlite3_step (statement), row++)
	{
		/* Check for errors. */
		if (ret != SQLITE_ROW)
		{
			lisys_error_set (EINVAL, "SQL step: %s", sqlite3_errmsg (self));
			lisys_error_report ();
			sqlite3_finalize (statement);
			return;
		}
		if (!row)
			liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE);

		/* Create a row table. */
		lua_newtable (args->lua);

		/* Push the columns to the table. */
		for (col = 0 ; col < sqlite3_column_count (statement) ; col++)
		{
			switch (sqlite3_column_type (statement, col))
			{
				case SQLITE_INTEGER:
					lua_pushnumber (args->lua, col + 1);
					lua_pushnumber (args->lua, sqlite3_column_int (statement, col));
					lua_settable (args->lua, -3);
					break;
				case SQLITE_FLOAT:
					lua_pushnumber (args->lua, col + 1);
					lua_pushnumber (args->lua, sqlite3_column_double (statement, col));
					lua_settable (args->lua, -3);
					break;
				case SQLITE_TEXT:
					str = (const char*) sqlite3_column_text (statement, col);
					size = sqlite3_column_bytes (statement, col);
					lua_pushnumber (args->lua, col + 1);
					if (size > 0 && str != NULL)
						lua_pushstring (args->lua, str);
					else
						lua_pushstring (args->lua, str);
					lua_settable (args->lua, -3);
					break;
				case SQLITE_BLOB:
					str = sqlite3_column_blob (statement, col);
					size = sqlite3_column_bytes (statement, col);
					packet = liarc_packet_new_readable (str, size);
					if (packet != NULL)
					{
						lua_pushnumber (args->lua, col + 1);
						data = liscr_data_new (args->script, args->lua, packet, LISCR_SCRIPT_PACKET, liarc_packet_free);
						if (data != NULL)
							lua_settable (args->lua, -3);
						else
						{
							lua_pop (args->lua, 1);
							liarc_packet_free (packet);
						}
					}
					break;
				case SQLITE_NULL:
					break;
				default:
					lisys_assert (0 && "invalid column type");
					break;
			}
		}

		/* Add the row to the return values. */
		liscr_args_seti_stack (args);
	}
	if (!row)
		liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE);
	sqlite3_finalize (statement);
}
Ejemplo n.º 15
0
LIExtThread* liext_thread_inst_new (
	LIMaiProgram* program,
	lua_State*    lua,
	const char*   file,
	const char*   code,
	const char*   args)
{
	LIExtThread* self;

	/* Allocate self. */
	self = lisys_calloc (1, sizeof (LIExtThread));
	if (self == NULL)
		return NULL;
	if (code != NULL)
	{
		self->code = lisys_string_dup (code);
		if (self->code == NULL)
		{
			lisys_free (self);
			return NULL;
		}
	}
	else if (file != NULL)
	{
		self->file = lisys_string_dup (file);
		if (self->file == NULL)
		{
			lisys_free (self);
			return NULL;
		}
	}

	/* Allocate the program. */
	self->program = limai_program_new (program->paths->root, program->paths->module_name, args);
	if (self->program == NULL)
	{
		lisys_free (self->file);
		lisys_free (self->code);
		lisys_free (self);
		return NULL;
	}
	self->program->parent = program;

	/* Allocate the host userdata. */
	self->script = liscr_data_new (program->script, lua, self, LIEXT_SCRIPT_THREAD, liext_thread_inst_free);
	if (self->script == NULL)
	{
		limai_program_free (self->program);
		lisys_free (self->file);
		lisys_free (self->code);
		lisys_free (self);
		return NULL;
	}

	/* Start the thread. */
	self->thread = lisys_thread_new (private_thread_main, self);
	if (self->thread == NULL)
		return self;

	return self;
}
Ejemplo n.º 16
0
static void Voxel_copy_region (LIScrArgs* args)
{
	int i;
	int length;
	int sector;
	int offset[3];
	LIArcPacket* packet;
	LIScrData* data;
	LIExtModule* module;
	LIMatVector point;
	LIMatVector size;
	LIVoxVoxel* result;

	/* Get region offset and size. */
	module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_VOXEL);
	if (liscr_args_gets_int (args, "sector", &sector))
	{
		lialg_sectors_index_to_offset (module->program->sectors, sector,
			offset + 0, offset + 1, offset + 2);
		point = limat_vector_init (offset[0], offset[1], offset[2]);
		point = limat_vector_multiply (point, module->voxels->tiles_per_line);
		size.x = size.y = size.z = module->voxels->tiles_per_line;
		length = module->voxels->tiles_per_sector;
	}
	else if (liscr_args_gets_vector (args, "point", &point) &&
	         liscr_args_gets_vector (args, "size", &size))
	{
		if (point.x < 0.0f || point.y < 0.0f || point.z < 0.0f ||
		    size.x < 1.0f || size.y < 1.0f || size.z < 1.0f)
			return;
		length = (int) size.x * (int) size.y * (int) size.z;
	}
	else
		return;

	/* Read voxel data. */
	result = lisys_calloc (length, sizeof (LIVoxVoxel));
	if (result == NULL)
		return;
	livox_manager_copy_voxels (module->voxels,
		(int) point.x, (int) point.y, (int) point.z,
		(int) size.x, (int) size.y, (int) size.z, result);

	/* Create a packet writer. */
	packet = liarc_packet_new_writable (0);
	if (packet == NULL)
	{
		lisys_free (result);
		return;
	}

	/* Write the dimensions. */
	if (!liarc_writer_append_uint32 (packet->writer, (int) size.x) ||
		!liarc_writer_append_uint32 (packet->writer, (int) size.y) ||
		!liarc_writer_append_uint32 (packet->writer, (int) size.z))
	{
		lisys_free (result);
		return;
	}

	/* Write voxel data. */
	for (i = 0 ; i < length ; i++)
	{
		if (!livox_voxel_write (result + i, packet->writer))
		{
			lisys_free (result);
			return;
		}
	}
	lisys_free (result);

	/* Return data. */
	data = liscr_data_new (args->script, args->lua, packet, LISCR_SCRIPT_PACKET, liarc_packet_free);
	if (data == NULL)
	{
		liarc_packet_free (packet);
		return;
	}
	liscr_args_seti_stack (args);
}
Ejemplo n.º 17
0
static void Database_new (LIScrArgs* args)
{
	int ok;
	char* path;
	char* path1;
	const char* ptr;
	const char* name;
	sqlite3* sql;
	LIExtModule* module;
	LIScrData* data;

	module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_DATABASE);

	/* Get and validate the filename. */
	if (!liscr_args_geti_string (args, 0, &name) &&
	    !liscr_args_gets_string (args, "name", &name))
		return;
	for (ptr = name ; *ptr != '\0' ; ptr++)
	{
		if (*ptr >= 'a' && *ptr <= 'z') ok = 1;
		else if (*ptr >= 'A' && *ptr <= 'Z') ok = 1;
		else if (*ptr >= '0' && *ptr <= '9') ok = 1;
		else if (*ptr == '-') ok = 1;
		else if (*ptr == '_') ok = 1;
		else if (*ptr == '.') ok = 1;
		else ok = 0;
		if (!ok)
		{
			lisys_error_set (EINVAL, "invalid database name `%s'", name);
			lisys_error_report ();
			return;
		}
	}

	/* Format the path. */
	ptr = lipth_paths_create_file (module->program->paths, name, 0);
	if (ptr == NULL)
	{
		lisys_error_report ();
		return;
	}
	path = lisys_string_dup (ptr);
	if (path == NULL)
		return;

	/* Convert the path to UTF-8. */
	/* Unlike other file functions we use, SQLite requires the filename to
	   be in UTF-8 instead of the system locale. */
	path1 = lisys_string_convert_sys_to_utf8 (path);
	if (path1 != NULL)
	{
		lisys_free (path);
		path = path1;
	}

	/* Open database. */
	if (sqlite3_open_v2 (path, &sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK)
	{
		lisys_error_set (EINVAL, "sqlite: %s", sqlite3_errmsg (sql));
		lisys_error_report ();
		lisys_free (path);
		lisys_free (sql);
		return;
	}
	lisys_free (path);

	/* Allocate userdata. */
	data = liscr_data_new (args->script, args->lua, sql, LIEXT_SCRIPT_DATABASE, private_free_database);
	if (data == NULL)
	{
		sqlite3_close (sql);
		return;
	}
	liscr_args_seti_stack (args);
}