2 Copyright (C) 2000-2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <cstdio> /* for sprintf */
27 #include <sys/types.h>
37 #include <pbd/error.h>
38 #include <pbd/xml++.h>
39 #include <ardour/utils.h>
43 using namespace ARDOUR;
47 elapsed_time_to_str (char *buf, uint32_t seconds)
56 days = s / (3600 * 24);
57 s -= (days * 3600 * 24);
64 snprintf (buf, sizeof (buf), "%" PRIu32 " day%s %" PRIu32 " hour%s",
68 hours > 1 ? "s" : "");
70 snprintf (buf, sizeof (buf), "%" PRIu32 " hour%s %" PRIu32 " minute%s",
74 minutes > 1 ? "s" : "");
76 snprintf (buf, sizeof (buf), "%" PRIu32 " minute%s",
78 minutes > 1 ? "s" : "");
80 snprintf (buf, sizeof (buf), "%" PRIu32 " second%s",
82 seconds > 1 ? "s" : "");
84 snprintf (buf, sizeof (buf), "no time");
89 legalize_for_path (string str)
91 string::size_type pos;
92 string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=: ";
98 while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) {
99 legal.replace (pos, 1, "_");
107 operator<< (ostream& o, const BBT_Time& bbt)
109 o << bbt.bars << '|' << bbt.beats << '|' << bbt.ticks;
114 find_named_node (const XMLNode& node, string name)
117 XMLNodeConstIterator niter;
120 nlist = node.children();
122 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
126 if (child->name() == name) {
135 cmp_nocase (const string& s, const string& s2)
137 string::const_iterator p = s.begin();
138 string::const_iterator p2 = s2.begin();
140 while (p != s.end() && p2 != s2.end()) {
141 if (toupper(*p) != toupper(*p2)) {
142 return (toupper(*p) < toupper(*p2)) ? -1 : 1;
148 return (s2.size() == s.size()) ? 0 : (s.size() < s2.size()) ? -1 : 1;
152 tokenize_fullpath (string fullpath, string& path, string& name)
154 string::size_type m = fullpath.find_last_of("/");
156 if (m == string::npos) {
162 // does it look like just a directory?
163 if (m == fullpath.length()-1) {
166 path = fullpath.substr(0, m+1);
168 string::size_type n = fullpath.find(".ardour", m);
170 if (n == string::npos) {
173 name = fullpath.substr(m+1, n - m - 1);
178 touch_file(string path)
180 FILE* file = fopen(path.c_str(), "a");
189 gettimeofday(&tv, 0);
191 return (uint32_t long) tv.tv_sec * 1000000 + tv.tv_usec;
195 placement_as_string (Placement p)
200 default: /* to get g++ to realize we have all the cases covered */
207 region_name_from_path (string path)
209 string::size_type pos;
211 /* remove filename suffixes etc. */
213 if ((pos = path.find_last_of ('.')) != string::npos) {
214 path = path.substr (0, pos);
217 /* remove any "?R", "?L" or "?[a-z]" channel identifier */
219 string::size_type len = path.length();
221 if (len > 3 && (path[len-2] == '%' || path[len-2] == '?') &&
222 (path[len-1] == 'R' || path[len-1] == 'L' || (islower (path[len-1])))) {
224 path = path.substr (0, path.length() - 2);
231 path_expand (string path)
234 /* Handle tilde and environment variable expansion in session path */
238 switch (wordexp (path.c_str(), &expansion, WRDE_NOCMD|WRDE_UNDEF)) {
242 error << string_compose (_("illegal or badly-formed string used for path (%1)"), path) << endmsg;
246 if (expansion.we_wordc > 1) {
247 error << string_compose (_("path (%1) is ambiguous"), path) << endmsg;
251 ret = expansion.we_wordv[0];
253 wordfree (&expansion);