Scott Kostyshak wrote:

> Do I understand correctly that this issue is no longer a beta blocker or
> is there still something that needs to be done here before beta?

The original reason why I viewed it as beta blocker (general user or sytem 
directory problems) turned out to be wrong.

I would not view it as beta blocker anymore, but you can judge yourself: 
tex2lyx is broken on OS X for files that contain any encoding changing 
instructions, e.g. \usepackage[latin1]{inputenc}. I am pretty sure that this 
can be fixed quite locally, so if we relase the beta without a fix, all 
testing effort on LyX itself will not be lost. Of course it would also mean 
that tex2lyx would be quite limited on OS X, but if this is mentioned in 
release notes it is not a problem IMHO.


Stephan, does the algo2e.tex test succeed if you apply the attached patch on 
a clean tree? If yes, then I have an idea how to work around the problem 
except for files using different encodings in different parts (which are 
rare anyway). The idea of the patch is to avoid changing the encoding of an 
open file stream. It should work for algo2e.tex out of the box, because the 
stream is opened with latin1 encoding by default with the patch. It should 
also work for CJKutf8.tex if you pass the -e UTF-8 commandline option to 
tex2lyx.


Georg
diff --git a/src/support/docstream.cpp b/src/support/docstream.cpp
index b07ac56..a98fcf0 100644
--- a/src/support/docstream.cpp
+++ b/src/support/docstream.cpp
@@ -88,6 +88,7 @@ public:
 		} else
 			out_cd_ = (iconv_t)(-1);
 	}
+	string const & encoding() const { return encoding_; }
 protected:
 	virtual ~iconv_codecvt_facet()
 	{
@@ -333,6 +334,12 @@ ifdocstream::ifdocstream() : base()
 }
 
 
+ifdocstream::ifdocstream(SetEnc const & enc) : base()
+{
+	setEncoding(*this, enc.encoding, in);
+}
+
+
 ifdocstream::ifdocstream(const char* s, ios_base::openmode mode,
 			 string const & encoding)
 	: base()
@@ -348,6 +355,12 @@ ofdocstream::ofdocstream(): base()
 }
 
 
+ofdocstream::ofdocstream(SetEnc const & enc) : base()
+{
+	setEncoding(*this, enc.encoding, out);
+}
+
+
 ofdocstream::ofdocstream(const char* s, ios_base::openmode mode,
 			 string const & encoding)
 	: base()
@@ -377,6 +390,12 @@ odocstream & operator<<(odocstream & os, SetEnc e)
 		// any other stream with a locale having a iconv_codecvt_facet.
 		// Flush the stream so that all pending output is written
 		// with the old encoding.
+		iconv_codecvt_facet const & facet =
+			use_facet<iconv_codecvt_facet>(os.rdbuf()->getloc());
+		// Avoid imbueing with the same encoding again, since this
+		// does not work with clang on OS X.
+		if (facet.encoding() == e.encoding)
+			return os;
 		os.flush();
 		locale locale(os.rdbuf()->getloc(),
 			new iconv_codecvt_facet(e.encoding, ios_base::out));
@@ -399,6 +418,12 @@ idocstream & operator<<(idocstream & is, SetEnc e)
 		// any other stream with a locale having a iconv_codecvt_facet.
 		// Flush the stream so that all pending output is written
 		// with the old encoding.
+		iconv_codecvt_facet const & facet =
+			use_facet<iconv_codecvt_facet>(is.rdbuf()->getloc());
+		// Avoid imbueing with the same encoding again, since this
+		// does not work with clang on OS X.
+		if (facet.encoding() == e.encoding)
+			return is;
 		//is.flush();
 		locale locale(is.rdbuf()->getloc(),
 			new iconv_codecvt_facet(e.encoding, ios_base::in));
