Prefer std::regex, and modern C++ string search

This commit is contained in:
Robin Gareus 2025-11-11 19:04:16 +01:00
parent 7eb92253c6
commit f6a2ee0103
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
10 changed files with 59 additions and 114 deletions

View file

@ -18,7 +18,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include <regex.h> #include <regex>
#include "pbd/error.h" #include "pbd/error.h"
@ -289,11 +289,14 @@ PortEngineSharedImpl::get_ports (
std::vector<std::string>& port_names) const std::vector<std::string>& port_names) const
{ {
int rv = 0; int rv = 0;
regex_t port_regex; std::regex port_regex;
bool use_regexp = false; bool use_regexp = false;
if (port_name_pattern.size () > 0) { if (!port_name_pattern.empty()) {
if (!regcomp (&port_regex, port_name_pattern.c_str (), REG_EXTENDED|REG_NOSUB)) { try {
port_regex.assign (port_name_pattern, std::regex::extended);
use_regexp = true; use_regexp = true;
} catch (const std::regex_error&) {
use_regexp = false;
} }
} }
@ -301,15 +304,12 @@ PortEngineSharedImpl::get_ports (
for (auto const& port : *p) { for (auto const& port : *p) {
if ((port->type () == type) && flags == (port->flags () & flags)) { if ((port->type () == type) && flags == (port->flags () & flags)) {
if (!use_regexp || !regexec (&port_regex, port->name ().c_str (), 0, NULL, 0)) { if (!use_regexp || std::regex_search (port->name(), port_regex)) {
port_names.push_back (port->name ()); port_names.push_back (port->name ());
++rv; ++rv;
} }
} }
} }
if (use_regexp) {
regfree (&port_regex);
}
return rv; return rv;
} }

View file

@ -24,8 +24,6 @@
#ifdef COMPILER_MSVC #ifdef COMPILER_MSVC
#include <ardourext/misc.h> #include <ardourext/misc.h>
#include <io.h> // Microsoft's nearest equivalent to <unistd.h> #include <io.h> // Microsoft's nearest equivalent to <unistd.h>
#else
#include <regex.h>
#endif #endif
#include <glibmm/fileutils.h> #include <glibmm/fileutils.h>
@ -1493,40 +1491,29 @@ PortManager::port_engine ()
bool bool
PortManager::port_is_control_only (std::string const& name) PortManager::port_is_control_only (std::string const& name)
{ {
static regex_t compiled_pattern; /* This is a list of substrings that identify ports related
static string pattern; * to physical MIDI devices that we do not want to expose as
* normal physical ports.
if (pattern.empty ()) {
/* This is a list of regular expressions that match ports
* related to physical MIDI devices that we do not want to
* expose as normal physical ports.
*/ */
const char* const control_only_ports[] = { static const char* const control_only_ports[] = {
X_(".*Ableton Push.*"), X_("Ableton Push"),
X_(".*FaderPort .*"), X_("FaderPort "),
X_(".*FaderPort8 .*"), X_("FaderPort8 "),
X_(".*FaderPort16 .*"), X_("FaderPort16 "),
X_(".*FaderPort2 .*"), X_("FaderPort2 "),
X_(".*US-2400 .*"), X_("US-2400 "),
X_(".*Mackie .*"), X_("Mackie "),
X_(".*MIDI Control .*"), X_("MIDI Control "),
X_(".*Console1 .*"), X_("Console1 "),
}; };
pattern = "(";
for (size_t n = 0; n < sizeof (control_only_ports) / sizeof (control_only_ports[0]); ++n) { for (size_t n = 0; n < sizeof (control_only_ports) / sizeof (control_only_ports[0]); ++n) {
if (n > 0) { if (name.find (control_only_ports[n]) != string::npos) {
pattern += '|'; return true;
} }
pattern += control_only_ports[n];
} }
pattern += ')'; return false;
regcomp (&compiled_pattern, pattern.c_str (), REG_EXTENDED | REG_NOSUB);
}
return regexec (&compiled_pattern, name.c_str (), 0, 0, 0) == 0;
} }
static bool static bool

View file

