/*
* The Spar Library - modular math parser
* Copyright (C) 2000,2001 Davide Angelocola <davide178@inwind.it>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <spar/sl_conf.h>
#include <spar/sl_io.h>
#include <spar/sl_module.h>
#include <spar/sl_error.h>
#include <spar/sl_util.h>
struct module_manager_node_s
{
int key;
sl_module module;
void *handle; /* dl interface */
struct module_manager_node_s *l;
struct module_manager_node_s *r;
};
typedef struct module_manager_node_s module_manager_node;
static module_manager_node *head;
static module_manager_node *z;
static void
_tree_init (void)
{
z = (module_manager_node *) sl_malloc (sizeof *z);
z->l = z;
z->r = z;
z->key = -1;
head = (module_manager_node *) sl_malloc (sizeof *head);
head->r = z;
head->key = 0;
}
static void
_tree_insert (int v, const sl_module * m, void *handle)
{
module_manager_node *p, *x;
p = head;
x = head->r;
while (x != z)
{
p = x;
x = (v < x->key) ? x->l : x->r;
}
x = (module_manager_node *) sl_malloc (sizeof *x);
x->key = v;
x->module = *m;
x->handle = handle;
x->l = z;
x->r = z;
if (v < p->key)
p->l = x;
else
p->r = x;
}
static module_manager_node *
_tree_search_by_name (const char *name)
{
module_manager_node *p;
module_manager_node *x;
p = head;
x = head->r;
while (x != z)
{
p = x;
if ((strcmp (name, x->module.name)) == 0)
return x;
else
x = ((strcmp (name, x->module.name)) < 0) ? x->l : x->r;
}
return (module_manager_node *) NULL;
}
static void
_tree_print_node (module_manager_node * x)
{
if (x != z)
{
_tree_print_node (x->l);
sl_writeln ("%s (ID %d)", x->module.name, x->key);
_tree_print_node (x->r);
}
}
static void
_tree_remove_node (int k)
{
module_manager_node *c;
module_manager_node *p;
module_manager_node *x;
module_manager_node *t;
z->key = k;
p = head;
x = head->r;
while (k != x->key)
{
p = x;
x = (k < x->key) ? x->l : x->r;
}
t = x;
if (t->r == z)
x = x->l;
else if (t->r->l == z)
{
x = x->r;
x->l = t->l;
}
else
{
c = x->r;
while (c->l->l != z)
c = c->l;
x = c->l;
c->l = x->r;
x->l = t->l;
x->r = t->r;
}
dlclose (t->handle);
sl_free (t->r, sizeof (*t->r));
sl_free (t->l, sizeof (*t->l));
sl_free (t, sizeof (*t));
if (k < p->key)
p->l = x;
else
p->r = x;
}
static void
_tree_free_node (module_manager_node * x)
{
if (x != z)
{
_tree_free_node (x->l);
_tree_free_node (x->r);
_tree_remove_node (x->key);
}
}
static void
_tree_free (void)
{
_tree_free_node (head->r);
}
int
sl_module_manager_add (const sl_module * m, int module_ID, void *handle)
{
module_manager_node *t;
if ((t = _tree_search_by_name (m->name)) == NULL)
{
_tree_insert (module_ID, m, handle);
#ifdef DEBUG
sl_writeln ("the module (ID %d) was loaded.", module_ID);
#endif
return SL_SUCCESS;
}
else
{
sl_error_throw (SL_ERROR_CLASS_ERROR, SL_ERROR_MODULE_LOAD, "(ID %d).",
module_ID);
return SL_ERROR;
}
}
int
sl_module_manager_remove (const char *name)
{
module_manager_node *t;
if ((t = _tree_search_by_name (name)) != NULL)
{
_tree_remove_node (t->key);
return SL_SUCCESS;
}
else
{
return SL_ERROR;
}
}
int
sl_module_manager_print (const char *name)
{
module_manager_node *t;
if ((t = _tree_search_by_name (name)) != NULL)
{
sl_writeln ("Detailed module info: ");
sl_writeln (" name : %s", t->module.name);
sl_writeln (" info : %s", t->module.description);
sl_writeln (" version : %s", t->module.version);
sl_writeln (" ID : %d", t->key);
return SL_SUCCESS;
}
else
{
return SL_ERROR;
}
}
void
sl_module_manager_remove_all (void)
{
_tree_free ();
}
void
sl_module_manager_print_all (void)
{
sl_writeln ("Modules loaded");
_tree_print_node (head->r);
}
void
sl_module_manager_init (void)
{
_tree_init ();
}
int
sl_module_manager_run (const char *name)
{
module_manager_node *t;
if ((t = _tree_search_by_name (name)) != NULL)
{
int rc;
sl_writeln ("Running module '%s' (ID %d)", t->module.name, t->key);
sl_writeln ("");
rc = t->module.main ();
if (rc == SL_ERROR)
{
sl_error_throw (SL_ERROR_CLASS_ERROR, SL_ERROR_MODULE_RUN,
"'%s' ID (%d)", t->module.name, t->key);
return SL_ERROR;
}
else
{
return SL_SUCCESS;
}
}
else
{
sl_writeln ("modules '%s' not found.", name);
return SL_ERROR;
}
}
syntax highlighted by Code2HTML, v. 0.9.1