Bernhard Roider schrieb:
In makeRelPath(..) for every umlaut in abspath or basepath there are two characters in the std::string. For determining the matching length of the two strings (using os::common_path()) they are converted to docstrings. Converting the strings to docstrings with from_utf8() results in one character for every umlaut. The resulting matching length of the two strings is based on the docstring length but is then used to split the std::strings (which are longer).

the bug was introduced with changeset 17430 (Georg?)

Bernhard, I am really impressed by your detailed analyses and patches! Welcome to the LyX team!

Meanwhile I created a patch for the problem above. IMHO we have to push docstring even further.

Georg, does the attached patch makes sense to you? If yes, could you please commit it? I may not be able to do so tomorrow.

Michael

Index: src/LaTeXFeatures.C
===================================================================
--- src/LaTeXFeatures.C	(Revision 17581)
+++ src/LaTeXFeatures.C	(Arbeitskopie)
@@ -544,7 +555,7 @@
 	     fi != end; ++fi)
 		sgmlpreamble << "\n<!ENTITY " << fi->first
 			     << (isSGMLFilename(fi->second) ? " SYSTEM \"" : " \"")
-			     << from_ascii(makeRelPath(fi->second, basename)) << "\">";
+			     << makeRelPath(from_utf8(fi->second), from_utf8(basename)) << "\">";
 
 	return sgmlpreamble.str();
 }
Index: src/insets/insetbibtex.C
===================================================================
--- src/insets/insetbibtex.C	(Revision 17581)
+++ src/insets/insetbibtex.C	(Arbeitskopie)
@@ -119,7 +119,8 @@
 	else if (!runparams.nice)
 		return fname;
 	else
-		return makeRelPath(fname, buffer.getMasterBuffer()->filePath());
+		return to_utf8(makeRelPath(from_utf8(fname),
+		                           from_utf8(buffer.getMasterBuffer()->filePath())));
 }
 
 }
Index: src/insets/ExternalSupport.C
===================================================================
--- src/insets/ExternalSupport.C	(Revision 17581)
+++ src/insets/ExternalSupport.C	(Arbeitskopie)
@@ -107,11 +107,13 @@
 			m_buffer->temppath() :
 			m_buffer->filePath();
 		string relToMasterPath = support::onlyPath(
-				support::makeRelPath(absname, masterpath));
+				to_utf8(support::makeRelPath(from_utf8(absname),
+		                                             from_utf8(masterpath))));
 		if (relToMasterPath == "./")
 			relToMasterPath.clear();
 		string relToParentPath = support::onlyPath(
-				support::makeRelPath(absname, parentpath));
+				to_utf8(support::makeRelPath(from_utf8(absname),
+				                             from_utf8(parentpath))));
 		if (relToParentPath == "./")
 			relToParentPath.clear();
 
Index: src/insets/insetinclude.C
===================================================================
--- src/insets/insetinclude.C	(Revision 17581)
+++ src/insets/insetinclude.C	(Arbeitskopie)
@@ -383,8 +383,8 @@
 	// if incfile is relative, make it relative to the master
 	// buffer directory.
 	if (!absolutePath(incfile)) {
-		incfile = makeRelPath(included_file.absFilename(),
-				      m_buffer->filePath());
+		incfile = to_utf8(makeRelPath(from_utf8(included_file.absFilename()),
+		                              from_utf8(m_buffer->filePath())));
 	}
 
 	// write it to a file (so far the complete file)
Index: src/converter.C
===================================================================
--- src/converter.C	(Revision 17581)
+++ src/converter.C	(Arbeitskopie)
@@ -398,9 +398,11 @@
 			}
 
 			string const infile2 = (conv.original_dir)
-				? infile.absFilename() : makeRelPath(infile.absFilename(), path);
+				? infile.absFilename() : to_utf8(makeRelPath(from_utf8(infile.absFilename()),
+				                                             from_utf8(path)));
 			string const outfile2 = (conv.original_dir)
-				? outfile.absFilename() : makeRelPath(outfile.absFilename(), path);
+				? outfile.absFilename() : to_utf8(makeRelPath(from_utf8(outfile.absFilename()),
+				                                              from_utf8(path)));
 
 			string command = conv.command;
 			command = subst(command, token_from, quoteName(infile2));
