# HG changeset patch # User Markus Mützel # Date 1701710689 -3600 # Mon Dec 04 18:24:49 2023 +0100 # Branch stable # Node ID 3f95008cc007c826b21512db3e1c76e44dd9d0d1 # Parent f561b6a31e02e1ce5ce7ed333f6ce8adce2cc69e Use native function for symbol name matching on Windows (bug #64975). * sysdep.h, sysdep.cc (symbol_match): Add new class that can efficiently match symbol names cross-platform. * call-stack.cc (call_stack::clear_global_variable_pattern), load-save.cc (matches_patterns, load_save_system::save_fields), ls-hdf5.cc (read_hdf5_data), stack-frame.cc (symbol_cleaner::clear_symbols, symbol_info_accumulator::filter), symtab.cc (symbol_table::clear_function_pattern), variables.cc (name_matches_any_pattern): Use new class to match symbol names. diff -r f561b6a31e02 -r 3f95008cc007 libinterp/corefcn/call-stack.cc --- a/libinterp/corefcn/call-stack.cc Wed Dec 06 15:02:58 2023 -0500 +++ b/libinterp/corefcn/call-stack.cc Mon Dec 04 18:24:49 2023 +0100 @@ -45,6 +45,7 @@ #include "syminfo.h" #include "symrec.h" #include "symscope.h" +#include "sysdep.h" #include "variables.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -840,7 +841,7 @@ void call_stack::clear_global_variable_pattern (const std::string& pattern) { - glob_match pat (pattern); + symbol_match pat (pattern); for (auto& nm_ov : m_global_values) { @@ -1064,7 +1065,7 @@ } else { - glob_match pat (pattern); + symbol_match pat (pattern); for (auto& nm_ov : m_global_values) { diff -r f561b6a31e02 -r 3f95008cc007 libinterp/corefcn/load-save.cc --- a/libinterp/corefcn/load-save.cc Wed Dec 06 15:02:58 2023 -0500 +++ b/libinterp/corefcn/load-save.cc Mon Dec 04 18:24:49 2023 +0100 @@ -113,7 +113,7 @@ { for (int i = pat_idx; i < num_pat; i++) { - glob_match pattern (patterns[i]); + symbol_match pattern (patterns[i]); if (pattern.match (name)) return true; @@ -1003,7 +1003,7 @@ const load_save_format& fmt, bool save_as_floats) { - glob_match pat (pattern); + symbol_match pat (pattern); std::size_t saved = 0; diff -r f561b6a31e02 -r 3f95008cc007 libinterp/corefcn/ls-hdf5.cc --- a/libinterp/corefcn/ls-hdf5.cc Wed Dec 06 15:02:58 2023 -0500 +++ b/libinterp/corefcn/ls-hdf5.cc Mon Dec 04 18:24:49 2023 +0100 @@ -1117,7 +1117,7 @@ for (int i = argv_idx; i < argc; i++) { - glob_match pattern (argv[i]); + octave::symbol_match pattern (argv[i]); if (pattern.match (std::string (&var_name[0]))) { found = true; diff -r f561b6a31e02 -r 3f95008cc007 libinterp/corefcn/stack-frame.cc --- a/libinterp/corefcn/stack-frame.cc Wed Dec 06 15:02:58 2023 -0500 +++ b/libinterp/corefcn/stack-frame.cc Mon Dec 04 18:24:49 2023 +0100 @@ -48,6 +48,7 @@ #include "syminfo.h" #include "symrec.h" #include "symscope.h" +#include "sysdep.h" #include "variables.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -760,7 +761,7 @@ { std::string pattern = m_patterns[j]; - glob_match pat (pattern); + symbol_match pat (pattern); for (const auto& sym : symbols) { @@ -1005,7 +1006,7 @@ { std::string pattern = m_patterns[j]; - glob_match pat (pattern); + symbol_match pat (pattern); for (const auto& sym : symbols) { diff -r f561b6a31e02 -r 3f95008cc007 libinterp/corefcn/symtab.cc --- a/libinterp/corefcn/symtab.cc Wed Dec 06 15:02:58 2023 -0500 +++ b/libinterp/corefcn/symtab.cc Mon Dec 04 18:24:49 2023 +0100 @@ -47,6 +47,7 @@ #include "pt-pr-code.h" #include "symscope.h" #include "symtab.h" +#include "sysdep.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -438,7 +439,7 @@ void symbol_table::clear_function_pattern (const std::string& pat) { - glob_match pattern (pat); + symbol_match pattern (pat); auto p = m_fcn_table.begin (); diff -r f561b6a31e02 -r 3f95008cc007 libinterp/corefcn/sysdep.cc --- a/libinterp/corefcn/sysdep.cc Wed Dec 06 15:02:58 2023 -0500 +++ b/libinterp/corefcn/sysdep.cc Mon Dec 04 18:24:49 2023 +0100 @@ -431,6 +431,83 @@ #endif } +symbol_match::symbol_match (const std::string& pat) +{ + m_pat = pat; + +#if defined (OCTAVE_USE_WINDOWS_API) + m_glob = nullptr; +#else + m_glob = new glob_match (pat); +#endif +} + +symbol_match::~symbol_match () +{ +#if ! defined (OCTAVE_USE_WINDOWS_API) + delete m_glob; +#endif +} + +bool symbol_match::match (const std::string& sym) +{ +#if defined (OCTAVE_USE_WINDOWS_API) + + // We don't need full POSIX compatibility to match symbol patterns. + // Glob patterns with '*' or '?' should be good enough. + // We also do not need to worry about multi-byte characters because symbols + // are ASCII-only. + octave_idx_type pat_len = m_pat.length (); + octave_idx_type pat_idx = 0; + octave_idx_type pat_wildc_idx = -1; + octave_idx_type sym_len = sym.length (); + octave_idx_type sym_idx = 0; + octave_idx_type sym_wildc_idx; + + while (sym_idx < sym_len) + { + if (pat_idx < pat_len + && (m_pat[pat_idx] == '?' || m_pat[pat_idx] == sym[sym_idx])) + { + // match to '?' or exact match + pat_idx++; + sym_idx++; + } + else if (pat_idx < pat_len && m_pat[pat_idx] == '*') + { + // remember position in pattern and symbol + pat_wildc_idx = pat_idx; + sym_wildc_idx = sym_idx; + pat_idx++; + } + else if (pat_wildc_idx != -1) + { + // no match but previous wildcard '*' + // revert pat_idx to previous position + pat_idx = pat_wildc_idx + 1; + // but proceed to next character in symbol and try to match again + sym_wildc_idx++; + sym_idx = sym_wildc_idx; + } + else + // no exact match and no wildcard + return false; + } + + // consume potentially trailing '*' in pattern + while (pat_idx < pat_len && m_pat[pat_idx] == '*') + pat_idx++; + + // check for remaining (unmatched) characters in pattern + return pat_idx == pat_len; + +#else + + return m_glob->match (sym); + +#endif +} + void sysdep_init () { // Use a function from libgomp to force loading of OpenMP library. diff -r f561b6a31e02 -r 3f95008cc007 libinterp/corefcn/sysdep.h --- a/libinterp/corefcn/sysdep.h Wed Dec 06 15:02:58 2023 -0500 +++ b/libinterp/corefcn/sysdep.h Mon Dec 04 18:24:49 2023 +0100 @@ -32,6 +32,8 @@ #include +#include "glob-match.h" + #include "lo-ieee.h" #include "lo-sysdep.h" @@ -55,6 +57,25 @@ extern OCTINTERP_API bool drive_or_unc_share (const std::string&); +class OCTINTERP_API symbol_match +{ +public: + + symbol_match (const std::string& pattern); + + OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (symbol_match) + + ~symbol_match (); + + bool match (const std::string& sym); + +private: + + std::string m_pat; + + glob_match *m_glob; +}; + OCTAVE_END_NAMESPACE(octave) #endif diff -r f561b6a31e02 -r 3f95008cc007 libinterp/corefcn/variables.cc --- a/libinterp/corefcn/variables.cc Wed Dec 06 15:02:58 2023 -0500 +++ b/libinterp/corefcn/variables.cc Mon Dec 04 18:24:49 2023 +0100 @@ -948,7 +948,7 @@ } else { - glob_match pattern (patstr); + symbol_match pattern (patstr); if (pattern.match (nm)) {