/* * The Spar Library - modular math parser * Copyright (C) 2000,2001 Davide Angelocola * * 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 #include #include #include #include #include #include #include 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; } }