forked from mia/Aegisub
Finish agi::Path so we can actually use it, our current path system is brutal and I needed this for libmedia. I'll be adding OS X support shortly: someone else will have to figure out what to do with windows it's completely trivial see unix/path.cpp and check libaegisub/path.h for the return values.
Originally committed to SVN as r5315.
This commit is contained in:
parent
7b06c334aa
commit
a35962923f
4 changed files with 198 additions and 37 deletions
|
@ -17,6 +17,7 @@ LDFLAGS += -L../universalchardet -luniversalchardet
|
||||||
endif
|
endif
|
||||||
|
|
||||||
common/charset_conv.o: CXXFLAGS += $(CFLAGS_ICONV)
|
common/charset_conv.o: CXXFLAGS += $(CFLAGS_ICONV)
|
||||||
|
unix/path.o: CXXFLAGS += -DDIR_DATA=\"$(P_DATA)\" -DDIR_DOC=\"$(P_DOC)\"
|
||||||
|
|
||||||
SRC = \
|
SRC = \
|
||||||
common/charset.cpp \
|
common/charset.cpp \
|
||||||
|
@ -27,6 +28,7 @@ SRC = \
|
||||||
common/mru.cpp \
|
common/mru.cpp \
|
||||||
common/option.cpp \
|
common/option.cpp \
|
||||||
common/option_visit.cpp \
|
common/option_visit.cpp \
|
||||||
|
common/path.cpp \
|
||||||
common/progress.cpp \
|
common/progress.cpp \
|
||||||
common/keyframe.cpp \
|
common/keyframe.cpp \
|
||||||
common/log.cpp \
|
common/log.cpp \
|
||||||
|
@ -35,7 +37,8 @@ SRC = \
|
||||||
unix/util.cpp \
|
unix/util.cpp \
|
||||||
unix/io.cpp \
|
unix/io.cpp \
|
||||||
unix/access.cpp \
|
unix/access.cpp \
|
||||||
unix/log.cpp
|
unix/log.cpp \
|
||||||
|
unix/path.cpp
|
||||||
|
|
||||||
ifeq (yes, $(BUILD_DARWIN))
|
ifeq (yes, $(BUILD_DARWIN))
|
||||||
SRC += \
|
SRC += \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
|
// Copyright (c) 2010-2011, Amar Takhar <verm@aegisub.org>
|
||||||
//
|
//
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -18,18 +18,130 @@
|
||||||
/// @brief Common paths.
|
/// @brief Common paths.
|
||||||
/// @ingroup libaegisub
|
/// @ingroup libaegisub
|
||||||
|
|
||||||
|
#ifndef LAGI_PRE
|
||||||
|
#include <vector>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <libaegisub/path.h>
|
#include "libaegisub/access.h"
|
||||||
|
#include "libaegisub/log.h"
|
||||||
|
#include "libaegisub/path.h"
|
||||||
|
|
||||||
namespace agi {
|
namespace agi {
|
||||||
|
|
||||||
Path::Path(const std::string &file, const std::string& default_path): path_file(file), path_default(default_path) {
|
Path::Path(const std::string &file, const std::string& default_path)
|
||||||
|
: path_file(file),
|
||||||
|
path_default(default_path) {
|
||||||
opt = new agi::Options(file, default_path);
|
opt = new agi::Options(file, default_path);
|
||||||
opt->ConfigUser();
|
opt->ConfigUser();
|
||||||
|
LOG_D("agi/path") << "New Path object";
|
||||||
}
|
}
|
||||||
|
|
||||||
Path::~Path() {
|
Path::~Path() {
|
||||||
opt->Flush();
|
opt->Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::string Path::Get(const char *name) {
|
||||||
|
std::string path;
|
||||||
|
try {
|
||||||
|
path = std::string(opt->Get(name)->GetString());
|
||||||
|
} catch (OptionErrorNotFound& e) {
|
||||||
|
throw PathErrorNotFound("Invalid path key");
|
||||||
|
}
|
||||||
|
|
||||||
|
Decode(path);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Path::Set(const char *name, const std::string &path) {
|
||||||
|
std::string set(path);
|
||||||
|
|
||||||
|
if (path[0] == 94) {
|
||||||
|
std::string tmp(path);
|
||||||
|
// Check that the used cookie exists.
|
||||||
|
Decode(tmp);
|
||||||
|
agi::acs::CheckDirWrite(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
opt->Get(name)->SetString(set);
|
||||||
|
} catch (OptionErrorNotFound& e) {
|
||||||
|
throw PathErrorNotFound("Invalid path key");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Path::ListGet(const char *name, std::vector<std::string> &out) {
|
||||||
|
opt->Get(name)->GetListString(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Path::ListSet(const char *name, std::vector<std::string> list) {
|
||||||
|
opt->Get(name)->SetListString(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const void Path::Decode(std::string &path) {
|
||||||
|
if (path[0] != 94) // "^"
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
if (path.find("^CONFIG") == 0) {
|
||||||
|
path.replace(0, 7, Config());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.find("^USER") == 0) {
|
||||||
|
path.replace(0, 5, User());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.find("^DATA") == 0) {
|
||||||
|
path.replace(0, 5, Data());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.find("^DOC") == 0) {
|
||||||
|
path.replace(0, 4, Doc());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.find("^TEMP") == 0) {
|
||||||
|
path.replace(0, 5, Temp());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.find("^AUDIO") == 0) {
|
||||||
|
std::string path_str(opt->Get("Last/Audio")->GetString());
|
||||||
|
Decode(path_str);
|
||||||
|
path.replace(0, 6, path_str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.find("^VIDEO") == 0) {
|
||||||
|
std::string path_str(opt->Get("Last/Video")->GetString());
|
||||||
|
Decode(path_str);
|
||||||
|
path.replace(0, 6, path_str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.find("^SUBTITLE") == 0) {
|
||||||
|
std::string path_str(opt->Get("Last/Subtitle")->GetString());
|
||||||
|
Decode(path_str);
|
||||||
|
path.replace(0, 5, path_str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw PathErrorInvalid("Invalid cookie used");
|
||||||
|
|
||||||
|
} catch (OptionErrorNotFound& e) {
|
||||||
|
throw PathErrorInternal("Failed to find key in Decode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Path::Encode(std::string &path) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace agi
|
} // namespace agi
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
|
// Copyright (c) 2010-2011, Amar Takhar <verm@aegisub.org>
|
||||||
//
|
//
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -21,14 +21,22 @@
|
||||||
#ifndef AGI_PRE
|
#ifndef AGI_PRE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <libaegisub/exception.h>
|
||||||
#include <libaegisub/option.h>
|
#include <libaegisub/option.h>
|
||||||
|
|
||||||
namespace agi {
|
namespace agi {
|
||||||
|
|
||||||
|
DEFINE_BASE_EXCEPTION_NOINNER(PathError, Exception)
|
||||||
|
DEFINE_SIMPLE_EXCEPTION_NOINNER(PathErrorNotFound, PathError, "path/not_found")
|
||||||
|
DEFINE_SIMPLE_EXCEPTION_NOINNER(PathErrorInvalid, PathError, "path/invalid")
|
||||||
|
DEFINE_SIMPLE_EXCEPTION_NOINNER(PathErrorInternal, PathError, "path")
|
||||||
|
|
||||||
/// @class Path
|
/// @class Path
|
||||||
// Internal representation of all paths in aegisub.
|
// Internal representation of all paths in aegisub.
|
||||||
class Path {
|
class Path {
|
||||||
public:
|
public:
|
||||||
|
// For unit testing.
|
||||||
|
friend class PathTest;
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Path(const std::string &file, const std::string& default_path);
|
Path(const std::string &file, const std::string& default_path);
|
||||||
|
@ -36,6 +44,37 @@ public:
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Path();
|
~Path();
|
||||||
|
|
||||||
|
/// @brief Get a path, this is automatically decoded.
|
||||||
|
/// @param name Path to get
|
||||||
|
/// @return Full path name in UTF-8
|
||||||
|
const std::string Get(const char *name);
|
||||||
|
|
||||||
|
/// @brief Set a path, this will be automaticalled encoded if a cookie matches.
|
||||||
|
/// @param[in] name Path name to save to.
|
||||||
|
void Set(const char *name, const std::string &path);
|
||||||
|
|
||||||
|
/// @brief Set a list of paths
|
||||||
|
/// @param name Path name.
|
||||||
|
/// @param out[out] Map to load list into
|
||||||
|
void ListGet(const char *name, std::vector<std::string> &out);
|
||||||
|
|
||||||
|
/// @brief Set a list of paths.
|
||||||
|
/// @param name Path name.
|
||||||
|
/// @param list List to set.
|
||||||
|
void ListSet(const char *name, std::vector<std::string> list);
|
||||||
|
|
||||||
|
/// @brief Get the default 'open' directory when no alternative is available.
|
||||||
|
/// @return Directory
|
||||||
|
/// This returns several different values based on OS:
|
||||||
|
/// Windows: Documents folder
|
||||||
|
/// OS X: ~/Documents
|
||||||
|
/// Unix: ~ or Documents folder if set in the environment
|
||||||
|
const std::string Default();
|
||||||
|
|
||||||
|
/// @brief Decode a path
|
||||||
|
/// @param path Decode a path in-place.
|
||||||
|
const void Decode(std::string &path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Location of path config file.
|
/// Location of path config file.
|
||||||
const std::string path_file;
|
const std::string path_file;
|
||||||
|
@ -43,14 +82,30 @@ private:
|
||||||
/// Internal default config.
|
/// Internal default config.
|
||||||
const std::string path_default;
|
const std::string path_default;
|
||||||
|
|
||||||
|
/// @brief Encode a path.
|
||||||
|
/// @param path Encode a path in-place.
|
||||||
|
/// ^CONFIG - Configuration directory (not changable)
|
||||||
|
/// ^USER - Users home directory
|
||||||
|
/// ^DATA - Aegisub data files
|
||||||
|
/// ^VIDEO - Last opened video directory
|
||||||
|
/// ^SUBTITLE - Last opened subtitle directory
|
||||||
|
/// ^AUDIO - Last opened audio directory
|
||||||
|
void Encode(std::string &path);
|
||||||
|
|
||||||
/// Options object.
|
/// Options object.
|
||||||
Options *opt;
|
Options *opt;
|
||||||
|
|
||||||
const char *Data(); ///< Shared resources
|
/// @brief Locale files
|
||||||
const char *Doc(); ///< Documents
|
/// @return Locale location
|
||||||
const char *User(); ///< User config directory
|
/// This is directly assessibly as the Locale directory will never change on any platform.
|
||||||
const char *Locale(); ///< Locale files
|
const std::string Locale();
|
||||||
const char *Temp(); ///< Temporary storage
|
|
||||||
|
protected:
|
||||||
|
const std::string Data(); ///< Shared resources
|
||||||
|
const std::string Config(); ///< Configuration directory
|
||||||
|
const std::string Doc(); ///< Documents
|
||||||
|
const std::string User(); ///< User config directory
|
||||||
|
const std::string Temp(); ///< Temporary storage
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace agi
|
} // namespace agi
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2010, Amar Takhar <verm@aegisub.org>
|
// Copyright (c) 2010-2011, Amar Takhar <verm@aegisub.org>
|
||||||
//
|
//
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -18,46 +18,37 @@
|
||||||
/// @brief Common paths.
|
/// @brief Common paths.
|
||||||
/// @ingroup libaegisub
|
/// @ingroup libaegisub
|
||||||
|
|
||||||
#include "acconf.h"
|
#include "../commit/acconf.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <libaegisub/path.h>
|
#include <libaegisub/path.h>
|
||||||
|
|
||||||
namespace agi {
|
namespace agi {
|
||||||
|
|
||||||
const char *Path::Data() {
|
const std::string Path::Data() {
|
||||||
std::string tmp;
|
return DIR_DATA;
|
||||||
tmp.assign(INSTALL_PREFIX);
|
|
||||||
tmp.append("-");
|
|
||||||
tmp.append(AEGISUB_VERSION_DATA);
|
|
||||||
return tmp.c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Path::Doc() {
|
const std::string Path::Doc() {
|
||||||
std::string tmp;
|
return DIR_DOC;
|
||||||
tmp.assign(INSTALL_PREFIX);
|
|
||||||
tmp.append("-");
|
|
||||||
tmp.append(AEGISUB_VERSION_DATA);
|
|
||||||
return tmp.c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Path::User() {
|
const std::string Path::User() {
|
||||||
std::string tmp;
|
return "~/";
|
||||||
tmp.assign("~/.aegisub-");
|
|
||||||
tmp.append(AEGISUB_VERSION_DATA);
|
|
||||||
return tmp.c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Path::Locale() {
|
const std::string Path::Locale() {
|
||||||
std::string tmp;
|
std::string tmp("~/.aegisub-");
|
||||||
tmp.assign("~/.aegisub-");
|
return tmp.append(AEGISUB_VERSION_DATA);
|
||||||
tmp.append(AEGISUB_VERSION_DATA);
|
|
||||||
return tmp.c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string Path::Config() {
|
||||||
|
std::string tmp("~/.aegisub-");
|
||||||
|
return tmp.append(AEGISUB_VERSION_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
const char *Path::Temp() {
|
const std::string Path::Temp() {
|
||||||
const char *tmp = "/tmp";
|
return "/tmp/";
|
||||||
return tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace agi
|
} // namespace agi
|
||||||
|
|
Loading…
Reference in a new issue