force IFS=/ when calling path_expand, so that whitespace in paths doesn't cause worde...
[ardour.git] / libs / ardour / utils.cc
index 4b7fdc2f9118325eddf2c9e10fdd8fbfc62248a8..c1192c4fe123acd645572cddd1bd08acbd54b6b6 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <cstdio> /* for sprintf */
 #include <cstring>
+#include <cstdlib>
 #include <cmath>
 #include <cctype>
 #include <cstring>
@@ -75,7 +76,7 @@ legalize_for_path (const string& str)
                pos += 1;
        }
 
-       return legal;
+       return string (legal);
 }
 
 string
@@ -285,16 +286,41 @@ path_expand (string path)
        string ret = path;
 
        wordexp_t expansion;
-       switch (wordexp (path.c_str(), &expansion, WRDE_NOCMD|WRDE_UNDEF)) {
+       
+       /* force field expansion to avoid use whitespace, since we know this is
+        * a path
+        */
+
+       char *oifs = getenv ("IFS");
+       setenv ("IFS", "/", 1);
+       int result = wordexp (path.c_str(), &expansion, WRDE_NOCMD|WRDE_UNDEF);
+       if (oifs) {
+               setenv ("IFS", oifs, 1);
+       } else {
+               unsetenv ("IFS");
+       }
+
+       switch (result) {
        case 0:
                break;
+       case WRDE_NOSPACE:
+               /* see docs on wordexp() */
+               wordfree (&expansion);
+               /* fallthru */
        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;
+               string all;
+               for (unsigned int i = 0; i < expansion.we_wordc; ++i) {
+                       if (i > 0) {
+                               all += " | ";
+                       } 
+                       all += expansion.we_wordv[i];
+               }
+               error << string_compose (_("path (%1) is ambiguous: %2"), path, all) << endmsg;
                goto out;
        }
 
@@ -565,6 +591,13 @@ string_is_affirmative (const std::string& str)
                return false;
        }
 
+       /* the use of g_strncasecmp() is solely to get around issues with
+        * charsets posed by trying to use C++ for the same
+        * comparison. switching a std::string to its lower- or upper-case
+        * version has several issues, but handled by default
+        * in the way we desire when doing it in C.
+        */
+
        return str == "1" || str == "y" || str == "Y" || (!g_strncasecmp(str.c_str(), "yes", str.length()));
 }