@ -27,9 +27,11 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <regex.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "pbd/file_utils.h" #include "pbd/file_utils.h"
#include "pbd/stl_delete.h" #include "pbd/stl_delete.h"
@ -688,11 +690,6 @@ SMFSource::valid_midi_file (const string& file)
bool bool
SMFSource::safe_midi_file_extension (const string& file) SMFSource::safe_midi_file_extension (const string& file)
{ {
static regex_t compiled_pattern;
static bool compile = true;
const int nmatches = 2;
regmatch_t matches[nmatches];
if (Glib::file_test (file, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test (file, Glib::FILE_TEST_EXISTS)) {
if (!Glib::file_test (file, Glib::FILE_TEST_IS_REGULAR)) { if (!Glib::file_test (file, Glib::FILE_TEST_IS_REGULAR)) {
/* exists but is not a regular file */ /* exists but is not a regular file */
@ -700,17 +697,14 @@ SMFSource::safe_midi_file_extension (const string& file)
} }
} }
if (compile && regcomp (&compiled_pattern, "\\.[mM][iI][dD][iI]?$", REG_EXTENDED)) { const size_t dot_pos = file.rfind ('.');
return false; if (dot_pos == string::npos) {
} else {
compile = false;
}
if (regexec (&compiled_pattern, file.c_str(), nmatches, matches, 0)) {
return false; return false;
} }
return true; std::string const ext = PBD::downcase (file.substr(dot_pos + 1));
return ext == "mid" || ext == "midi";
} }
static bool compare_eventlist ( static bool compare_eventlist (

View file

@ -37,14 +37,9 @@
#include <cstring> #include <cstring>
#include <cerrno> #include <cerrno>
#include <iostream> #include <iostream>
#include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <fcntl.h>
#ifndef COMPILER_MSVC
#include <dirent.h>
#endif
#include <errno.h> #include <errno.h>
#include <regex.h> #include <fcntl.h>
#include "pbd/gstdio_compat.h" #include "pbd/gstdio_compat.h"
@ -673,45 +668,30 @@ bool
ARDOUR::matching_unsuffixed_filename_exists_in (const string& dir, const string& path) ARDOUR::matching_unsuffixed_filename_exists_in (const string& dir, const string& path)
{ {
string bws = basename_nosuffix (path); string bws = basename_nosuffix (path);
struct dirent* dentry;
GStatBuf statbuf;
DIR* dead;
bool ret = false;
if ((dead = ::opendir (dir.c_str())) == 0) { try {
error << string_compose (_("cannot open directory %1 (%2)"), dir, strerror (errno)) << endl; Glib::Dir directory (dir);
for (const auto& name : directory) {
if (name == "." || name == "..") {
continue;
}
string fullpath = Glib::build_filename (dir, name);
if (!Glib::file_test (fullpath, Glib::FILE_TEST_IS_REGULAR)) {
continue;
}
if (basename_nosuffix (name) == bws) {
return true;
}
}
} catch (const Glib::Error& e) {
error << string_compose (_("cannot open directory %1 (%2)"), dir, e.what()) << endl;
return false; return false;
} }
while ((dentry = ::readdir (dead)) != 0) { return false;
/* avoid '.' and '..' */
if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
(dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
continue;
}
string fullpath = Glib::build_filename (dir, dentry->d_name);
if (g_stat (fullpath.c_str(), &statbuf)) {
continue;
}
if (!S_ISREG (statbuf.st_mode)) {
continue;
}
string bws2 = basename_nosuffix (dentry->d_name);
if (bws2 == bws) {
ret = true;
break;
}
}
::closedir (dead);
return ret;
} }
uint32_t uint32_t

View file

@ -18,7 +18,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include <regex.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/time.h> #include <sys/time.h>

View file

@ -17,7 +17,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include <regex.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/time.h> #include <sys/time.h>

View file

@ -21,7 +21,6 @@
#include <math.h> #include <math.h>
#include <sys/time.h> #include <sys/time.h>
#include <regex.h>
#include <stdlib.h> #include <stdlib.h>
#include <glibmm.h> #include <glibmm.h>

View file

@ -18,8 +18,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include <regex.h>
#ifndef PLATFORM_WINDOWS #ifndef PLATFORM_WINDOWS
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/time.h> #include <sys/time.h>

View file

@ -17,7 +17,6 @@
*/ */
#include <math.h> #include <math.h>
#include <regex.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/time.h> #include <sys/time.h>

View file

@ -25,6 +25,7 @@
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <regex>
#ifdef COMPILER_MSVC #ifdef COMPILER_MSVC
#include <io.h> // Microsoft's nearest equivalent to <unistd.h> #include <io.h> // Microsoft's nearest equivalent to <unistd.h>
@ -1029,24 +1030,13 @@ GenericMidiControlProtocol::lookup_controllable (const string & str, MIDIControl
int id = 1; int id = 1;
string name; string name;
static regex_t compiled_pattern;
static bool compiled = false;
if (!compiled) {
const char * const pattern = "^[BS]?[0-9]+";
/* this pattern compilation is not going to fail */
regcomp (&compiled_pattern, pattern, REG_EXTENDED|REG_NOSUB);
/* leak compiled pattern */
compiled = true;
}
/* Step 3: identify what "rest" looks like - name, or simple nueric, or /* Step 3: identify what "rest" looks like - name, or simple nueric, or
* banked/selection specifier * banked/selection specifier
*/ */
bool matched = (regexec (&compiled_pattern, rest[0].c_str(), 0, 0, 0) == 0); static const std::regex pattern ("^[BS]?[0-9]+", std::regex::extended);
if (matched) { if (std::regex_search (rest[0], pattern)) {
bool banked = false; bool banked = false;
if (rest[0][0] == 'B') { if (rest[0][0] == 'B') {