+ if (search_path.length() == 0) {
+ error << _("FileSource: search path not set") << endmsg;
+ goto out;
+ }
+
+ split (search_path, dirs, ':');
+
+ hits.clear ();
+
+ for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
+
+ fullpath = Glib::build_filename (*i, path);
+
+ if (Glib::file_test (fullpath, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
+ keeppath = fullpath;
+ hits.push_back (fullpath);
+ }
+ }
+
+ /* Remove duplicate inodes from the list of ambiguous files, since if there are symlinks
+ in the session path it is possible to arrive at the same file via more than one path.
+
+ I suppose this is not necessary on Windows.
+ */
+
+ vector<string> de_duped_hits;
+
+ for (vector<string>::iterator i = hits.begin(); i != hits.end(); ++i) {
+
+ vector<string>::iterator j = i;
+ ++j;
+
+ while (j != hits.end()) {
+ if (PBD::equivalent_paths (*i, *j)) {
+ /* *i and *j are the same file; break out of the loop early */
+ break;
+ }
+
+ ++j;
+ }
+
+ if (j == hits.end ()) {
+ de_duped_hits.push_back (*i);
+ }
+ }
+
+ if (de_duped_hits.size() > 1) {
+
+ /* more than one match: ask the user */
+
+ int which = FileSource::AmbiguousFileName (path, search_path, de_duped_hits).get_value_or (-1);
+
+ if (which < 0) {
+ goto out;
+ } else {
+ keeppath = de_duped_hits[which];
+ }
+
+ } else if (de_duped_hits.size() == 0) {
+
+ /* no match: error */
+
+ if (must_exist) {
+ error << string_compose(
+ _("Filesource: cannot find required file (%1): while searching %2"),
+ path, search_path) << endmsg;
+ goto out;
+ } else {
+ isnew = true;
+ }
+ } else {
+
+ /* only one match: happy days */
+
+ keeppath = de_duped_hits[0];
+ }
+
+ } else {
+ keeppath = path;
+ }
+
+ /* Current find() is unable to parse relative path names to yet non-existant
+ sources. QuickFix(tm)
+ */
+ if (keeppath == "") {
+ if (must_exist) {
+ error << "FileSource::find(), keeppath = \"\", but the file must exist" << endl;
+ } else {
+ keeppath = path;
+ }
+ }
+
+ found_path = keeppath;
+
+ ret = true;
+
+ out:
+ return ret;
+}
+
+/** Find the actual source file based on \a filename.
+ *
+ * If the source is within the session tree, \a filename should be a simple filename (no slashes).
+ * If the source is external, \a filename should be a full path.
+ * In either case, found_path is set to the complete absolute path of the source file.
+ * \return true iff the file was found.
+ */
+bool
+FileSource::find_2X (Session& s, DataType type, const string& path, bool must_exist,
+ bool& isnew, uint16_t& chan, string& found_path)
+{
+ string search_path = s.source_search_path (type);
+
+ string pathstr = path;
+ string::size_type pos;