Mercurial > octave-libtiff
changeset 26088:2b92498c111e
move symbol_info and symbol_info_list classes to separate file
* syminfo.h, syminfo.h: New files. Move symbol_info and
symbol_info_list classes here from variables.cc and move them inside
octave namespace. Change all uses.
* libinterp/corefcn/module.mk: Update.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 15 Nov 2018 22:45:04 -0500 |
parents | 7656fcd0ff9f |
children | e71893aa322c |
files | libinterp/corefcn/module.mk libinterp/corefcn/syminfo.cc libinterp/corefcn/syminfo.h libinterp/corefcn/variables.cc |
diffstat | 4 files changed, 697 insertions(+), 602 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/module.mk Thu Nov 15 15:05:36 2018 -0500 +++ b/libinterp/corefcn/module.mk Thu Nov 15 22:45:04 2018 -0500 @@ -82,6 +82,7 @@ %reldir%/sighandlers.h \ %reldir%/sparse-xdiv.h \ %reldir%/sparse-xpow.h \ + %reldir%/syminfo.h \ %reldir%/symrec.h \ %reldir%/symscope.h \ %reldir%/symtab.h \ @@ -237,6 +238,7 @@ %reldir%/sub2ind.cc \ %reldir%/svd.cc \ %reldir%/sylvester.cc \ + %reldir%/syminfo.cc \ %reldir%/symrec.cc \ %reldir%/symscope.cc \ %reldir%/symtab.cc \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/corefcn/syminfo.cc Thu Nov 15 22:45:04 2018 -0500 @@ -0,0 +1,560 @@ +/* + +Copyright (C) 2018 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 3 of the License, 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, see +<https://www.gnu.org/licenses/>. + +*/ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include <iomanip> +#include <list> +#include <ostream> +#include <sstream> + +#include "Cell.h" +#include "octave-preserve-stream-state.h" +#include "ov.h" +#include "oct-map.h" +#include "pager.h" +#include "syminfo.h" + +namespace octave +{ + void + symbol_info::display_line (std::ostream& os, + const std::list<whos_parameter>& params) const + { + std::string dims_str = m_value.get_dims_str (); + + auto i = params.begin (); + + octave::preserve_stream_state stream_state (os); + + while (i != params.end ()) + { + whos_parameter param = *i; + + if (param.command != '\0') + { + // Do the actual printing. + + switch (param.modifier) + { + case 'l': + os << std::setiosflags (std::ios::left) + << std::setw (param.parameter_length); + break; + + case 'r': + os << std::setiosflags (std::ios::right) + << std::setw (param.parameter_length); + break; + + case 'c': + if (param.command == 's') + { + int front = param.first_parameter_length + - dims_str.find ('x'); + int back = param.parameter_length + - dims_str.length () + - front; + front = (front > 0) ? front : 0; + back = (back > 0) ? back : 0; + + os << std::setiosflags (std::ios::left) + << std::setw (front) + << "" + << std::resetiosflags (std::ios::left) + << dims_str + << std::setiosflags (std::ios::left) + << std::setw (back) + << "" + << std::resetiosflags (std::ios::left); + } + else + { + os << std::setiosflags (std::ios::left) + << std::setw (param.parameter_length); + } + break; + + default: + error ("whos_line_format: modifier '%c' unknown", + param.modifier); + + os << std::setiosflags (std::ios::right) + << std::setw (param.parameter_length); + } + + switch (param.command) + { + case 'a': + { + char tmp[6]; + + tmp[0] = (m_is_automatic ? 'a' : ' '); + tmp[1] = (m_is_complex ? 'c' : ' '); + tmp[2] = (m_is_formal ? 'f' : ' '); + tmp[3] = (m_is_global ? 'g' : ' '); + tmp[4] = (m_is_persistent ? 'p' : ' '); + tmp[5] = 0; + + os << tmp; + } + break; + + case 'b': + os << m_value.byte_size (); + break; + + case 'c': + os << m_value.class_name (); + break; + + case 'e': + os << m_value.numel (); + break; + + case 'n': + os << m_name; + break; + + case 's': + if (param.modifier != 'c') + os << dims_str; + break; + + case 't': + os << m_value.type_name (); + break; + + default: + error ("whos_line_format: command '%c' unknown", + param.command); + } + + os << std::resetiosflags (std::ios::left) + << std::resetiosflags (std::ios::right); + i++; + } + else + { + os << param.text; + i++; + } + } + } + + octave_map + symbol_info_list::map_value (const std::string& caller_function_name, + int nesting_level) const + { + size_t len = m_lst.size (); + + Cell name_info (len, 1); + Cell size_info (len, 1); + Cell bytes_info (len, 1); + Cell class_info (len, 1); + Cell global_info (len, 1); + Cell sparse_info (len, 1); + Cell complex_info (len, 1); + Cell nesting_info (len, 1); + Cell persistent_info (len, 1); + + size_t j = 0; + + for (const auto& syminfo : m_lst) + { + octave_scalar_map ni; + + ni.assign ("function", caller_function_name); + ni.assign ("level", nesting_level); + + name_info(j) = syminfo.name (); + global_info(j) = syminfo.is_global (); + persistent_info(j) = syminfo.is_persistent (); + + octave_value val = syminfo.value (); + + size_info(j) = val.size (); + bytes_info(j) = val.byte_size (); + class_info(j) = val.class_name (); + sparse_info(j) = val.issparse (); + complex_info(j) = val.iscomplex (); + nesting_info(j) = ni; + + j++; + } + + octave_map info; + + info.assign ("name", name_info); + info.assign ("size", size_info); + info.assign ("bytes", bytes_info); + info.assign ("class", class_info); + info.assign ("global", global_info); + info.assign ("sparse", sparse_info); + info.assign ("complex", complex_info); + info.assign ("nesting", nesting_info); + info.assign ("persistent", persistent_info); + + return info; + } + + void + symbol_info_list::print_descriptor (std::ostream& os, + const std::list<whos_parameter> params) const + { + std::ostringstream param_buf; + + octave::preserve_stream_state stream_state (os); + + for (const auto& param : params) + { + if (param.command != '\0') + { + // Do the actual printing + switch (param.modifier) + { + case 'l': + os << std::setiosflags (std::ios::left) + << std::setw (param.parameter_length); + param_buf << std::setiosflags (std::ios::left) + << std::setw (param.parameter_length); + break; + + case 'r': + os << std::setiosflags (std::ios::right) + << std::setw (param.parameter_length); + param_buf << std::setiosflags (std::ios::right) + << std::setw (param.parameter_length); + break; + + case 'c': + if (param.command != 's') + { + os << std::setiosflags (std::ios::left) + << std::setw (param.parameter_length); + param_buf << std::setiosflags (std::ios::left) + << std::setw (param.parameter_length); + } + break; + + default: + os << std::setiosflags (std::ios::left) + << std::setw (param.parameter_length); + param_buf << std::setiosflags (std::ios::left) + << std::setw (param.parameter_length); + } + + if (param.command == 's' && param.modifier == 'c') + { + if (param.modifier == 'c') + { + int a = param.first_parameter_length - param.balance; + a = (a < 0 ? 0 : a); + int b = param.parameter_length - a - param.text.length (); + b = (b < 0 ? 0 : b); + os << std::setiosflags (std::ios::left) << std::setw (a) + << "" << std::resetiosflags (std::ios::left) << param.text + << std::setiosflags (std::ios::left) + << std::setw (b) << "" + << std::resetiosflags (std::ios::left); + param_buf << std::setiosflags (std::ios::left) + << std::setw (a) + << "" << std::resetiosflags (std::ios::left) + << param.line + << std::setiosflags (std::ios::left) + << std::setw (b) << "" + << std::resetiosflags (std::ios::left); + } + } + else + { + os << param.text; + param_buf << param.line; + } + os << std::resetiosflags (std::ios::left) + << std::resetiosflags (std::ios::right); + param_buf << std::resetiosflags (std::ios::left) + << std::resetiosflags (std::ios::right); + } + else + { + os << param.text; + param_buf << param.line; + } + } + + os << param_buf.str (); + } + + void symbol_info_list::display (std::ostream& os, const std::string& format) + { + if (! m_lst.empty ()) + { + size_t bytes = 0; + size_t elements = 0; + + std::list<whos_parameter> params = parse_whos_line_format (format); + + print_descriptor (os, params); + + octave_stdout << "\n"; + + for (const auto& syminfo : m_lst) + { + syminfo.display_line (os, params); + + octave_value val = syminfo.value (); + + elements += val.numel (); + bytes += val.byte_size (); + } + + os << "\nTotal is " << elements + << (elements == 1 ? " element" : " elements") + << " using " << bytes << (bytes == 1 ? " byte" : " bytes") + << "\n"; + } + } + + std::list<whos_parameter> + symbol_info_list::parse_whos_line_format (const std::string& format) + { + int idx; + size_t format_len = format.length (); + char garbage; + std::list<whos_parameter> params; + + size_t bytes1; + int elements1; + + std::string param_string = "abcenst"; + Array<int> param_length (dim_vector (param_string.length (), 1)); + Array<std::string> param_names (dim_vector (param_string.length (), 1)); + size_t pos_a, pos_b, pos_c, pos_e, pos_n, pos_s, pos_t; + + pos_a = param_string.find ('a'); // Attributes + pos_b = param_string.find ('b'); // Bytes + pos_c = param_string.find ('c'); // Class + pos_e = param_string.find ('e'); // Elements + pos_n = param_string.find ('n'); // Name + pos_s = param_string.find ('s'); // Size + pos_t = param_string.find ('t'); // Type + + param_names(pos_a) = "Attr"; + param_names(pos_b) = "Bytes"; + param_names(pos_c) = "Class"; + param_names(pos_e) = "Elements"; + param_names(pos_n) = "Name"; + param_names(pos_s) = "Size"; + param_names(pos_t) = "Type"; + + for (size_t i = 0; i < param_string.length (); i++) + param_length(i) = param_names(i).length (); + + // The attribute column needs size 5. + param_length(pos_a) = 5; + + // Calculating necessary spacing for name column, + // bytes column, elements column and class column + + for (const auto& syminfo : m_lst) + { + std::stringstream ss1, ss2; + std::string str; + + str = syminfo.name (); + param_length(pos_n) = ((str.length () + > static_cast<size_t> (param_length(pos_n))) + ? str.length () : param_length(pos_n)); + + octave_value val = syminfo.value (); + + str = val.type_name (); + param_length(pos_t) = ((str.length () + > static_cast<size_t> (param_length(pos_t))) + ? str.length () : param_length(pos_t)); + + elements1 = val.numel (); + ss1 << elements1; + str = ss1.str (); + param_length(pos_e) = ((str.length () + > static_cast<size_t> (param_length(pos_e))) + ? str.length () : param_length(pos_e)); + + bytes1 = val.byte_size (); + ss2 << bytes1; + str = ss2.str (); + param_length(pos_b) = ((str.length () + > static_cast<size_t> (param_length(pos_b))) + ? str.length () : param_length (pos_b)); + } + + idx = 0; + while (static_cast<size_t> (idx) < format_len) + { + whos_parameter param; + param.command = '\0'; + + if (format[idx] == '%') + { + bool error_encountered = false; + param.modifier = 'r'; + param.parameter_length = 0; + + int a = 0; + int b = -1; + int balance = 1; + unsigned int items; + size_t pos; + std::string cmd; + + // Parse one command from format + cmd = format.substr (idx, format.length ()); + pos = cmd.find (';'); + if (pos == std::string::npos) + error ("parameter without ; in format"); + + cmd = cmd.substr (0, pos+1); + + idx += cmd.length (); + + // FIXME: use iostream functions instead of sscanf! + + if (cmd.find_first_of ("crl") != 1) + items = sscanf (cmd.c_str (), "%c%c:%d:%d:%d;", + &garbage, ¶m.command, &a, &b, &balance); + else + items = sscanf (cmd.c_str (), "%c%c%c:%d:%d:%d;", + &garbage, ¶m.modifier, ¶m.command, + &a, &b, &balance) - 1; + + if (items < 2) + error ("whos_line_format: found parameter structure without command"); + + // Exception case of bare class command 'c' without modifier 'l/r' + if (param.modifier == 'c' + && param_string.find (param.command) == std::string::npos) + { + param.modifier = 'r'; + param.command = 'c'; + } + + // Insert data into parameter + param.first_parameter_length = 0; + pos = param_string.find (param.command); + if (pos == std::string::npos) + error ("whos_line_format: '%c' is not a command", param.command); + + param.parameter_length = param_length(pos); + param.text = param_names(pos); + param.line.assign (param_names(pos).length (), '='); + + param.parameter_length = (a > param.parameter_length + ? a : param.parameter_length); + if (param.command == 's' && param.modifier == 'c' && b > 0) + param.first_parameter_length = b; + + if (param.command == 's') + { + // Have to calculate space needed for printing + // matrix dimensions Space needed for Size column is + // hard to determine in prior, because it depends on + // dimensions to be shown. That is why it is + // recalculated for each Size-command int first, + // rest = 0, total; + int rest = 0; + int first = param.first_parameter_length; + int total = param.parameter_length; + + for (const auto& syminfo : m_lst) + { + octave_value val = syminfo.value (); + std::string dims_str = val.get_dims_str (); + int first1 = dims_str.find ('x'); + int total1 = dims_str.length (); + int rest1 = total1 - first1; + rest = (rest1 > rest ? rest1 : rest); + first = (first1 > first ? first1 : first); + total = (total1 > total ? total1 : total); + } + + if (param.modifier == 'c') + { + if (first < balance) + first += balance - first; + if (rest + balance < param.parameter_length) + rest += param.parameter_length - rest - balance; + + param.parameter_length = first + rest; + param.first_parameter_length = first; + param.balance = balance; + } + else + { + param.parameter_length = total; + param.first_parameter_length = 0; + } + } + else if (param.modifier == 'c') + error ("whos_line_format: modifier 'c' not available for command '%c'", + param.command); + + // What happens if format contains negative numbers + // at param_length positions? + param.balance = (b < 0 ? 0 : param.balance); + param.first_parameter_length = (b < 0 + ? 0 + : param.first_parameter_length); + param.parameter_length = (a < 0 + ? 0 + : (param.parameter_length + < param_length(pos_s) + ? param_length(pos_s) + : param.parameter_length)); + + // Parameter will not be pushed into parameter list if ... + if (! error_encountered) + params.push_back (param); + } + else + { + // Text string, to be printed as it is ... + std::string text; + size_t pos; + text = format.substr (idx, format.length ()); + pos = text.find ('%'); + if (pos != std::string::npos) + text = text.substr (0, pos); + + // Push parameter into list ... + idx += text.length (); + param.text=text; + param.line.assign (text.length (), ' '); + params.push_back (param); + } + } + + return params; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/corefcn/syminfo.h Thu Nov 15 22:45:04 2018 -0500 @@ -0,0 +1,129 @@ +/* + +Copyright (C) 2018 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 3 of the License, 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, see +<https://www.gnu.org/licenses/>. + +*/ + +#if ! defined (octave_syminfo_h) +#define octave_syminfo_h 1 + +#include "octave-config.h" + +#include <string> +#include <iosfwd> + +#include "ov.h" + +class octave_map; + +namespace octave +{ + struct whos_parameter + { + char command; + char modifier; + int parameter_length; + int first_parameter_length; + int balance; + std::string text; + std::string line; + }; + + class symbol_info + { + public: + + symbol_info (const std::string& name, const octave_value& value, + bool is_automatic, bool is_complex, bool is_formal, + bool is_global, bool is_persistent) + : m_name (name), m_value (value), m_is_automatic (is_automatic), + m_is_complex (is_complex), m_is_formal (is_formal), + m_is_global (is_global), m_is_persistent (is_persistent) + { } + + std::string name (void) const { return m_name; } + + octave_value value (void) const { return m_value; } + + bool is_automatic (void) const { return m_is_automatic; } + + bool is_complex (void) const { return m_is_complex; } + + bool is_formal (void) const { return m_is_formal; } + + bool is_global (void) const { return m_is_global; } + + bool is_persistent (void) const { return m_is_persistent; } + + void display_line (std::ostream& os, + const std::list<whos_parameter>& params) const; + private: + + std::string m_name; + octave_value m_value; + bool m_is_automatic; + bool m_is_complex; + bool m_is_formal; + bool m_is_global; + bool m_is_persistent; + }; + + class symbol_info_list + { + public: + + symbol_info_list (void) = default; + + symbol_info_list (const symbol_info_list&) = default; + + symbol_info_list& operator = (const symbol_info_list&) = default; + + ~symbol_info_list (void) = default; + + void append (const symbol_info& syminf) + { + m_lst.push_back (syminf); + } + + size_t size (void) const { return m_lst.size (); } + + bool empty (void) const { return m_lst.empty (); } + + octave_map map_value (const std::string& caller_function_name, + int nesting_level) const; + + // Print a line of information for a given symbol. + void print_descriptor (std::ostream& os, + const std::list<whos_parameter> params) const; + + void display (std::ostream& os, const std::string& format); + + // Parse FORMAT, and return a parameter list, + // containing all information needed to print the given + // attributes of the symbols. + std::list<whos_parameter> + parse_whos_line_format (const std::string& format); + + private: + + std::list<symbol_info> m_lst; + }; +} + +#endif
--- a/libinterp/corefcn/variables.cc Thu Nov 15 15:05:36 2018 -0500 +++ b/libinterp/corefcn/variables.cc Thu Nov 15 22:45:04 2018 -0500 @@ -60,6 +60,7 @@ #include "ov-usr-fcn.h" #include "pager.h" #include "parse.h" +#include "syminfo.h" #include "symtab.h" #include "unwind-prot.h" #include "utils.h" @@ -828,610 +829,12 @@ return retval; } -struct -whos_parameter -{ - char command; - char modifier; - int parameter_length; - int first_parameter_length; - int balance; - std::string text; - std::string line; -}; - -// Print a line of information for a given symbol. - -static void -print_descriptor (std::ostream& os, std::list<whos_parameter> params) -{ - std::ostringstream param_buf; - - octave::preserve_stream_state stream_state (os); - - for (const auto& param : params) - { - if (param.command != '\0') - { - // Do the actual printing - switch (param.modifier) - { - case 'l': - os << std::setiosflags (std::ios::left) - << std::setw (param.parameter_length); - param_buf << std::setiosflags (std::ios::left) - << std::setw (param.parameter_length); - break; - - case 'r': - os << std::setiosflags (std::ios::right) - << std::setw (param.parameter_length); - param_buf << std::setiosflags (std::ios::right) - << std::setw (param.parameter_length); - break; - - case 'c': - if (param.command != 's') - { - os << std::setiosflags (std::ios::left) - << std::setw (param.parameter_length); - param_buf << std::setiosflags (std::ios::left) - << std::setw (param.parameter_length); - } - break; - - default: - os << std::setiosflags (std::ios::left) - << std::setw (param.parameter_length); - param_buf << std::setiosflags (std::ios::left) - << std::setw (param.parameter_length); - } - - if (param.command == 's' && param.modifier == 'c') - { - if (param.modifier == 'c') - { - int a = param.first_parameter_length - param.balance; - a = (a < 0 ? 0 : a); - int b = param.parameter_length - a - param.text.length (); - b = (b < 0 ? 0 : b); - os << std::setiosflags (std::ios::left) << std::setw (a) - << "" << std::resetiosflags (std::ios::left) << param.text - << std::setiosflags (std::ios::left) - << std::setw (b) << "" - << std::resetiosflags (std::ios::left); - param_buf << std::setiosflags (std::ios::left) - << std::setw (a) - << "" << std::resetiosflags (std::ios::left) - << param.line - << std::setiosflags (std::ios::left) - << std::setw (b) << "" - << std::resetiosflags (std::ios::left); - } - } - else - { - os << param.text; - param_buf << param.line; - } - os << std::resetiosflags (std::ios::left) - << std::resetiosflags (std::ios::right); - param_buf << std::resetiosflags (std::ios::left) - << std::resetiosflags (std::ios::right); - } - else - { - os << param.text; - param_buf << param.line; - } - } - - os << param_buf.str (); -} - -class symbol_info -{ -public: - - symbol_info (const std::string& name, const octave_value& value, - bool is_automatic, bool is_complex, bool is_formal, - bool is_global, bool is_persistent) - : m_name (name), m_value (value), m_is_automatic (is_automatic), - m_is_complex (is_complex), m_is_formal (is_formal), - m_is_global (is_global), m_is_persistent (is_persistent) - { } - - std::string name (void) const { return m_name; } - - octave_value value (void) const { return m_value; } - - bool is_automatic (void) const { return m_is_automatic; } - - bool is_complex (void) const { return m_is_complex; } - - bool is_formal (void) const { return m_is_formal; } - - bool is_global (void) const { return m_is_global; } - - bool is_persistent (void) const { return m_is_persistent; } - - void display_line (std::ostream& os, - const std::list<whos_parameter>& params) const - { - std::string dims_str = m_value.get_dims_str (); - - auto i = params.begin (); - - octave::preserve_stream_state stream_state (os); - - while (i != params.end ()) - { - whos_parameter param = *i; - - if (param.command != '\0') - { - // Do the actual printing. - - switch (param.modifier) - { - case 'l': - os << std::setiosflags (std::ios::left) - << std::setw (param.parameter_length); - break; - - case 'r': - os << std::setiosflags (std::ios::right) - << std::setw (param.parameter_length); - break; - - case 'c': - if (param.command == 's') - { - int front = param.first_parameter_length - - dims_str.find ('x'); - int back = param.parameter_length - - dims_str.length () - - front; - front = (front > 0) ? front : 0; - back = (back > 0) ? back : 0; - - os << std::setiosflags (std::ios::left) - << std::setw (front) - << "" - << std::resetiosflags (std::ios::left) - << dims_str - << std::setiosflags (std::ios::left) - << std::setw (back) - << "" - << std::resetiosflags (std::ios::left); - } - else - { - os << std::setiosflags (std::ios::left) - << std::setw (param.parameter_length); - } - break; - - default: - error ("whos_line_format: modifier '%c' unknown", - param.modifier); - - os << std::setiosflags (std::ios::right) - << std::setw (param.parameter_length); - } - - switch (param.command) - { - case 'a': - { - char tmp[6]; - - tmp[0] = (m_is_automatic ? 'a' : ' '); - tmp[1] = (m_is_complex ? 'c' : ' '); - tmp[2] = (m_is_formal ? 'f' : ' '); - tmp[3] = (m_is_global ? 'g' : ' '); - tmp[4] = (m_is_persistent ? 'p' : ' '); - tmp[5] = 0; - - os << tmp; - } - break; - - case 'b': - os << m_value.byte_size (); - break; - - case 'c': - os << m_value.class_name (); - break; - - case 'e': - os << m_value.numel (); - break; - - case 'n': - os << m_name; - break; - - case 's': - if (param.modifier != 'c') - os << dims_str; - break; - - case 't': - os << m_value.type_name (); - break; - - default: - error ("whos_line_format: command '%c' unknown", - param.command); - } - - os << std::resetiosflags (std::ios::left) - << std::resetiosflags (std::ios::right); - i++; - } - else - { - os << param.text; - i++; - } - } - } - -private: - - std::string m_name; - octave_value m_value; - bool m_is_automatic; - bool m_is_complex; - bool m_is_formal; - bool m_is_global; - bool m_is_persistent; -}; - -class -symbol_info_list -{ -public: - - symbol_info_list (void) = default; - - symbol_info_list (const symbol_info_list&) = default; - - symbol_info_list& operator = (const symbol_info_list&) = default; - - ~symbol_info_list (void) = default; - - void append (const symbol_info& syminf) - { - m_lst.push_back (syminf); - } - - size_t size (void) const { return m_lst.size (); } - - bool empty (void) const { return m_lst.empty (); } - - octave_map - map_value (const std::string& caller_function_name, int nesting_level) const - { - size_t len = m_lst.size (); - - Cell name_info (len, 1); - Cell size_info (len, 1); - Cell bytes_info (len, 1); - Cell class_info (len, 1); - Cell global_info (len, 1); - Cell sparse_info (len, 1); - Cell complex_info (len, 1); - Cell nesting_info (len, 1); - Cell persistent_info (len, 1); - - size_t j = 0; - - for (const auto& syminfo : m_lst) - { - octave_scalar_map ni; - - ni.assign ("function", caller_function_name); - ni.assign ("level", nesting_level); - - name_info(j) = syminfo.name (); - global_info(j) = syminfo.is_global (); - persistent_info(j) = syminfo.is_persistent (); - - octave_value val = syminfo.value (); - - size_info(j) = val.size (); - bytes_info(j) = val.byte_size (); - class_info(j) = val.class_name (); - sparse_info(j) = val.issparse (); - complex_info(j) = val.iscomplex (); - nesting_info(j) = ni; - - j++; - } - - octave_map info; - - info.assign ("name", name_info); - info.assign ("size", size_info); - info.assign ("bytes", bytes_info); - info.assign ("class", class_info); - info.assign ("global", global_info); - info.assign ("sparse", sparse_info); - info.assign ("complex", complex_info); - info.assign ("nesting", nesting_info); - info.assign ("persistent", persistent_info); - - return info; - } - - void display (std::ostream& os, const std::string& format) - { - if (! m_lst.empty ()) - { - size_t bytes = 0; - size_t elements = 0; - - std::list<whos_parameter> params = parse_whos_line_format (format); - - print_descriptor (os, params); - - octave_stdout << "\n"; - - for (const auto& syminfo : m_lst) - { - syminfo.display_line (os, params); - - octave_value val = syminfo.value (); - - elements += val.numel (); - bytes += val.byte_size (); - } - - os << "\nTotal is " << elements - << (elements == 1 ? " element" : " elements") - << " using " << bytes << (bytes == 1 ? " byte" : " bytes") - << "\n"; - } - } - - // Parse FORMAT, and return a parameter list, - // containing all information needed to print the given - // attributes of the symbols. - std::list<whos_parameter> parse_whos_line_format (const std::string& format) - { - int idx; - size_t format_len = format.length (); - char garbage; - std::list<whos_parameter> params; - - size_t bytes1; - int elements1; - - std::string param_string = "abcenst"; - Array<int> param_length (dim_vector (param_string.length (), 1)); - Array<std::string> param_names (dim_vector (param_string.length (), 1)); - size_t pos_a, pos_b, pos_c, pos_e, pos_n, pos_s, pos_t; - - pos_a = param_string.find ('a'); // Attributes - pos_b = param_string.find ('b'); // Bytes - pos_c = param_string.find ('c'); // Class - pos_e = param_string.find ('e'); // Elements - pos_n = param_string.find ('n'); // Name - pos_s = param_string.find ('s'); // Size - pos_t = param_string.find ('t'); // Type - - param_names(pos_a) = "Attr"; - param_names(pos_b) = "Bytes"; - param_names(pos_c) = "Class"; - param_names(pos_e) = "Elements"; - param_names(pos_n) = "Name"; - param_names(pos_s) = "Size"; - param_names(pos_t) = "Type"; - - for (size_t i = 0; i < param_string.length (); i++) - param_length(i) = param_names(i).length (); - - // The attribute column needs size 5. - param_length(pos_a) = 5; - - // Calculating necessary spacing for name column, - // bytes column, elements column and class column - - for (const auto& syminfo : m_lst) - { - std::stringstream ss1, ss2; - std::string str; - - str = syminfo.name (); - param_length(pos_n) = ((str.length () - > static_cast<size_t> (param_length(pos_n))) - ? str.length () : param_length(pos_n)); - - octave_value val = syminfo.value (); - - str = val.type_name (); - param_length(pos_t) = ((str.length () - > static_cast<size_t> (param_length(pos_t))) - ? str.length () : param_length(pos_t)); - - elements1 = val.numel (); - ss1 << elements1; - str = ss1.str (); - param_length(pos_e) = ((str.length () - > static_cast<size_t> (param_length(pos_e))) - ? str.length () : param_length(pos_e)); - - bytes1 = val.byte_size (); - ss2 << bytes1; - str = ss2.str (); - param_length(pos_b) = ((str.length () - > static_cast<size_t> (param_length(pos_b))) - ? str.length () : param_length (pos_b)); - } - - idx = 0; - while (static_cast<size_t> (idx) < format_len) - { - whos_parameter param; - param.command = '\0'; - - if (format[idx] == '%') - { - bool error_encountered = false; - param.modifier = 'r'; - param.parameter_length = 0; - - int a = 0; - int b = -1; - int balance = 1; - unsigned int items; - size_t pos; - std::string cmd; - - // Parse one command from format - cmd = format.substr (idx, format.length ()); - pos = cmd.find (';'); - if (pos == std::string::npos) - error ("parameter without ; in format"); - - cmd = cmd.substr (0, pos+1); - - idx += cmd.length (); - - // FIXME: use iostream functions instead of sscanf! - - if (cmd.find_first_of ("crl") != 1) - items = sscanf (cmd.c_str (), "%c%c:%d:%d:%d;", - &garbage, ¶m.command, &a, &b, &balance); - else - items = sscanf (cmd.c_str (), "%c%c%c:%d:%d:%d;", - &garbage, ¶m.modifier, ¶m.command, - &a, &b, &balance) - 1; - - if (items < 2) - error ("whos_line_format: found parameter structure without command"); - - // Exception case of bare class command 'c' without modifier 'l/r' - if (param.modifier == 'c' - && param_string.find (param.command) == std::string::npos) - { - param.modifier = 'r'; - param.command = 'c'; - } - - // Insert data into parameter - param.first_parameter_length = 0; - pos = param_string.find (param.command); - if (pos == std::string::npos) - error ("whos_line_format: '%c' is not a command", param.command); - - param.parameter_length = param_length(pos); - param.text = param_names(pos); - param.line.assign (param_names(pos).length (), '='); - - param.parameter_length = (a > param.parameter_length - ? a : param.parameter_length); - if (param.command == 's' && param.modifier == 'c' && b > 0) - param.first_parameter_length = b; - - if (param.command == 's') - { - // Have to calculate space needed for printing - // matrix dimensions Space needed for Size column is - // hard to determine in prior, because it depends on - // dimensions to be shown. That is why it is - // recalculated for each Size-command int first, - // rest = 0, total; - int rest = 0; - int first = param.first_parameter_length; - int total = param.parameter_length; - - for (const auto& syminfo : m_lst) - { - octave_value val = syminfo.value (); - std::string dims_str = val.get_dims_str (); - int first1 = dims_str.find ('x'); - int total1 = dims_str.length (); - int rest1 = total1 - first1; - rest = (rest1 > rest ? rest1 : rest); - first = (first1 > first ? first1 : first); - total = (total1 > total ? total1 : total); - } - - if (param.modifier == 'c') - { - if (first < balance) - first += balance - first; - if (rest + balance < param.parameter_length) - rest += param.parameter_length - rest - balance; - - param.parameter_length = first + rest; - param.first_parameter_length = first; - param.balance = balance; - } - else - { - param.parameter_length = total; - param.first_parameter_length = 0; - } - } - else if (param.modifier == 'c') - error ("whos_line_format: modifier 'c' not available for command '%c'", - param.command); - - // What happens if format contains negative numbers - // at param_length positions? - param.balance = (b < 0 ? 0 : param.balance); - param.first_parameter_length = (b < 0 - ? 0 - : param.first_parameter_length); - param.parameter_length = (a < 0 - ? 0 - : (param.parameter_length - < param_length(pos_s) - ? param_length(pos_s) - : param.parameter_length)); - - // Parameter will not be pushed into parameter list if ... - if (! error_encountered) - params.push_back (param); - } - else - { - // Text string, to be printed as it is ... - std::string text; - size_t pos; - text = format.substr (idx, format.length ()); - pos = text.find ('%'); - if (pos != std::string::npos) - text = text.substr (0, pos); - - // Push parameter into list ... - idx += text.length (); - param.text=text; - param.line.assign (text.length (), ' '); - params.push_back (param); - } - } - - return params; - } - -private: - - std::list<symbol_info> m_lst; - -}; - static octave_value do_who_two (octave::interpreter& interp, const string_vector& pats, bool global_only, bool have_regexp, bool return_list, bool verbose = false, std::string msg = "") { - symbol_info_list symbol_stats; + octave::symbol_info_list symbol_stats; std::list<std::string> symbol_names; octave::tree_evaluator& tw = interp.get_evaluator (); @@ -1464,9 +867,10 @@ { if (verbose) { - symbol_info syminf (sr.name (), value, sr.is_automatic (), - value.iscomplex (), sr.is_formal (), - sr.is_global (), sr.is_persistent ()); + octave::symbol_info + syminf (sr.name (), value, sr.is_automatic (), + value.iscomplex (), sr.is_formal (), + sr.is_global (), sr.is_persistent ()); symbol_stats.append (syminf); }