add realloc pool to MSVC project
[ardour.git] / libs / pbd / search_path.cc
index e56e22fee391a3f4c0d1c35be0178371b8c7ab05..46292ef1f353dab4e8286dfd60353f82e7e1c730 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2007 Tim Mayberry 
+    Copyright (C) 2007 Tim Mayberry
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -17,6 +17,9 @@
 
 */
 
+#include <string>
+
+#include <glib.h>
 #include <glibmm/miscutils.h>
 
 #include "pbd/tokenizer.h"
 
 using namespace std;
 
-namespace {
-
-#ifdef PLATFORM_WINDOWS
-const char * const path_delimiter = ";";
-#else
-const char * const path_delimiter = ":";
-#endif
-
-}
-
 namespace PBD {
 
-SearchPath::SearchPath ()
+Searchpath::Searchpath ()
 {
 
 }
 
-SearchPath::SearchPath (const string& path)
+Searchpath::Searchpath (const string& path)
 {
        vector<std::string> tmp;
 
-       if (tokenize (path, string(path_delimiter), std::back_inserter (tmp))) {
+       if (tokenize (path, string(G_SEARCHPATH_SEPARATOR_S), std::back_inserter (tmp))) {
                add_directories (tmp);
        }
 }
 
-SearchPath::SearchPath (const vector<std::string>& paths)
+Searchpath::Searchpath (const vector<std::string>& paths)
 {
        add_directories (paths);
 }
 
 void
-SearchPath::add_directory (const std::string& directory_path)
+Searchpath::remove_directory (const std::string& directory_path)
+{
+       if (directory_path.empty()) {
+               return;
+       }
+
+       for (vector<std::string>::iterator i = begin(); i != end();) {
+               if (*i == directory_path) {
+                       i = erase (i);
+               } else {
+                       ++i;
+               }
+       }
+}
+
+void
+Searchpath::remove_directories (const vector<std::string>& paths)
 {
-       if (!directory_path.empty()) {
-               push_back(directory_path);
+       for(vector<std::string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
+               remove_directory (*i);
        }
 }
 
 void
-SearchPath::add_directories (const vector<std::string>& paths)
+Searchpath::add_directory (const std::string& directory_path)
+{
+       if (directory_path.empty()) {
+               return;
+       }
+       for (vector<std::string>::const_iterator i = begin(); i != end(); ++i) {
+               if (*i == directory_path) {
+                       return;
+               }
+       }
+       push_back(directory_path);
+}
+
+void
+Searchpath::add_directories (const vector<std::string>& paths)
 {
        for(vector<std::string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
                add_directory (*i);
@@ -73,13 +96,13 @@ SearchPath::add_directories (const vector<std::string>& paths)
 }
 
 const string
-SearchPath::to_string () const
+Searchpath::to_string () const
 {
        string path;
 
        for (vector<std::string>::const_iterator i = begin(); i != end(); ++i) {
                path += *i;
-               path += path_delimiter;
+               path += G_SEARCHPATH_SEPARATOR;
        }
 
        path = path.substr (0, path.length() - 1); // drop final separator
@@ -87,45 +110,90 @@ SearchPath::to_string () const
        return path;
 }
 
-SearchPath& 
-SearchPath::operator+= (const SearchPath& spath)
+Searchpath&
+Searchpath::operator+= (const Searchpath& spath)
 {
        insert(end(), spath.begin(), spath.end());
        return *this;
 }
 
-SearchPath& 
-SearchPath::operator+= (const std::string& directory_path)
+Searchpath&
+Searchpath::operator+= (const std::string& directory_path)
 {
        add_directory (directory_path);
        return *this;
 }
 
-SearchPath& 
-SearchPath::operator+ (const std::string& directory_path)
+const Searchpath
+Searchpath::operator+ (const std::string& directory_path)
 {
-       add_directory (directory_path);
+       return Searchpath (*this) += directory_path;
+}
+
+const Searchpath
+Searchpath::operator+ (const Searchpath& spath)
+{
+       return Searchpath (*this) += spath;
+}
+
+Searchpath&
+Searchpath::operator-= (const Searchpath& spath)
+{
+       remove_directories (spath);
        return *this;
 }
 
-SearchPath& 
-SearchPath::operator+ (const SearchPath& spath)
+Searchpath&
+Searchpath::operator-= (const std::string& directory_path)
 {
-       // concatenate paths into new SearchPath
-       insert(end(), spath.begin(), spath.end());
+       remove_directory (directory_path);
        return *this;
 }
 
-SearchPath&
-SearchPath::add_subdirectory_to_paths (const string& subdir)
+
+Searchpath&
+Searchpath::add_subdirectory_to_paths (const string& subdir)
 {
        for (vector<std::string>::iterator i = begin(); i != end(); ++i) {
-               // should these new paths just be added to the end of 
+               // should these new paths just be added to the end of
                // the search path rather than replace?
                *i = Glib::build_filename (*i, subdir);
        }
-       
+
        return *this;
 }
 
+bool
+Searchpath::contains (const string& path) const
+{
+       std::vector<std::string>::const_iterator i = find(begin(), end(), path);
+
+       if (i == end()) {
+               return false;
+       }
+       return true;
+}
+
+/* This is not part of the Searchpath object, but is closely related to the
+ * whole idea, and we put it here for convenience.
+ */
+
+void
+export_search_path (const string& base_dir, const char* varname, const char* dir)
+{
+       string path;
+       const char * cstr = g_getenv (varname);
+
+       if (cstr) {
+               path = cstr;
+               path += G_SEARCHPATH_SEPARATOR;
+       } else {
+               path = "";
+       }
+       path += base_dir;
+       path += dir;
+
+       g_setenv (varname, path.c_str(), 1);
+}
+
 } // namespace PBD