/* * 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 static sl_variable *head; static sl_variable *z; static sl_size __var_counter; static sl_variable * __tree_search (const char name[]) { sl_variable *p; sl_variable *x; p = head; x = head->r; while (x != z) { p = x; if ((strcmp (x->name, name)) == 0) { return x; } else { x = ((sl_strncmp (name, x->name, SL_IDENTIFIER_LENGHT)) < 0) ? x->l : x->r; } } return (sl_variable *) NULL; } static void __tree_insert (const char name[], double value) { if (__var_counter > SL_MAX_VARIABLES - 1) { sl_error_throw (SL_ERROR_CLASS_PARSER, SL_ERROR_MAXVARS, "the variable '%s' wasn't added", name); } else { sl_variable *p; sl_variable *x; p = head; x = head->r; while (x != z) { p = x; x = ((sl_strncmp (name, x->name, SL_IDENTIFIER_LENGHT)) < 0) ? x->l : x->r; } x = (sl_variable *) sl_malloc (sizeof *x); sl_variable_edit_name (x, name); sl_variable_edit_comment (x, "no comment"); sl_variable_edit_value (x, value); x->l = z; x->r = z; if ((sl_strncmp (name, p->name, SL_IDENTIFIER_LENGHT)) < 0) { p->l = x; } else { p->r = x; } __var_counter++; } } static void __tree_print_node (sl_variable * x) { if (x != z) { __tree_print_node (x->l); sl_writeln ("%15s = %g\t{%-s}", x->name, x->value, x->comment); __tree_print_node (x->r); } } static void __tree_print (void) { __tree_print_node (head->r); } static void __tree_delete_entry (const char *name) { sl_variable *c; sl_variable *p; sl_variable *x; sl_variable *t; sl_variable_edit_name (z, name); p = head; x = head->r; while ((sl_strncmp (name, x->name, SL_IDENTIFIER_LENGHT)) != 0) { p = x; if ((sl_strncmp (name, x->name, SL_IDENTIFIER_LENGHT)) < 0) { x = x->l; } else { x = 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; } sl_free (t->r, sizeof (*t->r)); sl_free (t->l, sizeof (*t->l)); sl_free (t, sizeof (*t)); if ((sl_strncmp (name, p->name, SL_IDENTIFIER_LENGHT)) < 0) { p->l = x; } else { x->r = x; } } static void __tree_free_node (sl_variable * x) { if (x != z) { __tree_free_node (x->l); __tree_free_node (x->r); __tree_delete_entry (x->name); } } static void __tree_free (void) { __tree_free_node (head->r); } int sl_variable_comment (const char name[], const char comment[]) { sl_variable *tmp; tmp = __tree_search (name); if (tmp != NULL) { sl_variable_edit_comment (tmp, comment); return SL_SUCCESS; } else { return SL_ERROR; } } int sl_variable_init (void) { z = (sl_variable *) sl_malloc (sizeof *z); z->l = z; z->r = z; head = (sl_variable *) sl_malloc (sizeof *head); head->r = z; head->l = z; __var_counter = 0; return SL_SUCCESS; } int sl_variable_remove_all (void) { __tree_free (); return SL_SUCCESS; } int sl_variable_old (const char name[]) { sl_variable *tmp; tmp = __tree_search (name); if (tmp != NULL) { sl_variable_old_value (tmp); return SL_SUCCESS; } else { return SL_ERROR; } } int sl_variable_get (const char name[], double *r) { sl_variable *tmp; tmp = __tree_search (name); if (tmp != NULL) { *r = tmp->value; return SL_SUCCESS; } else { return SL_ERROR; } } int sl_variable_set (const char name[], double value) { double tmp; if (sl_constant_get (name, &tmp) == SL_SUCCESS) { sl_error_throw (SL_ERROR_CLASS_PARSER, SL_ERROR_CONST, name); return SL_ERROR; } else { sl_variable *tmp; tmp = __tree_search (name); if (tmp == NULL) { __tree_insert (name, value); } else { sl_variable_edit_value (tmp, value); } return SL_SUCCESS; } } void sl_variable_print_all (void) { sl_writeln ("Vars Table"); __tree_print (); }