[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Changeset]: Add "-regexp" option to Fwho, Fwhos and Fclear
From: |
David Bateman |
Subject: |
[Changeset]: Add "-regexp" option to Fwho, Fwhos and Fclear |
Date: |
Sun, 18 May 2008 22:23:48 +0200 |
User-agent: |
Thunderbird 2.0.0.12 (X11/20080306) |
The attached changeset adds the "-regexp" option to Fwho, Fwhos, Fclear.
It uses regexcomp so it assume that regex is available, and so maybe a
pcre version of the regex_match class should be written as well, but as
we don't use named tokens in the case concerned this isn't important.
I also looked briefly at the "-file" option for Fwhos and it seems the
load-save.cc (do_load) function already partially implements this idea,
though hooking that up with the variables.cc (symbol_info_list) class is
not obvious. Also it seems to me that the reason for the -file option is
to allow variables in files to be listed even if they are too large to
be loaded, and so it doesn't make sense to have the octave_value stored
in the symbol_info_list class for that case. However, the changes to get
all this to work seem a bit invasive for the amount of time I have
available.
D.
# HG changeset patch
# User David Bateman <address@hidden>
# Date 1211141685 -7200
# Node ID 5f7268a38c64058a430cdb819d0be9d4b1b78279
# Parent 5d7b80a15330a8f5c79a463502b7d800d85b5f21
Add regexp matching to Fwho and Fclear
diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog
--- a/liboctave/ChangeLog
+++ b/liboctave/ChangeLog
@@ -1,3 +1,10 @@ 2008-05-14 David Bateman <address@hidden
+2008-05-18 David Bateman <address@hidden>
+
+ * regex-match.cc, regex-match.h: New class for simple regular
+ expression matching
+ * Makefile.in (INCLUDES): Add regex-match.h here, and
+ (LIBOCTAVE_CXX_SOURCES): regex-match.cc here.
+
2008-05-14 David Bateman <address@hidden>
* fCMatrix.cc (float rcond): Replace with float rcon everywhere
diff --git a/liboctave/Makefile.in b/liboctave/Makefile.in
--- a/liboctave/Makefile.in
+++ b/liboctave/Makefile.in
@@ -91,7 +91,7 @@ INCLUDES := Bounds.h CollocWt.h DAE.h DA
oct-rl-hist.h oct-shlib.h oct-sort.h oct-spparms.h oct-syscalls.h \
oct-sparse.h oct-time.h oct-uname.h \
pathlen.h pathsearch.h prog-args.h \
- randgamma.h randmtzig.h randpoisson.h \
+ randgamma.h randmtzig.h randpoisson.h regex-match.h \
so-array.h sparse-sort.h statdefs.h str-vec.h \
sparse-util.h sun-utils.h sysdir.h systime.h syswait.h \
$(MATRIX_INC)
@@ -148,7 +148,8 @@ LIBOCTAVE_CXX_SOURCES := Bounds.cc Collo
lo-utils.cc mach-info.cc oct-alloc.cc oct-env.cc \
oct-fftw.cc oct-group.cc oct-md5.cc oct-passwd.cc oct-rand.cc \
oct-shlib.cc oct-spparms.cc oct-syscalls.cc oct-time.cc oct-uname.cc \
- prog-args.cc so-array.cc sparse-sort.cc sparse-util.cc str-vec.cc \
+ prog-args.cc regex-match.cc \
+ so-array.cc sparse-sort.cc sparse-util.cc str-vec.cc \
$(TEMPLATE_SRC) \
$(TI_SRC) \
$(MATRIX_SRC)
diff --git a/liboctave/regex-match.cc b/liboctave/regex-match.cc
new file mode 100644
--- /dev/null
+++ b/liboctave/regex-match.cc
@@ -0,0 +1,153 @@
+/*
+
+Copyright (C) 2008 David Bateman
+
+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
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+#include <iostream>
+#include <string>
+
+#include "regex-match.h"
+#include "str-vec.h"
+
+regex_match&
+regex_match::operator = (const regex_match& gm)
+{
+ if (this != &gm)
+ {
+#if HAVE_REGEX
+ for (int i = 0; i < pat.length (); i++)
+ regfree (compiled +i);
+ delete [] compiled;
+#endif
+ pat = gm.pat;
+ case_insen = gm.case_insen;
+ init ();
+ }
+ return *this;
+}
+
+regex_match::~regex_match (void)
+{
+#if HAVE_REGEX
+ for (int i = 0; i < pat.length (); i++)
+ regfree (compiled +i);
+ delete [] compiled;
+#endif
+}
+
+
+void
+regex_match::set_pattern (const std::string& p)
+{
+#if HAVE_REGEX
+ for (int i = 0; i < pat.length (); i++)
+ regfree (compiled +i);
+ delete [] compiled;
+#endif
+ pat = p;
+ init ();
+}
+
+void
+regex_match::set_pattern (const string_vector& p)
+{
+#if HAVE_REGEX
+ for (int i = 0; i < pat.length (); i++)
+ regfree (compiled +i);
+ delete [] compiled;
+#endif
+ pat = p;
+ init ();
+}
+
+void
+regex_match::init (void)
+{
+#ifdef HAVE_REGEX
+ int npat = pat.length ();
+ int err;
+ int i;
+
+ compiled = new regex_t [npat];
+
+ for (i = 0; i < npat; i++)
+ if (err = regcomp (compiled + i, pat(i).c_str (),
+ (REG_NOSUB | REG_EXTENDED |
+ (case_insen ? REG_ICASE : 0))))
+ break;
+
+ if (err)
+ {
+ int len = regerror(err, compiled + i, 0, 0);
+ OCTAVE_LOCAL_BUFFER (char, errmsg, len);
+ regerror(err, compiled + i, errmsg, len);
+ (*current_liboctave_error_handler) ("%s in pattern (%s)", errmsg,
+ pat(i).c_str());
+
+ for (int j = 0; j < i + 1; j++)
+ regfree(compiled + j);
+ }
+#else
+ (*current_liboctave_error_handler)
+ ("regex not available in this version of Octave");
+#endif
+}
+
+bool
+regex_match::match (const std::string& s)
+{
+#if HAVE_REGEX
+ int npat = pat.length ();
+
+ const char *str = s.c_str ();
+
+ for (int i = 0; i < npat; i++)
+ if (regexec(compiled + i, str, 0, 0, 0) == 0)
+ return true;
+#endif
+
+ return false;
+}
+
+Array<bool>
+regex_match::match (const string_vector& s)
+{
+ int n = s.length ();
+
+ Array<bool> retval (n);
+
+ for (int i = 0; i < n; i++)
+ retval(i) = match (s[i]);
+
+ return retval;
+}
+
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
+
diff --git a/liboctave/regex-match.h b/liboctave/regex-match.h
new file mode 100644
--- /dev/null
+++ b/liboctave/regex-match.h
@@ -0,0 +1,90 @@
+/*
+
+Copyright (C) 2008 David Bateman
+
+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
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_regex_match_h)
+#define octave_regex_match_h 1
+
+#include <string>
+
+#if defined (HAVE_REGEX)
+#if defined (__MINGW32__)
+#define __restrict
+#endif
+#if defined (HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+#include <regex.h>
+#endif
+
+#include "Array.h"
+#include "str-vec.h"
+
+class
+OCTAVE_API
+regex_match
+{
+public:
+
+ regex_match (const std::string& p, bool insen = false)
+ : pat (p), case_insen (insen){ init (); }
+
+ regex_match (const string_vector& p = string_vector (), bool insen = false)
+ : pat (p), case_insen (insen) { init (); }
+
+ regex_match (const regex_match& gm)
+ : pat (gm.pat), case_insen (gm.case_insen) { init (); }
+
+ regex_match& operator = (const regex_match& gm);
+
+ ~regex_match (void);
+
+ void set_pattern (const std::string& p);
+
+ void set_pattern (const string_vector& p);
+
+ bool match (const std::string&);
+
+ Array<bool> match (const string_vector&);
+
+private:
+
+ void init (void);
+
+ // Regex pattern(s).
+ string_vector pat;
+
+ // Should match be case insensitive
+ bool case_insen;
+
+#if HAVE_REGEX
+ regex_t *compiled;
+#endif
+
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,28 @@ 2008-05-14 David Bateman <address@hidden
+2008-05-18 David Bateman <address@hidden>
+
+ * load-save.cc (do_load): Treat non verbose list_only output in
+ the same manner as Fwho.
+ * symtab.h (static void clear_variable_regexp (const
+ std::string&): New method.
+ (static std::list<symbol_record> regexp (const std::string&)): Ditto.
+ (static std::list<symbol_record> regexp_variables (const
+ std::string&)): Ditto.
+ (static std::list<symbol_record> regexp_global_variables (const
+ std::string&)): Ditto,
+ (static std::list<symbol_record> regexp_variables (const
+ string_vector&)): Ditto.
+ (void do_clear_variable_regexp (const std::string&)): Ditto.
+ (std::list<symbol_record> do_regexp (const std::string&, bool)
+ const): Ditto.
+ (do_who): Accept the "-regexp" option. Use regexp versions of
+ symbol table functions.
+ (static inline bool name_match_any_pattern (const string_vector&,
+ int, int, bool): Add regexp argument, and use regexp matching if
+ true.
+ (do_clear_variables): Add regexp option and pass to
+ name_match_any_pattern.
+ (Fclear): Accept the -regexp option.
+
2008-05-14 David Bateman <address@hidden>
* DLD-FUNCTIONS/rcond.cc (Frcond): Add support for single precision.
diff --git a/src/load-save.cc b/src/load-save.cc
--- a/src/load-save.cc
+++ b/src/load-save.cc
@@ -334,6 +334,7 @@ do_load (std::istream& stream, const std
Octave_map retstruct;
std::ostringstream output_buf;
+ std::list<std::string> symbol_names;
octave_idx_type count = 0;
@@ -411,9 +412,10 @@ do_load (std::istream& stream, const std
<< std::setiosflags (std::ios::right)
<< std::setw (7) << tc.rows ()
<< std::setw (7) << tc.columns ()
- << " ";
+ << " " << name << "\n";
}
- output_buf << name << "\n";
+ else
+ symbol_names.push_back (name);
}
else
{
@@ -449,12 +451,28 @@ do_load (std::istream& stream, const std
if (list_only && count)
{
- std::string msg = output_buf.str ();
-
- if (nargout > 0)
- retval = msg;
+ if (verbose)
+ {
+ std::string msg = output_buf.str ();
+
+ if (nargout > 0)
+ retval = msg;
+ else
+ octave_stdout << msg;
+ }
else
- octave_stdout << msg;
+ {
+ if (nargout > 0)
+ retval = Cell (string_vector (symbol_names));
+ else
+ {
+ string_vector names (symbol_names);
+
+ names.list_in_columns (octave_stdout);
+
+ octave_stdout << "\n";
+ }
+ }
}
else if (retstruct.nfields () != 0)
retval = retstruct;
diff --git a/src/symtab.h b/src/symtab.h
--- a/src/symtab.h
+++ b/src/symtab.h
@@ -31,6 +31,7 @@ along with Octave; see the file COPYING.
#include <string>
#include "glob-match.h"
+#include "regex-match.h"
class tree_argument_list;
@@ -1340,6 +1341,14 @@ public:
inst->do_clear_variable_pattern (pat);
}
+ static void clear_variable_regexp (const std::string& pat)
+ {
+ symbol_table *inst = get_instance (xcurrent_scope);
+
+ if (inst)
+ inst->do_clear_variable_regexp (pat);
+ }
+
static void clear_symbol_pattern (const std::string& pat)
{
// FIXME -- are we supposed to do both here?
@@ -1530,11 +1539,25 @@ public:
return inst ? inst->do_glob (pattern) : std::list<symbol_record> ();
}
+ static std::list<symbol_record> regexp (const std::string& pattern)
+ {
+ symbol_table *inst = get_instance (xcurrent_scope);
+
+ return inst ? inst->do_regexp (pattern) : std::list<symbol_record> ();
+ }
+
static std::list<symbol_record> glob_variables (const std::string& pattern)
{
symbol_table *inst = get_instance (xcurrent_scope);
return inst ? inst->do_glob (pattern, true) : std::list<symbol_record> ();
+ }
+
+ static std::list<symbol_record> regexp_variables (const std::string& pattern)
+ {
+ symbol_table *inst = get_instance (xcurrent_scope);
+
+ return inst ? inst->do_regexp (pattern, true) : std::list<symbol_record>
();
}
static std::list<symbol_record>
@@ -1559,6 +1582,28 @@ public:
return retval;
}
+ static std::list<symbol_record>
+ regexp_global_variables (const std::string& pattern)
+ {
+ std::list<symbol_record> retval;
+
+ regex_match pat (pattern);
+
+ for (global_table_const_iterator p = global_table.begin ();
+ p != global_table.end (); p++)
+ {
+ // We generate a list of symbol_record objects so that
+ // the results from regexp_variables and regexp_global_variables
+ // may be handled the same way.
+
+ if (pat.match (p->first))
+ retval.push_back (symbol_record (p->first, p->second,
+ symbol_record::global));
+ }
+
+ return retval;
+ }
+
static std::list<symbol_record> glob_variables (const string_vector&
patterns)
{
std::list<symbol_record> retval;
@@ -1568,6 +1613,23 @@ public:
for (size_t i = 0; i < len; i++)
{
std::list<symbol_record> tmp = glob_variables (patterns[i]);
+
+ retval.insert (retval.begin (), tmp.begin (), tmp.end ());
+ }
+
+ return retval;
+ }
+
+ static std::list<symbol_record> regexp_variables
+ (const string_vector& patterns)
+ {
+ std::list<symbol_record> retval;
+
+ size_t len = patterns.length ();
+
+ for (size_t i = 0; i < len; i++)
+ {
+ std::list<symbol_record> tmp = regexp_variables (patterns[i]);
retval.insert (retval.begin (), tmp.begin (), tmp.end ());
}
@@ -2034,6 +2096,22 @@ private:
}
}
+ void do_clear_variable_regexp (const std::string& pat)
+ {
+ regex_match pattern (pat);
+
+ for (table_iterator p = table.begin (); p != table.end (); p++)
+ {
+ symbol_record& sr = p->second;
+
+ if (sr.is_defined () || sr.is_global ())
+ {
+ if (pattern.match (sr.name ()))
+ sr.clear ();
+ }
+ }
+ }
+
void do_mark_hidden (const std::string& name)
{
table_iterator p = table.find (name);
@@ -2074,6 +2152,29 @@ private:
std::list<symbol_record> retval;
glob_match pat (pattern);
+
+ for (table_const_iterator p = table.begin (); p != table.end (); p++)
+ {
+ if (pat.match (p->first))
+ {
+ const symbol_record& sr = p->second;
+
+ if (vars_only && ! sr.is_variable ())
+ continue;
+
+ retval.push_back (sr);
+ }
+ }
+
+ return retval;
+ }
+
+ std::list<symbol_record> do_regexp (const std::string& pattern,
+ bool vars_only = false) const
+ {
+ std::list<symbol_record> retval;
+
+ regex_match pat (pattern);
for (table_const_iterator p = table.begin (); p != table.end (); p++)
{
diff --git a/src/variables.cc b/src/variables.cc
--- a/src/variables.cc
+++ b/src/variables.cc
@@ -36,6 +36,7 @@ along with Octave; see the file COPYING.
#include "oct-env.h"
#include "file-ops.h"
#include "glob-match.h"
+#include "regex-match.h"
#include "str-vec.h"
#include <defaults.h>
@@ -1637,17 +1638,15 @@ do_who (int argc, const string_vector& a
std::string my_name = argv[0];
bool global_only = false;
+ bool have_regexp = false;
int i;
for (i = 1; i < argc; i++)
{
- if (argv[i] == "-regexp" || argv[i] == "-file")
- {
- error ("%s: `%s' option not implemented", my_name.c_str (),
- argv[i].c_str ());
-
- return retval;
- }
+ if (argv[i] == "-file")
+ error ("%s: `-file' option not implemented", my_name.c_str ());
+ else if (argv[i] == "-regexp")
+ have_regexp = true;
else if (argv[i] == "global")
global_only = true;
else if (argv[i][0] == '-')
@@ -1678,46 +1677,11 @@ do_who (int argc, const string_vector& a
{
std::string pat = pats[j];
- size_t pos = pat.find_first_of (".({");
-
- if (pos != NPOS && pos > 0)
- {
- if (verbose)
- {
- // NOTE: we can only display information for
- // expressions based on global values if the variable is
- // global in the current scope because we currently have
- // no way of looking up the base value in the global
- // scope and then evaluating the arguments in the
- // current scope.
-
- std::string base_name = pat.substr (0, pos);
-
- if (symbol_table::is_variable (base_name))
- {
- symbol_table::symbol_record sr
- = symbol_table::find_symbol (base_name);
-
- if (! global_only || sr.is_global ())
- {
- int parse_status;
-
- octave_value expr_val
- = eval_string (pat, true, parse_status);
-
- if (! error_state)
- symbol_stats.append (sr, pat, expr_val);
- else
- return retval;
- }
- }
- }
- }
- else
+ if (have_regexp)
{
std::list<symbol_table::symbol_record> tmp = global_only
- ? symbol_table::glob_global_variables (pats[j])
- : symbol_table::glob_variables (pats[j]);
+ ? symbol_table::regexp_global_variables (pat)
+ : symbol_table::regexp_variables (pat);
for (std::list<symbol_table::symbol_record>::const_iterator p =
tmp.begin ();
p != tmp.end (); p++)
@@ -1726,6 +1690,59 @@ do_who (int argc, const string_vector& a
symbol_stats.append (*p);
else
symbol_names.push_back (p->name ());
+ }
+ }
+ else
+ {
+ size_t pos = pat.find_first_of (".({");
+
+ if (pos != NPOS && pos > 0)
+ {
+ if (verbose)
+ {
+ // NOTE: we can only display information for
+ // expressions based on global values if the variable is
+ // global in the current scope because we currently have
+ // no way of looking up the base value in the global
+ // scope and then evaluating the arguments in the
+ // current scope.
+
+ std::string base_name = pat.substr (0, pos);
+
+ if (symbol_table::is_variable (base_name))
+ {
+ symbol_table::symbol_record sr
+ = symbol_table::find_symbol (base_name);
+
+ if (! global_only || sr.is_global ())
+ {
+ int parse_status;
+
+ octave_value expr_val
+ = eval_string (pat, true, parse_status);
+
+ if (! error_state)
+ symbol_stats.append (sr, pat, expr_val);
+ else
+ return retval;
+ }
+ }
+ }
+ }
+ else
+ {
+ std::list<symbol_table::symbol_record> tmp = global_only
+ ? symbol_table::glob_global_variables (pat)
+ : symbol_table::glob_variables (pat);
+
+ for (std::list<symbol_table::symbol_record>::const_iterator p =
tmp.begin ();
+ p != tmp.end (); p++)
+ {
+ if (verbose)
+ symbol_stats.append (*p);
+ else
+ symbol_names.push_back (p->name ());
+ }
}
}
}
@@ -1775,25 +1792,12 @@ may not be combined.\n\
may not be combined.\n\
\n\
@table @code\n\
address@hidden -all\n\
-List all currently defined symbols.\n\
-\n\
address@hidden -builtins\n\
-List built-in functions. This includes all currently\n\
-compiled function files, but does not include all function files that\n\
-are in the search path.\n\
-\n\
address@hidden -functions\n\
-List user-defined functions.\n\
-\n\
address@hidden -long\n\
-Print a long listing including the type and dimensions of any symbols.\n\
-The symbols in the first column of output indicate whether it is\n\
-possible to redefine the symbol, and whether it is possible for it to be\n\
-cleared.\n\
-\n\
address@hidden -variables\n\
-List user-defined variables.\n\
address@hidden global\n\
+List the variables in the global scope rather than the current scope.\n\
address@hidden -regexp\n\
+The patterns are considered as regular expressions and will be used\n\
+for matching the variables to display. The same pattern syntax as for\n\
+the @code{regexp} function is used.\n\
@end table\n\
\n\
Valid patterns are the same as described for the @code{clear} command\n\
@@ -1802,6 +1806,7 @@ visible in the local scope are displayed
visible in the local scope are displayed.\n\
\n\
The command @kbd{whos} is equivalent to @kbd{who -long}.\n\
address@hidden
@end deffn")
{
octave_value retval;
@@ -2012,23 +2017,35 @@ then return true if the current function
// Deleting names from the symbol tables.
static inline bool
-name_matches_any_pattern (const std::string& nm,
- const string_vector& argv, int argc, int idx)
+name_matches_any_pattern (const std::string& nm, const string_vector& argv,
+ int argc, int idx, bool have_regexp = false)
{
bool retval = false;
for (int k = idx; k < argc; k++)
{
std::string patstr = argv[k];
-
if (! patstr.empty ())
{
- glob_match pattern (patstr);
-
- if (pattern.match (nm))
+ if (have_regexp)
{
- retval = true;
- break;
+ regex_match pattern (patstr);
+
+ if (pattern.match (nm))
+ {
+ retval = true;
+ break;
+ }
+ }
+ else
+ {
+ glob_match pattern (patstr);
+
+ if (pattern.match (nm))
+ {
+ retval = true;
+ break;
+ }
}
}
}
@@ -2112,7 +2129,7 @@ do_clear_globals (const string_vector& a
static void
do_clear_variables (const string_vector& argv, int argc, int idx,
- bool exclusive = false)
+ bool exclusive = false, bool have_regexp = false)
{
if (idx == argc)
symbol_table::clear_variables ();
@@ -2128,14 +2145,18 @@ do_clear_variables (const string_vector&
{
std::string nm = lvars[i];
- if (! name_matches_any_pattern (nm, argv, argc, idx))
+ if (! name_matches_any_pattern (nm, argv, argc, idx, have_regexp))
symbol_table::clear_variable (nm);
}
}
else
{
- while (idx < argc)
- symbol_table::clear_variable_pattern (argv[idx++]);
+ if (have_regexp)
+ while (idx < argc)
+ symbol_table::clear_variable_regexp (argv[idx++]);
+ else
+ while (idx < argc)
+ symbol_table::clear_variable_pattern (argv[idx++]);
}
}
}
@@ -2266,6 +2287,9 @@ Clears the global symbol names.\n\
Clears the global symbol names.\n\
@item -variables, -v\n\
Clears the local variable names.\n\
address@hidden -regexp, -r\n\
+The arguments are treated as regular expressions as any variables that\n\
+match will be cleared.\n\
@end table\n\
With the execption of @code{exclusive}, all long options can be used \n\
without the dash as well.\n\
@@ -2292,6 +2316,7 @@ without the dash as well.\n\
bool clear_globals = false;
bool clear_variables = false;
bool exclusive = false;
+ bool have_regexp = false;
bool have_dash_option = false;
while (++idx < argc)
@@ -2329,6 +2354,13 @@ without the dash as well.\n\
have_dash_option = true;
clear_variables = true;
}
+ else if (argv[idx] == "-regexp" || argv[idx] == "-r")
+ {
+ CLEAR_OPTION_ERROR (have_dash_option && ! exclusive);
+
+ have_dash_option = true;
+ have_regexp = true;
+ }
else
break;
}
@@ -2350,6 +2382,10 @@ without the dash as well.\n\
("clear: ignoring extra arguments after -all");
symbol_table::clear_all ();
+ }
+ else if (have_regexp)
+ {
+ do_clear_variables (argv, argc, idx, exclusive, true);
}
else if (clear_functions)
{
- [Changeset]: Add "-regexp" option to Fwho, Fwhos and Fclear,
David Bateman <=