Index: src/frontends/controllers/helper_funcs.C
===================================================================
--- src/frontends/controllers/helper_funcs.C	(Revision 17581)
+++ src/frontends/controllers/helper_funcs.C	(Arbeitskopie)
@@ -85,8 +85,7 @@
 
 	docstring const outname = browseFile(fname, title, filters, save,
 					  dir1, dir2);
-	docstring const reloutname = lyx::from_utf8(
-		makeRelPath(lyx::to_utf8(outname), lyx::to_utf8(refpath)));
+	docstring const reloutname = makeRelPath(outname, refpath);
 	if (prefixIs(lyx::to_utf8(reloutname), "../"))
 		return outname;
 	else
Index: src/support/filetools.C
===================================================================
--- src/support/filetools.C	(Revision 17581)
+++ src/support/filetools.C	(Arbeitskopie)
@@ -669,18 +669,16 @@
 
 
 // Make relative path out of two absolute paths
-string const makeRelPath(string const & abspath, string const & basepath)
+docstring const makeRelPath(docstring const & abspath, docstring const & basepath)
 // Makes relative path out of absolute path. If it is deeper than basepath,
 // it's easy. If basepath and abspath share something (they are all deeper
 // than some directory), it'll be rendered using ..'s. If they are completely
 // different, then the absolute path will be used as relative path.
 {
-	string::size_type const abslen = abspath.length();
-	string::size_type const baselen = basepath.length();
+	docstring::size_type const abslen = abspath.length();
+	docstring::size_type const baselen = basepath.length();
 
-	// FIXME UNICODE
-	docstring::size_type i =
-		os::common_path(from_utf8(abspath), from_utf8(basepath));
+	docstring::size_type i = os::common_path(abspath, basepath);
 
 	if (i == 0) {
 		// actually no match - cannot make it relative
@@ -689,8 +687,8 @@
 
 	// Count how many dirs there are in basepath above match
 	// and append as many '..''s into relpath
-	string buf;
-	string::size_type j = i;
+	docstring buf;
+	docstring::size_type j = i;
 	while (j < baselen) {
 		if (basepath[j] == '/') {
 			if (j + 1 == baselen)
Index: src/support/filetools.h
===================================================================
--- src/support/filetools.h	(Revision 17581)
+++ src/support/filetools.h	(Arbeitskopie)
@@ -252,8 +252,8 @@
   different, then the absolute path will be used as relative path
   WARNING: the absolute path and base path must really be absolute paths!!!
   */
-std::string const
-makeRelPath(std::string const & abspath, std::string const & basepath);
+docstring const
+makeRelPath(docstring const & abspath, docstring const & basepath);
 
 /// Strip filename from path name
 std::string const onlyPath(std::string const & fname);
Index: src/support/filename.C
===================================================================
--- src/support/filename.C	(Revision 17581)
+++ src/support/filename.C	(Arbeitskopie)
@@ -143,13 +143,13 @@
 
 string const DocFileName::relFilename(string const & path) const
 {
-	return makeRelPath(name_, path);
+	return to_utf8(makeRelPath(from_utf8(name_), from_utf8(path)));
 }
 
 
 string const DocFileName::outputFilename(string const & path) const
 {
-	return save_abs_path_ ? name_ : makeRelPath(name_, path);
+	return save_abs_path_ ? name_ : to_utf8(makeRelPath(from_utf8(name_), from_utf8(path)));
 }
 
 
Index: src/tex2lyx/text.C
===================================================================
--- src/tex2lyx/text.C	(Revision 17581)
+++ src/tex2lyx/text.C	(Arbeitskopie)
@@ -1024,8 +1024,8 @@
 		return;
 	// FIXME UNICODE encoding of name may be wrong (makeAbsPath expects
 	// utf8)
-	name = makeRelPath(makeAbsPath(name, getMasterFilePath()).absFilename(),
-			   getParentFilePath());
+	name = to_utf8(makeRelPath(from_utf8(makeAbsPath(name, getMasterFilePath()).absFilename()),
+			           from_utf8(getParentFilePath())));
 }
 
 

Reply via email to