X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Futils.cc;h=f23f1332b8a471333a04d1ca33e81058a37aab34;hb=4861eca97483128e5febb575b94688581abb0154;hp=2ea8b73dc262da227f7500b392d7f0f253e64246;hpb=a2354db3230d0e9408b455ca1c0eab361a33b319;p=ardour.git diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc index 2ea8b73dc2..f23f1332b8 100644 --- a/libs/ardour/utils.cc +++ b/libs/ardour/utils.cc @@ -25,6 +25,8 @@ #include /* for sprintf */ #include +#include +#include #include #include #include @@ -34,22 +36,22 @@ #include #include #include +#ifndef COMPILER_MSVC #include +#endif #include +#include #include #include -#ifdef HAVE_WORDEXP -#include -#endif - #include "pbd/cpus.h" #include "pbd/error.h" #include "pbd/stacktrace.h" #include "pbd/xml++.h" #include "pbd/basename.h" #include "pbd/strsplit.h" +#include "pbd/replace_all.h" #include "ardour/utils.h" #include "ardour/rc_configuration.h" @@ -60,41 +62,99 @@ using namespace ARDOUR; using namespace std; using namespace PBD; -string -legalize_for_path (const string& str) +static string +replace_chars (const string& str, const string& illegal_chars) { -#if OLD_SCHOOL_PROHIBITIVE string::size_type pos; - string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=: "; - string legal; + Glib::ustring legal; + + /* this is the one place in Ardour where we need to iterate across + * potential multibyte characters, and thus we need Glib::ustring + */ legal = str; pos = 0; - while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) { + while ((pos = legal.find_first_of (illegal_chars, pos)) != string::npos) { legal.replace (pos, 1, "_"); pos += 1; } - return legal; -#else + return string (legal); +} +/** take an arbitrary string as an argument, and return a version of it + * suitable for use as a path (directory/folder name). This is the Ardour 3.X + * and later version of this code. It defines a very small number of characters + * that are not allowed in a path on the build target filesystem (basically, + * POSIX or Windows) and replaces any instances of them with an underscore. + * + * NOTE: this is intended only to legalize for the filesystem that Ardour + * is running on. Export should use legalize_for_universal_path() since + * the goal there is to be legal across filesystems. + */ +string +legalize_for_path (const string& str) +{ + return replace_chars (str, "/\\"); +} + +/** take an arbitrary string as an argument, and return a version of it + * suitable for use as a path (directory/folder name). This is the Ardour 3.X + * and later version of this code. It defines a small number + * of characters that are not allowed in a path on any of our target + * filesystems, and replaces any instances of them with an underscore. + * + * NOTE: this is intended to create paths that should be legal on + * ANY filesystem. + */ +string +legalize_for_universal_path (const string& str) +{ + return replace_chars (str, "<>:\"/\\|?*"); +} + +/** Legalize for a URI path component. This is like + * legalize_for_universal_path, but stricter, disallowing spaces and hash. + * This avoids %20 escapes in URIs, but probably needs work to be more strictly + * correct. + */ +string +legalize_for_uri (const string& str) +{ + return replace_chars (str, "<>:\"/\\|?* #"); +} + +/** take an arbitrary string as an argument, and return a version of it + * suitable for use as a path (directory/folder name). This is the Ardour 2.X + * version of this code, which used an approach that came to be seen as + * problematic: defining the characters that were allowed and replacing all + * others with underscores. See legalize_for_path() for the 3.X and later + * version. + */ + +string +legalize_for_path_2X (const string& str) +{ string::size_type pos; - string illegal_chars = "/\\"; /* DOS, POSIX. Yes, we're going to ignore HFS */ - string legal; + string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=: "; + Glib::ustring legal; + + /* this is the one place in Ardour where we need to iterate across + * potential multibyte characters, and thus we need Glib::ustring + */ legal = str; pos = 0; - while ((pos = legal.find_first_of (illegal_chars, pos)) != string::npos) { + while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) { legal.replace (pos, 1, "_"); pos += 1; } - return legal; -#endif + return string (legal); } -string +string bump_name_once (const std::string& name, char delimiter) { string::size_type delim; @@ -136,46 +196,6 @@ bump_name_once (const std::string& name, char delimiter) } -bool -could_be_a_valid_path (const string& path) -{ - vector posix_dirs; - vector dos_dirs; - string testpath; - - split (path, posix_dirs, '/'); - split (path, dos_dirs, '\\'); - - /* remove the last component of each */ - - posix_dirs.erase (--posix_dirs.end()); - dos_dirs.erase (--dos_dirs.end()); - - if (G_DIR_SEPARATOR == '/') { - for (vector::iterator x = posix_dirs.begin(); x != posix_dirs.end(); ++x) { - testpath = Glib::build_filename (testpath, *x); - cerr << "Testing " << testpath << endl; - if (!Glib::file_test (testpath, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) { - return false; - } - } - } - - if (G_DIR_SEPARATOR == '\\') { - testpath = ""; - for (vector::iterator x = dos_dirs.begin(); x != dos_dirs.end(); ++x) { - testpath = Glib::build_filename (testpath, *x); - cerr << "Testing " << testpath << endl; - if (!Glib::file_test (testpath, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) { - return false; - } - } - } - - return true; -} - - XMLNode * find_named_node (const XMLNode& node, string name) { @@ -289,41 +309,6 @@ path_is_paired (string path, string& pair_base) return false; } -string -path_expand (string path) -{ - if (path.empty()) { - return path; - } - -#ifdef HAVE_WORDEXP - /* Handle tilde and environment variable expansion in session path */ - string ret = path; - - wordexp_t expansion; - switch (wordexp (path.c_str(), &expansion, WRDE_NOCMD|WRDE_UNDEF)) { - case 0: - break; - default: - error << string_compose (_("illegal or badly-formed string used for path (%1)"), path) << endmsg; - goto out; - } - - if (expansion.we_wordc > 1) { - error << string_compose (_("path (%1) is ambiguous"), path) << endmsg; - goto out; - } - - ret = expansion.we_wordv[0]; - out: - wordfree (&expansion); - return ret; - -#else - return path; -#endif -} - #if __APPLE__ string CFStringRefToStdString(CFStringRef stringRef) @@ -436,7 +421,14 @@ sync_source_to_string (SyncSource src, bool sh) } case MIDIClock: - return _("MIDI Clock"); + if (sh) { + return _("M-Clock"); + } else { + return _("MIDI Clock"); + } + + case LTC: + return _("LTC"); } /* GRRRR .... stupid, stupid gcc - you can't get here from there, all enum values are handled */ return _("JACK"); @@ -452,8 +444,12 @@ meter_falloff_to_float (MeterFalloff falloff) return METER_FALLOFF_SLOWEST; case MeterFalloffSlow: return METER_FALLOFF_SLOW; + case MeterFalloffSlowish: + return METER_FALLOFF_SLOWISH; case MeterFalloffMedium: return METER_FALLOFF_MEDIUM; + case MeterFalloffModerate: + return METER_FALLOFF_MODERATE; case MeterFalloffFast: return METER_FALLOFF_FAST; case MeterFalloffFaster: @@ -477,6 +473,12 @@ meter_falloff_from_float (float val) else if (val <= METER_FALLOFF_SLOW) { return MeterFalloffSlow; } + else if (val <= METER_FALLOFF_SLOWISH) { + return MeterFalloffSlowish; + } + else if (val <= METER_FALLOFF_MODERATE) { + return MeterFalloffModerate; + } else if (val <= METER_FALLOFF_MEDIUM) { return MeterFalloffMedium; } @@ -572,21 +574,13 @@ bool_as_string (bool yn) return (yn ? "yes" : "no"); } -bool -string_is_affirmative (const std::string& str) -{ - /* to be used only with XML data - not intended to handle user input */ - - return str == "1" || str == "y" || str == "Y" || (!g_strncasecmp(str.c_str(), "yes", str.length())); -} - const char* native_header_format_extension (HeaderFormat hf, const DataType& type) { if (type == DataType::MIDI) { return ".mid"; } - + switch (hf) { case BWF: return ".wav"; @@ -622,28 +616,28 @@ matching_unsuffixed_filename_exists_in (const string& dir, const string& path) error << string_compose (_("cannot open directory %1 (%2)"), dir, strerror (errno)) << endl; return false; } - + while ((dentry = ::readdir (dead)) != 0) { - + /* 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 (::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; @@ -673,21 +667,31 @@ how_many_dsp_threads () } else if (pu == 0) { - /* use all available CPUs + /* use all available CPUs */ - + num_threads = num_cpu; } else { /* use "pu" cores, if available */ - + num_threads = min (num_cpu, pu); } return num_threads; } +double gain_to_slider_position_with_max (double g, double max_gain) +{ + return gain_to_slider_position (g * 2.0/max_gain); +} + +double slider_position_to_gain_with_max (double g, double max_gain) +{ + return slider_position_to_gain (g * max_gain/2.0); +} + extern "C" { void c_stacktrace() { stacktrace (cerr); } }