# HG changeset patch # User jwe # Date 1095805333 0 # Node ID 1eb9ce5c0152b216daf7e3955b7d43a781b09455 # Parent ed25bed4340914737f2e773773734e264841f4c9 [project @ 2004-09-21 22:18:07 by jwe] diff --git a/liboctave/oct-alloc.cc b/liboctave/oct-alloc.cc --- a/liboctave/oct-alloc.cc +++ b/liboctave/oct-alloc.cc @@ -49,6 +49,9 @@ return tmp; } +// XXX FIXME XXX -- if we free the last item on the list, shouldn't we +// also free the underlying character array used for storage? + void octave_allocator::free (void *p, size_t size) { diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2004-09-21 David Bateman + + * data.cc (Freshape): Allow a single empty dimension argument + to flag unknown dimension and calculate its value from the + other dimensions. + +2004-09-21 John W. Eaton + + * symtab.h (symbol_record::~symbol_record): Delete definition if + count goes to zero. + * symtab.cc (symbol_table::~symbol_table): Move here from symtab.h. + Call delete on each symbol record in the table instead of just + clearing them. + 2004-09-17 David Bateman * DLD-FUNCTIONS/sort.cc (ascending_compare, descending_compare): diff --git a/src/data.cc b/src/data.cc --- a/src/data.cc +++ b/src/data.cc @@ -1646,6 +1646,9 @@ @noindent\n\ Note that the total number of elements in the original\n\ matrix must match the total number of elements in the new matrix.\n\ +\n\ +A single dimension of the return matrix can be unknown and is flagged\n\ +by an empty argument.\n\ @end deftypefn") { octave_value retval; @@ -1659,13 +1662,47 @@ else if (nargin > 2) { new_size.resize (nargin-1); - + int empty_dim = -1; + for (int i = 1; i < nargin; i++) { - new_size(i-1) = args(i).int_value (); + if (args(i).is_empty ()) + if (empty_dim > 0) + { + error ("reshape: only a single dimension can be unknown"); + break; + } + else + { + empty_dim = i; + new_size(i-1) = 1; + } + else + { + new_size(i-1) = args(i).int_value (); - if (error_state) - break; + if (error_state) + break; + } + } + + if (! error_state && (empty_dim > 0)) + { + int nel = 1; + for (int i = 0; i < nargin - 1; i++) + nel *= new_size(i); + + if (nel == 0) + new_size(empty_dim-1) = 0; + else + { + int size_empty_dim = args(0).numel () / nel; + + if (args(0).numel () != size_empty_dim * nel) + error ("reshape: size is not divisble by the product of known dimensions (= %d)", nel); + else + new_size(empty_dim-1) = size_empty_dim; + } } } else diff --git a/src/parse.y b/src/parse.y --- a/src/parse.y +++ b/src/parse.y @@ -1175,6 +1175,7 @@ symtab_context.push (curr_sym_tab); tmp_local_sym_tab = new symbol_table (); + curr_sym_tab = tmp_local_sym_tab; lexer_flags.looking_at_function_handle--; @@ -2034,8 +2035,8 @@ body->mark_as_function_body (); - octave_user_function *fcn - = new octave_user_function (param_list, ret_list, body, curr_sym_tab); + octave_value fcn (new octave_user_function (param_list, ret_list, + body, curr_sym_tab)); if (symtab_context.empty ()) panic_impossible (); diff --git a/src/symtab.cc b/src/symtab.cc --- a/src/symtab.cc +++ b/src/symtab.cc @@ -700,6 +700,25 @@ // A symbol table. +symbol_table::~symbol_table (void) +{ + for (unsigned int i = 0; i < table_size; i++) + { + symbol_record *ptr = table[i].next (); + + while (ptr) + { + symbol_record *tmp = ptr; + + ptr = ptr->next (); + + delete tmp; + } + } + + delete [] table; +} + symbol_record * symbol_table::lookup (const std::string& nm, bool insert, bool warn) { diff --git a/src/symtab.h b/src/symtab.h --- a/src/symtab.h +++ b/src/symtab.h @@ -258,7 +258,11 @@ can_hide_function (n != "__end__"), nm (n), chg_fcn (0), definition (new symbol_def ()), next_elem (nxt) { } - ~symbol_record (void) { } + ~symbol_record (void) + { + if (--definition->count <= 0) + delete definition; + } std::string name (void) const { return nm; } @@ -467,11 +471,7 @@ } } - ~symbol_table (void) - { - clear (); - delete [] table; - } + ~symbol_table (void); symbol_record *lookup (const std::string& nm, bool insert = false, bool warn = false);