Skip to content

Commit

Permalink
fs::get_config_dir, fs::get_executable_dir
Browse files Browse the repository at this point in the history
  • Loading branch information
Nekotekina committed Dec 20, 2015
1 parent 56ba5a7 commit 321e6d3
Show file tree
Hide file tree
Showing 21 changed files with 249 additions and 178 deletions.
4 changes: 2 additions & 2 deletions Utilities/AutoPause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ AutoPause::~AutoPause(void)
//This would be able to create in a GUI window.
void AutoPause::Reload(void)
{
if (fs::is_file("pause.bin"))
if (fs::is_file(fs::get_config_dir() + "pause.bin"))
{
m_pause_function.clear();
m_pause_function.reserve(16);
m_pause_syscall.clear();
m_pause_syscall.reserve(16);

fs::file list("pause.bin");
fs::file list(fs::get_config_dir() + "pause.bin");
//System calls ID and Function calls ID are all u32 iirc.
u32 num;
size_t fmax = list.size();
Expand Down
123 changes: 105 additions & 18 deletions Utilities/File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#define GET_API_ERROR static_cast<u64>(GetLastError())

std::unique_ptr<wchar_t[]> to_wchar(const std::string& source)
static std::unique_ptr<wchar_t[]> to_wchar(const std::string& source)
{
const auto length = source.size() + 1; // size + null terminator

Expand All @@ -24,7 +24,7 @@ std::unique_ptr<wchar_t[]> to_wchar(const std::string& source)
return buffer;
}

void to_utf8(std::string& result, const wchar_t* source)
static void to_utf8(std::string& result, const wchar_t* source)
{
const int length = lstrlenW(source); // source length

Expand All @@ -48,30 +48,30 @@ void to_utf8(std::string& result, const wchar_t* source)
}
}

time_t to_time_t(const ULARGE_INTEGER& ft)
static time_t to_time(const ULARGE_INTEGER& ft)
{
return ft.QuadPart / 10000000ULL - 11644473600ULL;
}

time_t to_time_t(const LARGE_INTEGER& ft)
static time_t to_time(const LARGE_INTEGER& ft)
{
ULARGE_INTEGER v;
v.LowPart = ft.LowPart;
v.HighPart = ft.HighPart;

return to_time_t(v);
return to_time(v);
}

time_t to_time_t(const FILETIME& ft)
static time_t to_time(const FILETIME& ft)
{
ULARGE_INTEGER v;
v.LowPart = ft.dwLowDateTime;
v.HighPart = ft.dwHighDateTime;

return to_time_t(v);
return to_time(v);
}

bool truncate_file(const std::string& file, u64 length)
static bool truncate_file(const std::string& file, u64 length)
{
// open the file
const auto handle = CreateFileW(to_wchar(file).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
Expand Down Expand Up @@ -105,6 +105,7 @@ bool truncate_file(const std::string& file, u64 length)
#include <unistd.h>
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <copyfile.h>
#include <mach-o/dyld.h>
#else
#include <sys/sendfile.h>
#endif
Expand All @@ -130,9 +131,9 @@ bool fs::stat(const std::string& path, stat_t& info)
info.is_directory = (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info.is_writable = (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
info.size = (u64)attrs.nFileSizeLow | ((u64)attrs.nFileSizeHigh << 32);
info.atime = to_time_t(attrs.ftLastAccessTime);
info.mtime = to_time_t(attrs.ftLastWriteTime);
info.ctime = to_time_t(attrs.ftCreationTime);
info.atime = to_time(attrs.ftLastAccessTime);
info.mtime = to_time(attrs.ftLastWriteTime);
info.ctime = to_time(attrs.ftCreationTime);
#else
struct stat file_info;
if (stat(path.c_str(), &file_info) < 0)
Expand Down Expand Up @@ -306,7 +307,7 @@ bool fs::rename(const std::string& from, const std::string& to)

#ifndef _WIN32

int OSCopyFile(const char* source, const char* destination, bool overwrite)
static int OSCopyFile(const char* source, const char* destination, bool overwrite)
{
/* Source: http://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c */

Expand Down Expand Up @@ -521,9 +522,9 @@ bool fs::file::stat(stat_t& info) const
info.is_directory = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info.is_writable = (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
info.size = this->size();
info.atime = to_time_t(basic_info.LastAccessTime);
info.mtime = to_time_t(basic_info.ChangeTime);
info.ctime = to_time_t(basic_info.CreationTime);
info.atime = to_time(basic_info.LastAccessTime);
info.mtime = to_time(basic_info.ChangeTime);
info.ctime = to_time(basic_info.CreationTime);
#else
struct stat file_info;
if (fstat(m_fd, &file_info) < 0)
Expand Down Expand Up @@ -565,6 +566,7 @@ u64 fs::file::read(void* buffer, u64 count) const
{
g_tls_error = fse::ok;

// TODO (call ReadFile multiple times if count is too big)
const int size = count <= INT_MAX ? static_cast<int>(count) : throw EXCEPTION("Invalid count (0x%llx)", count);

#ifdef _WIN32
Expand All @@ -584,6 +586,7 @@ u64 fs::file::write(const void* buffer, u64 count) const
{
g_tls_error = fse::ok;

// TODO (call WriteFile multiple times if count is too big)
const int size = count <= INT_MAX ? static_cast<int>(count) : throw EXCEPTION("Invalid count (0x%llx)", count);

#ifdef _WIN32
Expand Down Expand Up @@ -769,9 +772,9 @@ bool fs::dir::read(std::string& name, stat_t& info)
info.is_directory = (found.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info.is_writable = (found.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
info.size = ((u64)found.nFileSizeHigh << 32) | (u64)found.nFileSizeLow;
info.atime = to_time_t(found.ftLastAccessTime);
info.mtime = to_time_t(found.ftLastWriteTime);
info.ctime = to_time_t(found.ftCreationTime);
info.atime = to_time(found.ftLastAccessTime);
info.mtime = to_time(found.ftLastWriteTime);
info.ctime = to_time(found.ftCreationTime);
#else
const auto found = ::readdir((DIR*)m_dd);

Expand All @@ -793,3 +796,87 @@ bool fs::dir::read(std::string& name, stat_t& info)

return true;
}

std::string fs::get_config_dir()
{
// Use magic static for dir initialization
static const std::string s_dir = []
{
#ifdef _WIN32
return get_executable_dir(); // ?
#else
std::string dir;

if (const char* home = ::getenv("XDG_CONFIG_HOME"))
dir = home;
else if (const char* home = ::getenv("HOME"))
dir = home + "/.config"s;
else // Just in case
dir = "./config";

dir += "/rpcs3/";

if (::mkdir(dir.c_str(), 0777) == -1 && errno != EEXIST)
{
std::printf("Failed to create configuration directory '%s' (%d).\n", dir.c_str(), errno);
}

return dir;
#endif
}();

return s_dir;
}

std::string fs::get_executable_dir()
{
// Use magic static for dir initialization
static const std::string s_dir = []
{
std::string dir;

#ifdef _WIN32
wchar_t buf[2048];
if (GetModuleFileName(NULL, buf, ::size32(buf)) - 1 >= ::size32(buf) - 1)
{
MessageBoxA(0, fmt::format("GetModuleFileName() failed: 0x%x.", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR);
return dir; // empty
}

to_utf8(dir, buf); // Convert to UTF-8

#elif __APPLE__
char buf[4096];
u32 size = sizeof(buf);
if (_NSGetExecutablePath(buf, &size))
{
std::printf("_NSGetExecutablePath() failed (size=0x%x).\n", size);
return dir; // empty
}

dir = buf;
#else
char buf[4096];
const auto size = ::readlink("/proc/self/exe", buf, sizeof(buf));
if (size <= 0 || size >= sizeof(buf))
{
std::printf("readlink(/proc/self/exe) failed (%d).\n", errno);
return dir; // empty
}

dir = { buf, static_cast<std::size_t>(size) };
#endif

// Replace "\"
for (auto& c : dir)
{
if (c == '\\') c = '/';
}

// Leave only path
dir.resize(dir.rfind('/') + 1);
return dir;
}();

return s_dir;
}
51 changes: 51 additions & 0 deletions Utilities/File.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,51 @@ namespace fs
CHECK_ASSERTION(write(str.data(), str.size()) == str.size());
return *this;
}

// Write POD
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, const file&> operator <<(const T& data) const
{
CHECK_ASSERTION(write(std::addressof(data), sizeof(T)) == sizeof(T));
return *this;
}

// Write POD std::vector
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, const file&> operator <<(const std::vector<T>& vec) const
{
CHECK_ASSERTION(write(vec.data(), vec.size() * sizeof(T)) == vec.size() * sizeof(T));
return *this;
}

// Read std::string
bool read(std::string& str) const
{
return read(&str[0], str.size()) == str.size();
}

// Read POD
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, bool> read(T& data) const
{
return read(&data, sizeof(T)) == sizeof(T);
}

// Read POD std::vector
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, bool> read(std::vector<T>& vec) const
{
return read(vec.data(), sizeof(T) * vec.size()) == sizeof(T) * vec.size();
}

// Convert to std::string
operator std::string() const
{
std::string result;
result.resize(size() - seek(0, fsm::cur));
CHECK_ASSERTION(read(result));
return result;
}
};

class file_ptr final
Expand Down Expand Up @@ -245,4 +290,10 @@ namespace fs
// Get next directory entry (UTF-8 name and file stat)
bool read(std::string& name, stat_t& info);
};

// Get configuration directory
std::string get_config_dir();

// Get executable directory
std::string get_executable_dir();
}
2 changes: 1 addition & 1 deletion Utilities/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ struct FileListener : LogListener
bool mPrependChannelName;

FileListener(const std::string& name = _PRGNAME_, bool prependChannel = true)
: mFile(rPlatform::getConfigDir() + name + ".log", fom::rewrite)
: mFile(fs::get_config_dir() + name + ".log", fom::rewrite)
, mPrependChannelName(prependChannel)
{
if (!mFile)
Expand Down
7 changes: 7 additions & 0 deletions Utilities/config_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,10 @@ std::string config_context_t::to_string() const

return result.str();
}

void config_context_t::from_string(const std::string& str)
{
std::istringstream source(str);

deserialize(source);
}
1 change: 1 addition & 0 deletions Utilities/config_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,5 @@ class config_context_t
void set_defaults();

std::string to_string() const;
void from_string(const std::string&);
};
26 changes: 0 additions & 26 deletions Utilities/rPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,3 @@ void rImage::SaveFile(const std::string& name, rImageType type)
throw EXCEPTION("unsupported type");
}
}

std::string rPlatform::getConfigDir()
{
static std::string dir = ".";
if (dir == ".")
{
#ifdef _WIN32
dir = "";
//mkdir(dir.c_str());
#else
if (getenv("XDG_CONFIG_HOME") != NULL)
dir = getenv("XDG_CONFIG_HOME");
else if (getenv("HOME") != NULL)
dir = getenv("HOME") + std::string("/.config");
else // Just in case
dir = "./config";
dir = dir + "/rpcs3/";

if (mkdir(dir.c_str(), 0777) == -1)
{
printf("An error occured during the creation of the configuration directory. (%d)", errno);
}
#endif
}
return dir;
}
5 changes: 0 additions & 5 deletions Utilities/rPlatform.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
#pragma once

struct rPlatform
{
static std::string getConfigDir();
};

/**********************************************************************
*********** RSX Debugger
************************************************************************/
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ spu_recompiler::spu_recompiler()

LOG_SUCCESS(SPU, "SPU Recompiler (ASMJIT) created...");

fs::file("SPUJIT.log", fom::rewrite) << fmt::format("SPU JIT initialization...\n\nTitle: %s\nTitle ID: %s\n\n", Emu.GetTitle().c_str(), Emu.GetTitleID().c_str());
fs::file(fs::get_config_dir() + "SPUJIT.log", fom::rewrite) << fmt::format("SPU JIT initialization...\n\nTitle: %s\nTitle ID: %s\n\n", Emu.GetTitle().c_str(), Emu.GetTitleID().c_str());
}

void spu_recompiler::compile(spu_function_t& f)
Expand Down Expand Up @@ -218,7 +218,7 @@ void spu_recompiler::compile(spu_function_t& f)
log += "\n\n\n";

// Append log file
fs::file("SPUJIT.log", fom::write | fom::append) << log;
fs::file(fs::get_config_dir() + "SPUJIT.log", fom::write | fom::append) << log;
}

spu_recompiler::XmmLink spu_recompiler::XmmAlloc() // get empty xmm register
Expand Down
Loading

0 comments on commit 321e6d3

Please sign in to comment.