Add fs::create_directory() and move fs utility function to their own file

pull/929/head
Hleb Valoshka 2021-03-08 16:02:12 +02:00
parent f1d84435a0
commit df25eed5a2
9 changed files with 228 additions and 126 deletions

View File

@ -438,5 +438,31 @@ bool is_directory(const path& p)
return r;
}
bool create_directory(const path& p, std::error_code& ec) noexcept
{
bool r;
#ifdef _WIN32
r = _wmkdir(p.c_str()) == 0;
#else
r = mkdir(p.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0;
#endif
if (!r)
ec = std::error_code(errno, std::system_category());
return r;
}
bool create_directory(const path& p)
{
std::error_code ec;
bool r = create_directory(p, ec);
if (ec)
#if __cpp_exceptions
throw filesystem_error(ec, "celfs::create_directory error");
#else
std::abort();
#endif
return r;
}
}
}

View File

@ -409,5 +409,8 @@ bool exists(const path& p, std::error_code& ec) noexcept;
bool is_directory(const path& p);
bool is_directory(const path& p, std::error_code& ec) noexcept;
bool create_directory(const path& p);
bool create_directory(const path& p, std::error_code& ec) noexcept;
}
}

View File

@ -10,6 +10,7 @@
#include <utility>
#include <celutil/color.h>
#include <celutil/fsutils.h>
#include <celutil/util.h>
#include <celmath/mathlib.h>
#include "astro.h"
@ -19,7 +20,7 @@
using namespace Eigen;
using namespace std;
using namespace celmath;
using namespace celestia::util;
AssociativeArray::~AssociativeArray()
{

View File

@ -12,13 +12,14 @@
#include <fstream>
#include <cassert>
#include <celutil/debug.h>
#include <celutil/fsutils.h>
#include <celutil/util.h>
#include <celengine/texmanager.h>
#include <celengine/tokenizer.h>
#include "configfile.h"
using namespace std;
using namespace celestia::util;
static unsigned int getUint(Hash* params,
const string& paramName,

View File

@ -11,6 +11,8 @@ set(CELUTIL_SOURCES
filetype.h
formatnum.cpp
formatnum.h
fsutils.cpp
fsutils.h
#memorypool.cpp
#memorypool.h
reshandle.h

View File

@ -0,0 +1,161 @@
// fsutils.h
//
// Copyright (C) 2001-present, the Celestia Development Team
// Original version by Chris Laurel <claurel@shatters.net>
//
// Miscellaneous useful filesystem-related functions.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
#include <config.h>
#include <fmt/printf.h>
#include "gettext.h"
#ifdef _WIN32
#include <shlobj.h>
#include "winutil.h"
#else
#include <unistd.h>
#include <pwd.h>
#ifdef HAVE_WORDEXP
#include <wordexp.h>
#endif // HAVE_WORDEXP
#endif // !_WIN32
#include "fsutils.h"
using namespace std;
namespace celestia
{
namespace util
{
fs::path LocaleFilename(const fs::path &p)
{
fs::path::string_type format, lang;
#ifdef _WIN32
format = L"%s_%s%s";
lang = CurrentCPToWide(_("LANGUAGE"));
#else
format = "%s_%s%s";
lang = _("LANGUAGE");
#endif
fs::path locPath = p.parent_path() / fmt::sprintf(format, p.stem().native(), lang, p.extension().native());
if (fs::exists(locPath))
return locPath;
locPath = fs::path("locale") / locPath;
if (fs::exists(locPath))
return locPath;
return p;
}
fs::path PathExp(const fs::path& filename)
{
#ifdef _WIN32
auto str = filename.native();
if (str[0] == '~')
{
if (str.size() == 1)
return HomeDir();
if (str[1] == '\\' || str[1] == '/')
return HomeDir() / str.substr(2);
}
return filename;
#elif defined(HAVE_WORDEXP)
wordexp_t result;
switch(wordexp(filename.c_str(), &result, WRDE_NOCMD))
{
case 0: // successful
break;
case WRDE_NOSPACE:
// If the error was `WRDE_NOSPACE',
// then perhaps part of the result was allocated.
wordfree(&result);
default: // some other error
return filename;
}
if (result.we_wordc != 1)
{
wordfree(&result);
return filename;
}
fs::path::string_type expanded(result.we_wordv[0]);
wordfree(&result);
return expanded;
#else
return filename;
#endif
}
fs::path HomeDir()
{
#ifdef _WIN32
wstring p(MAX_PATH + 1, 0);
if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PROFILE, nullptr, 0, &p[0])))
return fs::path(p);
// fallback to environment variables
const auto *s = _wgetenv(L"USERPROFILE"); // FIXME: rewrite using _wgetenv_s
if (s != nullptr)
return fs::path(s);
auto *s1 = _wgetenv(L"HOMEDRIVE");
auto *s2 = _wgetenv(L"HOMEPATH");
if (s1 != nullptr && s2 != nullptr)
{
return fs::path(s1) / fs::path(s2);
}
// unlikely this is defined in woe but let's check
s = _wgetenv(L"HOME");
if (s != nullptr)
return fs::path(s);
#else
const auto *home = getenv("HOME");
if (home != nullptr)
return home;
// FIXME: rewrite using getpwuid_r
struct passwd *pw = getpwuid(geteuid());
home = pw->pw_dir;
if (home != nullptr)
return home;
#endif
return fs::path();
}
fs::path WriteableDataPath()
{
#if defined(_WIN32)
char s[MAX_PATH + 1];
if (SUCCEEDED(SHGetFolderPathA(nullptr, CSIDL_APPDATA, nullptr, 0, &s[0])))
return PathExp(s) / "Celestia";
// fallback to environment variables
const char *p = getenv("APPDATA");
p = p != nullptr ? p : "~\\AppData\\Roaming";
return PathExp(p) / "Celestia";
#elif defined(__APPLE__)
return PathExp("~/Library/Application Support/Celestia");
#else
const char *p = getenv("XDG_DATA_HOME");
p = p != nullptr ? p : "~/.local/share";
return PathExp(p) / "Celestia";
#endif
}
}
}

