On Sunday 24 December 2006 01:18, Enrico Forestieri wrote: > The problem here is that toqstr() expects an utf8 encoded argument, > whereas makeAbsPath() returns a path already in the filesystem encoding. > The attached patch solves the problem, but I don't know if it is the right > thing to do. Maybe getcwd() should be changed to return an utf8 encoded > string?
Many thanks, I forgot to convert getcwd. The attached patch changes getcwd and makeAbsPath to return a FileName. That makes it clear what encoding is used. I also updated tex2lyx a bit to cope with non-ascii filenames (although that does not work for inlcuded file, only for files given on the command line). I also found one other place where a conversion to filesystem encoding was missing (in LyXFunc::dispatch). Georg
Index: src/lyxvc.C =================================================================== --- src/lyxvc.C (Revision 16394) +++ src/lyxvc.C (Arbeitskopie) @@ -229,7 +229,7 @@ if (!vcs) return string(); - FileName const tmpf(tempName(string(), "lyxvclog")); + FileName const tmpf(tempName(FileName(), "lyxvclog")); if (tmpf.empty()) { lyxerr[Debug::LYXVC] << "Could not generate logfile " << tmpf << endl; Index: src/lyx_cb.C =================================================================== --- src/lyx_cb.C (Revision 16394) +++ src/lyx_cb.C (Arbeitskopie) @@ -155,7 +155,7 @@ return false; // Make sure the absolute filename ends with appropriate suffix - fname = makeAbsPath(fname); + fname = makeAbsPath(fname).absFilename(); if (!isLyXFilename(fname)) fname += ".lyx"; } else @@ -233,7 +233,7 @@ // anyway. bool failed = false; - FileName const tmp_ret(tempName(string(), "lyxauto")); + FileName const tmp_ret(tempName(FileName(), "lyxauto")); if (!tmp_ret.empty()) { bv_.buffer()->writeFile(tmp_ret); // assume successful write of tmp_ret @@ -359,7 +359,7 @@ if (result.first == FileDialog::Later) return string(); - fname = FileName(makeAbsPath(to_utf8(result.second))); + fname = makeAbsPath(to_utf8(result.second)); if (fname.empty()) return string(); Index: src/insets/insetbibtex.C =================================================================== --- src/insets/insetbibtex.C (Revision 16394) +++ src/insets/insetbibtex.C (Arbeitskopie) @@ -113,7 +113,7 @@ string normalize_name(Buffer const & buffer, OutputParams const & runparams, string const & name, string const & ext) { - string const fname = makeAbsPath(name, buffer.filePath()); + string const fname = makeAbsPath(name, buffer.filePath()).absFilename(); if (absolutePath(name) || !isFileReadable(FileName(fname + ext))) return name; else if (!runparams.nice) @@ -166,8 +166,8 @@ string utf8input(to_utf8(input)); string database = normalize_name(buffer, runparams, utf8input, ".bib"); - string const try_in_file = makeAbsPath(database + ".bib", buffer.filePath()); - bool const not_from_texmf = isFileReadable(FileName(try_in_file)); + FileName const try_in_file(makeAbsPath(database + ".bib", buffer.filePath())); + bool const not_from_texmf = isFileReadable(try_in_file); if (!runparams.inComment && !runparams.dryrun && !runparams.nice && not_from_texmf) { @@ -175,7 +175,7 @@ // mangledFilename() needs the extension DocFileName const in_file = DocFileName(try_in_file); database = removeExtension(in_file.mangledFilename()); - FileName const out_file = FileName(makeAbsPath(database + ".bib", + FileName const out_file(makeAbsPath(database + ".bib", buffer.getMasterBuffer()->temppath())); bool const success = copy(in_file, out_file); @@ -221,8 +221,8 @@ if (!style.empty()) { string base = normalize_name(buffer, runparams, style, ".bst"); - string const try_in_file = makeAbsPath(base + ".bst", buffer.filePath()); - bool const not_from_texmf = isFileReadable(FileName(try_in_file)); + FileName const try_in_file(makeAbsPath(base + ".bst", buffer.filePath())); + bool const not_from_texmf = isFileReadable(try_in_file); // If this style does not come from texmf and we are not // exporting to .tex copy it to the tmp directory. // This prevents problems with spaces and 8bit charcaters @@ -232,7 +232,7 @@ // use new style name DocFileName const in_file = DocFileName(try_in_file); base = removeExtension(in_file.mangledFilename()); - FileName const out_file = FileName(makeAbsPath(base + ".bst", + FileName const out_file(makeAbsPath(base + ".bst", buffer.getMasterBuffer()->temppath())); bool const success = copy(in_file, out_file); if (!success) { Index: src/insets/insetexternal.C =================================================================== --- src/insets/insetexternal.C (Revision 16394) +++ src/insets/insetexternal.C (Arbeitskopie) @@ -70,11 +70,11 @@ TempName::TempName() { - string const tempname = support::tempName(string(), "lyxext"); + support::FileName const tempname(support::tempName(support::FileName(), "lyxext")); // FIXME: This is unsafe - support::unlink(support::FileName(tempname)); + support::unlink(tempname); // must have an extension for the converter code to work correctly. - tempname_ = support::FileName(tempname + ".tmp"); + tempname_ = support::FileName(tempname.absFilename() + ".tmp"); } Index: src/insets/insetgraphics.C =================================================================== --- src/insets/insetgraphics.C (Revision 16394) +++ src/insets/insetgraphics.C (Arbeitskopie) @@ -502,9 +502,9 @@ string::size_type const ext_len = file_in.length() - base.length(); mangled[mangled.length() - ext_len] = '.'; } - string const file_out = support::makeAbsPath(mangled, dir); + FileName const file_out(support::makeAbsPath(mangled, dir)); - return copyFileIfNeeded(file, FileName(file_out)); + return copyFileIfNeeded(file, file_out); } Index: src/insets/ExternalSupport.C =================================================================== --- src/insets/ExternalSupport.C (Revision 16394) +++ src/insets/ExternalSupport.C (Arbeitskopie) @@ -91,7 +91,7 @@ params.filename.outputFilename(parentpath); string const basename = support::changeExtension( support::onlyFilename(filename), string()); - string const absname = support::makeAbsPath(filename, parentpath); + string const absname = support::makeAbsPath(filename, parentpath).absFilename(); string result = s; if (what != ALL_BUT_PATHS) { @@ -167,7 +167,7 @@ string const file = result.substr(pos + 12, end - (pos + 12)); string contents; - FileName const absfile = FileName( + FileName const absfile( support::makeAbsPath(file, m_buffer->temppath())); if (support::isFileReadable(absfile)) contents = support::getFileContents(absfile); @@ -242,7 +242,7 @@ // We copy the source file to the temp dir and do the conversion // there if necessary - FileName const temp_file = FileName( + FileName const temp_file( support::makeAbsPath(params.filename.mangledFilename(), m_buffer->temppath())); if (!params.filename.empty()) { @@ -265,7 +265,7 @@ string const to_file = doSubstitution(params, buffer, outputFormat.updateResult, false, true); - FileName const abs_to_file = FileName( + FileName const abs_to_file( support::makeAbsPath(to_file, m_buffer->temppath())); // Record the referenced files for the exporter. Index: src/insets/insetinclude.C =================================================================== --- src/insets/insetinclude.C (Revision 16394) +++ src/insets/insetinclude.C (Arbeitskopie) @@ -217,7 +217,7 @@ } -string const includedFilename(Buffer const & buffer, +FileName const includedFilename(Buffer const & buffer, InsetCommandParams const & params) { return makeAbsPath(to_utf8(params["filename"]), @@ -333,7 +333,7 @@ if (isVerbatim(params)) return 0; - string const included_file = includedFilename(buffer, params); + string const included_file = includedFilename(buffer, params).absFilename(); if (!isLyXFilename(included_file)) return 0; @@ -347,18 +347,17 @@ if (isVerbatim(params)) return false; - string const included_file = includedFilename(buffer, params); - if (!isLyXFilename(included_file)) + FileName const included_file = includedFilename(buffer, params); + if (!isLyXFilename(included_file.absFilename())) return false; - Buffer * buf = theBufferList().getBuffer(included_file); + Buffer * buf = theBufferList().getBuffer(included_file.absFilename()); if (!buf) { // the readonly flag can/will be wrong, not anymore I think. - FileName const fullname(included_file); - if (!fs::exists(fullname.toFilesystemEncoding())) + if (!fs::exists(included_file.toFilesystemEncoding())) return false; - buf = theBufferList().newBuffer(included_file); - if (!loadLyXFile(buf, fullname)) + buf = theBufferList().newBuffer(included_file.absFilename()); + if (!loadLyXFile(buf, included_file)) return false; } if (buf) @@ -498,7 +497,7 @@ if (isVerbatim(params_)) { // FIXME: We don't know the encoding of the file docstring const str = from_utf8( - getFileContents(FileName(includedFilename(buffer, params_)))); + getFileContents(includedFilename(buffer, params_))); os << str; // Return how many newlines we issued. return int(lyx::count(str.begin(), str.end(), '\n')); @@ -516,7 +515,7 @@ if (incfile.empty()) return 0; - string const included_file = includedFilename(buffer, params_); + string const included_file = includedFilename(buffer, params_).absFilename(); // write it to a file (so far the complete file) string const exportfile = changeExtension(incfile, ".sgml"); @@ -561,7 +560,7 @@ Buffer const & buffer = features.buffer(); - string const included_file = includedFilename(buffer, params_); + string const included_file = includedFilename(buffer, params_).absFilename(); if (isLyXFilename(included_file)) writefile = changeExtension(included_file, ".sgml"); @@ -571,7 +570,7 @@ if (!features.runparams().nice && !isVerbatim(params_)) { incfile = DocFileName(writefile).mangledFilename(); writefile = makeAbsPath(incfile, - buffer.getMasterBuffer()->temppath()); + buffer.getMasterBuffer()->temppath()).absFilename(); } features.includeFile(include_label, writefile); @@ -601,7 +600,7 @@ std::vector<docstring> & list) const { if (loadIfNeeded(buffer, params_)) { - string const included_file = includedFilename(buffer, params_); + string const included_file = includedFilename(buffer, params_).absFilename(); Buffer * tmp = theBufferList().getBuffer(included_file); tmp->setParentName(""); tmp->getLabelList(list); @@ -614,7 +613,7 @@ std::vector<std::pair<string, docstring> > & keys) const { if (loadIfNeeded(buffer, params_)) { - string const included_file = includedFilename(buffer, params_); + string const included_file = includedFilename(buffer, params_).absFilename(); Buffer * tmp = theBufferList().getBuffer(included_file); tmp->setParentName(""); tmp->fillWithBibKeys(keys); @@ -727,10 +726,10 @@ bool preview_wanted(InsetCommandParams const & params, Buffer const & buffer) { - string const included_file = includedFilename(buffer, params); + FileName const included_file = includedFilename(buffer, params); return type(params) == INPUT && params.preview() && - isFileReadable(FileName(included_file)); + isFileReadable(included_file); } @@ -751,7 +750,7 @@ InsetCommandParams const & params = inset.params(); if (RenderPreview::status() != LyXRC::PREVIEW_OFF && preview_wanted(params, buffer)) { - renderer.setAbsFile(FileName(includedFilename(buffer, params))); + renderer.setAbsFile(includedFilename(buffer, params)); docstring const snippet = latex_string(inset, buffer); renderer.addPreview(snippet, buffer); } @@ -764,7 +763,7 @@ { Buffer const & buffer = ploader.buffer(); if (preview_wanted(params(), buffer)) { - preview_->setAbsFile(FileName(includedFilename(buffer, params()))); + preview_->setAbsFile(includedFilename(buffer, params())); docstring const snippet = latex_string(*this, buffer); preview_->addPreview(snippet, ploader); } Index: src/exporter.C =================================================================== --- src/exporter.C (Revision 16394) +++ src/exporter.C (Arbeitskopie) @@ -243,7 +243,7 @@ string const fmt = formats.getFormatFromFile(it->sourceName); status = copyFile(fmt, it->sourceName, - FileName(makeAbsPath(it->exportName, dest)), + makeAbsPath(it->exportName, dest), it->exportName, status == FORCE); } if (status == CANCEL) { Index: src/graphics/GraphicsCacheItem.C =================================================================== --- src/graphics/GraphicsCacheItem.C (Revision 16394) +++ src/graphics/GraphicsCacheItem.C (Arbeitskopie) @@ -385,7 +385,7 @@ FileName filename; zipped_ = zippedFile(filename_); if (zipped_) { - unzipped_filename_ = FileName(tempName(string(), filename_.toFilesystemEncoding())); + unzipped_filename_ = tempName(FileName(), filename_.toFilesystemEncoding()); if (unzipped_filename_.empty()) { setStatus(ErrorConverting); lyxerr[Debug::GRAPHICS] @@ -432,17 +432,17 @@ // Add some stuff to create a uniquely named temporary file. // This file is deleted in loadImage after it is loaded into memory. - string const to_file_base = tempName(string(), "CacheItem"); + FileName const to_file_base(tempName(FileName(), "CacheItem")); remove_loaded_file_ = true; // Remove the temp file, we only want the name... // FIXME: This is unsafe! - unlink(FileName(to_file_base)); + unlink(to_file_base); // Connect a signal to this->imageConverted and pass this signal to // the graphics converter so that we can load the modified file // on completion of the conversion process. - converter_.reset(new Converter(filename, to_file_base, from, to_)); + converter_.reset(new Converter(filename, to_file_base.absFilename(), from, to_)); converter_->connect(boost::bind(&Impl::imageConverted, this, _1)); converter_->startConversion(); } Index: src/graphics/GraphicsConverter.C =================================================================== --- src/graphics/GraphicsConverter.C (Revision 16394) +++ src/graphics/GraphicsConverter.C (Arbeitskopie) @@ -30,6 +30,7 @@ namespace support = lyx::support; +using support::addExtension; using support::changeExtension; using support::FileName; using support::Forkedcall; @@ -301,14 +302,14 @@ // Remember to remove the temp file because we only want the name... static int counter = 0; string const tmp = "gconvert" + convert<string>(counter++); - string const to_base = tempName(string(), tmp); - unlink(FileName(to_base)); + FileName const to_base(tempName(FileName(), tmp)); + unlink(to_base); // Create a copy of the file in case the original name contains // problematic characters like ' or ". We can work around that problem // in python, but the converters might be shell scripts and have more // troubles with it. - string outfile = changeExtension(to_base, getExtension(from_file.absFilename())); + string outfile = addExtension(to_base.absFilename(), getExtension(from_file.absFilename())); script << "infile = " << quoteName(from_file.absFilename(), quote_python) << "\n" "outfile = " << quoteName(outfile, quote_python) << "\n" "shutil.copy(infile, outfile)\n"; @@ -363,7 +364,7 @@ // Build the conversion command string const infile = outfile; string const infile_base = changeExtension(infile, string()); - outfile = changeExtension(to_base, conv.To->extension()); + outfile = addExtension(to_base.absFilename(), conv.To->extension()); // Store these names in the python script script << "infile = " << quoteName(infile, quote_python) << "\n" Index: src/converter.C =================================================================== --- src/converter.C (Revision 16394) +++ src/converter.C (Arbeitskopie) @@ -451,7 +451,7 @@ " < " + quoteName(infile2 + ".out") + " > " + quoteName(logfile); one.startscript(Systemcall::Wait, command2); - if (!scanLog(*buffer, command, FileName(makeAbsPath(logfile, path)), errorList)) + if (!scanLog(*buffer, command, makeAbsPath(logfile, path), errorList)) return false; } Index: src/buffer.C =================================================================== --- src/buffer.C (Revision 16394) +++ src/buffer.C (Arbeitskopie) @@ -102,7 +102,6 @@ using support::destroyDir; using support::FileName; using support::getFormatFromContents; -using support::isDirWriteable; using support::libFileSearch; using support::latex_path; using support::ltrim; @@ -389,9 +388,8 @@ void Buffer::setFileName(string const & newfile) { - string const filename = makeAbsPath(newfile); - pimpl_->filename = FileName(filename); - params().filepath = onlyPath(filename); + pimpl_->filename = makeAbsPath(newfile); + params().filepath = onlyPath(pimpl_->filename.absFilename()); setReadonly(fs::is_readonly(pimpl_->filename.toFilesystemEncoding())); updateTitles(); } Index: src/lyxfunc.C =================================================================== --- src/lyxfunc.C (Revision 16394) +++ src/lyxfunc.C (Arbeitskopie) @@ -1017,7 +1017,7 @@ // case 1: print to a file command += lyxrc.print_to_file + quoteName(makeAbsPath(target_name, - path)) + path).toFilesystemEncoding()) + ' ' + quoteName(dviname); res = one.startscript(Systemcall::DontWait, @@ -1342,17 +1342,17 @@ case LFUN_BUFFER_CHILD_OPEN: { BOOST_ASSERT(lyx_view_); - string const filename = + FileName const filename = makeAbsPath(argument, lyx_view_->buffer()->filePath()); // FIXME Should use bformat setMessage(_("Opening child document ") + - makeDisplayPath(filename) + "..."); + makeDisplayPath(filename.absFilename()) + "..."); view()->saveBookmark(false); string const parentfilename = lyx_view_->buffer()->fileName(); - if (theBufferList().exists(filename)) - lyx_view_->setBuffer(theBufferList().getBuffer(filename)); + if (theBufferList().exists(filename.absFilename())) + lyx_view_->setBuffer(theBufferList().getBuffer(filename.absFilename())); else - lyx_view_->loadLyXFile(FileName(filename)); + lyx_view_->loadLyXFile(filename); // Set the parent name of the child document. // This makes insertion of citations and references in the child work, // when the target is in the parent or another child document. @@ -1412,8 +1412,8 @@ } case LFUN_PREFERENCES_SAVE: { - lyxrc.write(FileName(makeAbsPath("preferences", - package().user_support())), + lyxrc.write(makeAbsPath("preferences", + package().user_support()), false); break; } @@ -1796,7 +1796,7 @@ if (view()->buffer()) { string const trypath = lyx_view_->buffer()->filePath(); // If directory is writeable, use this as default. - if (isDirWriteable(trypath)) + if (isDirWriteable(FileName(trypath))) initpath = trypath; } @@ -1847,7 +1847,7 @@ if (view()->buffer()) { string const trypath = lyx_view_->buffer()->filePath(); // If directory is writeable, use this as default. - if (isDirWriteable(trypath)) + if (isDirWriteable(FileName(trypath))) initpath = trypath; } @@ -1920,7 +1920,7 @@ if (view()->buffer()) { string const trypath = lyx_view_->buffer()->filePath(); // If directory is writeable, use this as default. - if (isDirWriteable(trypath)) + if (isDirWriteable(FileName(trypath))) initpath = trypath; } Index: src/LaTeX.C =================================================================== --- src/LaTeX.C (Revision 16394) +++ src/LaTeX.C (Arbeitskopie) @@ -184,7 +184,7 @@ bool rerun = false; // rerun requested // The class LaTeX does not know the temp path. - theBufferList().updateIncludedTeXfiles(getcwd(), runparams); + theBufferList().updateIncludedTeXfiles(getcwd().absFilename(), runparams); // Never write the depfile if an error was encountered. @@ -512,7 +512,7 @@ aux_info.styles.insert(style); } else if (regex_match(token, sub, reg4)) { string const file2 = sub.str(1); - scanAuxFile(FileName(makeAbsPath(file2)), aux_info); + scanAuxFile(makeAbsPath(file2), aux_info); } } } @@ -809,7 +809,7 @@ // This line is not present if no toc should be created. static regex miktexTocReg("[EMAIL PROTECTED]"); - FileName const fn = FileName(makeAbsPath(logfile)); + FileName const fn(makeAbsPath(logfile)); ifstream ifs(fn.toFilesystemEncoding().c_str()); while (ifs) { // Ok, the scanning of files here is not sufficient. Index: src/frontends/qt4/FileDialog.C =================================================================== --- src/frontends/qt4/FileDialog.C (Revision 16394) +++ src/frontends/qt4/FileDialog.C (Arbeitskopie) @@ -82,8 +82,8 @@ result.first = FileDialog::Chosen; #ifdef USE_NATIVE_FILEDIALOG - docstring const startsWith - = lyx::from_utf8(makeAbsPath(lyx::to_utf8(suggested), lyx::to_utf8(path))); + docstring const startsWith = from_utf8( + makeAbsPath(to_utf8(suggested), to_utf8(path)).absFilename()); result.second = lyx::from_utf8(internal_path(fromqstr( QFileDialog::getSaveFileName(qApp->focusWidget(), toqstr(title_), toqstr(startsWith), toqstr(filters.as_string()) )))); @@ -118,8 +118,8 @@ result.first = FileDialog::Chosen; #ifdef USE_NATIVE_FILEDIALOG - docstring const startsWith = - lyx::from_utf8(makeAbsPath(lyx::to_utf8(suggested), lyx::to_utf8(path))); + docstring const startsWith = from_utf8( + makeAbsPath(to_utf8(suggested), to_utf8(path)).absFilename()); result.second = lyx::from_utf8(internal_path(fromqstr( QFileDialog::getOpenFileName(qApp->focusWidget(), toqstr(title_), toqstr(startsWith), toqstr(filters.as_string()) )))); @@ -150,8 +150,8 @@ result.first = FileDialog::Chosen; #ifdef USE_NATIVE_FILEDIALOG - docstring const startsWith - = lyx::from_utf8(makeAbsPath(lyx::to_utf8(suggested), lyx::to_utf8(path))); + docstring const startsWith = from_utf8( + makeAbsPath(to_utf8(suggested), to_utf8(path)).absFilename()); result.second = lyx::from_utf8(internal_path(fromqstr( QFileDialog::getExistingDirectory(qApp->focusWidget(), toqstr(title_),toqstr(startsWith))))); Index: src/frontends/controllers/ControlRef.C =================================================================== --- src/frontends/controllers/ControlRef.C (Revision 16394) +++ src/frontends/controllers/ControlRef.C (Arbeitskopie) @@ -38,7 +38,7 @@ vector<docstring> const ControlRef::getLabelList(string const & name) const { - Buffer const & buf = *theBufferList().getBuffer(makeAbsPath(name)); + Buffer const & buf = *theBufferList().getBuffer(makeAbsPath(name).absFilename()); vector<docstring> list; buf.getLabelList(list); return list; Index: src/frontends/controllers/ControlInclude.C =================================================================== --- src/frontends/controllers/ControlInclude.C (Revision 16394) +++ src/frontends/controllers/ControlInclude.C (Arbeitskopie) @@ -111,11 +111,10 @@ bool ControlInclude::fileExists(string const & file) { - string const fileWithAbsPath - = makeAbsPath(file, - onlyPath(kernel().buffer().fileName())); + FileName const fileWithAbsPath( + makeAbsPath(file, onlyPath(kernel().buffer().fileName()))); - if (isFileReadable(FileName(fileWithAbsPath))) + if (isFileReadable(fileWithAbsPath)) return true; return false; Index: src/frontends/controllers/helper_funcs.C =================================================================== --- src/frontends/controllers/helper_funcs.C (Revision 16394) +++ src/frontends/controllers/helper_funcs.C (Arbeitskopie) @@ -80,8 +80,8 @@ pair<docstring,docstring> const & dir1, pair<docstring,docstring> const & dir2) { - docstring const fname = lyx::from_utf8( - makeAbsPath(lyx::to_utf8(filename), lyx::to_utf8(refpath))); + docstring const fname = from_utf8(makeAbsPath( + to_utf8(filename), to_utf8(refpath)).absFilename()); docstring const outname = browseFile(fname, title, filters, save, dir1, dir2); Index: src/support/path.h =================================================================== --- src/support/path.h (Revision 16394) +++ src/support/path.h (Arbeitskopie) @@ -12,6 +12,8 @@ #ifndef PATH_H #define PATH_H +#include "support/filename.h" + #include <boost/utility.hpp> #include <string> @@ -46,7 +48,7 @@ /// whether we are in the new cwd or not bool popped_; /// the previous cwd - std::string pushedDir_; + FileName pushedDir_; }; // To avoid the wrong usage: Index: src/support/lyxlib.h =================================================================== --- src/support/lyxlib.h (Revision 16394) +++ src/support/lyxlib.h (Arbeitskopie) @@ -15,16 +15,16 @@ #ifndef LYX_LIB_H #define LYX_LIB_H +#include "support/filename.h" + #include <string> namespace lyx { namespace support { -class FileName; - /// get the current working directory -std::string const getcwd(); +FileName const getcwd(); /// change to a directory, 0 is returned on success. int chdir(FileName const & name); /// Change file permissions @@ -47,8 +47,9 @@ int mkdir(FileName const & pathname, unsigned long int mode); /// unlink the given file int unlink(FileName const & file); -/// (securely) create a temporary file in the given dir with the given prefix -std::string const tempName(std::string const & dir = std::string(), +/// (securely) create a temporary file in the given dir with the given mask +/// \p mask must be in filesystem encoding +FileName const tempName(FileName const & dir = FileName(), std::string const & mask = std::string()); Index: src/support/filetools.C =================================================================== --- src/support/filetools.C (Revision 16394) +++ src/support/filetools.C (Arbeitskopie) @@ -165,16 +165,16 @@ //returns true: dir writeable // false: not writeable -bool isDirWriteable(string const & path) +bool isDirWriteable(FileName const & path) { lyxerr[Debug::FILES] << "isDirWriteable: " << path << endl; - string const tmpfl = tempName(path, "lyxwritetest"); + FileName const tmpfl(tempName(path, "lyxwritetest")); if (tmpfl.empty()) return false; - unlink(FileName(tmpfl)); + unlink(tmpfl); return true; } @@ -242,7 +242,7 @@ string const & fil = dit->leaf(); if (suffixIs(fil, extension)) dirlist.push_back(FileName::fromFilesystemEncoding( - makeAbsPath(fil, encoded_dir))); + encoded_dir + '/' + fil)); } return dirlist; } @@ -376,20 +376,20 @@ << "createTmpDir: tempdir=`" << tempdir << "'\n" << "createTmpDir: mask=`" << mask << '\'' << endl; - string const tmpfl = tempName(tempdir.absFilename(), mask); + FileName const tmpfl(tempName(tempdir, mask)); // lyx::tempName actually creates a file to make sure that it // stays unique. So we have to delete it before we can create // a dir with the same name. Note also that we are not thread // safe because of the gap between unlink and mkdir. (Lgb) - unlink(FileName(tmpfl)); + unlink(tmpfl); - if (tmpfl.empty() || mkdir(FileName(tmpfl), 0700)) { + if (tmpfl.empty() || mkdir(tmpfl, 0700)) { lyxerr << "LyX could not create the temporary directory '" << tmpfl << "'" << endl; return FileName(); } - return FileName(tmpfl); + return tmpfl; } } // namespace anon @@ -429,7 +429,7 @@ { if (!deflt.empty() && deflt.absFilename() != "/tmp") { if (mkdir(deflt, 0777)) { - if (isDirWriteable(deflt.absFilename())) { + if (isDirWriteable(deflt)) { // deflt could not be created because it // did exist already, so let's create our own // dir inside deflt. @@ -470,11 +470,11 @@ // Convert relative path into absolute path based on a basepath. // If relpath is absolute, just use that. // If basepath is empty, use CWD as base. -string const makeAbsPath(string const & relPath, string const & basePath) +FileName const makeAbsPath(string const & relPath, string const & basePath) { // checks for already absolute path if (os::is_absolute_path(relPath)) - return relPath; + return FileName(relPath); // Copies given paths string tempRel = os::internal_path(relPath); @@ -486,7 +486,7 @@ if (os::is_absolute_path(basePath)) tempBase = basePath; else - tempBase = addPath(getcwd(), basePath); + tempBase = addPath(getcwd().absFilename(), basePath); // Handle /./ at the end of the path while (suffixIs(tempBase, "/./")) @@ -524,7 +524,7 @@ } // returns absolute path - return os::internal_path(tempBase); + return FileName(os::internal_path(tempBase)); } @@ -584,13 +584,13 @@ rTemp = split(rTemp, temp, '/'); if (temp == ".") - return getcwd() + '/' + rTemp; + return getcwd().absFilename() + '/' + rTemp; if (temp == "~") return package().home_dir() + '/' + rTemp; if (temp == "..") - return makeAbsPath(copy); + return makeAbsPath(copy).absFilename(); // Don't know how to handle this return copy; @@ -1035,7 +1035,7 @@ return false; linkbuffer[nRead] = '\0'; // terminator if (resolve) - link = makeAbsPath(linkbuffer, onlyPath(file)); + link = makeAbsPath(linkbuffer, onlyPath(file)).absFilename(); else link = linkbuffer; return true; @@ -1135,7 +1135,7 @@ cmd_ret const c = runCommand(kpsecmd); lyxerr[Debug::LATEX] << "kpse status = " << c.first << '\n' - << "kpse result = `" << rtrim(c.second, "\n") + << "kpse result = `" << rtrim(c.second, "\n\r") << '\'' << endl; if (c.first != -1) return FileName(os::internal_path(rtrim(c.second, "\n\r"))); Index: src/support/getcwd.C =================================================================== --- src/support/getcwd.C (Revision 16394) +++ src/support/getcwd.C (Arbeitskopie) @@ -17,8 +17,6 @@ #include <cerrno> - -namespace lyx { #ifdef HAVE_UNISTD_H # include <unistd.h> #endif @@ -28,11 +26,13 @@ #endif using boost::scoped_array; -using support::os::internal_path; using std::string; +namespace lyx { +namespace support { + namespace { inline @@ -50,7 +50,7 @@ // Returns current working directory -string const lyx::support::getcwd() +FileName const getcwd() { int n = 256; // Assume path is less than 256 chars char * err; @@ -66,8 +66,8 @@ string result; if (err) result = tbuf.get(); - return internal_path(result); + return FileName::fromFilesystemEncoding(os::internal_path(result)); } - +} // namespace support } // namespace lyx Index: src/support/filetools.h =================================================================== --- src/support/filetools.h (Revision 16394) +++ src/support/filetools.h (Arbeitskopie) @@ -81,7 +81,7 @@ true: dir writeable false: not writeable */ -bool isDirWriteable(std::string const & path); +bool isDirWriteable(FileName const & path); /** Is a file readable ? Returns true if the file `path' is readable. @@ -236,7 +236,7 @@ If relpath is absolute, just use that. If basepath doesn't exist use CWD. */ -std::string const makeAbsPath(std::string const & RelPath = std::string(), +FileName const makeAbsPath(std::string const & RelPath = std::string(), std::string const & BasePath = std::string()); /** Creates a nice compact path for displaying. The parameter Index: src/support/tempname.C =================================================================== --- src/support/tempname.C (Revision 16394) +++ src/support/tempname.C (Arbeitskopie) @@ -45,6 +45,7 @@ using std::endl; namespace lyx { +namespace support { namespace { @@ -77,9 +78,10 @@ } // namespace anon -string const lyx::support::tempName(string const & dir, string const & mask) +FileName const tempName(FileName const & dir, string const & mask) { - string const tmpdir(dir.empty() ? package().temp_dir() : dir); + // FIXME UNICODE encoding of package().temp_dir() is probably wrong + string const tmpdir(dir.empty() ? package().temp_dir() : dir.toFilesystemEncoding()); string tmpfl(addName(tmpdir, mask)); #if defined (HAVE_GETPID) tmpfl += convert<string>(getpid()); @@ -107,14 +109,14 @@ #endif lyxerr[Debug::FILES] << "Temporary file `" << t << "' created." << endl; - return t; + return FileName(t); } else { lyxerr[Debug::FILES] << "LyX Error: Unable to create temporary file." << endl; - return string(); + return FileName(); } } - +} // namespace support } // namespace lyx Index: src/support/filename.C =================================================================== --- src/support/filename.C (Revision 16394) +++ src/support/filename.C (Arbeitskopie) @@ -117,10 +117,15 @@ {} +DocFileName::DocFileName(FileName const & abs_filename, bool save_abs) + : FileName(abs_filename), save_abs_path_(save_abs), zipped_valid_(false) +{} + + void DocFileName::set(string const & name, string const & buffer_path) { save_abs_path_ = absolutePath(name); - name_ = save_abs_path_ ? name : makeAbsPath(name, buffer_path); + name_ = save_abs_path_ ? name : makeAbsPath(name, buffer_path).absFilename(); zipped_valid_ = false; } Index: src/support/path.C =================================================================== --- src/support/path.C (Revision 16394) +++ src/support/path.C (Arbeitskopie) @@ -53,7 +53,7 @@ return 0; } - if (chdir(FileName(pushedDir_))) { + if (chdir(pushedDir_)) { // should throw an exception // throw DirChangeError(); } Index: src/support/package.C.in =================================================================== --- src/support/package.C.in (Revision 16394) +++ src/support/package.C.in (Arbeitskopie) @@ -385,7 +385,7 @@ return string(); string const path = os::internal_path(command_line); - return os::is_absolute_path(path) ? path : makeAbsPath(path); + return os::is_absolute_path(path) ? path : makeAbsPath(path).absFilename(); } @@ -407,7 +407,7 @@ // Two possibilities present themselves. // 1. The binary is relative to the CWD. - string const abs_exe_path = makeAbsPath(exe_path); + string const abs_exe_path = makeAbsPath(exe_path).absFilename(); if (fs::exists(FileName(abs_exe_path).toFilesystemEncoding())) return abs_exe_path; @@ -422,7 +422,7 @@ std::vector<string>::const_iterator const end = path.end(); for (; it != end; ++it) { // This will do nothing if *it is already absolute. - string const exe_dir = makeAbsPath(*it); + string const exe_dir = makeAbsPath(*it).absFilename(); string const exe_path = addName(exe_dir, exe_name); if (fs::exists(FileName(exe_path).toFilesystemEncoding())) @@ -663,7 +663,7 @@ string const extract_env_var_dir(string const & env_var) { string const dir = os::internal_path(getEnv(env_var)); - return dir.empty() ? dir : makeAbsPath(dir); + return dir.empty() ? dir : makeAbsPath(dir).absFilename(); } Index: src/support/filename.h =================================================================== --- src/support/filename.h (Revision 16394) +++ src/support/filename.h (Arbeitskopie) @@ -32,14 +32,19 @@ * explicit because we don't want implicit conversion of relative * paths in function arguments (e.g. of unlink). * \param abs_filename the file in question. Must have an absolute path. + * Encoding is always UTF-8. */ explicit FileName(std::string const & abs_filename); virtual ~FileName(); + /** Set a new filename. + * \param filename the file in question. Must have an absolute path. + * Encoding is always UTF-8. + */ virtual void set(std::string const & filename); virtual void erase(); /// Is this filename empty? bool empty() const { return name_.empty(); } - /// get the absolute file name + /// get the absolute file name in UTF-8 encoding std::string const absFilename() const { return name_; } /** * Get the file name in the encoding used by the file system. @@ -81,6 +86,7 @@ * \param save_abs_path how is the file to be output to file? */ DocFileName(std::string const & abs_filename, bool save_abs_path = true); + DocFileName(FileName const & abs_filename, bool save_abs_path = true); /** \param filename the file in question. May have either a relative * or an absolute path. Index: src/BufferView.C =================================================================== --- src/BufferView.C (Revision 16394) +++ src/BufferView.C (Arbeitskopie) @@ -88,7 +88,6 @@ using support::isDirWriteable; using support::isFileReadable; using support::makeDisplayPath; -using support::makeAbsPath; using support::package; using std::distance; @@ -1393,7 +1392,7 @@ if (buffer_) { string const trypath = buffer_->filePath(); // If directory is writeable, use this as default. - if (isDirWriteable(trypath)) + if (isDirWriteable(FileName(trypath))) initpath = trypath; } Index: src/tex2lyx/tex2lyx.C =================================================================== --- src/tex2lyx/tex2lyx.C (Revision 16394) +++ src/tex2lyx/tex2lyx.C (Arbeitskopie) @@ -381,8 +381,8 @@ if (it == cmdmap.end()) continue; - string arg((i + 1 < argc) ? argv[i + 1] : ""); - string arg2((i + 2 < argc) ? argv[i + 2] : ""); + string arg(to_utf8(from_local8bit((i + 1 < argc) ? argv[i + 1] : ""))); + string arg2(to_utf8(from_local8bit((i + 2 < argc) ? argv[i + 2] : ""))); int const remove = 1 + it->second(arg, arg2); @@ -518,17 +518,18 @@ } lyx::support::os::init(argc, argv); - lyx::support::init_package(argv[0], cl_system_support, cl_user_support, - lyx::support::top_build_dir_is_two_levels_up); + support::init_package(to_utf8(from_local8bit(argv[0])), + cl_system_support, cl_user_support, + support::top_build_dir_is_two_levels_up); // Now every known option is parsed. Look for input and output // file name (the latter is optional). - string const infilename = makeAbsPath(argv[1]); + string const infilename = makeAbsPath(to_utf8(from_local8bit(argv[1]))).absFilename(); string outfilename; if (argc > 2) { - outfilename = argv[2]; + outfilename = to_utf8(from_local8bit(argv[2])); if (outfilename != "-") - outfilename = makeAbsPath(argv[2]); + outfilename = makeAbsPath(to_utf8(from_local8bit(argv[2]))).absFilename(); } else outfilename = changeExtension(infilename, ".lyx"); @@ -539,7 +540,7 @@ } read_syntaxfile(system_syntaxfile); if (!syntaxfile.empty()) - read_syntaxfile(FileName(makeAbsPath(syntaxfile))); + read_syntaxfile(makeAbsPath(syntaxfile)); masterFilePath = onlyPath(infilename); parentFilePath = masterFilePath; Index: src/tex2lyx/text.C =================================================================== --- src/tex2lyx/text.C (Revision 16394) +++ src/tex2lyx/text.C (Arbeitskopie) @@ -32,6 +32,7 @@ namespace lyx { +using support::addExtension; using support::changeExtension; using support::FileName; using support::makeAbsPath; @@ -354,11 +355,11 @@ string find_file(string const & name, string const & path, char const * const * extensions) { + // FIXME UNICODE encoding of name and path may be wrong (makeAbsPath + // expects utf8) for (char const * const * what = extensions; *what; ++what) { - // We don't use ChangeExtension() because it does the wrong - // thing if name contains a dot. - string const trial = name + '.' + (*what); - if (fs::exists(FileName(makeAbsPath(trial, path)).toFilesystemEncoding())) + string const trial = addExtension(name, *what); + if (fs::exists(makeAbsPath(trial, path).toFilesystemEncoding())) return trial; } return string(); @@ -1021,7 +1022,9 @@ { if (lyx::support::absolutePath(name)) return; - name = makeRelPath(makeAbsPath(name, getMasterFilePath()), + // FIXME UNICODE encoding of name may be wrong (makeAbsPath expects + // utf8) + name = makeRelPath(makeAbsPath(name, getMasterFilePath()).absFilename(), getParentFilePath()); } @@ -1480,7 +1483,9 @@ string const path = getMasterFilePath(); // We want to preserve relative / absolute filenames, // therefore path is only used for testing - if (!fs::exists(FileName(makeAbsPath(name, path)).toFilesystemEncoding())) { + // FIXME UNICODE encoding of name and path may be + // wrong (makeAbsPath expects utf8) + if (!fs::exists(makeAbsPath(name, path).toFilesystemEncoding())) { // The file extension is probably missing. // Now try to find it out. string const dvips_name = @@ -1510,7 +1515,9 @@ name = pdftex_name; } - if (fs::exists(FileName(makeAbsPath(name, path)).toFilesystemEncoding())) + // FIXME UNICODE encoding of name and path may be + // wrong (makeAbsPath expects utf8) + if (fs::exists(makeAbsPath(name, path).toFilesystemEncoding())) fix_relative_filename(name); else cerr << "Warning: Could not find graphics file '" @@ -2132,8 +2139,10 @@ string const path = getMasterFilePath(); // We want to preserve relative / absolute filenames, // therefore path is only used for testing + // FIXME UNICODE encoding of filename and path may be + // wrong (makeAbsPath expects utf8) if (t.cs() == "include" && - !fs::exists(FileName(makeAbsPath(filename, path)).toFilesystemEncoding())) { + !fs::exists(makeAbsPath(filename, path).toFilesystemEncoding())) { // The file extension is probably missing. // Now try to find it out. string const tex_name = @@ -2142,9 +2151,11 @@ if (!tex_name.empty()) filename = tex_name; } - if (fs::exists(FileName(makeAbsPath(filename, path)).toFilesystemEncoding())) { + // FIXME UNICODE encoding of filename and path may be + // wrong (makeAbsPath expects utf8) + if (fs::exists(makeAbsPath(filename, path).toFilesystemEncoding())) { string const abstexname = - makeAbsPath(filename, path); + makeAbsPath(filename, path).absFilename(); string const abslyxname = changeExtension(abstexname, ".lyx"); fix_relative_filename(filename); Index: src/buffer_funcs.C =================================================================== --- src/buffer_funcs.C (Revision 16394) +++ src/buffer_funcs.C (Arbeitskopie) @@ -191,7 +191,7 @@ if (templatename.empty()) tname = libFileSearch("templates", "defaults.lyx"); else - tname = FileName(makeAbsPath(templatename)); + tname = makeAbsPath(templatename); if (!tname.empty()) { if (!b->readFile(tname)) { Index: src/Chktex.C =================================================================== --- src/Chktex.C (Revision 16394) +++ src/Chktex.C (Arbeitskopie) @@ -63,7 +63,7 @@ { int retval = 0; - // FIXME: Find out whether we can onlyFilename() is really needed, + // FIXME: Find out whether onlyFilename() is really needed, // or whether makeAbsPath(onlyFilename()) is a noop here FileName const tmp(makeAbsPath(onlyFilename(changeExtension(file, ".log")))); Index: Status.15x =================================================================== --- Status.15x (Revision 16394) +++ Status.15x (Arbeitskopie) @@ -52,31 +52,7 @@ * agu-dtd is used as the default document class, which is not a good idea in 99% of all cases -* On Windows (using scons/MSVC): Create an empty bibtex file, called - 'lit.bib'. Create a new LyX document 'lit.lyx' in the same directory - that has a bibliography inset pointing to lit.bib. - Now, if lit.[lyx|bib] are stored in a path with ASCII characters only, - class FileName is used as follows: - FileName::FileName(string const &): C:/foo/lit.lyx.emergency - FileName::FileName(string const &): C:/foo/#lit.lyx# - FileName::FileName(string const &): C:/foo/ - FileName::FileName(string const &): C:/foo/lit.bib - FileName::FileName(string const &): C:/lyx-trunk/build-msvc/bin - FileName::FileName(string const &): C:/foo/lit.lyx,v - FileName::FileName(string const &): C:/foo/RCS/lit.lyx,v - FileName::FileName(string const &): C:/foo//CVS/Entries - FileName::FileName(string const &): C:/foo/lit.lyx - However, if the path contains a German Umlaut ("bäh"), LyX crashes: - FileName::FileName(string const &): C:/bäh/lit.lyx.emergency - FileName::FileName(string const &): C:/bäh/#lit.lyx# - FileName::FileName(string const &): C:/bäh/ - FileName::FileName(string const &): C:/bäh/lit.bib - FileName::FileName(string const &): lit.bib - Assertion triggered in __thiscall lyx::support::FileName::FileName(const class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &) by failing check "empty() || absolutePath(name_)" in fil -e C:\cygwin\home\ms\lyx-trunk\src\support\filename.C:48 - Odd, isn't it? - SPELL CHECKING (Joost 4/11/06) * Words with umlauts or accents do not arrive as a whole word in the spell @@ -662,4 +638,29 @@ FIXED (Abdel 2006-12-24): centralWidget() was not the WorkArea due to the new TabBar support. - \ Kein Zeilenvorschub am Ende der Datei + +* On Windows (using scons/MSVC): Create an empty bibtex file, called + 'lit.bib'. Create a new LyX document 'lit.lyx' in the same directory + that has a bibliography inset pointing to lit.bib. + Now, if lit.[lyx|bib] are stored in a path with ASCII characters only, + class FileName is used as follows: + FileName::FileName(string const &): C:/foo/lit.lyx.emergency + FileName::FileName(string const &): C:/foo/#lit.lyx# + FileName::FileName(string const &): C:/foo/ + FileName::FileName(string const &): C:/foo/lit.bib + FileName::FileName(string const &): C:/lyx-trunk/build-msvc/bin + FileName::FileName(string const &): C:/foo/lit.lyx,v + FileName::FileName(string const &): C:/foo/RCS/lit.lyx,v + FileName::FileName(string const &): C:/foo//CVS/Entries + FileName::FileName(string const &): C:/foo/lit.lyx + However, if the path contains a German Umlaut ("bäh"), LyX crashes: + FileName::FileName(string const &): C:/bäh/lit.lyx.emergency + FileName::FileName(string const &): C:/bäh/#lit.lyx# + FileName::FileName(string const &): C:/bäh/ + FileName::FileName(string const &): C:/bäh/lit.bib + FileName::FileName(string const &): lit.bib + Assertion triggered in __thiscall lyx::support::FileName::FileName(const class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &) by failing check "empty() || absolutePath(name_)" in fil +e C:\cygwin\home\ms\lyx-trunk\src\support\filename.C:48 + Odd, isn't it? + FIXED (Enrico (found problem) and Georg (fix) 2006-12-27) +