refactor: remove tr_snprintf() pt 1 (#2867)

* refactor use fmt instead of tr_snprintf in remote.cc

* refactor use fmt instead of tr_snprintf in daemon.cc

* refactor use fmt instead of tr_snprintf in cli.cc
This commit is contained in:
Charles Kerr 2022-04-02 14:34:29 -05:00 committed by GitHub
parent 1cc9da26ba
commit 392e511f7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 170 additions and 261 deletions

View File

@ -10,6 +10,8 @@
#include <string>
#include <string_view>
#include <fmt/format.h>
#include <libtransmission/transmission.h>
#include <libtransmission/error.h>
@ -96,30 +98,29 @@ static int parseCommandLine(tr_variant*, int argc, char const** argv);
static void sigHandler(int signal);
static char* tr_strlratio(char* buf, double ratio, size_t buflen)
static std::string tr_strlratio(double ratio)
{
if ((int)ratio == TR_RATIO_NA)
if (static_cast<int>(ratio) == TR_RATIO_NA)
{
tr_strlcpy(buf, _("None"), buflen);
}
else if ((int)ratio == TR_RATIO_INF)
{
tr_strlcpy(buf, "Inf", buflen);
}
else if (ratio < 10.0)
{
tr_snprintf(buf, buflen, "%.2f", ratio);
}
else if (ratio < 100.0)
{
tr_snprintf(buf, buflen, "%.1f", ratio);
}
else
{
tr_snprintf(buf, buflen, "%.0f", ratio);
return _("None");
}
return buf;
if (static_cast<int>(ratio) == TR_RATIO_INF)
{
return _("Inf");
}
if (ratio < 10.0)
{
return fmt::format(FMT_STRING("{:.2f}"), ratio);
}
if (ratio < 100.0)
{
return fmt::format(FMT_STRING("{:.1f}"), ratio);
}
return fmt::format(FMT_STRING("{:.0f}"), ratio);
}
static bool waitingOnWeb;
@ -131,56 +132,45 @@ static void onTorrentFileDownloaded(tr_web::FetchResponse const& response)
waitingOnWeb = false;
}
static void getStatusStr(tr_stat const* st, char* buf, size_t buflen)
static std::string getStatusStr(tr_stat const* st)
{
if (st->activity == TR_STATUS_CHECK_WAIT)
{
tr_snprintf(buf, buflen, "Waiting to verify local files");
return "Waiting to verify local files";
}
else if (st->activity == TR_STATUS_CHECK)
if (st->activity == TR_STATUS_CHECK)
{
tr_snprintf(
buf,
buflen,
"Verifying local files (%.2f%%, %.2f%% valid)",
return fmt::format(
FMT_STRING("Verifying local files ({:.2f}%, {:.2f}% valid)"),
tr_truncd(100 * st->recheckProgress, 2),
tr_truncd(100 * st->percentDone, 2));
}
else if (st->activity == TR_STATUS_DOWNLOAD)
{
char ratioStr[80];
tr_strlratio(ratioStr, st->ratio, sizeof(ratioStr));
tr_snprintf(
buf,
buflen,
"Progress: %.1f%%, dl from %d of %d peers (%s), ul to %d (%s) [%s]",
if (st->activity == TR_STATUS_DOWNLOAD)
{
return fmt::format(
FMT_STRING("Progress: {:.1f}%, dl from {:d} of {:d} peers ({:s}), ul to {:d} ({:s}) [{:s}]"),
tr_truncd(100 * st->percentDone, 1),
st->peersSendingToUs,
st->peersConnected,
tr_formatter_speed_KBps(st->pieceDownloadSpeed_KBps).c_str(),
tr_formatter_speed_KBps(st->pieceDownloadSpeed_KBps),
st->peersGettingFromUs,
tr_formatter_speed_KBps(st->pieceUploadSpeed_KBps).c_str(),
ratioStr);
tr_formatter_speed_KBps(st->pieceUploadSpeed_KBps),
tr_strlratio(st->ratio));
}
else if (st->activity == TR_STATUS_SEED)
{
char ratioStr[80];
tr_strlratio(ratioStr, st->ratio, sizeof(ratioStr));
tr_snprintf(
buf,
buflen,
"Seeding, uploading to %d of %d peer(s), %s [%s]",
if (st->activity == TR_STATUS_SEED)
{
return fmt::format(
FMT_STRING("Seeding, uploading to {:d} of {:d} peer(s), {:s} [{:s}]"),
st->peersGettingFromUs,
st->peersConnected,
tr_formatter_speed_KBps(st->pieceUploadSpeed_KBps).c_str(),
ratioStr);
}
else
{
*buf = '\0';
tr_formatter_speed_KBps(st->pieceUploadSpeed_KBps),
tr_strlratio(st->ratio));
}
return "";
}
static char const* getConfigDir(int argc, char const** argv)
@ -319,8 +309,6 @@ int tr_main(int argc, char* argv[])
for (;;)
{
char line[LineWidth];
tr_stat const* st;
static auto constexpr messageName = std::array<char const*, 4>{
nullptr,
"Tracker gave a warning:",
@ -352,15 +340,14 @@ int tr_main(int argc, char* argv[])
}
}
st = tr_torrentStat(tor);
auto const* const st = tr_torrentStat(tor);
if (st->activity == TR_STATUS_STOPPED)
{
break;
}
getStatusStr(st, line, sizeof(line));
printf("\r%-*s", TR_ARG_TUPLE(LineWidth, line));
auto const status_str = getStatusStr(st);
printf("\r%-*s", TR_ARG_TUPLE(LineWidth, status_str.c_str()));
if (messageName[st->error])
{

View File

@ -692,9 +692,12 @@ static int daemon_start(void* varg, [[maybe_unused]] bool foreground)
if (ev_base == nullptr)
{
char buf[256];
tr_snprintf(buf, sizeof(buf), "Couldn't initialize daemon event state: %s", tr_strerror(errno));
printMessage(logfile, TR_LOG_ERROR, MyName, buf, __FILE__, __LINE__);
auto const error_code = errno;
auto const errmsg = fmt::format(
_("Couldn't initialize daemon: {error} ({error_code})"),
fmt::arg("error", tr_strerror(error_code)),
fmt::arg("error_code", error_code));
printMessage(logfile, TR_LOG_ERROR, MyName, errmsg, __FILE__, __LINE__);
return 1;
}

View File

@ -80,38 +80,33 @@ static char constexpr SpeedTStr[] = "TB/s";
****
***/
static void etaToString(char* buf, size_t buflen, int64_t eta)
static std::string etaToString(int64_t eta)
{
if (eta < 0)
{
tr_snprintf(buf, buflen, "Unknown");
return "Unknown";
}
else if (eta < 60)
if (eta < 60)
{
tr_snprintf(buf, buflen, "%" PRId64 " sec", eta);
return fmt::format(FMT_STRING("{:d} sec"), eta);
}
else if (eta < (60 * 60))
if (eta < (60 * 60))
{
tr_snprintf(buf, buflen, "%" PRId64 " min", eta / 60);
return fmt::format(FMT_STRING("{:d} min"), eta / 60);
}
else if (eta < (60 * 60 * 24))
if (eta < (60 * 60 * 24))
{
tr_snprintf(buf, buflen, "%" PRId64 " hrs", eta / (60 * 60));
}
else
{
tr_snprintf(buf, buflen, "%" PRId64 " days", eta / (60 * 60 * 24));
return fmt::format(FMT_STRING("{:d} hrs"), eta / (60 * 60));
}
return fmt::format(FMT_STRING("{:d} days"), eta / (60 * 60 * 24));
}
static char* tr_strltime(char* buf, int seconds, size_t buflen)
static std::string tr_strltime(int seconds)
{
char b[128];
char h[128];
char m[128];
char s[128];
char t[128];
if (seconds < 0)
{
seconds = 0;
@ -123,54 +118,32 @@ static char* tr_strltime(char* buf, int seconds, size_t buflen)
auto const minutes = (seconds % 3600) / 60;
seconds = (seconds % 3600) % 60;
tr_snprintf(h, sizeof(h), "%d %s", hours, hours == 1 ? "hour" : "hours");
tr_snprintf(m, sizeof(m), "%d %s", minutes, minutes == 1 ? "minute" : "minutes");
tr_snprintf(s, sizeof(s), "%d %s", seconds, seconds == 1 ? "second" : "seconds");
tr_snprintf(t, sizeof(t), "%d %s", total_seconds, total_seconds == 1 ? "second" : "seconds");
auto tmpstr = std::string{};
if (days != 0)
{
char d[128];
tr_snprintf(d, sizeof(d), "%d %s", days, days == 1 ? "day" : "days");
auto const hstr = fmt::format(FMT_STRING("{:d} {:s}"), hours, ngettext("hour", "hours", hours));
auto const mstr = fmt::format(FMT_STRING("{:d} {:s}"), minutes, ngettext("minute", "minutes", minutes));
auto const sstr = fmt::format(FMT_STRING("{:d} {:s}"), seconds, ngettext("seconds", "seconds", seconds));
if (days >= 4 || hours == 0)
{
tr_strlcpy(b, d, sizeof(b));
}
else
{
tr_snprintf(b, sizeof(b), "%s, %s", d, h);
}
}
else if (hours != 0)
if (days > 0)
{
if (hours >= 4 || minutes == 0)
{
tr_strlcpy(b, h, sizeof(b));
}
else
{
tr_snprintf(b, sizeof(b), "%s, %s", h, m);
}
auto const dstr = fmt::format(FMT_STRING("{:d} {:s}"), hours, ngettext("day", "days", days));
tmpstr = days >= 4 || hours == 0 ? dstr : fmt::format(FMT_STRING("{:s}, {:s}"), dstr, hstr);
}
else if (minutes != 0)
else if (hours > 0)
{
if (minutes >= 4 || seconds == 0)
{
tr_strlcpy(b, m, sizeof(b));
}
else
{
tr_snprintf(b, sizeof(b), "%s, %s", m, s);
}
tmpstr = hours >= 4 || minutes == 0 ? hstr : fmt::format(FMT_STRING("{:s}, {:s}"), hstr, mstr);
}
else if (minutes > 0)
{
tmpstr = minutes >= 4 || seconds == 0 ? mstr : fmt::format(FMT_STRING("{:s}, {:s}"), mstr, sstr);
}
else
{
tr_strlcpy(b, s, sizeof(b));
tmpstr = sstr;
}
tr_snprintf(buf, buflen, "%s (%s)", b, t);
return buf;
auto const totstr = fmt::format(FMT_STRING("{:d} {:s}"), total_seconds, ngettext("seconds", "seconds", total_seconds));
return fmt::format(FMT_STRING("{:s} ({:s})"), tmpstr, totstr);
}
static std::string strlpercent(double x)
@ -826,99 +799,70 @@ static long getTimeoutSecs(std::string_view req)
return 60L; /* default value */
}
static char* getStatusString(tr_variant* t, char* buf, size_t buflen)
static std::string getStatusString(tr_variant* t)
{
int64_t status;
bool boolVal;
auto from_us = int64_t{};
auto status = int64_t{};
auto to_us = int64_t{};
if (!tr_variantDictFindInt(t, TR_KEY_status, &status))
{
*buf = '\0';
return "";
}
else
switch (status)
{
switch (status)
case TR_STATUS_DOWNLOAD_WAIT:
case TR_STATUS_SEED_WAIT:
return "Queued";
case TR_STATUS_STOPPED:
if (auto flag = bool{}; tr_variantDictFindBool(t, TR_KEY_isFinished, &flag) && flag)
{
case TR_STATUS_DOWNLOAD_WAIT:
case TR_STATUS_SEED_WAIT:
tr_strlcpy(buf, "Queued", buflen);
break;
case TR_STATUS_STOPPED:
if (tr_variantDictFindBool(t, TR_KEY_isFinished, &boolVal) && boolVal)
{
tr_strlcpy(buf, "Finished", buflen);
}
else
{
tr_strlcpy(buf, "Stopped", buflen);
}
break;
case TR_STATUS_CHECK_WAIT:
case TR_STATUS_CHECK:
{
char const* str = status == TR_STATUS_CHECK_WAIT ? "Will Verify" : "Verifying";
double percent;
if (tr_variantDictFindReal(t, TR_KEY_recheckProgress, &percent))
{
tr_snprintf(buf, buflen, "%s (%.0f%%)", str, floor(percent * 100.0));
}
else
{
tr_strlcpy(buf, str, buflen);
}
break;
}
case TR_STATUS_DOWNLOAD:
case TR_STATUS_SEED:
{
int64_t fromUs = 0;
int64_t toUs = 0;
tr_variantDictFindInt(t, TR_KEY_peersGettingFromUs, &fromUs);
tr_variantDictFindInt(t, TR_KEY_peersSendingToUs, &toUs);
if (fromUs != 0 && toUs != 0)
{
tr_strlcpy(buf, "Up & Down", buflen);
}
else if (toUs != 0)
{
tr_strlcpy(buf, "Downloading", buflen);
}
else if (fromUs != 0)
{
int64_t leftUntilDone = 0;
tr_variantDictFindInt(t, TR_KEY_leftUntilDone, &leftUntilDone);
if (leftUntilDone > 0)
{
tr_strlcpy(buf, "Uploading", buflen);
}
else
{
tr_strlcpy(buf, "Seeding", buflen);
}
}
else
{
tr_strlcpy(buf, "Idle", buflen);
}
break;
}
default:
tr_strlcpy(buf, "Unknown", buflen);
break;
return "Finished";
}
}
return "Stopped";
return buf;
case TR_STATUS_CHECK_WAIT:
if (auto percent = double{}; tr_variantDictFindReal(t, TR_KEY_recheckProgress, &percent))
{
return fmt::format(FMT_STRING("Will Verify ({:.0f}%)"), floor(percent * 100.0));
}
return "Will Verify";
case TR_STATUS_CHECK:
if (auto percent = double{}; tr_variantDictFindReal(t, TR_KEY_recheckProgress, &percent))
{
return fmt::format(FMT_STRING("Verifying ({:.0f}%)"), floor(percent * 100.0));
}
return "Verifying";
case TR_STATUS_DOWNLOAD:
case TR_STATUS_SEED:
tr_variantDictFindInt(t, TR_KEY_peersGettingFromUs, &from_us);
tr_variantDictFindInt(t, TR_KEY_peersSendingToUs, &to_us);
if (from_us != 0 && to_us != 0)
{
return "Up & Down";
}
if (to_us != 0)
{
return "Downloading";
}
if (from_us == 0)
{
return "Idle";
}
if (auto left_until_done = int64_t{};
tr_variantDictFindInt(t, TR_KEY_leftUntilDone, &left_until_done) && left_until_done > 0)
{
return "Uploading";
}
return "Seeding";
default:
return "Unknown";
}
}
static char const* bandwidthPriorityNames[] = {
@ -1002,8 +946,7 @@ static void printDetails(tr_variant* top)
printf("\n");
printf("TRANSFER\n");
getStatusString(t, buf, sizeof(buf));
printf(" State: %s\n", buf);
printf(" State: %s\n", getStatusString(t).c_str());
if (tr_variantDictFindStrView(t, TR_KEY_downloadDir, &sv))
{
@ -1017,7 +960,7 @@ static void printDetails(tr_variant* top)
if (tr_variantDictFindInt(t, TR_KEY_eta, &i))
{
printf(" ETA: %s\n", tr_strltime(buf, i, sizeof(buf)));
printf(" ETA: %s\n", tr_strltime(i).c_str());
}
if (tr_variantDictFindInt(t, TR_KEY_rateDownload, &i))
@ -1144,12 +1087,12 @@ static void printDetails(tr_variant* top)
if (tr_variantDictFindInt(t, TR_KEY_secondsDownloading, &i) && i > 0)
{
printf(" Downloading Time: %s\n", tr_strltime(buf, i, sizeof(buf)));
printf(" Downloading Time: %s\n", tr_strltime(i).c_str());
}
if (tr_variantDictFindInt(t, TR_KEY_secondsSeeding, &i) && i > 0)
{
printf(" Seeding Time: %s\n", tr_strltime(buf, i, sizeof(buf)));
printf(" Seeding Time: %s\n", tr_strltime(i).c_str());
}
printf("\n");
@ -1508,50 +1451,25 @@ static void printTorrentList(tr_variant* top)
tr_variantDictFindInt(d, TR_KEY_sizeWhenDone, &sizeWhenDone) &&
tr_variantDictFindInt(d, TR_KEY_status, &status) && tr_variantDictFindReal(d, TR_KEY_uploadRatio, &ratio))
{
char etaStr[16];
char statusStr[64];
char doneStr[8];
int64_t error;
char errorMark;
if (sizeWhenDone != 0)
{
tr_snprintf(doneStr, sizeof(doneStr), "%d%%", (int)(100.0 * (sizeWhenDone - leftUntilDone) / sizeWhenDone));
}
else
{
tr_strlcpy(doneStr, "n/a", sizeof(doneStr));
}
if (leftUntilDone != 0 || eta != -1)
{
etaToString(etaStr, sizeof(etaStr), eta);
}
else
{
tr_snprintf(etaStr, sizeof(etaStr), "Done");
}
if (tr_variantDictFindInt(d, TR_KEY_error, &error) && error)
{
errorMark = '*';
}
else
{
errorMark = ' ';
}
auto const eta_str = leftUntilDone != 0 || eta != -1 ? etaToString(eta) : "Done";
auto const error_mark = tr_variantDictFindInt(d, TR_KEY_error, &error) && error ? '*' : ' ';
auto const done_str = sizeWhenDone != 0 ?
fmt::format(FMT_STRING("{:.0f}%"), (100.0 * (sizeWhenDone - leftUntilDone) / sizeWhenDone)) :
std::string{ "n/a" };
printf(
"%6d%c %4s %9s %-8s %6.1f %6.1f %5s %-11s %" TR_PRIsv "\n",
(int)torId,
errorMark,
doneStr,
error_mark,
done_str.c_str(),
strlsize(sizeWhenDone - leftUntilDone).c_str(),
etaStr,
eta_str.c_str(),
up / (double)tr_speed_K,
down / (double)tr_speed_K,
strlratio2(ratio).c_str(),
getStatusString(d, statusStr, sizeof(statusStr)),
getStatusString(d).c_str(),
TR_PRIsv_ARG(name));
total_up += up;
@ -1570,8 +1488,6 @@ static void printTorrentList(tr_variant* top)
static void printTrackersImpl(tr_variant* trackerStats)
{
char buf[512];
for (size_t i = 0, n = tr_variantListSize(trackerStats); i < n; ++i)
{
tr_variant* const t = tr_variantListChild(trackerStats, i);
@ -1641,11 +1557,11 @@ static void printTrackersImpl(tr_variant* trackerStats)
{
if (hasAnnounced && announceState != TR_TRACKER_INACTIVE)
{
tr_strltime(buf, now - lastAnnounceTime, sizeof(buf));
auto const timestr = tr_strltime(now - lastAnnounceTime);
if (lastAnnounceSucceeded)
{
printf(" Got a list of %d peers %s ago\n", (int)lastAnnouncePeerCount, buf);
printf(" Got a list of %d peers %s ago\n", (int)lastAnnouncePeerCount, timestr.c_str());
}
else if (lastAnnounceTimedOut)
{
@ -1653,7 +1569,7 @@ static void printTrackersImpl(tr_variant* trackerStats)
}
else
{
printf(" Got an error \"%" TR_PRIsv "\" %s ago\n", TR_PRIsv_ARG(lastAnnounceResult), buf);
printf(" Got an error \"%" TR_PRIsv "\" %s ago\n", TR_PRIsv_ARG(lastAnnounceResult), timestr.c_str());
}
}
@ -1664,8 +1580,7 @@ static void printTrackersImpl(tr_variant* trackerStats)
break;
case TR_TRACKER_WAITING:
tr_strltime(buf, nextAnnounceTime - now, sizeof(buf));
printf(" Asking for more peers in %s\n", buf);
printf(" Asking for more peers in %s\n", tr_strltime(nextAnnounceTime - now).c_str());
break;
case TR_TRACKER_QUEUED:
@ -1673,18 +1588,21 @@ static void printTrackersImpl(tr_variant* trackerStats)
break;
case TR_TRACKER_ACTIVE:
tr_strltime(buf, now - lastAnnounceStartTime, sizeof(buf));
printf(" Asking for more peers now... %s\n", buf);
printf(" Asking for more peers now... %s\n", tr_strltime(now - lastAnnounceStartTime).c_str());
break;
}
if (hasScraped)
{
tr_strltime(buf, now - lastScrapeTime, sizeof(buf));
auto const timestr = tr_strltime(now - lastScrapeTime);
if (lastScrapeSucceeded)
{
printf(" Tracker had %d seeders and %d leechers %s ago\n", (int)seederCount, (int)leecherCount, buf);
printf(
" Tracker had %d seeders and %d leechers %s ago\n",
(int)seederCount,
(int)leecherCount,
timestr.c_str());
}
else if (lastScrapeTimedOut)
{
@ -1692,7 +1610,10 @@ static void printTrackersImpl(tr_variant* trackerStats)
}
else
{
printf(" Got a scrape error \"%" TR_PRIsv "\" %s ago\n", TR_PRIsv_ARG(lastScrapeResult), buf);
printf(
" Got a scrape error \"%" TR_PRIsv "\" %s ago\n",
TR_PRIsv_ARG(lastScrapeResult),
timestr.c_str());
}
}
@ -1702,8 +1623,7 @@ static void printTrackersImpl(tr_variant* trackerStats)
break;
case TR_TRACKER_WAITING:
tr_strltime(buf, nextScrapeTime - now, sizeof(buf));
printf(" Asking for peer counts in %s\n", buf);
printf(" Asking for peer counts in %s\n", tr_strltime(nextScrapeTime - now).c_str());
break;
case TR_TRACKER_QUEUED:
@ -1711,8 +1631,7 @@ static void printTrackersImpl(tr_variant* trackerStats)
break;
case TR_TRACKER_ACTIVE:
tr_strltime(buf, now - lastScrapeStartTime, sizeof(buf));
printf(" Asking for peer counts now... %s\n", buf);
printf(" Asking for peer counts now... %s\n", tr_strltime(now - lastScrapeStartTime).c_str());
break;
}
}
@ -1982,7 +1901,6 @@ static void printSessionStats(tr_variant* top)
if (tr_variantDictFindDict(top, TR_KEY_arguments, &args))
{
char buf[512];
int64_t up;
int64_t down;
int64_t secs;
@ -1995,7 +1913,7 @@ static void printSessionStats(tr_variant* top)
printf(" Uploaded: %s\n", strlsize(up).c_str());
printf(" Downloaded: %s\n", strlsize(down).c_str());
printf(" Ratio: %s\n", strlratio(up, down).c_str());
printf(" Duration: %s\n", tr_strltime(buf, secs, sizeof(buf)));
printf(" Duration: %s\n", tr_strltime(secs).c_str());
}
if (tr_variantDictFindDict(args, TR_KEY_cumulative_stats, &d) &&
@ -2007,7 +1925,7 @@ static void printSessionStats(tr_variant* top)
printf(" Uploaded: %s\n", strlsize(up).c_str());
printf(" Downloaded: %s\n", strlsize(down).c_str());
printf(" Ratio: %s\n", strlratio(up, down).c_str());
printf(" Duration: %s\n", tr_strltime(buf, secs, sizeof(buf)));
printf(" Duration: %s\n", tr_strltime(secs).c_str());
}
}
}
@ -2132,7 +2050,8 @@ static int processResponse(char const* rpcurl, std::string_view response)
if (tr_variantDictFindDict(&top, Arguments, &b) &&
tr_variantDictFindDict(b, TR_KEY_torrent_added, &b) && tr_variantDictFindInt(b, TR_KEY_id, &i))
{
tr_snprintf(id, sizeof(id), "%" PRId64, i);
auto const [out, len] = fmt::format_to_n(id, sizeof(id) - 1, FMT_STRING("{:d}"), i);
*out = '\0';
}
[[fallthrough]];
}