#include <config.h>
-#include "debug.h"
-#include "support/tostr.h"
+#include "support/convert.h"
+#include "support/environment.h"
+#include "support/filetools.h"
+#include "support/forkedcontr.h"
+#include "support/fs_extras.h"
+#include "support/lstrings.h"
+#include "support/lyxlib.h"
+#include "support/os.h"
+#include "support/package.h"
+#include "support/path.h"
#include "support/systemcall.h"
-#include "filetools.h"
-#include "lstrings.h"
-#include "FileInfo.h"
-#include "forkedcontr.h"
-#include "path.h"
-#include "path_defines.h"
+// FIXME Interface violation
#include "gettext.h"
-#include "lyxlib.h"
-#include "os.h"
+#include "debug.h"
#include <boost/assert.hpp>
+#include <boost/filesystem/operations.hpp>
#include <boost/regex.hpp>
#include <fcntl.h>
#include <fstream>
#include <sstream>
-
-// Which part of this is still necessary? (JMarc).
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif
-#endif
-
#ifndef CXX_GLOBAL_CSTD
using std::fgetc;
using std::isalnum;
using std::ostringstream;
using std::vector;
+namespace fs = boost::filesystem;
namespace lyx {
namespace support {
}
-// Substitutes spaces with underscores in filename (and path)
string const QuoteName(string const & name)
{
return (os::shell() == os::UNIX) ?
// Is a file readable ?
bool IsFileReadable(string const & path)
{
- FileInfo file(path);
- return file.isOK() && file.isRegular() && file.readable();
-}
-
-
-// Is a file read_only?
-// return 1 read-write
-// 0 read_only
-// -1 error (doesn't exist, no access, anything else)
-int IsFileWriteable(string const & path)
-{
- FileInfo fi(path);
-
- if (fi.access(FileInfo::wperm|FileInfo::rperm)) // read-write
- return 1;
- if (fi.readable()) // read-only
- return 0;
- return -1; // everything else.
+ return fs::exists(path) && !fs::is_directory(path) && fs::is_readable(path);
}
string tmppath = split(path, path_element, ';');
while (notfound && !path_element.empty()) {
- path_element = os::slashify_path(path_element);
+ path_element = os::internal_path(path_element);
if (!suffixIs(path_element, '/'))
path_element+= '/';
- path_element = subst(path_element, "$$LyX", system_lyxdir());
- path_element = subst(path_element, "$$User", user_lyxdir());
+ path_element = subst(path_element, "$$LyX",
+ package().system_support());
+ path_element = subst(path_element, "$$User",
+ package().user_support());
real_file = FileSearch(path_element, name, ext);
/// Returns a vector of all files in directory dir having extension ext.
vector<string> const DirList(string const & dir, string const & ext)
{
- // This is a non-error checking C/system implementation
- string extension;
- if (!ext.empty() && ext[0] != '.')
- extension += '.';
- extension += ext;
-
+ // EXCEPTIONS FIXME. Rewrite needed when we turn on exceptions. (Lgb)
vector<string> dirlist;
- DIR * dirp = ::opendir(dir.c_str());
- if (!dirp) {
+
+ if (!(fs::exists(dir) && fs::is_directory(dir))) {
lyxerr[Debug::FILES]
<< "Directory \"" << dir
<< "\" does not exist to DirList." << endl;
return dirlist;
}
- dirent * dire;
- while ((dire = ::readdir(dirp))) {
- string const fil = dire->d_name;
+ string extension;
+ if (!ext.empty() && ext[0] != '.')
+ extension += '.';
+ extension += ext;
+
+ fs::directory_iterator dit(dir);
+ fs::directory_iterator end;
+ for (; dit != end; ++dit) {
+ string const & fil = dit->leaf();
if (suffixIs(fil, extension)) {
dirlist.push_back(fil);
}
}
- ::closedir(dirp);
return dirlist;
- /* I would have prefered to take a vector<string>& as parameter so
- that we could avoid the copy of the vector when returning.
- Then we would use:
- dirlist.swap(argvec);
- to avoid the copy. (Lgb)
- */
- /* A C++ implementaion will look like this:
- string extension(ext);
- if (extension[0] != '.') extension.insert(0, 1, '.');
- vector<string> dirlist;
- directory_iterator dit("dir");
- while (dit != directory_iterator()) {
- string fil = dit->filename;
- if (prefixIs(fil, extension)) {
- dirlist.push_back(fil);
- }
- ++dit;
- }
- dirlist.swap(argvec);
- return;
- */
}
string const LibFileSearch(string const & dir, string const & name,
string const & ext)
{
- string fullname = FileSearch(AddPath(user_lyxdir(), dir), name, ext);
+ string fullname = FileSearch(AddPath(package().user_support(), dir),
+ name, ext);
if (!fullname.empty())
return fullname;
- if (!build_lyxdir().empty())
- fullname = FileSearch(AddPath(build_lyxdir(), dir), name, ext);
+ if (!package().build_support().empty())
+ fullname = FileSearch(AddPath(package().build_support(), dir),
+ name, ext);
if (!fullname.empty())
return fullname;
- return FileSearch(AddPath(system_lyxdir(), dir), name, ext);
+ return FileSearch(AddPath(package().system_support(), dir), name, ext);
}
/* [Otherwise] We have to proceed with the POSIX methods of
looking to `LC_ALL', `LC_xxx', and `LANG'. */
- string lang = GetEnv("LC_ALL");
+ string lang = getEnv("LC_ALL");
if (lang.empty()) {
- lang = GetEnv("LC_MESSAGES");
+ lang = getEnv("LC_MESSAGES");
if (lang.empty()) {
- lang = GetEnv("LANG");
+ lang = getEnv("LANG");
if (lang.empty())
lang = "C";
}
}
- string const language = GetEnv("LANGUAGE");
+ string const language = getEnv("LANGUAGE");
if (lang != "C" && lang != "POSIX" && !language.empty())
lang = language;
string::size_type const pos1 = command.find(token_scriptpath);
if (pos1 == string::npos)
return command;
- // Find the end of the "$$s/some_script" word within command
+ // Find the end of the "$$s/some_subdir/some_script" word within
+ // command. Assumes that the script name does not contain spaces.
string::size_type const start_script = pos1 + 4;
string::size_type const pos2 = command.find(' ', start_script);
string::size_type const size_script = pos2 == string::npos?
// Does this script file exist?
string const script =
- LibFileSearch("scripts", command.substr(start_script, size_script));
+ LibFileSearch(".", command.substr(start_script, size_script));
if (script.empty()) {
// Replace "$$s/" with ""
command.erase(pos1, 4);
} else {
- // Replace "$$s/some_script" with "$LYX_SCRIPT_PATH/some_script"
+ // Replace "$$s/foo/some_script" with "<path to>/some_script".
string::size_type const size_replace = size_script + 4;
- command.replace(pos1, size_replace, script);
+ command.replace(pos1, size_replace, QuoteName(script));
}
return command;
}
-string const GetEnv(string const & envname)
-{
- // f.ex. what about error checking?
- char const * const ch = getenv(envname.c_str());
- string const envstr = !ch ? "" : ch;
- return envstr;
-}
-
-
-string const GetEnvPath(string const & name)
-{
-#ifndef __EMX__
- string const pathlist = subst(GetEnv(name), ':', ';');
-#else
- string const pathlist = os::slashify_path(GetEnv(name));
-#endif
- return rtrim(pathlist, ";");
-}
-
-
namespace {
-int DeleteAllFilesInDir(string const & path)
-{
- // I have decided that we will be using parts from the boost
- // library. Check out http://www.boost.org/
- // For directory access we will then use the directory_iterator.
- // Then the code will be something like:
- // directory_iterator dit(path);
- // directory_iterator dend;
- // if (dit == dend) {
- // return -1;
- // }
- // for (; dit != dend; ++dit) {
- // string filename(*dit);
- // if (filename == "." || filename == "..")
- // continue;
- // string unlinkpath(AddName(path, filename));
- // lyx::unlink(unlinkpath);
- // }
- // return 0;
- DIR * dir = ::opendir(path.c_str());
- if (!dir)
- return -1;
-
- struct dirent * de;
- int return_value = 0;
- while ((de = readdir(dir))) {
- string const temp = de->d_name;
- if (temp == "." || temp == "..")
- continue;
- string const unlinkpath = AddName (path, temp);
-
- lyxerr[Debug::FILES] << "Deleting file: " << unlinkpath
- << endl;
-
- bool deleted = true;
- FileInfo fi(unlinkpath);
- if (fi.isOK() && fi.isDir()) {
- deleted = (DeleteAllFilesInDir(unlinkpath) == 0);
- deleted &= (rmdir(unlinkpath) == 0);
- } else
- deleted &= (unlink(unlinkpath) == 0);
- if (!deleted)
- return_value = -1;
- }
- closedir(dir);
- return return_value;
-}
-
-
string const createTmpDir(string const & tempdir, string const & mask)
{
lyxerr[Debug::FILES]
} // namespace anon
-int destroyDir(string const & tmpdir)
+bool destroyDir(string const & tmpdir)
{
+
#ifdef __EMX__
Path p(user_lyxdir());
#endif
- if (DeleteAllFilesInDir(tmpdir))
- return -1;
-
- if (rmdir(tmpdir))
- return -1;
-
- return 0;
+ return fs::remove_all(tmpdir) > 0;
}
{
static int count;
// We are in our own directory. Why bother to mangle name?
- // In fact I wrote this code to circumvent a problematic behaviour (bug?)
- // of EMX mkstemp().
- string const tmpfl = os::getTmpDir() + "/lyx_tmpbuf" + tostr(count++);
+ // In fact I wrote this code to circumvent a problematic behaviour
+ // (bug?) of EMX mkstemp().
+ string const tmpfl =
+ package().temp_dir() + "/lyx_tmpbuf" +
+ convert<string>(count++);
+
if (mkdir(tmpfl, 0777)) {
lyxerr << "LyX could not create the temporary directory '"
<< tmpfl << "'" << endl;
{
if (!deflt.empty() && deflt != "/tmp") {
if (mkdir(deflt, 0777)) {
- if (IsDirWriteable(deflt))
+#ifdef __EMX__
+ Path p(package().user_support());
+#endif
+ if (IsDirWriteable(deflt)) {
// deflt could not be created because it
// did exist already, so let's create our own
// dir inside deflt.
-#ifdef __EMX__
- Path p(user_lyxdir());
-#endif
return createTmpDir(deflt, "lyx_tmpdir");
- else
+ } else {
// some other error occured.
-#ifdef __EMX__
- Path p(user_lyxdir());
-#endif
return createTmpDir("/tmp", "lyx_tmpdir");
+ }
} else
return deflt;
} else {
#ifdef __EMX__
- Path p(user_lyxdir());
+ Path p(package().user_support());
#endif
return createTmpDir("/tmp", "lyx_tmpdir");
}
bool createDirectory(string const & path, int permission)
{
- string temp(rtrim(os::slashify_path(path), "/"));
+ string temp(rtrim(os::internal_path(path), "/"));
BOOST_ASSERT(!temp.empty());
return RelPath;
// Copies given paths
- string TempRel(os::slashify_path(RelPath));
+ string TempRel(os::internal_path(RelPath));
// Since TempRel is NOT absolute, we can safely replace "//" with "/"
TempRel = subst(TempRel, "//", "/");
}
// returns absolute path
- return os::slashify_path(TempBase);
+ return os::internal_path(TempBase);
}
string buf;
if (path != "." && path != "./" && !path.empty()) {
- buf = os::slashify_path(path);
+ buf = os::internal_path(path);
if (!suffixIs(path, '/'))
buf += '/';
}
return getcwd() + '/' + RTemp;
}
if (Temp == "~") {
- return GetEnvPath("HOME") + '/' + RTemp;
+ return package().home_dir() + '/' + RTemp;
}
if (Temp == "..") {
return MakeAbsPath(copy);
string const GetFileContents(string const & fname)
{
- FileInfo finfo(fname);
- if (finfo.exist()) {
+ if (fs::exists(fname)) {
ifstream ifs(fname.c_str());
ostringstream ofs;
if (ifs && ofs) {
if (!what[0].matched)
break;
}
- result = what.str(1) + GetEnv(what.str(2)) + what.str(3);
+ result = what.str(1) + getEnv(what.str(2)) + what.str(3);
}
return result;
}
string const AddPath(string const & path, string const & path_2)
{
string buf;
- string const path2 = os::slashify_path(path_2);
+ string const path2 = os::internal_path(path_2);
if (!path.empty() && path != "." && path != "./") {
- buf = os::slashify_path(path);
+ buf = os::internal_path(path);
if (path[path.length() - 1] != '/')
buf += '/';
}
else
ext = extension;
- return os::slashify_path(oldname.substr(0, last_dot) + ext);
+ return os::internal_path(oldname.substr(0, last_dot) + ext);
}
return string();
}
+
// the different filetypes and what they contain in one of the first lines
// (dots are any characters). (Herbert 20020131)
// AGR Grace...
// ZIP PK... http://www.halyava.ru/document/ind_arch.htm
// Z \037\235 UNIX compress
-/// return the "extension" which belongs to the contents.
-/// for no knowing contents return the extension. Without
-/// an extension and unknown contents we return "user"
-string const getExtFromContents(string const & filename)
+string const getFormatFromContents(string const & filename)
{
// paranoia check
if (filename.empty() || !IsFileReadable(filename))
return string();
-
ifstream ifs(filename.c_str());
if (!ifs)
// Couldn't open file...
int const max_count = 50;
int count = 0;
- string str, format;
+ string str;
+ string format;
bool firstLine = true;
while ((count++ < max_count) && format.empty()) {
if (ifs.eof()) {
lyxerr[Debug::GRAPHICS]
- << "filetools(getExtFromContents)\n"
+ << "filetools(getFormatFromContents)\n"
<< "\tFile type not recognised before EOF!"
<< endl;
break;
return format;
}
- string const ext(GetExtension(filename));
lyxerr[Debug::GRAPHICS]
- << "filetools(getExtFromContents)\n"
- << "\tCouldn't find a known Type!\n";
- if (!ext.empty()) {
- lyxerr[Debug::GRAPHICS]
- << "\twill take the file extension -> "
- << ext << endl;
- return ext;
- } else {
- lyxerr[Debug::GRAPHICS]
- << "\twill use ext or a \"user\" defined format" << endl;
- return "user";
- }
+ << "filetools(getFormatFromContents)\n"
+ << "\tCouldn't find a known format!\n";
+ return string();
}
/// check for zipped file
bool zippedFile(string const & name)
{
- string const type = getExtFromContents(name);
+ string const type = getFormatFromContents(name);
if (contains("gzip zip compress", type) && !type.empty())
return true;
return false;
{
string str = path;
- string const home(GetEnvPath("HOME"));
+ string const home(package().home_dir());
// replace /home/blah with ~/
if (prefixIs(str, home))
bool LyXReadLink(string const & file, string & link, bool resolve)
{
+#ifdef HAVE_READLINK
char linkbuffer[512];
// Should be PATH_MAX but that needs autconf support
int const nRead = ::readlink(file.c_str(),
else
link = linkbuffer;
return true;
+#else
+ return false;
+#endif
}
// If the file can be found directly, we just return a
// absolute path version of it.
- if (FileInfo(fil).exist())
+ if (fs::exists(fil))
return MakeAbsPath(fil);
// No we try to find it using kpsewhich.
a += '#';
a += OnlyFilename(filename);
a += '#';
- FileInfo const fileinfo(a);
- if (fileinfo.exist())
+ if (fs::exists(a))
unlink(a);
}
bool zipped = zippedFile(file);
string const file_ = zipped ?
string(unzipFile(file)) : string(file);
- string const format = getExtFromContents(file_);
+ string const format = getFormatFromContents(file_);
if (format != "eps" && format != "ps") {
readBB_lyxerrMessage(file_, zipped,"no(e)ps-format");
// If the original is newer than the copy, then copy the original
// to the new directory.
- FileInfo f1(file1);
- FileInfo f2(file2);
int cmp = 0;
- if (f1.exist() && f2.exist()) {
- double const tmp = difftime(f1.getModificationTime(),
- f2.getModificationTime());
+ if (fs::exists(file1) && fs::exists(file2)) {
+ double const tmp = difftime(fs::last_write_time(file1),
+ fs::last_write_time(file2));
if (tmp != 0)
cmp = tmp > 0 ? 1 : -1;
- } else if (f1.exist()) {
+ } else if (fs::exists(file1)) {
cmp = 1;
- } else if (f2.exist()) {
+ } else if (fs::exists(file2)) {
cmp = -1;
}