View File

@ -0,0 +1,26 @@
// fsutils.h
//
// Copyright (C) 2001-present, the Celestia Development Team
// Original version by Chris Laurel <claurel@shatters.net>
//
// Miscellaneous useful filesystem-related functions.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
#pragma once
#include <celcompat/filesystem.h>
namespace celestia
{
namespace util
{
fs::path LocaleFilename(const fs::path& filename);
fs::path PathExp(const fs::path& filename);
fs::path HomeDir();
fs::path WriteableDataPath();
}
}

View File

@ -9,127 +9,16 @@
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
#include <config.h>
#include <fmt/printf.h>
#ifdef _WIN32
#include <windows.h>
#include <celutil/winutil.h>
#endif
#include <iostream>
#include "util.h"
#include "gettext.h"
#ifdef _WIN32
#include <shlobj.h>
#include "winutil.h"
#else
#include <unistd.h>
#include <pwd.h>
#ifdef HAVE_WORDEXP
#include <wordexp.h>
#endif // HAVE_WORDEXP
#endif // !_WIN32
using namespace std;
fs::path LocaleFilename(const fs::path &p)
{
fs::path::string_type format, lang;
#ifdef _WIN32
format = L"%s_%s%s";
lang = CurrentCPToWide(_("LANGUAGE"));
#else
format = "%s_%s%s";
lang = _("LANGUAGE");
#endif
fs::path locPath = p.parent_path() / fmt::sprintf(format, p.stem().native(), lang, p.extension().native());
if (exists(locPath))
return locPath;
locPath = fs::path("locale") / locPath;
if (exists(locPath))
return locPath;
return p;
}
fs::path PathExp(const fs::path& filename)
{
#ifdef _WIN32
auto str = filename.native();
if (str[0] == '~')
{
if (str.size() == 1)
return homeDir();
if (str[1] == '\\' || str[1] == '/')
return homeDir() / str.substr(2);
}
return filename;
#elif defined(HAVE_WORDEXP)
wordexp_t result;
switch(wordexp(filename.string().c_str(), &result, WRDE_NOCMD))
{
case 0: // successful
break;
case WRDE_NOSPACE:
// If the error was `WRDE_NOSPACE',
// then perhaps part of the result was allocated.
wordfree(&result);
default: // some other error
return filename;
}
if (result.we_wordc != 1)
{
wordfree(&result);
return filename;
}
fs::path::string_type expanded(result.we_wordv[0]);
wordfree(&result);
return expanded;
#else
return filename;
#endif
}
fs::path homeDir()
{
#ifdef _WIN32
wstring p(MAX_PATH + 1, 0);
if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PROFILE, nullptr, 0, &p[0])))
return fs::path(p);
// fallback to environment variables
const auto *s = _wgetenv(L"USERPROFILE"); // FIXME: rewrite using _wgetenv_s
if (s != nullptr)
return fs::path(s);
auto *s1 = _wgetenv(L"HOMEDRIVE");
auto *s2 = _wgetenv(L"HOMEPATH");
if (s1 != nullptr && s2 != nullptr)
{
return fs::path(s1) / fs::path(s2);
}
// unlikely this is defined in woe but let's check
s = _wgetenv(L"HOME");
if (s != nullptr)
return fs::path(s);
#else
const auto *home = getenv("HOME");
if (home != nullptr)
return home;
// FIXME: rewrite using getpwuid_r
struct passwd *pw = getpwuid(geteuid());
home = pw->pw_dir;
if (home != nullptr)
return home;
#endif
return fs::path();
}
bool GetTZInfo(std::string_view tzName, int &dstBias)
{
#ifdef _WIN32

View File

@ -12,14 +12,10 @@
#ifndef _CELUTIL_UTIL_H_
#define _CELUTIL_UTIL_H_
#include <string>
#include <iostream>
#include <iosfwd>
#include <functional>
#include <celcompat/filesystem.h>
#include <celcompat/string_view.h>
fs::path LocaleFilename(const fs::path& filename);
template <class T> struct printlineFunc
{
printlineFunc(std::ostream& o) : out(o) {};
@ -38,9 +34,6 @@ template<typename T> constexpr typename T::size_type memsize(const T &c)
return c.size() * sizeof(typename T::value_type);
}
fs::path PathExp(const fs::path& filename);
fs::path homeDir();
bool GetTZInfo(std::string_view, int&);
#endif // _CELUTIL_UTIL_H_