# HG changeset patch # User jwe # Date 865280477 0 # Node ID 66a1cede95e7d43ccd67c77835caa778b329c342 # Parent 0ea30e0e86ccfc9a50f3281ecd7ce52c874cd0ea [project @ 1997-06-02 19:35:05 by jwe] diff -r 0ea30e0e86cc -r 66a1cede95e7 src/Makefile.in --- a/src/Makefile.in Mon Jun 02 18:58:13 1997 +0000 +++ b/src/Makefile.in Mon Jun 02 19:41:17 1997 +0000 @@ -87,7 +87,7 @@ systime.h syswait.h token.h toplev.h unwind-prot.h utils.h \ variables.h version.h xdiv.h xpow.h $(OV_INCLUDES) $(PT_INCLUDES) -TI_XSRC := Array-oc.cc Array-os.cc Array-tc.cc Map-fnc.cc \ +TI_XSRC := Array-oc.cc Array-os.cc Array-sym.cc Array-tc.cc Map-fnc.cc \ Map-tc.cc SLList-expr.cc SLList-misc.cc SLList-plot.cc \ SLList-tc.cc SLList-tm.cc SLStack-i.cc SLStack-pc.cc \ SLStack-str.cc SLStack-sym.cc SLStack-tok.cc \ diff -r 0ea30e0e86cc -r 66a1cede95e7 src/TEMPLATE-INST/Array-sym.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/TEMPLATE-INST/Array-sym.cc Mon Jun 02 19:41:17 1997 +0000 @@ -0,0 +1,40 @@ +/* + +Copyright (C) 1996, 1997 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave 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 General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// Instantiate Arrays of octave_child objects. + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "Array.h" +#include "Array.cc" + +#include "symtab.h" + +template class Array; + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/ diff -r 0ea30e0e86cc -r 66a1cede95e7 src/help.cc --- a/src/help.cc Mon Jun 02 18:58:13 1997 +0000 +++ b/src/help.cc Mon Jun 02 19:41:17 1997 +0000 @@ -483,7 +483,7 @@ do \ { \ int count; \ - string_vector names = global_sym_tab->list (count, 0, 0, 1, type); \ + string_vector names = global_sym_tab->name_list (count, 0, 0, 1, type); \ display_symtab_names (octave_stdout, names, count, msg); \ } \ while (0) diff -r 0ea30e0e86cc -r 66a1cede95e7 src/load-save.cc --- a/src/load-save.cc Mon Jun 02 18:58:13 1997 +0000 +++ b/src/load-save.cc Mon Jun 02 19:41:17 1997 +0000 @@ -30,6 +30,7 @@ #include +#include #include #include #include @@ -1355,17 +1356,18 @@ // Return nonzero if NAME matches one of the given globbing PATTERNS. -static int +static bool matches_patterns (const string_vector& patterns, int pat_idx, int num_pat, const string& name) { for (int i = pat_idx; i < num_pat; i++) { glob_match pattern (patterns[i]); + if (pattern.match (name)) - return 1; + return true; } - return 0; + return false; } static int @@ -1533,11 +1535,13 @@ << "type rows cols name\n" << "==== ==== ==== ====\n"; - string type = tc.type_name (); - output_buf.form ("%-16s", type.c_str ()); - output_buf.form ("%7d", tc.rows ()); - output_buf.form ("%7d", tc.columns ()); - output_buf << " "; + output_buf + << setiosflags (ios::left) + << setw (16) << tc.type_name () . c_str () + << setiosflags (ios::right) + << setw (7) << tc.rows () + << setw (7) << tc.columns () + << " "; } output_buf << name << "\n"; } diff -r 0ea30e0e86cc -r 66a1cede95e7 src/oct-stream.cc --- a/src/oct-stream.cc Mon Jun 02 18:58:13 1997 +0000 +++ b/src/oct-stream.cc Mon Jun 02 19:41:17 1997 +0000 @@ -2639,8 +2639,13 @@ string name = os->name (); - buf.form (" %4d %-3s %-9s %s\n", - i, mode.c_str (), arch.c_str (), name.c_str ()); + buf << " " + << setiosflags (ios::right) + << setw (4) << i << " " + << setiosflags (ios::left) + << setw (3) << mode.c_str () << " " + << setw (9) << arch.c_str () << " " + << name << "\n"; } } diff -r 0ea30e0e86cc -r 66a1cede95e7 src/pr-output.cc --- a/src/pr-output.cc Mon Jun 02 18:58:13 1997 +0000 +++ b/src/pr-output.cc Mon Jun 02 19:41:17 1997 +0000 @@ -30,6 +30,7 @@ #include +#include #include #include @@ -882,7 +883,7 @@ stmp[6] = (ctmp & 0x02) ? '1' : '0'; \ stmp[7] = (ctmp & 0x01) ? '1' : '0'; \ stmp[8] = '\0'; \ - os.form ("%s", stmp); \ + os << stmp; \ } \ while (0) @@ -900,7 +901,7 @@ stmp[6] = (ctmp & 0x40) ? '1' : '0'; \ stmp[7] = (ctmp & 0x80) ? '1' : '0'; \ stmp[8] = '\0'; \ - os.form ("%s", stmp); \ + os << stmp; \ } \ while (0) @@ -929,22 +930,34 @@ // XXX FIXME XXX -- is it correct to swap bytes for VAX // formats and not for Cray? + // XXX FIXME XXX -- will bad things happen if we are + // interrupted before resetting the format flags and fill + // character? + oct_mach_info::float_format flt_fmt = oct_mach_info::native_float_format (); + char ofill = os.fill ('0'); + + ios::fmtflags oflags = os.setf (ios::right); + os.setf (ios::hex, ios::basefield); + if (hex_format > 1 || flt_fmt == oct_mach_info::ieee_big_endian || flt_fmt == oct_mach_info::cray || flt_fmt == oct_mach_info::unknown) { for (size_t i = 0; i < sizeof (double); i++) - os.form ("%02x", static_cast (tmp.i[i])); + os << setw (2) << static_cast (tmp.i[i]); } else { for (int i = sizeof (double) - 1; i >= 0; i--) - os.form ("%02x", static_cast (tmp.i[i])); + os << setw (2) << static_cast (tmp.i[i]); } + + os.fill (ofill); + os.setf (oflags); } else if (bit_format) { @@ -990,14 +1003,14 @@ s = "Inf"; if (fw > 0) - os.form ("%*s", fw, s); + os << setw (fw) << s; else os << s; } else if (xisnan (d)) { if (fw > 0) - os.form ("%*s", fw, "NaN"); + os << setw (fw) << "NaN"; else os << "NaN"; } @@ -1078,7 +1091,7 @@ int num_cols = lim - col; - os.form ("%*s", extra_indent, ""); + os << setw (extra_indent) << ""; if (num_cols == 1) os << " Column " << col + 1 << ":\n"; @@ -1226,7 +1239,7 @@ for (int i = 0; i < nr; i++) { - os.form ("%*s", extra_indent, ""); + os << setw (extra_indent) << ""; for (int j = col; j < lim; j++) { @@ -1379,7 +1392,7 @@ for (int i = 0; i < nr; i++) { - os.form ("%*s", extra_indent, ""); + os << setw (extra_indent) << ""; for (int j = col; j < lim; j++) { @@ -1476,7 +1489,7 @@ pr_col_num_header (os, total_width, max_width, lim, col, extra_indent); - os.form ("%*s", extra_indent, ""); + os << setw (extra_indent) << ""; for (int i = col; i < lim; i++) { diff -r 0ea30e0e86cc -r 66a1cede95e7 src/symtab.cc --- a/src/symtab.cc Mon Jun 02 18:58:13 1997 +0000 +++ b/src/symtab.cc Mon Jun 02 19:41:17 1997 +0000 @@ -28,7 +28,11 @@ #include #endif +#include #include +#include + +#include #include "glob-match.h" #include "str-vec.h" @@ -36,196 +40,18 @@ #include "error.h" #include "oct-lvalue.h" #include "ov.h" +#include "pager.h" #include "symtab.h" #include "utils.h" #include "variables.h" -// Variables and functions. - -symbol_def::symbol_def (void) -{ - init_state (); -} - -symbol_def::symbol_def (const octave_value& val, unsigned int sym_type) -{ - init_state (); - definition = val; - type = sym_type; -} - -void -symbol_def::init_state (void) -{ - type = UNKNOWN; - eternal = 0; - read_only = 0; - - next_elem = 0; - count = 0; -} - -bool -symbol_def::is_variable (void) const -{ - return (type & USER_VARIABLE || type & BUILTIN_VARIABLE); -} - -bool -symbol_def::is_function (void) const -{ - return (type & USER_FUNCTION || type & BUILTIN_FUNCTION); -} - -bool -symbol_def::is_user_variable (void) const -{ - return (type & USER_VARIABLE); -} - -bool -symbol_def::is_text_function (void) const -{ - return (type & TEXT_FUNCTION); -} - -bool -symbol_def::is_mapper_function (void) const -{ - return (type & MAPPER_FUNCTION); -} - -bool -symbol_def::is_user_function (void) const -{ - return (type & USER_FUNCTION); -} - -bool -symbol_def::is_builtin_variable (void) const -{ - return (type & BUILTIN_VARIABLE); -} - -bool -symbol_def::is_builtin_function (void) const -{ - return (type & BUILTIN_FUNCTION); -} - -// XXX FIXME XXX -bool -symbol_def::is_map_element (const string& /* elts */) const -{ - return false; -} - -void -symbol_def::define (const octave_value& val, unsigned int sym_type) -{ - definition = val; - - type = sym_type; -} - -void -symbol_def::protect (void) -{ - read_only = 1; -} - -void -symbol_def::unprotect (void) -{ - read_only = 0; - -} - -void -symbol_def::make_eternal (void) -{ - eternal = 1; -} - -octave_value& -symbol_def::def (void) -{ - return definition; -} - -string -symbol_def::help (void) const -{ - return help_string; -} - -void -symbol_def::document (const string& h) -{ - help_string = h; -} - -int -maybe_delete (symbol_def *def) -{ - int count = 0; - if (def && def->count > 0) - { - def->count--; - count = def->count; - if (def->count == 0) - delete def; - } - return count; -} +octave_allocator +symbol_record::symbol_def::allocator (sizeof (symbol_record::symbol_def)); // Individual records in a symbol table. -symbol_record::symbol_record (void) -{ - init_state (); -} - -symbol_record::symbol_record (const string& n, symbol_record *nxt) -{ - init_state (); - nm = n; - next_elem = nxt; -} - -void -symbol_record::init_state (void) -{ - formal_param = 0; - linked_to_global = 0; - tagged_static = 0; - sv_fcn = 0; - definition = 0; - next_elem = 0; -} - -string -symbol_record::name (void) const -{ - return nm; -} - -string -symbol_record::help (void) const -{ - string retval; - if (definition) - retval = definition->help (); - return retval; -} - -octave_value& -symbol_record::def (void) -{ - static octave_value foo; - - return definition ? definition->def () : foo; -} +// XXX FIXME XXX -- there are lots of places below where we should +// probably be temporarily ignoring interrupts. void symbol_record::rename (const string& new_name) @@ -234,270 +60,104 @@ nm = new_name; } -bool -symbol_record::is_function (void) const -{ - return definition ? definition->is_function () : false; -} - -bool -symbol_record::is_text_function (void) const -{ - return definition ? definition->is_text_function () : false; -} - -bool -symbol_record::is_mapper_function (void) const -{ - return definition ? definition->is_mapper_function () : false; -} - -bool -symbol_record::is_user_function (void) const +void +symbol_record::define (const octave_value& v, unsigned int sym_type) { - return definition ? definition->is_user_function () : false; -} - -bool -symbol_record::is_builtin_function (void) const -{ - return definition ? definition->is_builtin_function () : false; -} - -bool -symbol_record::is_variable (void) const -{ - return definition ? definition->is_variable () : false; -} - -bool -symbol_record::is_user_variable (void) const -{ - return definition ? definition->is_user_variable () : false; -} + if (! (is_variable () && read_only_error ("redefine"))) + { + if (is_function ()) + push_def (new symbol_def ()); -bool -symbol_record::is_builtin_variable (void) const -{ - return definition ? definition->is_builtin_variable () : false; -} - -bool -symbol_record::is_map_element (const string& elts) const -{ - return definition ? definition->is_map_element (elts) : false; -} - -unsigned int -symbol_record::type (void) const -{ - return definition ? definition->type : false; -} + if (definition->type () == symbol_record::BUILTIN_VARIABLE) + sym_type = symbol_record::BUILTIN_VARIABLE; -bool -symbol_record::is_defined (void) const -{ - return (definition != 0); -} - -bool -symbol_record::is_read_only (void) const -{ - return definition ? definition->read_only : false; -} - -bool -symbol_record::is_eternal (void) const -{ - return definition ? definition->eternal : false; -} - -void -symbol_record::protect (void) -{ - if (definition) - { - definition->protect (); - - if (! is_defined ()) - warning ("protecting undefined variable `%s'", nm.c_str ()); + definition->define (v, sym_type); } } void -symbol_record::unprotect (void) -{ - if (definition) - definition->unprotect (); -} - -void -symbol_record::make_eternal (void) +symbol_record::define_builtin_var (const octave_value& v) { - if (definition) - { - definition->make_eternal (); + define (v, symbol_record::BUILTIN_VARIABLE); - if (! is_defined ()) - warning ("giving eternal life to undefined variable `%s'", - nm.c_str ()); - } + if (chg_fcn) + chg_fcn (); } -void -symbol_record::set_sv_function (sv_function f) +bool +symbol_record::define_as_fcn (const octave_value& v) { - sv_fcn = f; -} + bool retval = false; -int -symbol_record::define (const octave_value& v, unsigned int sym_type) -{ - int retval = 0; - - if (! (is_variable () && read_only_error ("redefine"))) + if (! (is_variable () || read_only_error ("redefine"))) { - if (! definition) - { - definition = new symbol_def (); - definition->count = 1; - } - else if (is_function ()) - { - push_def (new symbol_def ()); - definition->count = 1; - } + replace_all_defs (new symbol_def (v, symbol_record::BUILTIN_FUNCTION)); - if (definition->symbol_type () == symbol_def::BUILTIN_VARIABLE) - sym_type = symbol_def::BUILTIN_VARIABLE; - - definition->define (v, sym_type); + retval = true; } return retval; } -int -symbol_record::define_builtin_var (const octave_value& v) +bool +symbol_record::define (octave_function *f, unsigned int sym_type) { - int retval = define (v, symbol_def::BUILTIN_VARIABLE); + bool retval = false; - if (sv_fcn) - sv_fcn (); + if (! read_only_error ("redefine")) + { + octave_value tmp (f); + + replace_all_defs (new symbol_def (tmp, sym_type)); + + retval = true; + } return retval; } -int -symbol_record::define_as_fcn (const octave_value& v) -{ - if (is_variable () && read_only_error ("redefine")) - return 0; - - if (is_variable ()) - { - symbol_def *old_def = pop_def (); - maybe_delete (old_def); - } - - if (is_function ()) - { - symbol_def *old_def = pop_def (); - maybe_delete (old_def); - } - - push_def (new symbol_def (v, symbol_def::BUILTIN_FUNCTION)); - - definition->count = 1; - - return 1; -} - -int -symbol_record::define (octave_function *f, unsigned int sym_type) -{ - if (read_only_error ("redefine")) - return 0; - - if (is_variable ()) - { - symbol_def *old_def = pop_def (); - maybe_delete (old_def); - } - - if (is_function ()) - { - symbol_def *old_def = pop_def (); - maybe_delete (old_def); - } - - octave_value tmp (f); - - push_def (new symbol_def (tmp, sym_type)); - - definition->count = 1; - - return 1; -} - void -symbol_record::document (const string& h) -{ - if (definition) - { - definition->document (h); - - if (! is_defined ()) - warning ("documenting undefined variable `%s'", nm.c_str ()); - } -} - -int symbol_record::clear (void) { - int count = 0; if (linked_to_global) { - count = maybe_delete (definition); - definition = 0; + if (--definition->count <= 0) + delete definition; + + definition = new symbol_def (); + linked_to_global = 0; } else if (! tagged_static) { - symbol_def *old_def = pop_def (); - count = maybe_delete (old_def); + remove_top_def (); + + if (! definition) + definition = new symbol_def (); } - return count; } void -symbol_record::alias (symbol_record *s, bool force) +symbol_record::alias (symbol_record *s, bool /* force */) { - sv_fcn = s->sv_fcn; + chg_fcn = s->chg_fcn; - if (force && ! s->definition) - { - s->definition = new symbol_def (); - definition = s->definition; - definition->count = 2; // Yes, this is correct. - } - else if (s->definition) - { - definition = s->definition; - definition->count++; - } + replace_all_defs (s->definition); + + definition->count++; } void symbol_record::mark_as_formal_parameter (void) { - formal_param = 1; -} - -bool -symbol_record::is_formal_parameter (void) const -{ - return formal_param; + if (is_linked_to_global ()) + error ("can't mark global variable `%s' as function parameter", + nm.c_str ()); + else if (is_static ()) + error ("can't mark static variable `%s' as function paraemter", + nm.c_str ()); + else + formal_param = 1; } void @@ -511,12 +171,6 @@ linked_to_global = 1; } -bool -symbol_record::is_linked_to_global (void) const -{ - return linked_to_global; -} - void symbol_record::mark_as_static (void) { @@ -529,9 +183,35 @@ } bool -symbol_record::is_static (void) const +symbol_record::hides_fcn (void) const { - return tagged_static; + bool retval = false; + + if (is_variable () && is_defined ()) + { + symbol_def *hidden_def = definition->next_elem; + + if (hidden_def && hidden_def->is_builtin_function ()) + retval = true; + } + + return retval; +} + +bool +symbol_record::hides_builtin (void) const +{ + bool retval = false; + + if (is_variable () && is_defined ()) + { + symbol_def *hidden_def = definition->next_elem; + + if (hidden_def && hidden_def->is_user_function ()) + retval = true; + } + + return retval; } octave_value& @@ -560,19 +240,7 @@ } } - return octave_lvalue (&(def ()), sv_fcn); -} - -symbol_record * -symbol_record::next (void) const -{ - return next_elem; -} - -void -symbol_record::chain (symbol_record *s) -{ - next_elem = s; + return octave_lvalue (&(def ()), chg_fcn); } void @@ -581,9 +249,11 @@ if (! is_static ()) { context.push (definition); - definition = 0; + + definition = new symbol_def (); global_link_context.push (static_cast (linked_to_global)); + linked_to_global = 0; } } @@ -597,45 +267,59 @@ if (! context.empty ()) { - if (is_variable ()) - { - symbol_def *old_def = pop_def (); - maybe_delete (old_def); - } + replace_all_defs (context.pop ()); - if (is_function ()) - { - symbol_def *old_def = pop_def (); - maybe_delete (old_def); - } - - definition = context.pop (); linked_to_global = global_link_context.pop (); } } -int +void +symbol_record::print_symbol_info_line (ostream& os) +{ + os << (is_read_only () ? " r-" : " rw") + << (is_eternal () ? "-" : "d") +#if 0 + << (hides_fcn () ? "f" : (hides_builtin () ? "F" : "-")) +#endif + << " " + << setiosflags (ios::left) << setw (24) << type_name () . c_str (); + + os << resetiosflags (ios::left); + + int nr = rows (); + int nc = columns (); + + if (nr < 0) + os << " -"; + else + os << setiosflags (ios::right) << setw (7) << nr; + + if (nc < 0) + os << " -"; + else + os << setiosflags (ios::right) << setw (7) << nc; + + os << resetiosflags (ios::right); + + os << " " << name () << "\n"; +} + +bool symbol_record::read_only_error (const char *action) { if (is_read_only ()) { if (is_variable ()) - { - ::error ("can't %s read-only constant `%s'", action, nm.c_str ()); - } + ::error ("can't %s read-only constant `%s'", action, nm.c_str ()); else if (is_function ()) - { - ::error ("can't %s read-only function `%s'", action, nm.c_str ()); - } + ::error ("can't %s read-only function `%s'", action, nm.c_str ()); else - { - ::error ("can't %s read-only symbol `%s'", action, nm.c_str ()); - } + ::error ("can't %s read-only symbol `%s'", action, nm.c_str ()); - return 1; + return true; } else - return 0; + return false; } void @@ -644,172 +328,39 @@ if (! sd) return; + assert (definition == 0 || definition->next_elem == 0); + sd->next_elem = definition; + definition = sd; } -symbol_def * -symbol_record::pop_def (void) +void +symbol_record::remove_top_def (void) { symbol_def *top = definition; - if (definition) - definition = definition->next_elem; - return top; -} -// A structure for handling verbose information about a symbol_record. - -symbol_record_info::symbol_record_info (void) - : initialized (0), nr (-1), nc (-1), type (symbol_def::UNKNOWN), - hides (SR_INFO_NONE), eternal (0), read_only (0), nm (), - const_type () { } - -symbol_record_info::symbol_record_info (symbol_record& sr) - : initialized (0), nr (-1), nc (-1), type (sr.type ()), - hides (SR_INFO_NONE), eternal (0), read_only (0), nm (), - const_type () -{ - if (sr.is_variable () && sr.is_defined ()) - { - octave_value tmp = sr.def (); - - const_type = tmp.type_name (); - - nr = tmp.rows (); - nc = tmp.columns (); - - symbol_def *sr_def = sr.definition; - symbol_def *hidden_def = sr_def->next_elem; + definition = definition->next_elem; - if (hidden_def) - { - if (hidden_def->is_user_function ()) - hides = SR_INFO_USER_FUNCTION; - else if (hidden_def->is_builtin_function ()) - hides = SR_INFO_BUILTIN_FUNCTION; - } - } - - eternal = sr.is_eternal (); - read_only = sr.is_read_only (); - - nm = sr.name (); - - initialized = 1; -} - -symbol_record_info::symbol_record_info (const symbol_record_info& s) - : initialized (s.initialized), nr (s.nr), nc (s.nc), type (s.type), - hides (s.hides), eternal (s.eternal), read_only (s.read_only), - nm (s.nm), const_type (s.const_type) { } - -symbol_record_info& -symbol_record_info::operator = (const symbol_record_info& s) -{ - if (this != &s) - { - initialized = s.initialized; - nr = s.nr; - nc = s.nc; - type = s.type; - hides = s.hides; - eternal = s.eternal; - read_only = s.read_only; - nm = s.nm; - const_type = s.const_type; - } - return *this; + if (--top->count <= 0) + delete top; } -bool -symbol_record_info::is_defined (void) const -{ - return initialized; -} - -bool -symbol_record_info::is_read_only (void) const -{ - return read_only; -} - -bool -symbol_record_info::is_eternal (void) const +void +symbol_record::replace_all_defs (symbol_def *sd) { - return eternal; -} - -bool -symbol_record_info::hides_fcn (void) const -{ - return (hides & SR_INFO_USER_FUNCTION); -} - -bool -symbol_record_info::hides_builtin (void) const -{ - return (hides & SR_INFO_BUILTIN_FUNCTION); -} - -string -symbol_record_info::type_name (void) const -{ - string retval; + while (definition) + remove_top_def (); - if (type == symbol_def::USER_FUNCTION) - retval = "user function"; - else if (type & symbol_def::BUILTIN_FUNCTION) - { - if (type & symbol_def::TEXT_FUNCTION) - retval = "text function"; - else if (type & symbol_def::MAPPER_FUNCTION) - retval = "mapper function"; - else - retval = "builtin function"; - } - else - retval = const_type; - - return retval; -} - -bool -symbol_record_info::is_function (void) const -{ - return (type == symbol_def::USER_FUNCTION - || type == symbol_def::BUILTIN_FUNCTION - || symbol_def::TEXT_FUNCTION - || symbol_def::MAPPER_FUNCTION); -} - -int -symbol_record_info::rows (void) const -{ - return nr; -} - -int -symbol_record_info::columns (void) const -{ - return nc; -} - -string -symbol_record_info::name (void) const -{ - return nm; + push_def (sd); } // A symbol table. -symbol_table::symbol_table (void) -{ -} - symbol_record * symbol_table::lookup (const string& nm, bool insert, bool warn) { - int index = hash (nm) & HASH_MASK; + unsigned int index = hash (nm); symbol_record *ptr = table[index].next (); @@ -817,15 +368,17 @@ { if (ptr->name () == nm) return ptr; + ptr = ptr->next (); } if (insert) { - symbol_record *new_sym; - new_sym = new symbol_record (nm, table[index].next ()); - table[index].chain (new_sym); - return new_sym; + symbol_record *sr = new symbol_record (nm, table[index].next ()); + + table[index].chain (sr); + + return sr; } else if (warn) warning ("lookup: symbol`%s' not found", nm.c_str ()); @@ -836,7 +389,7 @@ void symbol_table::rename (const string& old_name, const string& new_name) { - int index = hash (old_name) & HASH_MASK; + unsigned int index = hash (old_name); symbol_record *prev = &table[index]; symbol_record *ptr = prev->next (); @@ -851,7 +404,7 @@ { prev->chain (ptr->next ()); - index = hash (new_name) & HASH_MASK; + index = hash (new_name); table[index].chain (ptr); return; @@ -871,7 +424,7 @@ void symbol_table::clear (bool clear_user_functions) { - for (int i = 0; i < HASH_TABLE_SIZE; i++) + for (unsigned int i = 0; i < table_size; i++) { symbol_record *ptr = table[i].next (); @@ -888,10 +441,10 @@ } } -int +bool symbol_table::clear (const string& nm, bool clear_user_functions) { - int index = hash (nm) & HASH_MASK; + unsigned int index = hash (nm); symbol_record *ptr = table[index].next (); @@ -902,72 +455,63 @@ || (clear_user_functions && ptr->is_user_function ()))) { ptr->clear (); - return 1; + return true; } ptr = ptr->next (); } - return 0; + return false; } int symbol_table::size (void) const { int count = 0; - for (int i = 0; i < HASH_TABLE_SIZE; i++) + + for (unsigned int i = 0; i < table_size; i++) { symbol_record *ptr = table[i].next (); + while (ptr) { count++; ptr = ptr->next (); } } + return count; } -static inline int -pstrcmp (char **a, char **b) +static bool +matches_patterns (const string& name, const string_vector& pats) { - return strcmp (*a, *b); -} + int npats = pats.length (); -static inline int -symbol_record_info_cmp (symbol_record_info *a, symbol_record_info *b) -{ - return (a->name () == b->name ()); + if (npats == 0) + return true; + + glob_match pattern (pats); + + return pattern.match (name); } -static int -matches_patterns (const string& name, const string_vector& pats, int npats) -{ - for (int i = 0; i < npats; i++) - { - glob_match pattern (pats[i]); - if (pattern.match (name)) - return 1; - } - - return 0; -} - -// This function should probably share code with symbol_table::list. -// XXX FIXME XXX - -symbol_record_info * -symbol_table::long_list (int& count, const string_vector& pats, - int npats, bool sort, unsigned int type, - unsigned int scope) const +Array +symbol_table::symbol_list (int& count, const string_vector& pats, + unsigned int type, unsigned int scope) const { count = 0; + int n = size (); + if (n == 0) return 0; - symbol_record_info *symbols = new symbol_record_info [n+1]; - for (int i = 0; i < HASH_TABLE_SIZE; i++) + Array symbols (n); + + for (unsigned int i = 0; i < table_size; i++) { symbol_record *ptr = table[i].next (); + while (ptr) { assert (count < n); @@ -979,48 +523,8 @@ string my_name = ptr->name (); if ((type & my_type) && (scope & my_scope) - && (npats == 0 || matches_patterns (my_name, pats, npats))) - symbols[count++] = symbol_record_info (*ptr); - - ptr = ptr->next (); - } - } - symbols[count] = symbol_record_info (); - - if (sort && symbols) - qsort (symbols, count, sizeof (symbol_record_info), - symbol_record_info_cmp); - - return symbols; -} - -string_vector -symbol_table::list (int& count, const string_vector& pats, int npats, - bool sort, unsigned int type, unsigned int scope) const -{ - count = 0; - int n = size (); - if (n == 0) - return 0; - - string_vector symbols (n); - - for (int i = 0; i < HASH_TABLE_SIZE; i++) - { - symbol_record *ptr = table[i].next (); - while (ptr) - { - assert (count < n); - - unsigned int my_scope = ptr->is_linked_to_global () + 1; // Tricky... - - unsigned int my_type = ptr->type (); - - string my_name = ptr->name (); - - if ((type & my_type) && (scope & my_scope) - && (npats == 0 || matches_patterns (my_name, pats, npats))) - symbols[count++] = ptr->name (); + && matches_patterns (my_name, pats)) + symbols(count++) = ptr; ptr = ptr->next (); } @@ -1028,10 +532,87 @@ symbols.resize (count); - if (sort && ! symbols.empty ()) - symbols.qsort (); + return symbols; +} + +string_vector +symbol_table::name_list (int& count, const string_vector& pats, bool sort, + unsigned int type, unsigned int scope) const +{ + Array symbols + = symbol_list (count, pats, type, scope); + + string_vector names; + + int n = symbols.length (); + + if (n > 0) + { + names.resize (n); + + for (int i = 0; i < n; i++) + names[i] = symbols(i)->name (); + } + + if (sort) + names.qsort (); + + return names; +} + +static int +maybe_list_cmp_fcn (symbol_record **a_arg, symbol_record **b_arg) +{ + string a = (*a_arg)->name (); + string b = (*b_arg)->name (); + + return a.compare (b); +} - return symbols; +int +symbol_table::maybe_list (const char *header, const string_vector& argv, + ostream& os, bool show_verbose, + unsigned type, unsigned scope) +{ + int count; + + int status = 0; + + if (show_verbose) + { + Array symbols = symbol_list (count, argv, type, scope); + + int len = symbols.length (); + + if (len > 0 && count > 0) + { + os << "\n" << header << "\n\n" + << "prot type rows cols name\n" + << "==== ==== ==== ==== ====\n"; + + symbols.qsort (maybe_list_cmp_fcn); + + for (int i = 0; i < len; i++) + symbols(i)->print_symbol_info_line (os); + + status = 1; + } + } + else + { + string_vector symbols = name_list (count, argv, 1, type, scope); + + if (symbols.length () > 0 && count > 0) + { + os << "\n" << header << "\n\n"; + + symbols.list_in_columns (os); + + status = 1; + } + } + + return status; } symbol_record ** @@ -1044,9 +625,11 @@ return 0; symbol_record **symbols = new symbol_record * [n+1]; - for (int i = 0; i < HASH_TABLE_SIZE; i++) + + for (unsigned int i = 0; i < table_size; i++) { symbol_record *ptr = table[i].next (); + while (ptr) { assert (count < n); @@ -1074,7 +657,7 @@ void symbol_table::push_context (void) { - for (int i = 0; i < HASH_TABLE_SIZE; i++) + for (unsigned int i = 0; i < table_size; i++) { symbol_record *ptr = table[i].next (); @@ -1089,7 +672,7 @@ void symbol_table::pop_context (void) { - for (int i = 0; i < HASH_TABLE_SIZE; i++) + for (unsigned int i = 0; i < table_size; i++) { symbol_record *ptr = table[i].next (); @@ -1101,36 +684,67 @@ } } +void +symbol_table::print_stats (void) +{ + int count = 0; + int empty_chains = 0; + int max_chain_length = 0; + int min_chain_length = INT_MAX; + + for (unsigned int i = 0; i < table_size; i++) + { + int num_this_chain = 0; + + symbol_record *ptr = table[i].next (); + + if (ptr) + octave_stdout << "chain number " << i << ":\n"; + else + { + empty_chains++; + min_chain_length = 0; + } + + while (ptr) + { + num_this_chain++; + + octave_stdout << " " << ptr->name () << "\n"; + + ptr = ptr->next (); + } + + count += num_this_chain; + + if (num_this_chain > max_chain_length) + max_chain_length = num_this_chain; + + if (num_this_chain < min_chain_length) + min_chain_length = num_this_chain; + + if (num_this_chain > 0) + octave_stdout << "\n"; + } + + octave_stdout << "max chain length: " << max_chain_length << "\n"; + octave_stdout << "min chain length: " << min_chain_length << "\n"; + octave_stdout << "empty chains: " << empty_chains << "\n"; + octave_stdout << "total chains: " << table_size << "\n"; + octave_stdout << "total symbols: " << count << "\n"; +} + // Chris Torek's fave hash function. unsigned int symbol_table::hash (const string& str) { unsigned int h = 0; + for (unsigned int i = 0; i < str.length (); i++) h = h * 33 + str[i]; - return h; -} -// Return nonzero if S is a valid identifier. - -bool -valid_identifier (const char *s) -{ - if (! s || ! (isalnum (*s) || *s == '_')) - return false; - - while (*++s != '\0') - if (! (isalnum (*s) || *s == '_')) - return false; - - return true; -} - -bool -valid_identifier (const string& s) -{ - return valid_identifier (s.c_str ()); + return h & (table_size - 1); } /* diff -r 0ea30e0e86cc -r 66a1cede95e7 src/symtab.h --- a/src/symtab.h Mon Jun 02 18:58:13 1997 +0000 +++ b/src/symtab.h Mon Jun 02 19:41:17 1997 +0000 @@ -121,6 +121,11 @@ bool is_eternal (void) const { return eternal; } + int rows (void) const { return definition.rows (); } + int columns (void) const { return definition.columns (); } + + string type_name (void) const { return definition.type_name (); } + void define (const octave_value& val, unsigned int sym_type) { definition = val; @@ -269,6 +274,14 @@ void mark_as_static (void); bool is_static (void) const { return tagged_static; } + bool hides_fcn (void) const; + bool hides_builtin (void) const; + + int rows (void) const { return definition->rows (); } + int columns (void) const { return definition->columns (); } + + string type_name (void) const { return definition->type_name (); } + octave_value& variable_value (void); octave_lvalue variable_reference (void); @@ -280,6 +293,8 @@ void pop_context (void); + void print_symbol_info_line (ostream& os); + private: unsigned int formal_param : 1; @@ -311,55 +326,6 @@ symbol_record& operator = (const symbol_record& s); }; -#if 0 -// A structure for handling verbose information about a symbol_record. - -class -symbol_record_info -{ -public: - - symbol_record_info (void); - symbol_record_info (symbol_record& s); - - symbol_record_info (const symbol_record_info& s); - - ~symbol_record_info (void) { } - - symbol_record_info& operator = (const symbol_record_info& s); - - bool is_defined (void) const; - bool is_read_only (void) const; - bool is_eternal (void) const; - bool hides_fcn (void) const; - bool hides_builtin (void) const; - string type_name (void) const; - bool is_function (void) const; - int rows (void) const; - int columns (void) const; - string name (void) const; - - enum HIDES - { - SR_INFO_NONE = 0, - SR_INFO_USER_FUNCTION = 1, - SR_INFO_BUILTIN_FUNCTION = 2 - }; - -private: - - bool initialized; - int nr; - int nc; - unsigned int type : 6; - unsigned int hides : 2; - unsigned int eternal : 1; - unsigned int read_only : 1; - string nm; - string const_type; -}; -#endif - // A symbol table. #define SYMTAB_LOCAL_SCOPE 1 @@ -403,23 +369,20 @@ int size (void) const; -#if 0 - symbol_record_info * - long_list (int& count, const string_vector& pats = string_vector (), - int npats = 0, bool sort = false, - unsigned int type = SYMTAB_ALL_TYPES, - unsigned int scope = SYMTAB_ALL_SCOPES) const; -#endif + Array + symbol_list (int& count, const string_vector& pats = string_vector (), + unsigned int type = SYMTAB_ALL_TYPES, + unsigned int scope = SYMTAB_ALL_SCOPES) const; + string_vector - list (int& count, const string_vector& pats = string_vector (), - int npats = 0, bool sort = false, - unsigned int type = SYMTAB_ALL_TYPES, - unsigned int scope = SYMTAB_ALL_SCOPES) const; + name_list (int& count, const string_vector& pats = string_vector (), + bool sort = false, unsigned int type = SYMTAB_ALL_TYPES, + unsigned int scope = SYMTAB_ALL_SCOPES) const; int maybe_list (const char *header, const string_vector& argv, - int argc, ostream& os, bool show_verbose, + ostream& os, bool show_verbose, unsigned type, unsigned scope); symbol_record **glob (int& count, const string& pat = string ("*"), diff -r 0ea30e0e86cc -r 66a1cede95e7 src/variables.cc --- a/src/variables.cc Mon Jun 02 18:58:13 1997 +0000 +++ b/src/variables.cc Mon Jun 02 19:41:17 1997 +0000 @@ -1156,12 +1156,12 @@ key = names (keyword_help (), key_len); - glb = global_sym_tab->list (glb_len); + glb = global_sym_tab->name_list (glb_len); - top = top_level_sym_tab->list (top_len); + top = top_level_sym_tab->name_list (top_len); if (top_level_sym_tab != curr_sym_tab) - lcl = curr_sym_tab->list (lcl_len); + lcl = curr_sym_tab->name_list (lcl_len); ffl = octave_fcn_file_name_cache::list_no_suffix (); int ffl_len = ffl.length (); @@ -1302,18 +1302,18 @@ if (show_builtins) { pad_after += global_sym_tab->maybe_list - ("*** built-in variables:", pats, npats, octave_stdout, + ("*** built-in variables:", pats, octave_stdout, show_verbose, symbol_record::BUILTIN_VARIABLE, SYMTAB_ALL_SCOPES); pad_after += global_sym_tab->maybe_list - ("*** built-in functions:", pats, npats, octave_stdout, + ("*** built-in functions:", pats, octave_stdout, show_verbose, symbol_record::BUILTIN_FUNCTION, SYMTAB_ALL_SCOPES); } if (show_functions) { pad_after += global_sym_tab->maybe_list - ("*** currently compiled functions:", pats, npats, + ("*** currently compiled functions:", pats, octave_stdout, show_verbose, symbol_record::USER_FUNCTION, SYMTAB_ALL_SCOPES); } @@ -1321,11 +1321,11 @@ if (show_variables) { pad_after += curr_sym_tab->maybe_list - ("*** local user variables:", pats, npats, octave_stdout, + ("*** local user variables:", pats, octave_stdout, show_verbose, symbol_record::USER_VARIABLE, SYMTAB_LOCAL_SCOPE); pad_after += curr_sym_tab->maybe_list - ("*** globally visible user variables:", pats, npats, + ("*** globally visible user variables:", pats, octave_stdout, show_verbose, symbol_record::USER_VARIABLE, SYMTAB_GLOBAL_SCOPE); } @@ -1645,17 +1645,19 @@ if (argc > 0) { - lvars = curr_sym_tab->list (lcount, 0, 0, 0, - SYMTAB_VARIABLES, - SYMTAB_LOCAL_SCOPE); + string_vector tmp; + + lvars = curr_sym_tab->name_list (lcount, tmp, false, + SYMTAB_VARIABLES, + SYMTAB_LOCAL_SCOPE); - gvars = curr_sym_tab->list (gcount, 0, 0, 0, - SYMTAB_VARIABLES, - SYMTAB_GLOBAL_SCOPE); + gvars = curr_sym_tab->name_list (gcount, tmp, false, + SYMTAB_VARIABLES, + SYMTAB_GLOBAL_SCOPE); - fcns = global_sym_tab->list (fcount, 0, 0, 0, - symbol_record::USER_FUNCTION, - SYMTAB_ALL_SCOPES); + fcns = global_sym_tab->name_list (fcount, tmp, false, + symbol_record::USER_FUNCTION, + SYMTAB_ALL_SCOPES); } // XXX FIXME XXX -- this needs to be optimized to avoid the