diff --git a/src/support/docstream.h b/src/support/docstream.h
index 108d00e..3c8762b 100644
--- a/src/support/docstream.h
+++ b/src/support/docstream.h
@@ -40,12 +40,17 @@ typedef std::basic_istream<char_type> idocstream;
  */
 typedef std::basic_ostream<char_type> odocstream;
 
+struct SetEnc;
+
 /// File stream for reading UTF8-encoded files with automatic conversion to
 /// UCS4.
 class ifdocstream : public std::basic_ifstream<char_type> {
 	typedef std::basic_ifstream<char_type> base;
 public:
 	ifdocstream();
+	/// Create a stream with a specific encoding \p enc.
+	/// We must not pass \p enc as string, to avoid confusing it with a file name.
+	explicit ifdocstream(SetEnc const & enc);
 	explicit ifdocstream(const char* s,
 		std::ios_base::openmode mode = std::ios_base::in,
 		std::string const & encoding = "UTF-8");
@@ -59,6 +64,9 @@ class ofdocstream : public std::basic_ofstream<char_type> {
 	typedef std::basic_ofstream<char_type> base;
 public:
 	ofdocstream();
+	/// Create a stream with a specific encoding \p enc.
+	/// We must not pass \p enc as string, to avoid confusing it with a file name.
+	explicit ofdocstream(SetEnc const & enc);
 	explicit ofdocstream(const char* s,
 		std::ios_base::openmode mode = std::ios_base::out|std::ios_base::trunc,
 		std::string const & encoding = "UTF-8");
diff --git a/src/tex2lyx/tex2lyx.cpp b/src/tex2lyx/tex2lyx.cpp
index 5001ad0..0a48c0f 100644
--- a/src/tex2lyx/tex2lyx.cpp
+++ b/src/tex2lyx/tex2lyx.cpp
@@ -839,24 +839,9 @@ namespace {
  *  You must ensure that \p parentFilePathTeX is properly set before calling
  *  this function!
  */
-bool tex2lyx(idocstream & is, ostream & os, string encoding,
+bool tex2lyx(idocstream & is, ostream & os, string const & encoding,
              string const & outfiledir)
 {
-	// Set a sensible default encoding.
-	// This is used until an encoding command is found.
-	// For child documents use the encoding of the master, else ISO8859-1,
-	// (formerly known by its latex name latin1), since ISO8859-1 does not
-	// cause an iconv error if the actual encoding is different (bug 7509).
-	if (encoding.empty()) {
-		if (preamble.inputencoding() == "auto")
-			encoding = "ISO8859-1";
-		else {
-			Encoding const * const enc = encodings.fromLyXName(
-				preamble.inputencoding(), true);
-			encoding = enc->iconvName();
-		}
-	}
-
 	Parser p(is, fixed_encoding ? default_encoding : string());
 	p.setEncoding(encoding);
 	//p.dump();
@@ -925,10 +910,25 @@ bool tex2lyx(idocstream & is, ostream & os, string encoding,
 
 
 /// convert TeX from \p infilename to LyX and write it to \p os
-bool tex2lyx(FileName const & infilename, ostream & os, string const & encoding,
+bool tex2lyx(FileName const & infilename, ostream & os, string encoding,
              string const & outfiledir)
 {
-	ifdocstream is;
+	// Set a sensible default encoding.
+	// This is used until an encoding command is found.
+	// For child documents use the encoding of the master, else ISO8859-1,
+	// (formerly known by its latex name latin1), since ISO8859-1 does not
+	// cause an iconv error if the actual encoding is different (bug 7509).
+	if (encoding.empty()) {
+		if (preamble.inputencoding() == "auto")
+			encoding = "ISO8859-1";
+		else {
+			Encoding const * const enc = encodings.fromLyXName(
+					preamble.inputencoding(), true);
+			encoding = enc->iconvName();
+		}
+	}
+
+	ifdocstream is(setEncoding(encoding));
 	// forbid buffering on this stream
 	is.rdbuf()->pubsetbuf(0,0);
 	is.open(infilename.toFilesystemEncoding().c_str());

Reply via email to