mirror of
https://github.com/transmission/transmission
synced 2024-12-21 23:32:35 +00:00
feat: add tr_strvToBuf() (#3657)
* feat: add tr_getDefaultConfigDirToBuf() * feat: add tr_getDefaultDownloadDirToBuf() * feat: add tr_strvToBuf() * feat: add tr_torrentFindFileToBuf() * feat: add tr_torrentGetMagnetLinkToBuf() * refactor: remove unused makeString() from tests * feat: add tr_torrentFilenameToBuf() * feat: add tr_torrentGetTrackerListToBuf() * chore: remove obsolete comment references to tr_free * chore: remove unused tr_strdup() * chore: remove unused forward declarations
This commit is contained in:
parent
988d8ff9ac
commit
e49747ab51
24 changed files with 193 additions and 305 deletions
20
cli/cli.cc
20
cli/cli.cc
|
@ -173,10 +173,9 @@ static std::string getStatusStr(tr_stat const* st)
|
|||
return "";
|
||||
}
|
||||
|
||||
static char const* getConfigDir(int argc, char const** argv)
|
||||
static std::string getConfigDir(int argc, char const** argv)
|
||||
{
|
||||
int c;
|
||||
char const* configDir = nullptr;
|
||||
char const* my_optarg;
|
||||
int const ind = tr_optind;
|
||||
|
||||
|
@ -184,19 +183,14 @@ static char const* getConfigDir(int argc, char const** argv)
|
|||
{
|
||||
if (c == 'g')
|
||||
{
|
||||
configDir = my_optarg;
|
||||
return my_optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tr_optind = ind;
|
||||
|
||||
if (configDir == nullptr)
|
||||
{
|
||||
configDir = tr_getDefaultConfigDir(MyConfigName);
|
||||
}
|
||||
|
||||
return configDir;
|
||||
return tr_getDefaultConfigDir(MyConfigName);
|
||||
}
|
||||
|
||||
int tr_main(int argc, char* argv[])
|
||||
|
@ -218,8 +212,8 @@ int tr_main(int argc, char* argv[])
|
|||
|
||||
/* load the defaults from config file + libtransmission defaults */
|
||||
tr_variantInitDict(&settings, 0);
|
||||
char const* const configDir = getConfigDir(argc, (char const**)argv);
|
||||
tr_sessionLoadSettings(&settings, configDir, MyConfigName);
|
||||
auto const config_dir = getConfigDir(argc, (char const**)argv);
|
||||
tr_sessionLoadSettings(&settings, config_dir.c_str(), MyConfigName);
|
||||
|
||||
/* the command line overrides defaults */
|
||||
if (parseCommandLine(&settings, argc, (char const**)argv) != 0)
|
||||
|
@ -256,7 +250,7 @@ int tr_main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
auto* const h = tr_sessionInit(configDir, false, &settings);
|
||||
auto* const h = tr_sessionInit(config_dir.c_str(), false, &settings);
|
||||
auto* const ctor = tr_ctorNew(h);
|
||||
|
||||
tr_ctorSetPaused(ctor, TR_FORCE, false);
|
||||
|
@ -353,7 +347,7 @@ int tr_main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
tr_sessionSaveSettings(h, configDir, &settings);
|
||||
tr_sessionSaveSettings(h, config_dir.c_str(), &settings);
|
||||
|
||||
printf("\n");
|
||||
tr_variantFree(&settings);
|
||||
|
|
|
@ -202,10 +202,9 @@ static bool reopen_log_file(char const* filename)
|
|||
return true;
|
||||
}
|
||||
|
||||
static char const* getConfigDir(int argc, char const* const* argv)
|
||||
static std::string getConfigDir(int argc, char const* const* argv)
|
||||
{
|
||||
int c;
|
||||
char const* configDir = nullptr;
|
||||
char const* optstr;
|
||||
int const ind = tr_optind;
|
||||
|
||||
|
@ -213,19 +212,13 @@ static char const* getConfigDir(int argc, char const* const* argv)
|
|||
{
|
||||
if (c == 'g')
|
||||
{
|
||||
configDir = optstr;
|
||||
break;
|
||||
return optstr;
|
||||
}
|
||||
}
|
||||
|
||||
tr_optind = ind;
|
||||
|
||||
if (configDir == nullptr)
|
||||
{
|
||||
configDir = tr_getDefaultConfigDir(MyName);
|
||||
}
|
||||
|
||||
return configDir;
|
||||
return tr_getDefaultConfigDir(MyName);
|
||||
}
|
||||
|
||||
static auto onFileAdded(tr_session* session, std::string_view dirname, std::string_view basename)
|
||||
|
@ -671,7 +664,7 @@ static bool parse_args(
|
|||
struct daemon_data
|
||||
{
|
||||
tr_variant settings;
|
||||
char const* configDir;
|
||||
std::string config_dir;
|
||||
bool paused;
|
||||
};
|
||||
|
||||
|
@ -719,7 +712,7 @@ static int daemon_start(void* varg, [[maybe_unused]] bool foreground)
|
|||
|
||||
auto* arg = static_cast<daemon_data*>(varg);
|
||||
tr_variant* const settings = &arg->settings;
|
||||
char const* const configDir = arg->configDir;
|
||||
char const* const config_dir = arg->config_dir.c_str();
|
||||
|
||||
sd_notifyf(0, "MAINPID=%d\n", (int)getpid());
|
||||
|
||||
|
@ -744,10 +737,10 @@ static int daemon_start(void* varg, [[maybe_unused]] bool foreground)
|
|||
tr_formatter_mem_init(MemK, MemKStr, MemMStr, MemGStr, MemTStr);
|
||||
tr_formatter_size_init(DiskK, DiskKStr, DiskMStr, DiskGStr, DiskTStr);
|
||||
tr_formatter_speed_init(SpeedK, SpeedKStr, SpeedMStr, SpeedGStr, SpeedTStr);
|
||||
session = tr_sessionInit(configDir, true, settings);
|
||||
session = tr_sessionInit(config_dir, true, settings);
|
||||
tr_sessionSetRPCCallback(session, on_rpc_callback, nullptr);
|
||||
tr_logAddInfo(fmt::format(_("Loading settings from '{path}'"), fmt::arg("path", configDir)));
|
||||
tr_sessionSaveSettings(session, configDir, settings);
|
||||
tr_logAddInfo(fmt::format(_("Loading settings from '{path}'"), fmt::arg("path", config_dir)));
|
||||
tr_sessionSaveSettings(session, config_dir, settings);
|
||||
|
||||
auto sv = std::string_view{};
|
||||
(void)tr_variantDictFindStrView(settings, key_pidfile, &sv);
|
||||
|
@ -893,7 +886,7 @@ CLEANUP:
|
|||
|
||||
event_base_free(ev_base);
|
||||
|
||||
tr_sessionSaveSettings(mySession, configDir, settings);
|
||||
tr_sessionSaveSettings(mySession, config_dir, settings);
|
||||
tr_sessionClose(mySession);
|
||||
pumpLogMessages(logfile);
|
||||
printf(" done.\n");
|
||||
|
@ -922,12 +915,12 @@ CLEANUP:
|
|||
|
||||
static bool init_daemon_data(int argc, char* argv[], struct daemon_data* data, bool* foreground, int* ret)
|
||||
{
|
||||
data->configDir = getConfigDir(argc, (char const* const*)argv);
|
||||
data->config_dir = getConfigDir(argc, (char const* const*)argv);
|
||||
|
||||
/* load settings from defaults + config file */
|
||||
tr_variantInitDict(&data->settings, 0);
|
||||
tr_variantDictAddBool(&data->settings, TR_KEY_rpc_enabled, true);
|
||||
bool const loaded = tr_sessionLoadSettings(&data->settings, data->configDir, MyName);
|
||||
bool const loaded = tr_sessionLoadSettings(&data->settings, data->config_dir.c_str(), MyName);
|
||||
|
||||
bool dumpSettings;
|
||||
|
||||
|
|
|
@ -1382,7 +1382,7 @@ tr_torrent* Application::Impl::get_first_selected_torrent() const
|
|||
|
||||
void Application::Impl::copy_magnet_link_to_clipboard(tr_torrent* tor) const
|
||||
{
|
||||
char* magnet = tr_torrentGetMagnetLink(tor);
|
||||
auto const magnet = tr_torrentGetMagnetLink(tor);
|
||||
auto const display = wind_->get_display();
|
||||
GdkAtom selection;
|
||||
Glib::RefPtr<Gtk::Clipboard> clipboard;
|
||||
|
@ -1396,9 +1396,6 @@ void Application::Impl::copy_magnet_link_to_clipboard(tr_torrent* tor) const
|
|||
selection = GDK_SELECTION_PRIMARY;
|
||||
clipboard = Gtk::Clipboard::get_for_display(display, selection);
|
||||
clipboard->set_text(magnet);
|
||||
|
||||
/* cleanup */
|
||||
tr_free(magnet);
|
||||
}
|
||||
|
||||
void gtr_actions_handler(Glib::ustring const& action_name, gpointer user_data)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <fmt/format.h>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
#include <libtransmission/utils.h> /* tr_free */
|
||||
#include <libtransmission/utils.h>
|
||||
#include <libtransmission/web-utils.h>
|
||||
|
||||
#include "Actions.h"
|
||||
|
@ -2299,19 +2299,6 @@ void DetailsDialog::Impl::on_edit_trackers_response(int response, std::shared_pt
|
|||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string get_editable_tracker_list(tr_torrent const* tor)
|
||||
{
|
||||
char* cstr = tr_torrentGetTrackerList(tor);
|
||||
auto str = std::string{ cstr != nullptr ? cstr : "" };
|
||||
tr_free(cstr);
|
||||
return str;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void DetailsDialog::Impl::on_edit_trackers()
|
||||
{
|
||||
tr_torrent const* tor = tracker_list_get_current_torrent();
|
||||
|
@ -2343,7 +2330,7 @@ void DetailsDialog::Impl::on_edit_trackers()
|
|||
t->add_wide_control(row, *l);
|
||||
|
||||
auto* w = Gtk::make_managed<Gtk::TextView>();
|
||||
w->get_buffer()->set_text(get_editable_tracker_list(tor));
|
||||
w->get_buffer()->set_text(tr_torrentGetTrackerList(tor));
|
||||
auto* fr = Gtk::make_managed<Gtk::Frame>();
|
||||
fr->set_shadow_type(Gtk::SHADOW_IN);
|
||||
auto* sw = Gtk::make_managed<Gtk::ScrolledWindow>();
|
||||
|
|
|
@ -49,9 +49,7 @@ static void tr_prefs_init_defaults(tr_variant* d)
|
|||
|
||||
if (dir.empty())
|
||||
{
|
||||
auto* const tmp = tr_getDefaultDownloadDir();
|
||||
dir = tmp;
|
||||
tr_free(tmp);
|
||||
dir = tr_getDefaultDownloadDir();
|
||||
}
|
||||
|
||||
tr_variantDictReserve(d, 31);
|
||||
|
|
|
@ -96,9 +96,7 @@ int main(int argc, char** argv)
|
|||
/* set up the config dir */
|
||||
if (std::empty(config_dir))
|
||||
{
|
||||
auto* const default_config_dir = tr_getDefaultConfigDir(AppConfigDirName);
|
||||
config_dir = default_config_dir;
|
||||
tr_free(default_config_dir);
|
||||
config_dir = tr_getDefaultConfigDir(AppConfigDirName);
|
||||
}
|
||||
|
||||
gtr_pref_init(config_dir);
|
||||
|
|
|
@ -110,40 +110,45 @@ static std::string xdgConfigHome()
|
|||
return fmt::format("{:s}/.config"sv, getHomeDir());
|
||||
}
|
||||
|
||||
char* tr_getDefaultConfigDir(char const* appname)
|
||||
std::string tr_getDefaultConfigDir(std::string_view appname)
|
||||
{
|
||||
if (auto dir = tr_env_get_string("TRANSMISSION_HOME"sv); !std::empty(dir))
|
||||
if (std::empty(appname))
|
||||
{
|
||||
return tr_strvDup(dir);
|
||||
appname = "Transmission"sv;
|
||||
}
|
||||
|
||||
if (tr_str_is_empty(appname))
|
||||
if (auto dir = tr_env_get_string("TRANSMISSION_HOME"sv); !std::empty(dir))
|
||||
{
|
||||
appname = "Transmission";
|
||||
return dir;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
return tr_strvDup(fmt::format("{:s}/Library/Application Support/{:s}"sv, getHomeDir(), appname));
|
||||
return fmt::format("{:s}/Library/Application Support/{:s}"sv, getHomeDir(), appname);
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
auto const appdata = win32_get_known_folder(FOLDERID_LocalAppData);
|
||||
return tr_strvDup(fmt::format("{:s}/{:s}"sv, appdata, appname));
|
||||
return fmt::format("{:s}/{:s}"sv, appdata, appname);
|
||||
|
||||
#elif defined(__HAIKU__)
|
||||
|
||||
char buf[PATH_MAX];
|
||||
find_directory(B_USER_SETTINGS_DIRECTORY, -1, true, buf, sizeof(buf));
|
||||
return tr_strvDup(fmt::format("{:s}/{:s}"sv, buf, appname);
|
||||
return fmt::format("{:s}/{:s}"sv, buf, appname);
|
||||
|
||||
#else
|
||||
|
||||
return tr_strvDup(fmt::format("{:s}/{:s}"sv, xdgConfigHome(), appname));
|
||||
return fmt::format("{:s}/{:s}"sv, xdgConfigHome(), appname);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t tr_getDefaultConfigDirToBuf(char const* appname, char* buf, size_t buflen)
|
||||
{
|
||||
return tr_strvToBuf(tr_getDefaultConfigDir(appname != nullptr ? appname : ""), buf, buflen);
|
||||
}
|
||||
|
||||
static std::string getXdgEntryFromUserDirs(std::string_view key)
|
||||
{
|
||||
auto content = std::vector<char>{};
|
||||
|
@ -178,25 +183,30 @@ static std::string getXdgEntryFromUserDirs(std::string_view key)
|
|||
return val;
|
||||
}
|
||||
|
||||
char* tr_getDefaultDownloadDir()
|
||||
std::string tr_getDefaultDownloadDir()
|
||||
{
|
||||
if (auto const dir = getXdgEntryFromUserDirs("XDG_DOWNLOAD_DIR"sv); !std::empty(dir))
|
||||
if (auto dir = getXdgEntryFromUserDirs("XDG_DOWNLOAD_DIR"sv); !std::empty(dir))
|
||||
{
|
||||
return tr_strvDup(dir);
|
||||
return dir;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (auto dir = win32_get_known_folder(FOLDERID_Downloads); !std::empty(dir))
|
||||
{
|
||||
return tr_strvDup(dir);
|
||||
return dir;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
return tr_strvDup(fmt::format("{:s}/Desktop"sv, getHomeDir()));
|
||||
return fmt::format("{:s}/Desktop"sv, getHomeDir());
|
||||
#endif
|
||||
|
||||
return tr_strvDup(fmt::format("{:s}/Downloads"sv, getHomeDir()));
|
||||
return fmt::format("{:s}/Downloads"sv, getHomeDir());
|
||||
}
|
||||
|
||||
size_t tr_getDefaultDownloadDirToBuf(char* buf, size_t buflen)
|
||||
{
|
||||
return tr_strvToBuf(tr_getDefaultDownloadDir(), buf, buflen);
|
||||
}
|
||||
|
||||
/***
|
||||
|
|
|
@ -296,7 +296,7 @@ tr_session::PublicAddressResult tr_session::publicAddress(tr_address_type type)
|
|||
|
||||
void tr_sessionGetDefaultSettings(tr_variant* setme_dictionary)
|
||||
{
|
||||
auto* const download_dir = tr_getDefaultDownloadDir();
|
||||
auto const download_dir = tr_getDefaultDownloadDir();
|
||||
|
||||
auto* const d = setme_dictionary;
|
||||
TR_ASSERT(tr_variantIsDict(d));
|
||||
|
@ -376,8 +376,6 @@ void tr_sessionGetDefaultSettings(tr_variant* setme_dictionary)
|
|||
tr_variantDictAddBool(d, TR_KEY_anti_brute_force_enabled, true);
|
||||
tr_variantDictAddStrView(d, TR_KEY_announce_ip, "");
|
||||
tr_variantDictAddBool(d, TR_KEY_announce_ip_enabled, false);
|
||||
|
||||
tr_free(download_dir);
|
||||
}
|
||||
|
||||
void tr_sessionGetSettings(tr_session const* s, tr_variant* setme_dictionary)
|
||||
|
@ -469,9 +467,8 @@ static void getSettingsFilename(tr_pathbuf& setme, char const* config_dir, char
|
|||
return;
|
||||
}
|
||||
|
||||
auto* const default_config_dir = tr_getDefaultConfigDir(appname);
|
||||
auto const default_config_dir = tr_getDefaultConfigDir(appname);
|
||||
setme.assign(std::string_view{ default_config_dir }, "/settings.json"sv);
|
||||
tr_free(default_config_dir);
|
||||
}
|
||||
|
||||
bool tr_sessionLoadSettings(tr_variant* dict, char const* config_dir, char const* appName)
|
||||
|
|
|
@ -414,7 +414,12 @@ double tr_torrentGetMetadataPercent(tr_torrent const* tor)
|
|||
return m == nullptr || m->piece_count == 0 ? 0.0 : (m->piece_count - std::size(m->pieces_needed)) / (double)m->piece_count;
|
||||
}
|
||||
|
||||
char* tr_torrentGetMagnetLink(tr_torrent const* tor)
|
||||
std::string tr_torrentGetMagnetLink(tr_torrent const* tor)
|
||||
{
|
||||
return tr_strvDup(tor->metainfo_.magnet());
|
||||
return std::string{ tor->metainfo_.magnet().sv() };
|
||||
}
|
||||
|
||||
size_t tr_torrentGetMagnetLinkToBuf(tr_torrent const* tor, char* buf, size_t buflen)
|
||||
{
|
||||
return tr_strvToBuf(tr_torrentGetMagnetLink(tor), buf, buflen);
|
||||
}
|
||||
|
|
|
@ -30,108 +30,6 @@
|
|||
|
||||
using namespace std::literals;
|
||||
|
||||
//// C BINDINGS
|
||||
|
||||
#if 0
|
||||
/// Lifecycle
|
||||
|
||||
tr_torrent_metainfo* tr_torrentMetainfoNewFromData(char const* data, size_t data_len, struct tr_error** error)
|
||||
{
|
||||
auto* tm = new tr_torrent_metainfo{};
|
||||
if (!tm->parseBenc(std::string_view{ data, data_len }, error))
|
||||
{
|
||||
delete tm;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tm;
|
||||
}
|
||||
|
||||
tr_torrent_metainfo* tr_torrentMetainfoNewFromFile(char const* filename, struct tr_error** error)
|
||||
{
|
||||
auto* tm = new tr_torrent_metainfo{};
|
||||
if (!tm->parseBencFromFile(filename ? filename : "", nullptr, error))
|
||||
{
|
||||
delete tm;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return tm;
|
||||
}
|
||||
|
||||
void tr_torrentMetainfoFree(tr_torrent_metainfo* tm)
|
||||
{
|
||||
delete tm;
|
||||
}
|
||||
|
||||
//// Accessors
|
||||
|
||||
char* tr_torrentMetainfoMagnet(struct tr_torrent_metainfo const* tm)
|
||||
{
|
||||
return tr_strvDup(tm->magnet());
|
||||
}
|
||||
|
||||
/// Info
|
||||
|
||||
tr_torrent_metainfo_info* tr_torrentMetainfoGet(tr_torrent_metainfo const* tm, tr_torrent_metainfo_info* setme)
|
||||
{
|
||||
setme->comment = tm->comment.c_str();
|
||||
setme->creator = tm->creator.c_str();
|
||||
setme->info_hash = tm->info_hash;
|
||||
setme->info_hash_string = std::data(tm->info_hash_chars);
|
||||
setme->is_private = tm->is_private;
|
||||
setme->n_pieces = tm->n_pieces;
|
||||
setme->name = tm->name.c_str();
|
||||
setme->source = tm->source.c_str();
|
||||
setme->time_created = tm->time_created;
|
||||
setme->total_size = tm->total_size;
|
||||
return setme;
|
||||
}
|
||||
|
||||
/// Files
|
||||
|
||||
size_t tr_torrentMetainfoFileCount(tr_torrent_metainfo const* tm)
|
||||
{
|
||||
return std::size(tm->files);
|
||||
}
|
||||
|
||||
tr_torrent_metainfo_file_info* tr_torrentMetainfoFile(
|
||||
tr_torrent_metainfo const* tm,
|
||||
size_t n,
|
||||
tr_torrent_metainfo_file_info* setme)
|
||||
{
|
||||
auto& file = tm->files[n];
|
||||
setme->path = file.path.c_str();
|
||||
setme->size = file.size;
|
||||
return setme;
|
||||
}
|
||||
|
||||
/// Trackers
|
||||
|
||||
size_t tr_torrentMetainfoTrackerCount(tr_torrent_metainfo const* tm)
|
||||
{
|
||||
return std::size(tm->trackers);
|
||||
}
|
||||
|
||||
tr_torrent_metainfo_tracker_info* tr_torrentMetainfoTracker(
|
||||
tr_torrent_metainfo const* tm,
|
||||
size_t n,
|
||||
tr_torrent_metainfo_tracker_info* setme)
|
||||
{
|
||||
auto it = std::begin(tm->trackers);
|
||||
std::advance(it, n);
|
||||
auto const& tracker = it->second;
|
||||
setme->announce_url = tr_quark_get_string(tracker.announce_url);
|
||||
setme->scrape_url = tr_quark_get_string(tracker.scrape_url);
|
||||
setme->tier = tracker.tier;
|
||||
return setme;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
/**
|
||||
* @brief Ensure that the URLs for multfile torrents end in a slash.
|
||||
*
|
||||
|
|
|
@ -1243,9 +1243,14 @@ tr_torrent_view tr_torrentView(tr_torrent const* tor)
|
|||
return ret;
|
||||
}
|
||||
|
||||
char* tr_torrentFilename(tr_torrent const* tor)
|
||||
std::string tr_torrentFilename(tr_torrent const* tor)
|
||||
{
|
||||
return tr_strvDup(tor->torrentFile());
|
||||
return std::string{ tor->torrentFile() };
|
||||
}
|
||||
|
||||
size_t tr_torrentFilenameToBuf(tr_torrent const* tor, char* buf, size_t buflen)
|
||||
{
|
||||
return tr_strvToBuf(tr_torrentFilename(tor), buf, buflen);
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -2058,9 +2063,14 @@ bool tr_torrentSetTrackerList(tr_torrent* tor, char const* text)
|
|||
return text != nullptr && tor->setTrackerList(text);
|
||||
}
|
||||
|
||||
char* tr_torrentGetTrackerList(tr_torrent const* tor)
|
||||
std::string tr_torrentGetTrackerList(tr_torrent const* tor)
|
||||
{
|
||||
return tr_strvDup(tor->trackerList());
|
||||
return tor->trackerList();
|
||||
}
|
||||
|
||||
size_t tr_torrentGetTrackerListToBuf(tr_torrent const* tor, char* buf, size_t buflen)
|
||||
{
|
||||
return tr_strvToBuf(tr_torrentGetTrackerList(tor), buf, buflen);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2310,11 +2320,15 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block)
|
|||
****
|
||||
***/
|
||||
|
||||
// TODO: clients that call this should call tr_torrent::findFile() instead
|
||||
char* tr_torrentFindFile(tr_torrent const* tor, tr_file_index_t fileNum)
|
||||
std::string tr_torrentFindFile(tr_torrent const* tor, tr_file_index_t file_num)
|
||||
{
|
||||
auto const found = tor->findFile(fileNum);
|
||||
return found ? tr_strdup(found->filename()) : nullptr;
|
||||
auto const found = tor->findFile(file_num);
|
||||
return std::string{ found ? found->filename().sv() : ""sv };
|
||||
}
|
||||
|
||||
size_t tr_torrentFindFileToBuf(tr_torrent const* tor, tr_file_index_t file_num, char* buf, size_t buflen)
|
||||
{
|
||||
return tr_strvToBuf(tr_torrentFindFile(tor, file_num), buf, buflen);
|
||||
}
|
||||
|
||||
// decide whether we should be looking for files in downloadDir or incompleteDir
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
#pragma once
|
||||
|
||||
/***
|
||||
****
|
||||
**** Basic Types
|
||||
****
|
||||
***/
|
||||
|
||||
#include <stdbool.h> /* bool */
|
||||
|
@ -25,6 +23,11 @@
|
|||
#include <stdint.h> /* uintN_t */
|
||||
#include <time.h> /* time_t */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#endif
|
||||
|
||||
#include "tr-macros.h"
|
||||
|
||||
using tr_file_index_t = uint32_t;
|
||||
|
@ -49,8 +52,6 @@ struct tr_byte_span_t
|
|||
uint64_t end;
|
||||
};
|
||||
|
||||
class tr_announce_list;
|
||||
|
||||
struct tr_ctor;
|
||||
struct tr_error;
|
||||
struct tr_session;
|
||||
|
@ -97,9 +98,7 @@ enum tr_encryption_mode
|
|||
*/
|
||||
|
||||
/**
|
||||
* @brief returns Transmission's default configuration file directory.
|
||||
*
|
||||
* Use tr_free() to free the string when done.
|
||||
* @brief get Transmission's default configuration file directory.
|
||||
*
|
||||
* The default configuration directory is determined this way:
|
||||
* -# If the TRANSMISSION_HOME environment variable is set, its value is used.
|
||||
|
@ -108,19 +107,27 @@ enum tr_encryption_mode
|
|||
* -# If XDG_CONFIG_HOME is set, "${XDG_CONFIG_HOME}/${appname}" is used.
|
||||
* -# ${HOME}/.config/${appname}" is used as a last resort.
|
||||
*/
|
||||
char* tr_getDefaultConfigDir(char const* appname);
|
||||
#ifdef __cplusplus
|
||||
[[nodiscard]] std::string tr_getDefaultConfigDir(std::string_view appname);
|
||||
#endif
|
||||
|
||||
/** @brief buffer variant of tr_getDefaultConfigDir(). See tr_strvToBuf(). */
|
||||
size_t tr_getDefaultConfigDirToBuf(char const* appname, char* buf, size_t buflen);
|
||||
|
||||
/**
|
||||
* @brief returns Transmisson's default download directory.
|
||||
*
|
||||
* Use tr_free() to free the string when done.
|
||||
*
|
||||
* The default download directory is determined this way:
|
||||
* -# If the HOME environment variable is set, "${HOME}/Downloads" is used.
|
||||
* -# On Windows, "${CSIDL_MYDOCUMENTS}/Downloads" is used.
|
||||
* -# Otherwise, getpwuid(getuid())->pw_dir + "/Downloads" is used.
|
||||
*/
|
||||
char* tr_getDefaultDownloadDir();
|
||||
#ifdef __cplusplus
|
||||
[[nodiscard]] std::string tr_getDefaultDownloadDir();
|
||||
#endif
|
||||
|
||||
/** @brief buffer variant of tr_getDefaultDownloadDir(). See tr_strvToBuf(). */
|
||||
size_t tr_getDefaultDownloadDirToBuf(char* buf, size_t buflen);
|
||||
|
||||
#define TR_DEFAULT_BIND_ADDRESS_IPV4 "0.0.0.0"
|
||||
#define TR_DEFAULT_BIND_ADDRESS_IPV6 "::"
|
||||
|
@ -1010,13 +1017,16 @@ uint64_t tr_torrentTotalSize(tr_torrent const*);
|
|||
/**
|
||||
* @brief find the location of a torrent's file by looking with and without
|
||||
* the ".part" suffix, looking in downloadDir and incompleteDir, etc.
|
||||
* @return a newly-allocated string (that must be tr_free()d by the caller
|
||||
* when done) that gives the location of this file on disk,
|
||||
* or nullptr if no file exists yet.
|
||||
* @return the path of this file, or an empty string if no file exists yet.
|
||||
* @param tor the torrent whose file we're looking for
|
||||
* @param fileNum the fileIndex, in [0...tr_torrentFileCount())
|
||||
*/
|
||||
char* tr_torrentFindFile(tr_torrent const* tor, tr_file_index_t fileNum);
|
||||
#ifdef __cplusplus
|
||||
[[nodiscard]] std::string tr_torrentFindFile(tr_torrent const* tor, tr_file_index_t file_num);
|
||||
#endif
|
||||
|
||||
/** @brief buffer variant of tr_torrentFindFile(). See tr_strvToBuf(). */
|
||||
size_t tr_torrentFindFileToBuf(tr_torrent const* tor, tr_file_index_t file_num, char* buf, size_t buflen);
|
||||
|
||||
/***
|
||||
**** Torrent speed limits
|
||||
|
@ -1130,17 +1140,21 @@ char const* tr_torrentGetDownloadDir(tr_torrent const* torrent);
|
|||
char const* tr_torrentGetCurrentDir(tr_torrent const* tor);
|
||||
|
||||
/**
|
||||
* Returns a newly-allocated string with a magnet link of the torrent.
|
||||
* Use tr_free() to free the string when done.
|
||||
* Returns a the magnet link to the torrent.
|
||||
*/
|
||||
char* tr_torrentGetMagnetLink(tr_torrent const* tor);
|
||||
#ifdef __cplusplus
|
||||
[[nodiscard]] std::string tr_torrentGetMagnetLink(tr_torrent const* tor);
|
||||
#endif
|
||||
|
||||
/** @brief buffer variant of tr_torrentGetMagnetLink(). See tr_strvToBuf(). */
|
||||
size_t tr_torrentGetMagnetLinkToBuf(tr_torrent const* tor, char* buf, size_t buflen);
|
||||
|
||||
/**
|
||||
***
|
||||
**/
|
||||
|
||||
/**
|
||||
* Returns a newly-allocated string listing its tracker's announce URLs.
|
||||
* Returns a string listing its tracker's announce URLs.
|
||||
* One URL per line, with a blank line between tiers.
|
||||
*
|
||||
* NOTE: this only includes the trackers included in the torrent and,
|
||||
|
@ -1149,7 +1163,12 @@ char* tr_torrentGetMagnetLink(tr_torrent const* tor);
|
|||
* are applied to all public torrents. If you want a full display of all
|
||||
* trackers, use tr_torrentTracker() and tr_torrentTrackerCount()
|
||||
*/
|
||||
char* tr_torrentGetTrackerList(tr_torrent const* tor);
|
||||
#ifdef __cplusplus
|
||||
[[nodiscard]] std::string tr_torrentGetTrackerList(tr_torrent const* tor);
|
||||
#endif
|
||||
|
||||
/** @brief buffer variant of tr_torrentGetTrackerList(). See tr_strvToBuf(). */
|
||||
size_t tr_torrentGetTrackerListToBuf(tr_torrent const* tor, char* buf, size_t buflen);
|
||||
|
||||
/**
|
||||
* Sets a torrent's tracker list from a list of announce URLs with one
|
||||
|
@ -1436,9 +1455,13 @@ struct tr_torrent_view tr_torrentView(tr_torrent const* tor);
|
|||
|
||||
/*
|
||||
* Get the filename of Transmission's internal copy of the torrent file.
|
||||
* This is a duplicate that must be freed with tr_free() when done.
|
||||
*/
|
||||
char* tr_torrentFilename(tr_torrent const* tor);
|
||||
#ifdef __cplusplus
|
||||
[[nodiscard]] std::string tr_torrentFilename(tr_torrent const* tor);
|
||||
#endif
|
||||
|
||||
/** @brief buffer variant of tr_torrentFilename(). See tr_strvToBuf(). */
|
||||
size_t tr_torrentFilenameToBuf(tr_torrent const* tor, char* buf, size_t buflen);
|
||||
|
||||
/***********************************************************************
|
||||
* tr_torrentAvailability
|
||||
|
@ -1475,7 +1498,6 @@ enum tr_torrent_activity
|
|||
TR_STATUS_SEED_WAIT = 5, /* Queued to seed */
|
||||
TR_STATUS_SEED = 6 /* Seeding */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TR_PEER_FROM_INCOMING = 0, /* connections made to the listening port */
|
||||
|
|
|
@ -217,9 +217,21 @@ char* tr_strvDup(std::string_view in)
|
|||
return ret;
|
||||
}
|
||||
|
||||
char* tr_strdup(void const* in)
|
||||
size_t tr_strvToBuf(std::string_view src, char* buf, size_t buflen)
|
||||
{
|
||||
return in == nullptr ? nullptr : tr_strvDup(static_cast<char const*>(in));
|
||||
size_t const len = std::size(src);
|
||||
|
||||
if (buflen >= len)
|
||||
{
|
||||
auto const out = std::copy(std::begin(src), std::end(src), buf);
|
||||
|
||||
if (buflen > len)
|
||||
{
|
||||
*out = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
|
@ -625,7 +637,6 @@ static bool parseNumberSection(std::string_view str, number_range& range)
|
|||
* Given a string like "1-4" or "1-4,6,9,14-51", this allocates and returns an
|
||||
* array of setmeCount ints of all the values in the array.
|
||||
* For example, "5-8" will return [ 5, 6, 7, 8 ] and setmeCount will be 4.
|
||||
* It's the caller's responsibility to call tr_free () on the returned array.
|
||||
* If a fragment of the string can't be parsed, nullptr is returned.
|
||||
*/
|
||||
std::vector<int> tr_parseNumberRange(std::string_view str)
|
||||
|
|
|
@ -141,13 +141,6 @@ void tr_free(void* p);
|
|||
#define tr_renew(struct_type, mem, n_structs) \
|
||||
(static_cast<struct_type*>(tr_realloc((mem), sizeof(struct_type) * (size_t)(n_structs))))
|
||||
|
||||
/**
|
||||
* @brief make a newly-allocated copy of a string
|
||||
* @param in is a void* so that callers can pass in both signed & unsigned without a cast
|
||||
* @return a newly-allocated copy of `in' that can be freed with tr_free()
|
||||
*/
|
||||
[[nodiscard]] char* tr_strdup(void const* in);
|
||||
|
||||
constexpr bool tr_str_is_empty(char const* value)
|
||||
{
|
||||
return value == nullptr || *value == '\0';
|
||||
|
@ -236,6 +229,15 @@ constexpr bool tr_strvSep(std::string_view* sv, std::string_view* token, char de
|
|||
|
||||
std::string& tr_strvUtf8Clean(std::string_view cleanme, std::string& setme);
|
||||
|
||||
/**
|
||||
* @brief copies `src` into `buf`.
|
||||
*
|
||||
* - Always returns std::size(src).
|
||||
* - `src` will be copied into `buf` iff `buflen >= std::size(src)`
|
||||
* - `buf` will also be zero terminated iff `buflen >= std::size(src) + 1`.
|
||||
*/
|
||||
size_t tr_strvToBuf(std::string_view src, char* buf, size_t buflen);
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
@ -247,8 +249,7 @@ std::string& tr_strvUtf8Clean(std::string_view cleanme, std::string& setme);
|
|||
/**
|
||||
* @brief Given a string like "1-4" or "1-4,6,9,14-51", this returns a
|
||||
* newly-allocated array of all the integers in the set.
|
||||
* @return a newly-allocated array of integers that must be freed with tr_free(),
|
||||
* or nullptr if a fragment of the string can't be parsed.
|
||||
* @return a vector of integers, which is empty if the string can't be parsed.
|
||||
*
|
||||
* For example, "5-8" will return [ 5, 6, 7, 8 ] and setmeCount will be 4.
|
||||
*/
|
||||
|
|
|
@ -563,11 +563,10 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
|
|||
|
||||
tr_formatter_mem_init(1000, kbString.UTF8String, mbString.UTF8String, gbString.UTF8String, tbString.UTF8String);
|
||||
|
||||
char* const default_config_dir = tr_getDefaultConfigDir("Transmission");
|
||||
_fLib = tr_sessionInit(default_config_dir, YES, &settings);
|
||||
auto const default_config_dir = tr_getDefaultConfigDir("Transmission");
|
||||
_fLib = tr_sessionInit(default_config_dir.c_str(), YES, &settings);
|
||||
tr_variantFree(&settings);
|
||||
_fConfigDirectory = @(default_config_dir);
|
||||
tr_free(default_config_dir);
|
||||
_fConfigDirectory = @(default_config_dir.c_str());
|
||||
|
||||
tr_sessionSetIdleLimitHitCallback(_fLib, onIdleLimitHit, (__bridge void*)(self));
|
||||
tr_sessionSetQueueStartCallback(_fLib, onStartQueue, (__bridge void*)(self));
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <libtransmission/error.h>
|
||||
#include <libtransmission/log.h>
|
||||
#include <libtransmission/utils.h> // tr_free()
|
||||
#include <libtransmission/utils.h>
|
||||
|
||||
#import "Torrent.h"
|
||||
#import "GroupsController.h"
|
||||
|
@ -361,7 +361,7 @@ bool trashDataFile(char const* filename, tr_error** error)
|
|||
|
||||
- (NSString*)magnetLink
|
||||
{
|
||||
return @(tr_torrentGetMagnetLink(self.fHandle));
|
||||
return @(tr_torrentGetMagnetLink(self.fHandle).c_str());
|
||||
}
|
||||
|
||||
- (CGFloat)ratio
|
||||
|
@ -682,10 +682,9 @@ bool trashDataFile(char const* filename, tr_error** error)
|
|||
new_tracker = [@"http://" stringByAppendingString:new_tracker];
|
||||
}
|
||||
|
||||
char* old_list = tr_torrentGetTrackerList(self.fHandle);
|
||||
auto const old_list = tr_torrentGetTrackerList(self.fHandle);
|
||||
auto const new_list = fmt::format(FMT_STRING("{:s}\n\n{:s}"), old_list, new_tracker.UTF8String);
|
||||
BOOL const success = tr_torrentSetTrackerList(self.fHandle, new_list.c_str());
|
||||
tr_free(old_list);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -759,10 +758,7 @@ bool trashDataFile(char const* filename, tr_error** error)
|
|||
|
||||
- (NSString*)torrentLocation
|
||||
{
|
||||
auto* const filename = tr_torrentFilename(self.fHandle);
|
||||
NSString* ret = @(filename ? filename : "");
|
||||
tr_free(filename);
|
||||
return ret;
|
||||
return @(tr_torrentFilename(self.fHandle).c_str());
|
||||
}
|
||||
|
||||
- (NSString*)dataLocation
|
||||
|
@ -785,16 +781,8 @@ bool trashDataFile(char const* filename, tr_error** error)
|
|||
}
|
||||
else
|
||||
{
|
||||
char* location = tr_torrentFindFile(self.fHandle, 0);
|
||||
if (location == NULL)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString* dataLocation = @(location);
|
||||
free(location);
|
||||
|
||||
return dataLocation;
|
||||
auto const location = tr_torrentFindFile(self.fHandle, 0);
|
||||
return std::empty(location) ? nil : @(location.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -814,16 +802,8 @@ bool trashDataFile(char const* filename, tr_error** error)
|
|||
}
|
||||
else
|
||||
{
|
||||
char* location = tr_torrentFindFile(self.fHandle, node.indexes.firstIndex);
|
||||
if (location == NULL)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString* dataLocation = @(location);
|
||||
free(location);
|
||||
|
||||
return dataLocation;
|
||||
auto const location = tr_torrentFindFile(self.fHandle, node.indexes.firstIndex);
|
||||
return std::empty(location) ? nil : @(location.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -220,9 +220,7 @@ Application::Application(int& argc, char** argv)
|
|||
// set the fallback config dir
|
||||
if (config_dir.isNull())
|
||||
{
|
||||
auto* const default_config_dir = tr_getDefaultConfigDir("transmission");
|
||||
config_dir = QString::fromUtf8(default_config_dir);
|
||||
tr_free(default_config_dir);
|
||||
config_dir = QString::fromStdString(tr_getDefaultConfigDir("transmission"));
|
||||
}
|
||||
|
||||
// ensure our config directory exists
|
||||
|
|
|
@ -432,7 +432,7 @@ void Prefs::initDefaults(tr_variant* d) const
|
|||
auto constexpr StatsMode = std::string_view{ "total-ratio" };
|
||||
auto constexpr WindowLayout = std::string_view{ "menu,toolbar,filter,list,statusbar" };
|
||||
|
||||
auto* const download_dir = tr_getDefaultDownloadDir();
|
||||
auto const download_dir = tr_getDefaultDownloadDir();
|
||||
|
||||
tr_variantDictReserve(d, 38);
|
||||
dictAdd(d, TR_KEY_blocklist_updates_enabled, true);
|
||||
|
@ -462,7 +462,7 @@ void Prefs::initDefaults(tr_variant* d) const
|
|||
dictAdd(d, TR_KEY_main_window_x, 50);
|
||||
dictAdd(d, TR_KEY_main_window_y, 50);
|
||||
dictAdd(d, TR_KEY_remote_session_port, TR_DEFAULT_RPC_PORT);
|
||||
dictAdd(d, TR_KEY_download_dir, std::string_view{ download_dir });
|
||||
dictAdd(d, TR_KEY_download_dir, download_dir);
|
||||
dictAdd(d, TR_KEY_filter_mode, FilterMode);
|
||||
dictAdd(d, TR_KEY_main_window_layout_order, WindowLayout);
|
||||
dictAdd(d, TR_KEY_open_dialog_dir, QDir::home().absolutePath());
|
||||
|
@ -471,10 +471,8 @@ void Prefs::initDefaults(tr_variant* d) const
|
|||
dictAdd(d, TR_KEY_remote_session_username, SessionUsername);
|
||||
dictAdd(d, TR_KEY_sort_mode, SortMode);
|
||||
dictAdd(d, TR_KEY_statusbar_stats, StatsMode);
|
||||
dictAdd(d, TR_KEY_watch_dir, std::string_view{ download_dir });
|
||||
dictAdd(d, TR_KEY_watch_dir, download_dir);
|
||||
dictAdd(d, TR_KEY_read_clipboard, false);
|
||||
|
||||
tr_free(download_dir);
|
||||
}
|
||||
|
||||
/***
|
||||
|
|
|
@ -60,9 +60,9 @@ TEST_P(IncompleteDirTest, incompleteDir)
|
|||
auto path = tr_pathbuf{};
|
||||
|
||||
path.assign(incomplete_dir, '/', tr_torrentFile(tor, 0).name, tr_torrent_files::PartialFileSuffix);
|
||||
EXPECT_EQ(path, makeString(tr_torrentFindFile(tor, 0)));
|
||||
EXPECT_EQ(path, tr_torrentFindFile(tor, 0));
|
||||
path.assign(incomplete_dir, '/', tr_torrentFile(tor, 1).name);
|
||||
EXPECT_EQ(path, makeString(tr_torrentFindFile(tor, 1)));
|
||||
EXPECT_EQ(path, tr_torrentFindFile(tor, 1));
|
||||
EXPECT_EQ(tor->pieceSize(), tr_torrentStat(tor)->leftUntilDone);
|
||||
|
||||
// auto constexpr completeness_unset = tr_completeness { -1 };
|
||||
|
@ -129,7 +129,7 @@ TEST_P(IncompleteDirTest, incompleteDir)
|
|||
for (tr_file_index_t i = 0; i < n; ++i)
|
||||
{
|
||||
auto const expected = tr_pathbuf{ download_dir, '/', tr_torrentFile(tor, i).name };
|
||||
EXPECT_EQ(expected, makeString(tr_torrentFindFile(tor, i)));
|
||||
EXPECT_EQ(expected, tr_torrentFindFile(tor, i));
|
||||
}
|
||||
|
||||
// cleanup
|
||||
|
@ -183,7 +183,7 @@ TEST_F(MoveTest, setLocation)
|
|||
for (tr_file_index_t i = 0; i < n; ++i)
|
||||
{
|
||||
auto const expected = tr_pathbuf{ target_dir, '/', tr_torrentFile(tor, i).name };
|
||||
EXPECT_EQ(expected, makeString(tr_torrentFindFile(tor, i)));
|
||||
EXPECT_EQ(expected, tr_torrentFindFile(tor, i));
|
||||
}
|
||||
|
||||
// cleanup
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
using namespace std::literals;
|
||||
using PlatformTest = ::libtransmission::test::SessionTest;
|
||||
using ::libtransmission::test::makeString;
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
@ -28,8 +27,8 @@ TEST_F(PlatformTest, defaultDownloadDirXdg)
|
|||
setenv("HOME", sandboxDir().c_str(), 1);
|
||||
setenv("XDG_CONFIG_HOME", LIBTRANSMISSION_TEST_ASSETS_DIR, 1);
|
||||
|
||||
auto actual = makeString(tr_getDefaultDownloadDir());
|
||||
auto expected = fmt::format("{:s}/UserDirsDownloads"sv, sandboxDir());
|
||||
auto const expected = fmt::format("{:s}/UserDirsDownloads"sv, sandboxDir());
|
||||
auto const actual = tr_getDefaultDownloadDir();
|
||||
EXPECT_EQ(expected, actual);
|
||||
|
||||
unsetenv("XDG_CONFIG_HOME");
|
||||
|
@ -41,8 +40,8 @@ TEST_F(PlatformTest, defaultDownloadDir)
|
|||
{
|
||||
setenv("HOME", sandboxDir().c_str(), 1);
|
||||
|
||||
auto expected = fmt::format("{:s}/Downloads"sv, sandboxDir());
|
||||
auto actual = makeString(tr_getDefaultDownloadDir());
|
||||
auto const expected = fmt::format("{:s}/Downloads"sv, sandboxDir());
|
||||
auto const actual = tr_getDefaultDownloadDir();
|
||||
EXPECT_EQ(expected, actual);
|
||||
|
||||
unsetenv("HOME");
|
||||
|
@ -53,8 +52,8 @@ TEST_F(PlatformTest, defaultConfigDirEnv)
|
|||
{
|
||||
setenv("TRANSMISSION_HOME", sandboxDir().c_str(), 1);
|
||||
|
||||
auto actual = makeString(tr_getDefaultConfigDir("appname"));
|
||||
auto expected = sandboxDir();
|
||||
auto const expected = sandboxDir();
|
||||
auto const actual = tr_getDefaultConfigDir("appname");
|
||||
EXPECT_EQ(expected, actual);
|
||||
|
||||
unsetenv("TRANSMISSION_HOME");
|
||||
|
@ -66,8 +65,8 @@ TEST_F(PlatformTest, defaultConfigDirXdgConfig)
|
|||
{
|
||||
setenv("XDG_CONFIG_HOME", sandboxDir().c_str(), 1);
|
||||
|
||||
auto expected = fmt::format("{:s}/appname", sandboxDir());
|
||||
auto actual = makeString(tr_getDefaultConfigDir("appname"));
|
||||
auto const expected = fmt::format("{:s}/appname", sandboxDir());
|
||||
auto const actual = tr_getDefaultConfigDir("appname");
|
||||
EXPECT_EQ(expected, actual);
|
||||
|
||||
unsetenv("XDG_CONFIG_HOME");
|
||||
|
@ -78,8 +77,8 @@ TEST_F(PlatformTest, defaultConfigDirXdgConfigHome)
|
|||
auto const home = tr_pathbuf{ sandboxDir(), "/home/user" };
|
||||
setenv("HOME", home, 1);
|
||||
|
||||
auto expected = fmt::format("{:s}/.config/appname", home.sv());
|
||||
auto actual = makeString(tr_getDefaultConfigDir("appname"));
|
||||
auto const expected = fmt::format("{:s}/.config/appname", home.sv());
|
||||
auto const actual = tr_getDefaultConfigDir("appname");
|
||||
EXPECT_EQ(expected, actual);
|
||||
|
||||
unsetenv("HOME");
|
||||
|
|
|
@ -189,9 +189,8 @@ TEST_F(RenameTest, singleFilenameTorrent)
|
|||
EXPECT_FALSE(tr_sys_path_exists(tmpstr)); // confirm the old filename can't be found
|
||||
EXPECT_STREQ("foobar", tr_torrentName(tor)); // confirm the torrent's name is now 'foobar'
|
||||
EXPECT_STREQ("foobar", tr_torrentFile(tor, 0).name); // confirm the file's name is now 'foobar'
|
||||
char* const torrent_filename = tr_torrentFilename(tor);
|
||||
EXPECT_STREQ(nullptr, strstr(torrent_filename, "foobar")); // confirm torrent file hasn't changed
|
||||
tr_free(torrent_filename);
|
||||
auto const torrent_filename = tr_torrentFilename(tor);
|
||||
EXPECT_EQ(std::string::npos, torrent_filename.find("foobar")); // confirm torrent file hasn't changed
|
||||
tmpstr.assign(tor->currentDir(), "/foobar");
|
||||
EXPECT_TRUE(tr_sys_path_exists(tmpstr)); // confirm the file's name is now 'foobar' on the disk
|
||||
EXPECT_TRUE(testFileExistsAndConsistsOfThisString(tor, 0, "hello, world!\n")); // confirm the contents are right
|
||||
|
@ -228,7 +227,6 @@ TEST_F(RenameTest, singleFilenameTorrent)
|
|||
|
||||
TEST_F(RenameTest, multifileTorrent)
|
||||
{
|
||||
char* str;
|
||||
auto constexpr TotalSize = size_t{ 67 };
|
||||
auto constexpr ExpectedFiles = std::array<std::string_view, 4>{
|
||||
"Felidae/Felinae/Acinonyx/Cheetah/Chester"sv,
|
||||
|
@ -332,15 +330,13 @@ TEST_F(RenameTest, multifileTorrent)
|
|||
***/
|
||||
|
||||
// remove the directory Felidae/Felinae/Felis/catus
|
||||
str = tr_torrentFindFile(tor, 1);
|
||||
EXPECT_NE(nullptr, str);
|
||||
auto str = tr_torrentFindFile(tor, 1);
|
||||
EXPECT_NE(""sv, str);
|
||||
tr_sys_path_remove(str);
|
||||
tr_free(str);
|
||||
str = tr_torrentFindFile(tor, 2);
|
||||
EXPECT_NE(nullptr, str);
|
||||
EXPECT_NE(""sv, str);
|
||||
tr_sys_path_remove(str);
|
||||
tr_sys_path_remove(std::string{ tr_sys_path_dirname(str) });
|
||||
tr_free(str);
|
||||
sync();
|
||||
blockingTorrentVerify(tor);
|
||||
testFileExistsAndConsistsOfThisString(tor, 0, ExpectedContents[0]);
|
||||
|
@ -348,8 +344,7 @@ TEST_F(RenameTest, multifileTorrent)
|
|||
for (tr_file_index_t i = 1; i <= 2; ++i)
|
||||
{
|
||||
str = tr_torrentFindFile(tor, i);
|
||||
EXPECT_STREQ(nullptr, str);
|
||||
tr_free(str);
|
||||
EXPECT_EQ(""sv, str);
|
||||
}
|
||||
|
||||
testFileExistsAndConsistsOfThisString(tor, 3, ExpectedContents[3]);
|
||||
|
@ -485,9 +480,8 @@ TEST_F(RenameTest, partialFile)
|
|||
for (tr_file_index_t i = 0; i < 3; ++i)
|
||||
{
|
||||
auto const expected = tr_pathbuf{ tor->currentDir(), '/', strings[i] };
|
||||
char* path = tr_torrentFindFile(tor, i);
|
||||
EXPECT_EQ(expected, path);
|
||||
tr_free(path);
|
||||
auto const actual = tr_torrentFindFile(tor, i);
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
|
||||
torrentRemoveAndWait(tor, 0);
|
||||
|
|
|
@ -256,9 +256,11 @@ TEST_P(SubprocessTest, SpawnAsyncCwdExplicit)
|
|||
|
||||
auto buffer = std::array<char, 1024>{};
|
||||
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size()));
|
||||
EXPECT_EQ(
|
||||
makeString(tr_sys_path_native_separators(tr_strdup(test_dir.c_str()))),
|
||||
tr_sys_path_native_separators(&buffer.front()));
|
||||
auto expected = std::string{ test_dir };
|
||||
tr_sys_path_native_separators(std::data(expected));
|
||||
auto actual = std::string{ std::data(buffer) };
|
||||
tr_sys_path_native_separators(std::data(actual));
|
||||
EXPECT_EQ(expected, actual);
|
||||
|
||||
EXPECT_FALSE(tr_sys_file_read_line(fd, buffer.data(), buffer.size()));
|
||||
|
||||
|
|
|
@ -71,13 +71,6 @@ static void depthFirstWalk(char const* path, file_func_t func)
|
|||
func(path);
|
||||
}
|
||||
|
||||
inline std::string makeString(char*&& s)
|
||||
{
|
||||
auto const ret = std::string(s != nullptr ? s : "");
|
||||
tr_free(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool waitFor(std::function<bool()> const& test, int msec)
|
||||
{
|
||||
auto const deadline = std::chrono::milliseconds{ msec };
|
||||
|
|
|
@ -2447,7 +2447,7 @@ static int processArgs(char const* rpcurl, int argc, char const* const* argv)
|
|||
break;
|
||||
|
||||
case 'n': /* auth */
|
||||
auth = tr_strdup(optarg);
|
||||
auth = tr_strvDup(optarg);
|
||||
break;
|
||||
|
||||
case 810: /* authenv */
|
||||
|
@ -2464,7 +2464,7 @@ static int processArgs(char const* rpcurl, int argc, char const* const* argv)
|
|||
break;
|
||||
|
||||
case 'N': /* netrc */
|
||||
netrc = tr_strdup(optarg);
|
||||
netrc = tr_strvDup(optarg);
|
||||
break;
|
||||
|
||||
case 820: /* UseSSL */
|
||||
|
@ -2543,7 +2543,7 @@ static int processArgs(char const* rpcurl, int argc, char const* const* argv)
|
|||
switch (c)
|
||||
{
|
||||
case 'F':
|
||||
filter = tr_strdup(optarg); /* Unnecessary dup? we will use it before optarg will be changed */
|
||||
filter = tr_strvDup(optarg); /* Unnecessary dup? we will use it before optarg will be changed */
|
||||
tr_variantDictAddInt(top, TR_KEY_tag, TAG_FILTER);
|
||||
|
||||
for (size_t i = 0; i < TR_N_ELEMENTS(details_keys); ++i)
|
||||
|
|
Loading…
Reference in a new issue