2003-07-22 20:42:40 +00:00
|
|
|
/**
|
Rename files in src/support, step one.
src/support/package.h src/support/Package.h Package
src/support/package.C.in src/support/Package.C.in Package
src/support/path.h src/support/Path.h Path
src/support/fs_extras.h src/support/fs_extras.h NOCLASSES
src/support/RandomAccessList.h src/support/RandomAccessList.h RandomAccessList
src/support/lyxmanip.h src/support/lyxmanip.h NOCLASSES
src/support/rename.C src/support/rename.cpp NOCLASSES
src/support/abort.C src/support/abort.cpp NOCLASSES
src/support/lyxlib.h src/support/lyxlib.h NOCLASSES
src/support/ExceptionMessage.h src/support/ExceptionMessage.h ExceptionMessage
src/support/copy.C src/support/copy.cpp NOCLASSES
src/support/limited_stack.h src/support/limited_stack.h limited_stack
src/support/filefilterlist.C src/support/FileFilterList.cpp ['FileFilterList', 'Filter']
src/support/cow_ptr.h src/support/cow_ptr.h cow_ptr
src/support/os_unix.C src/support/os_unix.cpp NOCLASSES
src/support/socktools.h src/support/socktools.h NOCLASSES
src/support/forkedcontr.h src/support/ForkedcallsController.h ForkedcallsController
src/support/os.h src/support/os.h NOCLASSES
src/support/FileMonitor.h src/support/FileMonitor.h FileMonitor
src/support/copied_ptr.h src/support/copied_ptr.h copied_ptr
src/support/translator.h src/support/Translator.h Translator
src/support/filetools.C src/support/filetools.cpp NOCLASSES
src/support/unlink.C src/support/unlink.cpp NOCLASSES
src/support/os_win32.C src/support/os_win32.cpp GetFolderPath
src/support/lstrings.C src/support/lstrings.cpp NOCLASSES
src/support/qstring_helpers.C src/support/qstring_helpers.cpp NOCLASSES
src/support/getcwd.C src/support/getcwd.cpp NOCLASSES
src/support/systemcall.C src/support/Systemcall.cpp Systemcall
src/support/lyxalgo.h src/support/lyxalgo.h NOCLASSES
src/support/filefilterlist.h src/support/FileFilterList.h ['FileFilterList', 'Filter']
src/support/unicode.C src/support/unicode.cpp IconvProcessor
src/support/userinfo.C src/support/userinfo.cpp NOCLASSES
src/support/lyxtime.C src/support/lyxtime.cpp NOCLASSES
src/support/kill.C src/support/kill.cpp NOCLASSES
src/support/docstring.C src/support/docstring.cpp to_local8bit_failure
src/support/os_cygwin.C src/support/os_cygwin.cpp NOCLASSES
src/support/lyxsum.C src/support/lyxsum.cpp NOCLASSES
src/support/environment.C src/support/environment.cpp NOCLASSES
src/support/filetools.h src/support/filetools.h NOCLASSES
src/support/textutils.C src/support/textutils.cpp NOCLASSES
src/support/mkdir.C src/support/mkdir.cpp NOCLASSES
src/support/forkedcall.C src/support/Forkedcall.cpp ['ForkedProcess', 'Forkedcall']
src/support/tempname.C src/support/tempname.cpp NOCLASSES
src/support/os_win32.h src/support/os_win32.h GetFolderPath
src/support/types.h src/support/types.h NOCLASSES
src/support/lstrings.h src/support/lstrings.h NOCLASSES
src/support/forkedcallqueue.C src/support/ForkedCallQueue.cpp ForkedCallQueue
src/support/qstring_helpers.h src/support/qstring_helpers.h NOCLASSES
src/support/convert.C src/support/convert.cpp NOCLASSES
src/support/filename.C src/support/FileName.cpp ['FileName', 'DocFileName']
src/support/tests/convert.C src/support/tests/convert.cpp NOCLASSES
src/support/tests/filetools.C src/support/tests/filetools.cpp NOCLASSES
src/support/tests/lstrings.C src/support/tests/lstrings.cpp NOCLASSES
src/support/tests/boost.C src/support/tests/boost.cpp NOCLASSES
src/support/docstream.C src/support/docstream.cpp ['iconv_codecvt_facet_exception', 'idocfstream', 'odocfstream']
src/support/std_istream.h src/support/std_istream.h NOCLASSES
src/support/systemcall.h src/support/Systemcall.h Systemcall
src/support/chdir.C src/support/chdir.cpp NOCLASSES
src/support/std_ostream.h src/support/std_ostream.h NOCLASSES
src/support/unicode.h src/support/unicode.h IconvProcessor
src/support/path.C src/support/Path.cpp Path
src/support/fs_extras.C src/support/fs_extras.cpp NOCLASSES
src/support/userinfo.h src/support/userinfo.h NOCLASSES
src/support/lyxtime.h src/support/lyxtime.h NOCLASSES
src/support/docstring.h src/support/docstring.h to_local8bit_failure
src/support/debugstream.h src/support/debugstream.h basic_debugstream
src/support/environment.h src/support/environment.h NOCLASSES
src/support/textutils.h src/support/textutils.h NOCLASSES
src/support/forkedcall.h src/support/Forkedcall.h ['ForkedProcess', 'Forkedcall']
src/support/socktools.C src/support/socktools.cpp NOCLASSES
src/support/forkedcallqueue.h src/support/ForkedCallQueue.h ForkedCallQueue
src/support/forkedcontr.C src/support/ForkedcallsController.cpp ForkedcallsController
src/support/os.C src/support/os.cpp NOCLASSES
src/support/convert.h src/support/convert.h NOCLASSES
src/support/filename.h src/support/FileName.h ['FileName', 'DocFileName']
src/support/docstream.h src/support/docstream.h ['iconv_codecvt_facet_exception', 'idocfstream', 'odocfstream']
src/support/FileMonitor.C src/support/FileMonitor.cpp FileMonitor
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18024 a592a061-630c-0410-9148-cb99ea01b6c8
2007-04-26 05:12:52 +00:00
|
|
|
* \file FileName.cpp
|
2003-07-22 20:42:40 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author Angus Leeming
|
|
|
|
*
|
2003-09-08 09:51:40 +00:00
|
|
|
* Full author contact details are available in file CREDITS.
|
2003-07-22 20:42:40 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
Rename files in src/support, step one.
src/support/package.h src/support/Package.h Package
src/support/package.C.in src/support/Package.C.in Package
src/support/path.h src/support/Path.h Path
src/support/fs_extras.h src/support/fs_extras.h NOCLASSES
src/support/RandomAccessList.h src/support/RandomAccessList.h RandomAccessList
src/support/lyxmanip.h src/support/lyxmanip.h NOCLASSES
src/support/rename.C src/support/rename.cpp NOCLASSES
src/support/abort.C src/support/abort.cpp NOCLASSES
src/support/lyxlib.h src/support/lyxlib.h NOCLASSES
src/support/ExceptionMessage.h src/support/ExceptionMessage.h ExceptionMessage
src/support/copy.C src/support/copy.cpp NOCLASSES
src/support/limited_stack.h src/support/limited_stack.h limited_stack
src/support/filefilterlist.C src/support/FileFilterList.cpp ['FileFilterList', 'Filter']
src/support/cow_ptr.h src/support/cow_ptr.h cow_ptr
src/support/os_unix.C src/support/os_unix.cpp NOCLASSES
src/support/socktools.h src/support/socktools.h NOCLASSES
src/support/forkedcontr.h src/support/ForkedcallsController.h ForkedcallsController
src/support/os.h src/support/os.h NOCLASSES
src/support/FileMonitor.h src/support/FileMonitor.h FileMonitor
src/support/copied_ptr.h src/support/copied_ptr.h copied_ptr
src/support/translator.h src/support/Translator.h Translator
src/support/filetools.C src/support/filetools.cpp NOCLASSES
src/support/unlink.C src/support/unlink.cpp NOCLASSES
src/support/os_win32.C src/support/os_win32.cpp GetFolderPath
src/support/lstrings.C src/support/lstrings.cpp NOCLASSES
src/support/qstring_helpers.C src/support/qstring_helpers.cpp NOCLASSES
src/support/getcwd.C src/support/getcwd.cpp NOCLASSES
src/support/systemcall.C src/support/Systemcall.cpp Systemcall
src/support/lyxalgo.h src/support/lyxalgo.h NOCLASSES
src/support/filefilterlist.h src/support/FileFilterList.h ['FileFilterList', 'Filter']
src/support/unicode.C src/support/unicode.cpp IconvProcessor
src/support/userinfo.C src/support/userinfo.cpp NOCLASSES
src/support/lyxtime.C src/support/lyxtime.cpp NOCLASSES
src/support/kill.C src/support/kill.cpp NOCLASSES
src/support/docstring.C src/support/docstring.cpp to_local8bit_failure
src/support/os_cygwin.C src/support/os_cygwin.cpp NOCLASSES
src/support/lyxsum.C src/support/lyxsum.cpp NOCLASSES
src/support/environment.C src/support/environment.cpp NOCLASSES
src/support/filetools.h src/support/filetools.h NOCLASSES
src/support/textutils.C src/support/textutils.cpp NOCLASSES
src/support/mkdir.C src/support/mkdir.cpp NOCLASSES
src/support/forkedcall.C src/support/Forkedcall.cpp ['ForkedProcess', 'Forkedcall']
src/support/tempname.C src/support/tempname.cpp NOCLASSES
src/support/os_win32.h src/support/os_win32.h GetFolderPath
src/support/types.h src/support/types.h NOCLASSES
src/support/lstrings.h src/support/lstrings.h NOCLASSES
src/support/forkedcallqueue.C src/support/ForkedCallQueue.cpp ForkedCallQueue
src/support/qstring_helpers.h src/support/qstring_helpers.h NOCLASSES
src/support/convert.C src/support/convert.cpp NOCLASSES
src/support/filename.C src/support/FileName.cpp ['FileName', 'DocFileName']
src/support/tests/convert.C src/support/tests/convert.cpp NOCLASSES
src/support/tests/filetools.C src/support/tests/filetools.cpp NOCLASSES
src/support/tests/lstrings.C src/support/tests/lstrings.cpp NOCLASSES
src/support/tests/boost.C src/support/tests/boost.cpp NOCLASSES
src/support/docstream.C src/support/docstream.cpp ['iconv_codecvt_facet_exception', 'idocfstream', 'odocfstream']
src/support/std_istream.h src/support/std_istream.h NOCLASSES
src/support/systemcall.h src/support/Systemcall.h Systemcall
src/support/chdir.C src/support/chdir.cpp NOCLASSES
src/support/std_ostream.h src/support/std_ostream.h NOCLASSES
src/support/unicode.h src/support/unicode.h IconvProcessor
src/support/path.C src/support/Path.cpp Path
src/support/fs_extras.C src/support/fs_extras.cpp NOCLASSES
src/support/userinfo.h src/support/userinfo.h NOCLASSES
src/support/lyxtime.h src/support/lyxtime.h NOCLASSES
src/support/docstring.h src/support/docstring.h to_local8bit_failure
src/support/debugstream.h src/support/debugstream.h basic_debugstream
src/support/environment.h src/support/environment.h NOCLASSES
src/support/textutils.h src/support/textutils.h NOCLASSES
src/support/forkedcall.h src/support/Forkedcall.h ['ForkedProcess', 'Forkedcall']
src/support/socktools.C src/support/socktools.cpp NOCLASSES
src/support/forkedcallqueue.h src/support/ForkedCallQueue.h ForkedCallQueue
src/support/forkedcontr.C src/support/ForkedcallsController.cpp ForkedcallsController
src/support/os.C src/support/os.cpp NOCLASSES
src/support/convert.h src/support/convert.h NOCLASSES
src/support/filename.h src/support/FileName.h ['FileName', 'DocFileName']
src/support/docstream.h src/support/docstream.h ['iconv_codecvt_facet_exception', 'idocfstream', 'odocfstream']
src/support/FileMonitor.C src/support/FileMonitor.cpp FileMonitor
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18024 a592a061-630c-0410-9148-cb99ea01b6c8
2007-04-26 05:12:52 +00:00
|
|
|
#include "support/FileName.h"
|
2007-12-05 10:32:49 +00:00
|
|
|
#include "support/FileNameList.h"
|
2007-11-29 07:04:28 +00:00
|
|
|
|
|
|
|
#include "support/debug.h"
|
2004-11-07 13:22:51 +00:00
|
|
|
#include "support/filetools.h"
|
2008-09-27 09:15:55 +00:00
|
|
|
#include "support/lassert.h"
|
2004-11-07 13:22:51 +00:00
|
|
|
#include "support/lstrings.h"
|
2014-07-05 10:22:08 +00:00
|
|
|
#include "support/mutex.h"
|
2004-11-07 13:22:51 +00:00
|
|
|
#include "support/os.h"
|
2007-12-16 07:52:38 +00:00
|
|
|
#include "support/Package.h"
|
Make libQtCore a support library like boost and implement encoding conversion
from/to the local 8bit encoding with it.
Only the autotools build system is updated, scons and cmake users need to
add qt4 cpp flags when compiling libsupport, and link libsupport against
libQtCore.
* src/frontends/qt4/qt_helpers.[Ch]
(toqstr, qchar_to_ucs4, ucs4_to_qchar, ucs4_to_qstring,
qstring_to_ucs4, fromqstr): Move these qstring conversion functions
from here ...
* src/support/qstring_helpers.[Ch] ... to these new files
* src/support/docstring.[Ch]
(from_local8bit): new conversion function from local 8bit encoding
to ucs4
(to_local8bit): new conversion function from ucs4 to local 8bit
encoding to ucs4
(to_local8bit_failure): exception that is thrown by to_local8bit if
the argument cannot be converted to the local encoding
* src/support/filename.C
(FileName::toFilesystemEncoding): implement with the help of QFile
* src/support/Makefile.am: Add new files, qt4 cpp flags and link
against libQtCore
* src/client/client.C: Convert commandline input from local encoding
to ucs4. Convert stuff that is sent to to the server to utf8,
because LyX interprets it as utf8 on the other end of the pipe.
* src/lyx_main.C
(LyX::exec): convert commandline input from local encoding to utf8
(LyX::init): ditto
(LyX::easyParse): ditto
* development/scons/scons_manifest.py: Add new files
* config/qt4.m4: Define new variables QT4_CORE_INCLUDES,
QT4_CORE_LDFLAGS and QT4_CORE_LIB
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16257 a592a061-630c-0410-9148-cb99ea01b6c8
2006-12-12 20:19:46 +00:00
|
|
|
#include "support/qstring_helpers.h"
|
|
|
|
|
2007-11-25 23:21:39 +00:00
|
|
|
#include <QDateTime>
|
|
|
|
#include <QDir>
|
2006-12-13 16:23:29 +00:00
|
|
|
#include <QFile>
|
2007-10-17 22:21:50 +00:00
|
|
|
#include <QFileInfo>
|
2007-11-25 23:21:39 +00:00
|
|
|
#include <QList>
|
2008-07-23 05:17:31 +00:00
|
|
|
#include <QTemporaryFile>
|
2007-12-12 10:16:00 +00:00
|
|
|
#include <QTime>
|
2003-07-22 20:42:40 +00:00
|
|
|
|
2019-07-07 17:13:52 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <QThread>
|
|
|
|
#endif
|
|
|
|
|
2008-09-27 09:15:55 +00:00
|
|
|
#include <boost/crc.hpp>
|
2003-09-09 17:25:35 +00:00
|
|
|
|
2008-09-27 09:15:55 +00:00
|
|
|
#include <algorithm>
|
|
|
|
#include <iterator>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iomanip>
|
2004-03-11 11:45:08 +00:00
|
|
|
#include <map>
|
|
|
|
#include <sstream>
|
2003-07-22 20:42:40 +00:00
|
|
|
|
2007-11-07 19:52:11 +00:00
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
|
|
# include <sys/stat.h>
|
|
|
|
#endif
|
2007-12-14 22:43:39 +00:00
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
# include <unistd.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_DIRECT_H
|
|
|
|
# include <direct.h>
|
|
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
|
|
# include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <cerrno>
|
2007-12-16 07:52:38 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
|
2008-09-27 10:54:26 +00:00
|
|
|
// Three implementations of checksum(), depending on having mmap support or not.
|
2008-09-27 09:15:55 +00:00
|
|
|
#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP)
|
|
|
|
#define SUM_WITH_MMAP
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#endif // SUM_WITH_MMAP
|
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2010-02-21 04:51:27 +00:00
|
|
|
using namespace lyx::support;
|
2007-11-25 23:25:00 +00:00
|
|
|
|
2007-11-26 10:29:04 +00:00
|
|
|
namespace lyx {
|
|
|
|
namespace support {
|
2007-11-25 23:25:00 +00:00
|
|
|
|
2008-09-27 10:54:26 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// FileName::Private
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
struct FileName::Private
|
2008-09-27 09:15:55 +00:00
|
|
|
{
|
2008-09-27 10:54:26 +00:00
|
|
|
Private() {}
|
|
|
|
|
2017-04-15 11:30:27 +00:00
|
|
|
Private(string const & abs_filename) : fi(toqstr(handleTildeName(abs_filename)))
|
2008-09-27 10:54:26 +00:00
|
|
|
{
|
2009-05-12 20:12:04 +00:00
|
|
|
name = fromqstr(fi.absoluteFilePath());
|
2008-09-27 10:54:26 +00:00
|
|
|
fi.setCaching(fi.exists() ? true : false);
|
|
|
|
}
|
|
|
|
///
|
2017-07-03 17:53:14 +00:00
|
|
|
inline void refresh()
|
2008-09-27 10:54:26 +00:00
|
|
|
{
|
|
|
|
fi.refresh();
|
|
|
|
}
|
|
|
|
|
2008-10-05 11:51:18 +00:00
|
|
|
static
|
|
|
|
bool isFilesystemEqual(QString const & lhs, QString const & rhs)
|
|
|
|
{
|
|
|
|
return QString::compare(lhs, rhs, os::isFilesystemCaseSensitive() ?
|
|
|
|
Qt::CaseSensitive : Qt::CaseInsensitive) == 0;
|
|
|
|
}
|
|
|
|
|
2017-04-15 11:30:27 +00:00
|
|
|
static
|
|
|
|
string const handleTildeName(string const & name)
|
|
|
|
{
|
2018-08-05 07:54:44 +00:00
|
|
|
string resname;
|
|
|
|
if ( name == "~" )
|
|
|
|
resname = Package::get_home_dir().absFileName();
|
|
|
|
else if ( prefixIs(name, "~/"))
|
|
|
|
resname = Package::get_home_dir().absFileName() + name.substr(1);
|
|
|
|
else if ( prefixIs(name, "~:s/"))
|
|
|
|
resname = package().system_support().absFileName() + name.substr(3);
|
|
|
|
else
|
|
|
|
resname = name;
|
|
|
|
return resname;
|
2017-04-15 11:30:27 +00:00
|
|
|
}
|
|
|
|
|
2009-05-02 17:12:31 +00:00
|
|
|
/// The absolute file name in UTF-8 encoding.
|
|
|
|
std::string name;
|
2008-09-27 10:54:26 +00:00
|
|
|
///
|
|
|
|
QFileInfo fi;
|
|
|
|
};
|
|
|
|
|
2007-11-26 10:29:04 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// FileName
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
2007-11-07 19:52:11 +00:00
|
|
|
|
|
|
|
|
2007-11-26 10:29:04 +00:00
|
|
|
FileName::FileName() : d(new Private)
|
2007-11-27 10:01:34 +00:00
|
|
|
{
|
|
|
|
}
|
2007-11-07 19:52:11 +00:00
|
|
|
|
2007-11-28 15:25:07 +00:00
|
|
|
|
2007-11-26 10:29:04 +00:00
|
|
|
FileName::FileName(string const & abs_filename)
|
|
|
|
: d(abs_filename.empty() ? new Private : new Private(abs_filename))
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
//LYXERR(Debug::FILES, "FileName(" << abs_filename << ')');
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(empty() || isAbsolute(d->name));
|
2007-11-26 10:29:04 +00:00
|
|
|
}
|
2007-11-07 19:52:11 +00:00
|
|
|
|
2007-11-26 10:29:04 +00:00
|
|
|
|
2007-12-01 10:23:16 +00:00
|
|
|
FileName::~FileName()
|
|
|
|
{
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-26 10:29:04 +00:00
|
|
|
FileName::FileName(FileName const & rhs) : d(new Private)
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
d->name = rhs.d->name;
|
2007-11-26 10:29:04 +00:00
|
|
|
d->fi = rhs.d->fi;
|
2007-11-07 19:52:11 +00:00
|
|
|
}
|
|
|
|
|
2007-11-07 20:22:46 +00:00
|
|
|
|
2008-07-23 09:23:23 +00:00
|
|
|
FileName::FileName(FileName const & rhs, string const & suffix) : d(new Private)
|
|
|
|
{
|
2008-07-29 07:47:16 +00:00
|
|
|
set(rhs, suffix);
|
2008-07-23 09:23:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-26 10:29:04 +00:00
|
|
|
FileName & FileName::operator=(FileName const & rhs)
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
if (&rhs == this)
|
|
|
|
return *this;
|
|
|
|
d->name = rhs.d->name;
|
2007-11-26 10:29:04 +00:00
|
|
|
d->fi = rhs.d->fi;
|
|
|
|
return *this;
|
|
|
|
}
|
2003-07-22 20:42:40 +00:00
|
|
|
|
|
|
|
|
2007-11-26 10:29:04 +00:00
|
|
|
bool FileName::empty() const
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
return d->name.empty();
|
2007-11-26 10:29:04 +00:00
|
|
|
}
|
2006-11-26 21:30:39 +00:00
|
|
|
|
|
|
|
|
2009-05-02 17:12:31 +00:00
|
|
|
bool FileName::isAbsolute(string const & name)
|
2007-12-17 15:15:37 +00:00
|
|
|
{
|
2017-04-15 11:30:27 +00:00
|
|
|
QFileInfo fi(toqstr(Private::handleTildeName(name)));
|
2009-05-02 17:12:31 +00:00
|
|
|
return fi.isAbsolute();
|
2007-12-17 15:15:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-21 01:19:09 +00:00
|
|
|
string FileName::absFileName() const
|
2003-09-03 17:23:38 +00:00
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
return d->name;
|
2003-09-03 17:23:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-05-01 15:18:11 +00:00
|
|
|
string FileName::realPath() const
|
|
|
|
{
|
2010-04-21 01:19:09 +00:00
|
|
|
return os::real_path(absFileName());
|
2009-05-01 15:18:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-26 21:30:39 +00:00
|
|
|
void FileName::set(string const & name)
|
|
|
|
{
|
2017-04-15 11:30:27 +00:00
|
|
|
d->fi.setFile(toqstr(Private::handleTildeName(name)));
|
2009-05-12 20:16:43 +00:00
|
|
|
d->name = fromqstr(d->fi.absoluteFilePath());
|
2009-05-02 17:12:31 +00:00
|
|
|
//LYXERR(Debug::FILES, "FileName::set(" << name << ')');
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(empty() || isAbsolute(d->name));
|
2006-11-26 21:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-29 07:47:16 +00:00
|
|
|
void FileName::set(FileName const & rhs, string const & suffix)
|
|
|
|
{
|
|
|
|
if (!rhs.d->fi.isDir())
|
|
|
|
d->fi.setFile(rhs.d->fi.filePath() + toqstr(suffix));
|
|
|
|
else
|
|
|
|
d->fi.setFile(QDir(rhs.d->fi.absoluteFilePath()), toqstr(suffix));
|
2009-05-02 21:29:54 +00:00
|
|
|
d->name = fromqstr(d->fi.absoluteFilePath());
|
2009-05-02 17:12:31 +00:00
|
|
|
//LYXERR(Debug::FILES, "FileName::set(" << d->name << ')');
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(empty() || isAbsolute(d->name));
|
2008-07-29 07:47:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-26 21:30:39 +00:00
|
|
|
void FileName::erase()
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
d->name.clear();
|
2007-11-26 10:29:04 +00:00
|
|
|
d->fi = QFileInfo();
|
2006-11-26 21:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-09 09:08:24 +00:00
|
|
|
bool FileName::copyTo(FileName const & name, bool keepsymlink) const
|
2007-11-07 19:52:11 +00:00
|
|
|
{
|
2014-06-09 09:08:24 +00:00
|
|
|
FileNameSet visited;
|
|
|
|
return copyTo(name, keepsymlink, visited);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool FileName::copyTo(FileName const & name, bool keepsymlink,
|
|
|
|
FileName::FileNameSet & visited) const
|
|
|
|
{
|
|
|
|
LYXERR(Debug::FILES, "Copying " << name << " keep symlink: " << keepsymlink);
|
|
|
|
if (keepsymlink && name.isSymLink()) {
|
2014-06-09 20:06:58 +00:00
|
|
|
visited.insert(*this);
|
2014-06-09 09:08:24 +00:00
|
|
|
FileName const target(fromqstr(name.d->fi.symLinkTarget()));
|
|
|
|
if (visited.find(target) != visited.end()) {
|
|
|
|
LYXERR(Debug::FILES, "Found circular symlink: " << target);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return copyTo(target, true);
|
|
|
|
}
|
2007-12-15 08:25:53 +00:00
|
|
|
QFile::remove(name.d->fi.absoluteFilePath());
|
2007-11-28 09:01:49 +00:00
|
|
|
bool success = QFile::copy(d->fi.absoluteFilePath(), name.d->fi.absoluteFilePath());
|
|
|
|
if (!success)
|
2008-07-19 11:47:20 +00:00
|
|
|
LYXERR0("FileName::copyTo(): Could not copy file "
|
|
|
|
<< *this << " to " << name);
|
2007-11-28 09:01:49 +00:00
|
|
|
return success;
|
2007-11-07 19:52:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-13 07:36:47 +00:00
|
|
|
bool FileName::renameTo(FileName const & name) const
|
|
|
|
{
|
2014-10-27 22:28:33 +00:00
|
|
|
LYXERR(Debug::FILES, "Renaming " << name << " as " << *this);
|
2007-12-13 07:36:47 +00:00
|
|
|
bool success = QFile::rename(d->fi.absoluteFilePath(), name.d->fi.absoluteFilePath());
|
|
|
|
if (!success)
|
2007-12-13 08:02:46 +00:00
|
|
|
LYXERR0("Could not rename file " << *this << " to " << name);
|
2007-12-13 07:36:47 +00:00
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-14 18:16:25 +00:00
|
|
|
bool FileName::moveTo(FileName const & name) const
|
|
|
|
{
|
2017-05-14 23:42:24 +00:00
|
|
|
LYXERR(Debug::FILES, "Moving " << *this << " to " << name);
|
2019-07-07 17:13:52 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
// there's a locking problem on Windows sometimes, so
|
|
|
|
// we will keep trying for five seconds, in the hope
|
|
|
|
// that clears.
|
|
|
|
bool removed = QFile::remove(name.d->fi.absoluteFilePath());
|
|
|
|
int tries = 1;
|
|
|
|
while (!removed && tries < 6) {
|
|
|
|
QThread::sleep(1);
|
|
|
|
removed = QFile::remove(name.d->fi.absoluteFilePath());
|
|
|
|
tries++;
|
|
|
|
}
|
|
|
|
#else
|
2007-12-14 23:47:59 +00:00
|
|
|
QFile::remove(name.d->fi.absoluteFilePath());
|
2019-07-07 17:13:52 +00:00
|
|
|
#endif
|
2007-12-14 18:16:25 +00:00
|
|
|
|
2019-07-07 17:13:52 +00:00
|
|
|
bool const success = QFile::rename(d->fi.absoluteFilePath(),
|
2007-12-14 18:16:25 +00:00
|
|
|
name.d->fi.absoluteFilePath());
|
|
|
|
if (!success)
|
|
|
|
LYXERR0("Could not move file " << *this << " to " << name);
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-13 10:38:31 +00:00
|
|
|
bool FileName::changePermission(unsigned long int mode) const
|
|
|
|
{
|
2007-12-13 11:24:10 +00:00
|
|
|
#if defined (HAVE_CHMOD) && defined (HAVE_MODE_T)
|
2007-12-13 11:25:45 +00:00
|
|
|
if (::chmod(toFilesystemEncoding().c_str(), mode_t(mode)) != 0) {
|
2007-12-13 11:24:10 +00:00
|
|
|
LYXERR0("File " << *this << ": cannot change permission to "
|
|
|
|
<< mode << ".");
|
2007-12-13 10:38:31 +00:00
|
|
|
return false;
|
|
|
|
}
|
2017-12-16 04:25:51 +00:00
|
|
|
#else
|
|
|
|
// squash warning
|
|
|
|
(void) mode;
|
2007-12-13 11:24:10 +00:00
|
|
|
#endif
|
2007-12-13 10:38:31 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-12-07 22:10:46 +00:00
|
|
|
bool FileName::clonePermissions(FileName const & source)
|
|
|
|
{
|
|
|
|
QFile fin(toqstr(source.absFileName()));
|
|
|
|
QFile f(toqstr(absFileName()));
|
|
|
|
|
|
|
|
return f.setPermissions(fin.permissions());
|
|
|
|
}
|
2007-12-13 10:38:31 +00:00
|
|
|
|
2007-10-18 23:03:51 +00:00
|
|
|
string FileName::toFilesystemEncoding() const
|
2006-11-26 21:30:39 +00:00
|
|
|
{
|
2010-02-21 04:51:27 +00:00
|
|
|
// This doesn't work on Windows for non ascii file names.
|
2007-11-26 10:29:04 +00:00
|
|
|
QByteArray const encoded = QFile::encodeName(d->fi.absoluteFilePath());
|
Make libQtCore a support library like boost and implement encoding conversion
from/to the local 8bit encoding with it.
Only the autotools build system is updated, scons and cmake users need to
add qt4 cpp flags when compiling libsupport, and link libsupport against
libQtCore.
* src/frontends/qt4/qt_helpers.[Ch]
(toqstr, qchar_to_ucs4, ucs4_to_qchar, ucs4_to_qstring,
qstring_to_ucs4, fromqstr): Move these qstring conversion functions
from here ...
* src/support/qstring_helpers.[Ch] ... to these new files
* src/support/docstring.[Ch]
(from_local8bit): new conversion function from local 8bit encoding
to ucs4
(to_local8bit): new conversion function from ucs4 to local 8bit
encoding to ucs4
(to_local8bit_failure): exception that is thrown by to_local8bit if
the argument cannot be converted to the local encoding
* src/support/filename.C
(FileName::toFilesystemEncoding): implement with the help of QFile
* src/support/Makefile.am: Add new files, qt4 cpp flags and link
against libQtCore
* src/client/client.C: Convert commandline input from local encoding
to ucs4. Convert stuff that is sent to to the server to utf8,
because LyX interprets it as utf8 on the other end of the pipe.
* src/lyx_main.C
(LyX::exec): convert commandline input from local encoding to utf8
(LyX::init): ditto
(LyX::easyParse): ditto
* development/scons/scons_manifest.py: Add new files
* config/qt4.m4: Define new variables QT4_CORE_INCLUDES,
QT4_CORE_LDFLAGS and QT4_CORE_LIB
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16257 a592a061-630c-0410-9148-cb99ea01b6c8
2006-12-12 20:19:46 +00:00
|
|
|
return string(encoded.begin(), encoded.end());
|
2006-11-26 21:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-22 19:34:25 +00:00
|
|
|
string FileName::toSafeFilesystemEncoding(os::file_access how) const
|
2010-02-21 04:51:27 +00:00
|
|
|
{
|
|
|
|
// This will work on Windows for non ascii file names.
|
2010-02-22 19:34:25 +00:00
|
|
|
QString const safe_path =
|
2010-04-21 01:19:09 +00:00
|
|
|
toqstr(os::safe_internal_path(absFileName(), how));
|
2010-02-21 04:51:27 +00:00
|
|
|
QByteArray const encoded = QFile::encodeName(safe_path);
|
|
|
|
return string(encoded.begin(), encoded.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-18 23:03:51 +00:00
|
|
|
FileName FileName::fromFilesystemEncoding(string const & name)
|
2006-12-21 13:01:47 +00:00
|
|
|
{
|
|
|
|
QByteArray const encoded(name.c_str(), name.length());
|
|
|
|
return FileName(fromqstr(QFile::decodeName(encoded)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-17 22:21:50 +00:00
|
|
|
bool FileName::exists() const
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
return !empty() && d->fi.exists();
|
2007-10-17 22:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-25 21:21:03 +00:00
|
|
|
bool FileName::isSymLink() const
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
return !empty() && d->fi.isSymLink();
|
2007-11-25 21:21:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-01-18 22:29:37 +00:00
|
|
|
//QFileInfo caching info might fool this test if file was changed meanwhile.
|
|
|
|
//refresh() helps, but we don't want to put it blindly here, because it might
|
|
|
|
//trigger slowdown on networked file systems.
|
2007-11-25 21:21:03 +00:00
|
|
|
bool FileName::isFileEmpty() const
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
LASSERT(!empty(), return true);
|
2007-11-26 10:29:04 +00:00
|
|
|
return d->fi.size() == 0;
|
2007-11-25 21:21:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-18 21:10:35 +00:00
|
|
|
bool FileName::isDirectory() const
|
2007-10-18 19:38:24 +00:00
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
return !empty() && d->fi.isDir();
|
2007-10-18 19:38:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-17 22:21:50 +00:00
|
|
|
bool FileName::isReadOnly() const
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
LASSERT(!empty(), return true);
|
2007-11-26 10:29:04 +00:00
|
|
|
return d->fi.isReadable() && !d->fi.isWritable();
|
2007-10-17 22:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-25 11:18:16 +00:00
|
|
|
bool FileName::isReadableDirectory() const
|
2007-10-18 21:10:35 +00:00
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
return isDirectory() && d->fi.isReadable();
|
2007-10-18 21:10:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
string FileName::onlyFileName() const
|
2007-11-03 17:37:37 +00:00
|
|
|
{
|
2007-12-17 17:09:30 +00:00
|
|
|
return fromqstr(d->fi.fileName());
|
2007-11-03 17:37:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-04-29 15:44:07 +00:00
|
|
|
string FileName::onlyFileNameWithoutExt() const
|
|
|
|
{
|
2008-10-24 16:59:11 +00:00
|
|
|
return fromqstr(d->fi.completeBaseName());
|
2008-04-29 15:44:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-22 09:44:44 +00:00
|
|
|
string FileName::extension() const
|
|
|
|
{
|
2008-10-24 16:59:11 +00:00
|
|
|
return fromqstr(d->fi.suffix());
|
2008-09-22 09:44:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-05 11:51:18 +00:00
|
|
|
bool FileName::hasExtension(const string & ext)
|
|
|
|
{
|
|
|
|
return Private::isFilesystemEqual(d->fi.suffix(), toqstr(ext));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-25 21:21:03 +00:00
|
|
|
FileName FileName::onlyPath() const
|
2007-11-03 17:37:37 +00:00
|
|
|
{
|
2007-12-17 17:09:30 +00:00
|
|
|
FileName path;
|
2009-05-02 17:12:31 +00:00
|
|
|
if (empty())
|
|
|
|
return path;
|
2007-12-18 10:34:53 +00:00
|
|
|
path.d->fi.setFile(d->fi.path());
|
2009-05-02 17:12:31 +00:00
|
|
|
path.d->name = fromqstr(path.d->fi.absoluteFilePath());
|
2007-12-17 17:09:30 +00:00
|
|
|
return path;
|
2007-11-03 17:37:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-11 11:12:12 +00:00
|
|
|
FileName FileName::parentPath() const
|
|
|
|
{
|
|
|
|
FileName path;
|
|
|
|
// return empty path for parent of root dir
|
|
|
|
// parent of empty path is empty too
|
|
|
|
if (empty() || d->fi.isRoot())
|
|
|
|
return path;
|
|
|
|
path.d->fi.setFile(d->fi.path());
|
|
|
|
path.d->name = fromqstr(path.d->fi.absoluteFilePath());
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-25 11:18:16 +00:00
|
|
|
bool FileName::isReadableFile() const
|
2007-10-18 23:03:51 +00:00
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
return !empty() && d->fi.isFile() && d->fi.isReadable();
|
2007-10-18 23:03:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool FileName::isWritable() const
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
return !empty() && d->fi.isWritable();
|
2007-10-18 23:03:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool FileName::isDirWritable() const
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
LASSERT(isDirectory(), return false);
|
2008-10-01 09:36:01 +00:00
|
|
|
QFileInfo tmp(QDir(d->fi.absoluteFilePath()), "lyxwritetest");
|
2008-07-23 08:14:24 +00:00
|
|
|
QTemporaryFile qt_tmp(tmp.absoluteFilePath());
|
|
|
|
if (qt_tmp.open()) {
|
|
|
|
LYXERR(Debug::FILES, "Directory " << *this << " is writable");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
LYXERR(Debug::FILES, "Directory " << *this << " is not writable");
|
|
|
|
return false;
|
2007-10-18 23:03:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
FileNameList FileName::dirList(string const & ext) const
|
2007-12-05 10:32:49 +00:00
|
|
|
{
|
|
|
|
FileNameList dirlist;
|
|
|
|
if (!isDirectory()) {
|
|
|
|
LYXERR0("Directory '" << *this << "' does not exist!");
|
|
|
|
return dirlist;
|
|
|
|
}
|
|
|
|
|
2009-05-10 02:25:25 +00:00
|
|
|
// If the directory is specified without a trailing '/', absoluteDir()
|
|
|
|
// would return the parent dir, so we must use absoluteFilePath() here.
|
|
|
|
QDir dir = d->fi.absoluteFilePath();
|
2007-12-05 10:32:49 +00:00
|
|
|
|
|
|
|
if (!ext.empty()) {
|
|
|
|
QString filter;
|
|
|
|
switch (ext[0]) {
|
|
|
|
case '.': filter = "*" + toqstr(ext); break;
|
|
|
|
case '*': filter = toqstr(ext); break;
|
|
|
|
default: filter = "*." + toqstr(ext);
|
|
|
|
}
|
|
|
|
dir.setNameFilters(QStringList(filter));
|
|
|
|
LYXERR(Debug::FILES, "filtering on extension "
|
|
|
|
<< fromqstr(filter) << " is requested.");
|
|
|
|
}
|
|
|
|
|
|
|
|
QFileInfoList list = dir.entryInfoList();
|
|
|
|
for (int i = 0; i != list.size(); ++i) {
|
|
|
|
FileName fi(fromqstr(list.at(i).absoluteFilePath()));
|
|
|
|
dirlist.push_back(fi);
|
|
|
|
LYXERR(Debug::FILES, "found file " << fi);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dirlist;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-16 10:18:00 +00:00
|
|
|
FileName FileName::getcwd()
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
// return makeAbsPath("."); would create an infinite loop
|
|
|
|
QFileInfo fi(".");
|
|
|
|
return FileName(fromqstr(fi.absoluteFilePath()));
|
2007-12-16 10:18:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-22 17:45:40 +00:00
|
|
|
FileName FileName::tempPath()
|
|
|
|
{
|
2008-10-04 15:57:26 +00:00
|
|
|
return FileName(os::internal_path(fromqstr(QDir::tempPath())));
|
2008-07-22 17:45:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-05 02:50:34 +00:00
|
|
|
void FileName::refresh() const
|
|
|
|
{
|
|
|
|
d->refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
time_t FileName::lastModified() const
|
2007-10-17 22:21:50 +00:00
|
|
|
{
|
2008-07-19 15:57:07 +00:00
|
|
|
// QFileInfo caches information about the file. So, in case this file has
|
|
|
|
// been touched between the object creation and now, we refresh the file
|
|
|
|
// information.
|
2008-07-21 16:39:46 +00:00
|
|
|
d->refresh();
|
2007-11-26 10:29:04 +00:00
|
|
|
return d->fi.lastModified().toTime_t();
|
2007-11-25 23:21:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-01 00:06:50 +00:00
|
|
|
bool FileName::chdir() const
|
|
|
|
{
|
|
|
|
return QDir::setCurrent(d->fi.absoluteFilePath());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-03 20:08:21 +00:00
|
|
|
bool FileName::link(FileName const & name) const
|
|
|
|
{
|
|
|
|
return QFile::link(toqstr(absFileName()), toqstr(name.absFileName()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-24 10:12:55 +00:00
|
|
|
unsigned long checksum_ifstream_fallback(char const * file)
|
|
|
|
{
|
|
|
|
unsigned long result = 0;
|
|
|
|
//LYXERR(Debug::FILES, "lyx::sum() using istreambuf_iterator (fast)");
|
|
|
|
ifstream ifs(file, ios_base::in | ios_base::binary);
|
|
|
|
if (!ifs)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
istreambuf_iterator<char> beg(ifs);
|
|
|
|
istreambuf_iterator<char> end;
|
|
|
|
boost::crc_32_type crc;
|
|
|
|
crc = for_each(beg, end, crc);
|
|
|
|
result = crc.checksum();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2007-11-30 09:23:44 +00:00
|
|
|
unsigned long FileName::checksum() const
|
|
|
|
{
|
|
|
|
if (!exists()) {
|
2010-04-21 01:19:09 +00:00
|
|
|
//LYXERR0("File \"" << absFileName() << "\" does not exist!");
|
2019-09-13 20:36:53 +00:00
|
|
|
return 0;
|
2007-11-30 09:23:44 +00:00
|
|
|
}
|
|
|
|
// a directory may be passed here so we need to test it. (bug 3622)
|
|
|
|
if (isDirectory()) {
|
2010-04-21 01:19:09 +00:00
|
|
|
LYXERR0('"' << absFileName() << "\" is a directory!");
|
2019-09-13 20:36:53 +00:00
|
|
|
return 0;
|
2008-09-29 09:35:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// This is used in the debug output at the end of the method.
|
|
|
|
static QTime t;
|
|
|
|
if (lyxerr.debugging(Debug::FILES))
|
|
|
|
t.restart();
|
|
|
|
|
2019-09-13 20:36:53 +00:00
|
|
|
unsigned long result = 0;
|
|
|
|
|
2008-09-29 09:35:13 +00:00
|
|
|
#if QT_VERSION >= 0x999999
|
|
|
|
// First version of checksum uses Qt4.4 mmap support.
|
|
|
|
// FIXME: This code is not ready with Qt4.4.2,
|
2009-12-11 00:59:10 +00:00
|
|
|
// see http://www.lyx.org/trac/ticket/5293
|
2008-09-29 09:35:13 +00:00
|
|
|
// FIXME: should we check if the MapExtension extension is supported?
|
2017-07-03 17:53:14 +00:00
|
|
|
// see QAbstractFileEngine::supportsExtension() and
|
2008-09-29 09:35:13 +00:00
|
|
|
// QAbstractFileEngine::MapExtension)
|
|
|
|
QFile qf(fi.filePath());
|
|
|
|
if (!qf.open(QIODevice::ReadOnly))
|
2019-09-13 20:36:53 +00:00
|
|
|
return 0;
|
2008-09-29 09:35:13 +00:00
|
|
|
qint64 size = fi.size();
|
|
|
|
uchar * ubeg = qf.map(0, size);
|
|
|
|
uchar * uend = ubeg + size;
|
|
|
|
boost::crc_32_type ucrc;
|
|
|
|
ucrc.process_block(ubeg, uend);
|
|
|
|
qf.unmap(ubeg);
|
|
|
|
qf.close();
|
|
|
|
result = ucrc.checksum();
|
|
|
|
|
|
|
|
#else // QT_VERSION
|
|
|
|
|
2010-02-21 13:51:06 +00:00
|
|
|
string const encoded = toSafeFilesystemEncoding();
|
2008-09-29 09:35:13 +00:00
|
|
|
char const * file = encoded.c_str();
|
|
|
|
|
|
|
|
#ifdef SUM_WITH_MMAP
|
|
|
|
//LYXERR(Debug::FILES, "using mmap (lightning fast)");
|
|
|
|
|
|
|
|
int fd = open(file, O_RDONLY);
|
|
|
|
if (!fd)
|
2019-09-13 20:36:53 +00:00
|
|
|
return 0;
|
2008-09-29 09:35:13 +00:00
|
|
|
|
|
|
|
struct stat info;
|
2011-03-24 10:12:55 +00:00
|
|
|
if (fstat(fd, &info)){
|
2011-03-23 14:52:18 +00:00
|
|
|
// fstat fails on samba shares (bug 5891)
|
2011-03-24 10:12:55 +00:00
|
|
|
close(fd);
|
|
|
|
return checksum_ifstream_fallback(file);
|
|
|
|
}
|
2008-09-29 09:35:13 +00:00
|
|
|
|
|
|
|
void * mm = mmap(0, info.st_size, PROT_READ,
|
|
|
|
MAP_PRIVATE, fd, 0);
|
|
|
|
// Some platforms have the wrong type for MAP_FAILED (compaq cxx).
|
|
|
|
if (mm == reinterpret_cast<void*>(MAP_FAILED)) {
|
|
|
|
close(fd);
|
2019-09-13 20:36:53 +00:00
|
|
|
return 0;
|
2007-11-30 09:23:44 +00:00
|
|
|
}
|
2008-09-29 09:35:13 +00:00
|
|
|
|
|
|
|
char * beg = static_cast<char*>(mm);
|
|
|
|
char * end = beg + info.st_size;
|
|
|
|
|
|
|
|
boost::crc_32_type crc;
|
|
|
|
crc.process_block(beg, end);
|
2008-09-29 10:13:28 +00:00
|
|
|
result = crc.checksum();
|
2008-09-29 09:35:13 +00:00
|
|
|
|
|
|
|
munmap(mm, info.st_size);
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
#else // no SUM_WITH_MMAP
|
2011-03-24 10:12:55 +00:00
|
|
|
result = checksum_ifstream_fallback(file);
|
2008-09-29 09:35:13 +00:00
|
|
|
#endif // SUM_WITH_MMAP
|
|
|
|
#endif // QT_VERSION
|
|
|
|
|
2010-04-21 01:19:09 +00:00
|
|
|
LYXERR(Debug::FILES, "Checksumming \"" << absFileName() << "\" "
|
2008-09-29 09:35:13 +00:00
|
|
|
<< result << " lasted " << t.elapsed() << " ms.");
|
|
|
|
return result;
|
2007-11-30 09:23:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-28 09:01:49 +00:00
|
|
|
bool FileName::removeFile() const
|
|
|
|
{
|
|
|
|
bool const success = QFile::remove(d->fi.absoluteFilePath());
|
2008-11-26 01:22:05 +00:00
|
|
|
d->refresh();
|
2007-12-01 00:30:12 +00:00
|
|
|
if (!success && exists())
|
2007-12-06 16:54:02 +00:00
|
|
|
LYXERR0("Could not delete file " << *this);
|
2007-11-28 09:01:49 +00:00
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-25 23:21:39 +00:00
|
|
|
static bool rmdir(QFileInfo const & fi)
|
|
|
|
{
|
|
|
|
QDir dir(fi.absoluteFilePath());
|
|
|
|
QFileInfoList list = dir.entryInfoList();
|
2007-12-06 16:54:02 +00:00
|
|
|
bool success = true;
|
2007-11-30 20:57:53 +00:00
|
|
|
for (int i = 0; i != list.size(); ++i) {
|
2007-11-25 23:21:39 +00:00
|
|
|
if (list.at(i).fileName() == ".")
|
|
|
|
continue;
|
|
|
|
if (list.at(i).fileName() == "..")
|
|
|
|
continue;
|
2007-12-06 16:54:02 +00:00
|
|
|
bool removed;
|
2007-11-25 23:21:39 +00:00
|
|
|
if (list.at(i).isDir()) {
|
2017-07-03 17:53:14 +00:00
|
|
|
LYXERR(Debug::FILES, "Removing dir "
|
2007-11-27 21:43:46 +00:00
|
|
|
<< fromqstr(list.at(i).absoluteFilePath()));
|
2007-12-06 16:54:02 +00:00
|
|
|
removed = rmdir(list.at(i));
|
2007-11-25 23:21:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2017-07-03 17:53:14 +00:00
|
|
|
LYXERR(Debug::FILES, "Removing file "
|
2007-11-27 21:43:46 +00:00
|
|
|
<< fromqstr(list.at(i).absoluteFilePath()));
|
2007-12-06 16:54:02 +00:00
|
|
|
removed = dir.remove(list.at(i).fileName());
|
2007-11-26 10:58:00 +00:00
|
|
|
}
|
2007-12-06 16:54:02 +00:00
|
|
|
if (!removed) {
|
|
|
|
success = false;
|
|
|
|
LYXERR0("Could not delete "
|
|
|
|
<< fromqstr(list.at(i).absoluteFilePath()));
|
2007-11-25 23:21:39 +00:00
|
|
|
}
|
2017-07-03 17:53:14 +00:00
|
|
|
}
|
2007-11-25 23:21:39 +00:00
|
|
|
QDir parent = fi.absolutePath();
|
2007-12-06 16:54:02 +00:00
|
|
|
success &= parent.rmdir(fi.fileName());
|
|
|
|
return success;
|
2007-10-20 17:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool FileName::destroyDirectory() const
|
|
|
|
{
|
2007-11-26 10:29:04 +00:00
|
|
|
bool const success = rmdir(d->fi);
|
2007-11-25 23:21:39 +00:00
|
|
|
if (!success)
|
2007-12-06 16:54:02 +00:00
|
|
|
LYXERR0("Could not delete " << *this);
|
2007-11-25 23:21:39 +00:00
|
|
|
|
|
|
|
return success;
|
2007-10-20 17:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-01 09:36:01 +00:00
|
|
|
// Only used in non Win32 platforms
|
2018-01-12 11:22:28 +00:00
|
|
|
#ifndef Q_OS_WIN32
|
2007-12-14 22:43:39 +00:00
|
|
|
static int mymkdir(char const * pathname, unsigned long int mode)
|
|
|
|
{
|
|
|
|
// FIXME: why don't we have mode_t in lyx::mkdir prototype ??
|
2018-01-12 11:27:03 +00:00
|
|
|
# if HAVE_MKDIR
|
|
|
|
# if MKDIR_TAKES_ONE_ARG
|
2007-12-14 22:43:39 +00:00
|
|
|
// MinGW32
|
|
|
|
return ::mkdir(pathname);
|
|
|
|
// FIXME: "Permissions of created directories are ignored on this system."
|
2018-01-12 11:27:03 +00:00
|
|
|
# else
|
2007-12-14 22:43:39 +00:00
|
|
|
// POSIX
|
|
|
|
return ::mkdir(pathname, mode_t(mode));
|
2018-01-12 11:27:03 +00:00
|
|
|
# endif
|
|
|
|
# elif defined(_WIN32)
|
2007-12-14 22:43:39 +00:00
|
|
|
// plain Windows 32
|
|
|
|
return CreateDirectory(pathname, 0) != 0 ? 0 : -1;
|
|
|
|
// FIXME: "Permissions of created directories are ignored on this system."
|
2018-01-12 11:27:03 +00:00
|
|
|
# elif HAVE__MKDIR
|
2007-12-14 22:43:39 +00:00
|
|
|
return ::_mkdir(pathname);
|
|
|
|
// FIXME: "Permissions of created directories are ignored on this system."
|
2018-01-12 11:27:03 +00:00
|
|
|
# else
|
2007-12-14 22:43:39 +00:00
|
|
|
# error "Don't know how to create a directory on this system."
|
2018-01-12 11:27:03 +00:00
|
|
|
# endif
|
2007-12-14 22:43:39 +00:00
|
|
|
}
|
2018-01-12 11:22:28 +00:00
|
|
|
#endif
|
2007-12-14 22:43:39 +00:00
|
|
|
|
|
|
|
|
2007-10-20 17:35:27 +00:00
|
|
|
bool FileName::createDirectory(int permission) const
|
|
|
|
{
|
2008-10-01 09:36:01 +00:00
|
|
|
LASSERT(!empty(), return false);
|
|
|
|
#ifdef Q_OS_WIN32
|
|
|
|
// FIXME: "Permissions of created directories are ignored on this system."
|
2017-12-16 04:25:51 +00:00
|
|
|
(void) permission;
|
2008-10-01 09:36:01 +00:00
|
|
|
return createPath();
|
|
|
|
#else
|
2007-12-14 22:43:39 +00:00
|
|
|
return mymkdir(toFilesystemEncoding().c_str(), permission) == 0;
|
2008-10-01 09:36:01 +00:00
|
|
|
#endif
|
2007-12-14 22:43:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool FileName::createPath() const
|
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
LASSERT(!empty(), return false);
|
2008-10-01 09:36:01 +00:00
|
|
|
LYXERR(Debug::FILES, "creating path '" << *this << "'.");
|
2007-12-14 22:43:39 +00:00
|
|
|
if (isDirectory())
|
2008-10-01 09:36:01 +00:00
|
|
|
return false;
|
2007-12-14 22:43:39 +00:00
|
|
|
|
|
|
|
QDir dir;
|
|
|
|
bool success = dir.mkpath(d->fi.absoluteFilePath());
|
|
|
|
if (!success)
|
|
|
|
LYXERR0("Cannot create path '" << *this << "'!");
|
|
|
|
return success;
|
2007-10-20 17:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-02 09:19:43 +00:00
|
|
|
docstring const FileName::absoluteFilePath() const
|
2007-11-27 09:43:30 +00:00
|
|
|
{
|
2007-12-02 09:19:43 +00:00
|
|
|
return qstring_to_ucs4(d->fi.absoluteFilePath());
|
2007-11-27 09:43:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-03 17:37:37 +00:00
|
|
|
docstring FileName::displayName(int threshold) const
|
|
|
|
{
|
2010-04-21 01:19:09 +00:00
|
|
|
return makeDisplayPath(absFileName(), threshold);
|
2007-11-03 17:37:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-02 11:55:25 +00:00
|
|
|
docstring FileName::fileContents(string const & encoding) const
|
|
|
|
{
|
|
|
|
if (!isReadableFile()) {
|
2012-08-17 15:24:09 +00:00
|
|
|
LYXERR0("File '" << *this << "' is not readable!");
|
2007-12-02 11:55:25 +00:00
|
|
|
return docstring();
|
|
|
|
}
|
|
|
|
|
|
|
|
QFile file(d->fi.absoluteFilePath());
|
|
|
|
if (!file.open(QIODevice::ReadOnly)) {
|
|
|
|
LYXERR0("File '" << *this
|
|
|
|
<< "' could not be opened in read only mode!");
|
|
|
|
return docstring();
|
2007-10-20 17:35:27 +00:00
|
|
|
}
|
2007-12-02 11:55:25 +00:00
|
|
|
QByteArray contents = file.readAll();
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
if (contents.isEmpty()) {
|
|
|
|
LYXERR(Debug::FILES, "File '" << *this
|
|
|
|
<< "' is either empty or some error happened while reading it.");
|
|
|
|
return docstring();
|
|
|
|
}
|
|
|
|
|
|
|
|
QString s;
|
|
|
|
if (encoding.empty() || encoding == "UTF-8")
|
|
|
|
s = QString::fromUtf8(contents.data());
|
|
|
|
else if (encoding == "ascii")
|
2013-02-03 11:23:31 +00:00
|
|
|
#if (QT_VERSION < 0x050000)
|
2007-12-02 11:55:25 +00:00
|
|
|
s = QString::fromAscii(contents.data());
|
2013-02-03 11:23:31 +00:00
|
|
|
#else
|
|
|
|
s = QString::fromLatin1(contents.data());
|
|
|
|
#endif
|
2007-12-02 11:55:25 +00:00
|
|
|
else if (encoding == "local8bit")
|
|
|
|
s = QString::fromLocal8Bit(contents.data());
|
|
|
|
else if (encoding == "latin1")
|
|
|
|
s = QString::fromLatin1(contents.data());
|
|
|
|
|
|
|
|
return qstring_to_ucs4(s);
|
2007-10-20 17:35:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
void FileName::changeExtension(string const & extension)
|
2007-11-28 15:25:07 +00:00
|
|
|
{
|
|
|
|
// FIXME: use Qt native methods...
|
2010-04-21 01:19:09 +00:00
|
|
|
string const oldname = absFileName();
|
2007-11-28 15:25:07 +00:00
|
|
|
string::size_type const last_slash = oldname.rfind('/');
|
|
|
|
string::size_type last_dot = oldname.rfind('.');
|
|
|
|
if (last_dot < last_slash && last_slash != string::npos)
|
|
|
|
last_dot = string::npos;
|
|
|
|
|
|
|
|
string ext;
|
|
|
|
// Make sure the extension starts with a dot
|
|
|
|
if (!extension.empty() && extension[0] != '.')
|
|
|
|
ext= '.' + extension;
|
|
|
|
else
|
|
|
|
ext = extension;
|
|
|
|
|
|
|
|
set(oldname.substr(0, last_dot) + ext);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-01 10:23:16 +00:00
|
|
|
docstring const FileName::relPath(string const & path) const
|
|
|
|
{
|
|
|
|
// FIXME UNICODE
|
2007-12-02 09:19:43 +00:00
|
|
|
return makeRelPath(absoluteFilePath(), from_utf8(path));
|
2007-12-01 10:23:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-05-02 16:39:14 +00:00
|
|
|
// Note: According to Qt, QFileInfo::operator== is undefined when
|
|
|
|
// both files do not exist (Qt4.5 gives true for all non-existent
|
|
|
|
// files, while Qt4.4 compares the filenames).
|
|
|
|
// see:
|
|
|
|
// http://www.qtsoftware.com/developer/task-tracker/
|
|
|
|
// index_html?id=248471&method=entry.
|
2009-05-02 17:12:31 +00:00
|
|
|
bool equivalent(FileName const & l, FileName const & r)
|
2009-05-02 16:39:14 +00:00
|
|
|
{
|
|
|
|
// FIXME: In future use Qt.
|
|
|
|
// Qt 4.4: We need to solve this warning from Qt documentation:
|
|
|
|
// * Long and short file names that refer to the same file on Windows are
|
|
|
|
// treated as if they referred to different files.
|
|
|
|
// This is supposed to be fixed for Qt5.
|
2010-04-21 01:19:09 +00:00
|
|
|
FileName const lhs(os::internal_path(l.absFileName()));
|
|
|
|
FileName const rhs(os::internal_path(r.absFileName()));
|
2009-05-02 16:39:14 +00:00
|
|
|
|
|
|
|
if (lhs.empty())
|
|
|
|
// QFileInfo::operator==() returns false if the two QFileInfo are empty.
|
|
|
|
return rhs.empty();
|
|
|
|
|
|
|
|
if (rhs.empty())
|
|
|
|
// Avoid unnecessary checks below.
|
|
|
|
return false;
|
2009-05-01 15:18:11 +00:00
|
|
|
|
2009-05-02 16:39:14 +00:00
|
|
|
lhs.d->refresh();
|
|
|
|
rhs.d->refresh();
|
|
|
|
|
|
|
|
if (!lhs.d->fi.isSymLink() && !rhs.d->fi.isSymLink()) {
|
|
|
|
// Qt already checks if the filesystem is case sensitive or not.
|
|
|
|
// see note above why the extra check with fileName is needed.
|
|
|
|
return lhs.d->fi == rhs.d->fi
|
|
|
|
&& lhs.d->fi.fileName() == rhs.d->fi.fileName();
|
2008-10-05 11:51:18 +00:00
|
|
|
}
|
2008-07-29 18:13:52 +00:00
|
|
|
|
2009-05-02 16:39:14 +00:00
|
|
|
// FIXME: When/if QFileInfo support symlink comparison, remove this code.
|
|
|
|
QFileInfo fi1(lhs.d->fi);
|
|
|
|
if (fi1.isSymLink())
|
|
|
|
fi1 = QFileInfo(fi1.symLinkTarget());
|
|
|
|
QFileInfo fi2(rhs.d->fi);
|
|
|
|
if (fi2.isSymLink())
|
|
|
|
fi2 = QFileInfo(fi2.symLinkTarget());
|
|
|
|
// see note above why the extra check with fileName is needed.
|
|
|
|
return fi1 == fi2 && fi1.fileName() == fi2.fileName();
|
2006-11-18 12:49:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-05-02 17:12:31 +00:00
|
|
|
bool operator==(FileName const & lhs, FileName const & rhs)
|
|
|
|
{
|
2009-05-04 22:16:37 +00:00
|
|
|
return os::isFilesystemCaseSensitive()
|
2010-04-21 01:19:09 +00:00
|
|
|
? lhs.absFileName() == rhs.absFileName()
|
|
|
|
: !QString::compare(toqstr(lhs.absFileName()),
|
|
|
|
toqstr(rhs.absFileName()), Qt::CaseInsensitive);
|
2009-05-02 17:12:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-18 12:49:47 +00:00
|
|
|
bool operator!=(FileName const & lhs, FileName const & rhs)
|
|
|
|
{
|
2008-07-29 09:07:37 +00:00
|
|
|
return !(operator==(lhs, rhs));
|
2006-11-18 12:49:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-26 21:30:39 +00:00
|
|
|
bool operator<(FileName const & lhs, FileName const & rhs)
|
|
|
|
{
|
2010-04-21 01:19:09 +00:00
|
|
|
return lhs.absFileName() < rhs.absFileName();
|
2006-11-26 21:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool operator>(FileName const & lhs, FileName const & rhs)
|
|
|
|
{
|
2010-04-21 01:19:09 +00:00
|
|
|
return lhs.absFileName() > rhs.absFileName();
|
2006-11-26 21:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
ostream & operator<<(ostream & os, FileName const & filename)
|
2006-11-26 21:30:39 +00:00
|
|
|
{
|
2010-04-21 01:19:09 +00:00
|
|
|
return os << filename.absFileName();
|
2006-11-26 21:30:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-17 22:21:50 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// DocFileName
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
2006-11-18 12:49:47 +00:00
|
|
|
DocFileName::DocFileName()
|
|
|
|
: save_abs_path_(true)
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
DocFileName::DocFileName(string const & abs_filename, bool save_abs)
|
2012-01-12 19:48:08 +00:00
|
|
|
: FileName(abs_filename), save_abs_path_(save_abs)
|
2006-11-18 12:49:47 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
|
2006-12-27 10:56:11 +00:00
|
|
|
DocFileName::DocFileName(FileName const & abs_filename, bool save_abs)
|
2012-01-12 19:48:08 +00:00
|
|
|
: FileName(abs_filename), save_abs_path_(save_abs)
|
2006-12-27 10:56:11 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
|
2006-11-18 12:49:47 +00:00
|
|
|
void DocFileName::set(string const & name, string const & buffer_path)
|
2003-07-22 20:42:40 +00:00
|
|
|
{
|
2009-05-02 17:12:31 +00:00
|
|
|
save_abs_path_ = isAbsolute(name);
|
|
|
|
if (save_abs_path_)
|
|
|
|
FileName::set(name);
|
|
|
|
else
|
2010-04-21 01:19:09 +00:00
|
|
|
FileName::set(makeAbsPath(name, buffer_path).absFileName());
|
2003-07-22 20:42:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-18 12:49:47 +00:00
|
|
|
void DocFileName::erase()
|
2003-07-22 20:42:40 +00:00
|
|
|
{
|
2007-11-26 10:29:04 +00:00
|
|
|
FileName::erase();
|
2003-07-22 20:42:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-21 01:19:20 +00:00
|
|
|
string DocFileName::relFileName(string const & path) const
|
2003-07-22 20:42:40 +00:00
|
|
|
{
|
2007-03-27 07:24:16 +00:00
|
|
|
// FIXME UNICODE
|
2007-12-01 10:23:16 +00:00
|
|
|
return to_utf8(relPath(path));
|
2003-07-22 20:42:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-21 01:19:25 +00:00
|
|
|
string DocFileName::outputFileName(string const & path) const
|
2003-07-22 20:42:40 +00:00
|
|
|
{
|
2010-04-21 01:19:20 +00:00
|
|
|
return save_abs_path_ ? absFileName() : relFileName(path);
|
2003-07-22 20:42:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-21 01:19:22 +00:00
|
|
|
string DocFileName::mangledFileName(string const & dir) const
|
2003-09-03 17:23:38 +00:00
|
|
|
{
|
2013-10-07 22:59:05 +00:00
|
|
|
// Concurrent access to these variables is possible.
|
|
|
|
|
2006-11-18 12:49:47 +00:00
|
|
|
// We need to make sure that every DocFileName instance for a given
|
2004-03-11 11:45:08 +00:00
|
|
|
// filename returns the same mangled name.
|
2004-10-05 10:11:42 +00:00
|
|
|
typedef map<string, string> MangledMap;
|
2004-03-11 11:45:08 +00:00
|
|
|
static MangledMap mangledNames;
|
2014-07-05 10:22:08 +00:00
|
|
|
static Mutex mangledMutex;
|
2017-07-03 17:53:14 +00:00
|
|
|
// this locks both access to mangledNames and counter below
|
2014-07-05 10:22:08 +00:00
|
|
|
Mutex::Locker lock(&mangledMutex);
|
2010-04-21 01:19:09 +00:00
|
|
|
MangledMap::const_iterator const it = mangledNames.find(absFileName());
|
2004-03-11 11:45:08 +00:00
|
|
|
if (it != mangledNames.end())
|
|
|
|
return (*it).second;
|
|
|
|
|
2010-04-21 01:19:09 +00:00
|
|
|
string const name = absFileName();
|
2004-03-11 11:45:08 +00:00
|
|
|
// Now the real work
|
2007-11-26 10:29:04 +00:00
|
|
|
string mname = os::internal_path(name);
|
2003-09-03 17:23:38 +00:00
|
|
|
// Remove the extension.
|
2007-11-28 15:25:07 +00:00
|
|
|
mname = support::changeExtension(name, string());
|
2007-02-27 19:01:10 +00:00
|
|
|
// The mangled name must be a valid LaTeX name.
|
|
|
|
// The list of characters to keep is probably over-restrictive,
|
|
|
|
// but it is not really a problem.
|
|
|
|
// Apart from non-ASCII characters, at least the following characters
|
|
|
|
// are forbidden: '/', '.', ' ', and ':'.
|
|
|
|
// On windows it is not possible to create files with '<', '>' or '?'
|
|
|
|
// in the name.
|
|
|
|
static string const keep = "abcdefghijklmnopqrstuvwxyz"
|
2007-05-28 22:27:45 +00:00
|
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
2010-09-24 16:12:02 +00:00
|
|
|
"+-0123456789;=";
|
2007-02-27 19:01:10 +00:00
|
|
|
string::size_type pos = 0;
|
|
|
|
while ((pos = mname.find_first_not_of(keep, pos)) != string::npos)
|
|
|
|
mname[pos++] = '_';
|
2003-09-03 17:23:38 +00:00
|
|
|
// Add the extension back on
|
2007-11-28 15:25:07 +00:00
|
|
|
mname = support::changeExtension(mname, getExtension(name));
|
2004-12-17 12:30:48 +00:00
|
|
|
|
2004-03-11 11:45:08 +00:00
|
|
|
// Prepend a counter to the filename. This is necessary to make
|
|
|
|
// the mangled name unique.
|
|
|
|
static int counter = 0;
|
2007-12-12 19:28:07 +00:00
|
|
|
ostringstream s;
|
2005-07-14 12:53:12 +00:00
|
|
|
s << counter++ << mname;
|
|
|
|
mname = s.str();
|
|
|
|
|
2006-04-05 23:39:11 +00:00
|
|
|
// MiKTeX's YAP (version 2.4.1803) crashes if the file name
|
2006-04-01 13:04:23 +00:00
|
|
|
// is longer than about 160 characters. MiKTeX's pdflatex
|
|
|
|
// is even pickier. A maximum length of 100 has been proven to work.
|
|
|
|
// If dir.size() > max length, all bets are off for YAP. We truncate
|
|
|
|
// the filename nevertheless, keeping a minimum of 10 chars.
|
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
string::size_type max_length = max(100 - ((int)dir.size() + 1), 10);
|
2006-03-15 21:00:15 +00:00
|
|
|
|
|
|
|
// If the mangled file name is too long, hack it to fit.
|
|
|
|
// We know we're guaranteed to have a unique file name because
|
|
|
|
// of the counter.
|
|
|
|
if (mname.size() > max_length) {
|
|
|
|
int const half = (int(max_length) / 2) - 2;
|
|
|
|
if (half > 0) {
|
|
|
|
mname = mname.substr(0, half) + "___" +
|
|
|
|
mname.substr(mname.size() - half);
|
2005-07-14 12:53:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-21 01:19:09 +00:00
|
|
|
mangledNames[absFileName()] = mname;
|
2004-03-11 11:45:08 +00:00
|
|
|
return mname;
|
2003-09-03 17:23:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-21 01:19:26 +00:00
|
|
|
string DocFileName::unzippedFileName() const
|
2003-09-03 17:23:38 +00:00
|
|
|
{
|
2010-04-21 01:19:26 +00:00
|
|
|
return support::unzippedFileName(absFileName());
|
2003-09-03 17:23:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-18 12:49:47 +00:00
|
|
|
bool operator==(DocFileName const & lhs, DocFileName const & rhs)
|
2003-07-22 20:42:40 +00:00
|
|
|
{
|
2008-07-29 14:41:46 +00:00
|
|
|
return static_cast<FileName const &>(lhs)
|
|
|
|
== static_cast<FileName const &>(rhs)
|
2007-10-20 17:35:27 +00:00
|
|
|
&& lhs.saveAbsPath() == rhs.saveAbsPath();
|
2003-07-22 20:42:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-18 12:49:47 +00:00
|
|
|
bool operator!=(DocFileName const & lhs, DocFileName const & rhs)
|
2003-07-22 20:42:40 +00:00
|
|
|
{
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
2003-09-03 17:23:38 +00:00
|
|
|
} // namespace support
|
2003-07-22 20:42:40 +00:00
|
|
|
} // namespace lyx
|