diff --git a/build/libaegisub/libaegisub.vcxproj b/build/libaegisub/libaegisub.vcxproj
index d688c5161..a778d8d15 100644
--- a/build/libaegisub/libaegisub.vcxproj
+++ b/build/libaegisub/libaegisub.vcxproj
@@ -54,6 +54,7 @@
+
@@ -104,6 +105,7 @@
+
diff --git a/build/libaegisub/libaegisub.vcxproj.filters b/build/libaegisub/libaegisub.vcxproj.filters
index 9608b93dd..71d5059d4 100644
--- a/build/libaegisub/libaegisub.vcxproj.filters
+++ b/build/libaegisub/libaegisub.vcxproj.filters
@@ -170,6 +170,9 @@
Header Files
+
+ Header Files
+
Header Files
diff --git a/libaegisub/common/color.cpp b/libaegisub/common/color.cpp
index 387b27a93..7381e92ff 100644
--- a/libaegisub/common/color.cpp
+++ b/libaegisub/common/color.cpp
@@ -16,7 +16,7 @@
#include "parser.h"
-#include
+#include "libaegisub/format.h"
namespace agi {
@@ -29,11 +29,11 @@ Color::Color(std::string const& str) {
}
std::string Color::GetAssStyleFormatted() const {
- return str(boost::format("&H%02X%02X%02X%02X") % (int)a % (int)b % (int)g % (int)r);
+ return agi::format("&H%02X%02X%02X%02X", a, b, g, r);
}
std::string Color::GetAssOverrideFormatted() const {
- return str(boost::format("&H%02X%02X%02X&") % (int)b % (int)g % (int)r);
+ return agi::format("&H%02X%02X%02X&", b, g, r);
}
std::string Color::GetSsaFormatted() const {
@@ -42,12 +42,12 @@ std::string Color::GetSsaFormatted() const {
std::string Color::GetHexFormatted(bool rgba) const {
if (rgba)
- return str(boost::format("#%02X%02X%02X%02X") % (int)r % (int)g % (int)b % (int)a);
- return str(boost::format("#%02X%02X%02X") % (int)r % (int)g % (int)b);
+ return agi::format("#%02X%02X%02X%02X", r, g, b, a);
+ return agi::format("#%02X%02X%02X", r, g, b);
}
std::string Color::GetRgbFormatted() const {
- return str(boost::format("rgb(%d, %d, %d)") % (int)r % (int)g % (int)b);
+ return agi::format("rgb(%d, %d, %d)", r, g, b);
}
bool Color::operator==(Color const& col) const {
diff --git a/libaegisub/include/libaegisub/format.h b/libaegisub/include/libaegisub/format.h
new file mode 100644
index 000000000..bda534f2a
--- /dev/null
+++ b/libaegisub/include/libaegisub/format.h
@@ -0,0 +1,324 @@
+// Copyright (c) 2014, Thomas Goyne
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+// Aegisub Project http://www.aegisub.org/
+
+#include
+#include
+#include
+#include
+
+namespace agi { namespace format_detail {
+// A static cast which throws at runtime if the cast is invalid rather than
+// failing to compile, as with format strings we don't know what type to cast
+// to at compile time.
+template::value>
+struct runtime_cast_helper {
+ static Out cast(In const&) { throw std::bad_cast(); }
+};
+
+template
+struct runtime_cast_helper {
+ static Out cast(In const& value) {
+ return static_cast(value);
+ }
+};
+
+template
+Out runtime_cast(In const& value) {
+ return runtime_cast_helper::cast(value);
+}
+
+template
+void write_string(std::ostream& out, int, T const& value) {
+ out << value;
+}
+
+// Check length for string types
+inline void write_string(std::ostream& out, int max_len, const char *value) {
+ if (max_len <= 0)
+ out << value;
+ else {
+ std::streamsize len = 0;
+ for (; len < max_len && value[len]; ++len) ;
+ out.write(value, len);
+ }
+}
+
+inline void write_string(std::ostream& out, int max_len, std::string const& value) {
+ if (max_len > 0 && static_cast(max_len) < value.size())
+ out.write(value.data(), max_len);
+ else
+ out << value;
+}
+
+class formatter {
+ formatter(const formatter&) = delete;
+ formatter& operator=(const formatter&) = delete;
+
+ std::ostream& out;
+ const char *fmt;
+ const char *fmt_cur = nullptr;
+
+ bool read_width = false;
+ bool read_precision = false;
+ bool pending = false;
+
+ int width = 0;
+ int precision = 0;
+
+ boost::io::ios_all_saver saver;
+
+ void read_and_append_up_to_next_specifier() {
+ for (std::streamsize len = 0; ; ++len) {
+ // Ran out of format specifiers; not an error due to that
+ // translated strings may not need them all
+ if (!fmt[len]) {
+ out.write(fmt, len);
+ fmt += len;
+ return;
+ }
+
+ if (fmt[len] == '%') {
+ if (fmt[len + 1] == '%') {
+ out.write(fmt, len);
+ fmt += len + 1;
+ len = 0;
+ continue;
+ }
+
+ out.write(fmt, len);
+ fmt += len;
+ break;
+ }
+ }
+ }
+
+ int read_int() {
+ int i = 0;
+ for (; *fmt_cur >= '0' && *fmt_cur <= '9'; ++fmt_cur)
+ i = 10 * i + (*fmt_cur - '0');
+ return i;
+ }
+
+ void parse_flags() {
+ for (; ; ++fmt_cur) {
+ switch (*fmt_cur) {
+ // Not supported: ' ' (add a space before positive numers to align with negative)
+ case '#':
+ out.setf(std::ios::showpoint | std::ios::showbase);
+ continue;
+ case '0':
+ // overridden by left alignment ('-' flag)
+ if (!(out.flags() & std::ios::left)) {
+ // Use internal padding so that numeric values are
+ // formatted correctly, eg -00010 rather than 000-10
+ out.fill('0');
+ out.setf(std::ios::internal, std::ios::adjustfield);
+ }
+ continue;
+ case '-':
+ out.fill(' ');
+ out.setf(std::ios::left, std::ios::adjustfield);
+ continue;
+ case '+':
+ out.setf(std::ios::showpos);
+ continue;
+ }
+ break;
+ }
+ }
+
+ void parse_width() {
+ if (*fmt_cur >= '0' && *fmt_cur <= '9')
+ width = read_int();
+ else if (*fmt_cur == '*') {
+ read_width = true;
+ pending = true;
+ ++fmt_cur;
+ }
+ }
+
+ void parse_precision() {
+ if (*fmt_cur != '.') return;
+ ++fmt_cur;
+
+ // Ignoring negative precision because it's dumb and pointless
+ if (*fmt_cur >= '0' && *fmt_cur <= '9')
+ precision = read_int();
+ else if (*fmt_cur == '*') {
+ read_precision = true;
+ pending = true;
+ ++fmt_cur;
+ }
+ else
+ precision = 0;
+ }
+
+ void parse_length_modifiers() {
+ // Where "parse" means "skip" since we don't need them
+ for (char c = *fmt_cur;
+ c == 'l' || c == 'h' || c == 'L' || c == 'j' || c == 'z' || c == 't';
+ c = *++fmt_cur);
+ }
+
+ void parse_format_specifier() {
+ width = 0;
+ precision = -1;
+ out.fill(' ');
+ out.unsetf(
+ std::ios::adjustfield |
+ std::ios::basefield |
+ std::ios::boolalpha |
+ std::ios::floatfield |
+ std::ios::showbase |
+ std::ios::showpoint |
+ std::ios::showpos |
+ std::ios::uppercase);
+
+ // Don't touch fmt until the specifier is fully applied so that if we
+ // have insufficient arguments it'll get passed through to the output
+ fmt_cur = fmt + 1;
+
+ parse_flags();
+ parse_width();
+ parse_precision();
+ parse_length_modifiers();
+ }
+
+public:
+ formatter(std::ostream& out, const char *fmt) : out(out), fmt(fmt), saver(out) { }
+ ~formatter() {
+ // Write remaining formatting string
+ for (std::streamsize len = 0; ; ++len) {
+ if (!fmt[len]) {
+ out.write(fmt, len);
+ return;
+ }
+
+ if (fmt[len] == '%' && fmt[len + 1] == '%') {
+ out.write(fmt, len);
+ fmt += len + 1;
+ len = 0;
+ continue;
+ }
+ }
+ }
+
+ template
+ void operator()(T&& value) {
+ if (!pending) {
+ read_and_append_up_to_next_specifier();
+ if (!*fmt) return;
+ parse_format_specifier();
+ }
+
+ if (read_width) {
+ width = runtime_cast(value);
+ read_width = false;
+ return;
+ }
+
+ if (read_precision) {
+ precision = runtime_cast(value);
+ read_precision = false;
+ return;
+ }
+ pending = false;
+
+ if (width < 0) {
+ out.fill(' ');
+ out.setf(std::ios::left, std::ios::adjustfield);
+ width = -width;
+ }
+ out.width(width);
+ out.precision(precision < 0 ? 6 : precision);
+
+ char c = *fmt_cur ? fmt_cur[0] : 's';
+ if (c >= 'A' && c <= 'Z') {
+ out.setf(std::ios::uppercase);
+ c += 'a' - 'A';
+ }
+
+ switch (c) {
+ case 'c':
+ out.setf(std::ios::dec, std::ios::basefield);
+ out << runtime_cast(value);
+ break;
+ case 'd': case 'i':
+ out.setf(std::ios::dec, std::ios::basefield);
+ out << runtime_cast(value);
+ break;
+ case 'o':
+ out.setf(std::ios::oct, std::ios::basefield);
+ out << runtime_cast(value);
+ break;
+ case 'x':
+ out.setf(std::ios::hex, std::ios::basefield);
+ out << runtime_cast(value);
+ break;
+ case 'u':
+ out.setf(std::ios::dec, std::ios::basefield);
+ out << runtime_cast(value);
+ break;
+ case 'e':
+ out.setf(std::ios::scientific, std::ios::floatfield);
+ out.setf(std::ios::dec, std::ios::basefield);
+ out << runtime_cast(value);
+ break;
+ case 'f':
+ out.setf(std::ios::fixed, std::ios::floatfield);
+ out << runtime_cast(value);
+ break;
+ case 'g':
+ out.setf(std::ios::dec, std::ios::basefield);
+ out.flags(out.flags() & ~std::ios::floatfield);
+ out << runtime_cast(value);
+ break;
+ case 'p':
+ out.setf(std::ios::hex, std::ios::basefield);
+ out << runtime_cast(value);
+ break;
+ default: // s and other
+ out.setf(std::ios::boolalpha);
+ write_string(out, precision, value);
+ break;
+ }
+
+ fmt = *fmt_cur ? fmt_cur + 1 : fmt_cur;
+ }
+};
+
+// Base case for variadic template recursion
+inline void format(formatter&&) { }
+
+template
+void format(formatter&& fmt, T&& first, Args&&... rest) {
+ fmt(first);
+ format(std::move(fmt), std::forward(rest)...);
+}
+} // namespace format_detail
+
+template
+void format(std::ostream& out, const char *fmt, Args&&... args) {
+ format(format_detail::formatter(out, fmt), std::forward(args)...);
+}
+
+template
+std::string format(const char *fmt, Args&&... args) {
+ boost::interprocess::basic_vectorstream out;
+ format(out, fmt, std::forward(args)...);
+ return out.vector();
+}
+}
diff --git a/libaegisub/lua/utils.cpp b/libaegisub/lua/utils.cpp
index cab65aef8..8a5770e3d 100644
--- a/libaegisub/lua/utils.cpp
+++ b/libaegisub/lua/utils.cpp
@@ -16,11 +16,11 @@
#include "libaegisub/lua/utils.h"
+#include "libaegisub/format.h"
#include "libaegisub/log.h"
#include
#include
-#include
#include
#include
@@ -170,9 +170,9 @@ int add_stack_trace(lua_State *L) {
else if (*ar.what == 'C')
function = '?';
else if (!*ar.namewhat)
- function = str(boost::format("") % real_line(ar.linedefined) % real_line(ar.lastlinedefined - 1));
+ function = agi::format("", real_line(ar.linedefined), real_line(ar.lastlinedefined - 1));
- frames.emplace_back(str(boost::format(" File \"%s\", line %d\n%s") % file % real_line(ar.currentline) % function));
+ frames.emplace_back(agi::format(" File \"%s\", line %d\n%s", file, real_line(ar.currentline), function));
}
}
diff --git a/libaegisub/windows/access.cpp b/libaegisub/windows/access.cpp
index 01d0df643..d817ef553 100644
--- a/libaegisub/windows/access.cpp
+++ b/libaegisub/windows/access.cpp
@@ -18,12 +18,13 @@
#include
+#include
+#include
#include
#include
#include
#include
-#include
#include
@@ -63,7 +64,7 @@ void Check(fs::path const& file, acs::Type type) {
case ERROR_ACCESS_DENIED:
throw fs::ReadDenied(file);
default:
- throw fs::FileSystemUnknownError(str(boost::format("Unexpected error when getting attributes for \"%s\": %s") % file % util::ErrorString(GetLastError())));
+ throw fs::FileSystemUnknownError(agi::format("Unexpected error when getting attributes for \"%s\": %s", file, util::ErrorString(GetLastError())));
}
}
diff --git a/src/ass_export_filter.cpp b/src/ass_export_filter.cpp
index 65ee02715..4f092d351 100644
--- a/src/ass_export_filter.cpp
+++ b/src/ass_export_filter.cpp
@@ -34,7 +34,7 @@
#include "ass_export_filter.h"
-#include
+#include
static FilterList& filters() {
static FilterList instance;
@@ -53,7 +53,7 @@ void AssExportFilterChain::Register(std::unique_ptr filter) {
std::string name = filter->name;
// Find a unique name
while (GetFilter(name))
- name = str(boost::format("%s (%d)") % filter->name % filter_copy++);
+ name = agi::format("%s (%d)", filter->name, filter_copy++);
filter->name = name;
diff --git a/src/ass_karaoke.cpp b/src/ass_karaoke.cpp
index 7d9c100f0..fab0621ca 100644
--- a/src/ass_karaoke.cpp
+++ b/src/ass_karaoke.cpp
@@ -18,7 +18,8 @@
#include "ass_dialogue.h"
-#include
+#include
+
#include
#include
@@ -26,7 +27,7 @@ std::string AssKaraoke::Syllable::GetText(bool k_tag) const {
std::string ret;
if (k_tag)
- ret = str(boost::format("{%s%d}") % tag_type % ((duration + 5) / 10));
+ ret = agi::format("{%s%d}", tag_type, ((duration + 5) / 10));
size_t idx = 0;
for (auto const& ovr : ovr_tags) {
diff --git a/src/ass_override.cpp b/src/ass_override.cpp
index 2491ff6c7..abcca5531 100644
--- a/src/ass_override.cpp
+++ b/src/ass_override.cpp
@@ -38,12 +38,12 @@
#include "utils.h"
#include
+#include
#include
#include
#include
#include
-#include
#include
#include
#include
@@ -128,7 +128,7 @@ template<> void AssOverrideParameter::Set(std::string new_value) {
template<> void AssOverrideParameter::Set(int new_value) {
if (classification == AssParameterClass::ALPHA)
- Set(str(boost::format("&H%02X&") % mid(0, new_value, 255)));
+ Set(agi::format("&H%02X&", mid(0, new_value, 255)));
else
Set(std::to_string(new_value));
}
diff --git a/src/ass_style.cpp b/src/ass_style.cpp
index 0fd93413b..901ddbeab 100644
--- a/src/ass_style.cpp
+++ b/src/ass_style.cpp
@@ -37,10 +37,10 @@
#include "subtitle_format.h"
#include "utils.h"
+#include
#include
#include
-#include
#include
#include
@@ -175,17 +175,17 @@ void AssStyle::UpdateData() {
replace(name.begin(), name.end(), ',', ';');
replace(font.begin(), font.end(), ',', ';');
- data = str(boost::format("Style: %s,%s,%g,%s,%s,%s,%s,%d,%d,%d,%d,%g,%g,%g,%g,%d,%g,%g,%i,%i,%i,%i,%i")
- % name % font % fontsize
- % primary.GetAssStyleFormatted()
- % secondary.GetAssStyleFormatted()
- % outline.GetAssStyleFormatted()
- % shadow.GetAssStyleFormatted()
- % (bold? -1 : 0) % (italic ? -1 : 0)
- % (underline ? -1 : 0) % (strikeout ? -1 : 0)
- % scalex % scaley % spacing % angle
- % borderstyle % outline_w % shadow_w % alignment
- % Margin[0] % Margin[1] % Margin[2] % encoding);
+ data = agi::format("Style: %s,%s,%g,%s,%s,%s,%s,%d,%d,%d,%d,%g,%g,%g,%g,%d,%g,%g,%i,%i,%i,%i,%i",
+ name, font, fontsize,
+ primary.GetAssStyleFormatted(),
+ secondary.GetAssStyleFormatted(),
+ outline.GetAssStyleFormatted(),
+ shadow.GetAssStyleFormatted(),
+ (bold? -1 : 0), (italic ? -1 : 0),
+ (underline ? -1 : 0), (strikeout ? -1 : 0),
+ scalex, scaley, spacing, angle,
+ borderstyle, outline_w, shadow_w, alignment,
+ Margin[0], Margin[1], Margin[2], encoding);
}
void AssStyle::GetEncodings(wxArrayString &encodingStrings) {
diff --git a/src/ass_time.cpp b/src/ass_time.cpp
index 070bbd5eb..585fa7cf7 100644
--- a/src/ass_time.cpp
+++ b/src/ass_time.cpp
@@ -23,12 +23,12 @@
#include "utils.h"
+#include
#include
#include
#include
#include
-#include
#include
AssTime::AssTime(int time) : time(mid(0, time, 10 * 60 * 60 * 1000 - 1)) { }
@@ -94,7 +94,7 @@ SmpteFormatter::SmpteFormatter(agi::vfr::Framerate fps, std::string sep)
std::string SmpteFormatter::ToSMPTE(AssTime time) const {
int h=0, m=0, s=0, f=0;
fps.SmpteAtTime(time, &h, &m, &s, &f);
- return str(boost::format("%02d%s%02d%s%02d%c%02d") % h % sep % m % sep % s % sep % f);
+ return agi::format("%02d%s%02d%s%02d%c%02d", h, sep, m, sep, s, sep, f);
}
AssTime SmpteFormatter::FromSMPTE(std::string const& str) const {
diff --git a/src/audio_provider_hd.cpp b/src/audio_provider_hd.cpp
index 2ad845b01..bc191af82 100644
--- a/src/audio_provider_hd.cpp
+++ b/src/audio_provider_hd.cpp
@@ -20,12 +20,12 @@
#include "options.h"
#include
+#include
#include
#include
#include
#include
-#include
#include
#include
@@ -64,9 +64,8 @@ public:
if ((uint64_t)num_samples * bytes_per_sample > agi::fs::FreeSpace(cache_dir))
throw agi::AudioCacheOpenError("Not enough free disk space in " + cache_dir.string() + " to cache the audio", nullptr);
- auto filename = str(boost::format("audio-%lld-%lld")
- % (long long)time(nullptr)
- % (long long)boost::interprocess::ipcdetail::get_current_process_id());
+ auto filename = agi::format("audio-%lld-%lld", time(nullptr),
+ boost::interprocess::ipcdetail::get_current_process_id());
file = agi::make_unique(cache_dir / filename, num_samples * bytes_per_sample);
decoder = std::thread([&] {
diff --git a/src/auto4_base.cpp b/src/auto4_base.cpp
index f113a544e..f2af62ba7 100644
--- a/src/auto4_base.cpp
+++ b/src/auto4_base.cpp
@@ -39,13 +39,13 @@
#include "subs_controller.h"
#include
+#include
#include
#include
#include
#include
#include
-#include
#include
#include
@@ -490,7 +490,7 @@ namespace Automation4 {
std::string filter(fact->GetFilenamePattern());
boost::replace_all(filter, ",", ";");
- fnfilter += str(boost::format("%s scripts (%s)|%s|") % fact->GetEngineName() % fact->GetFilenamePattern() % filter);
+ fnfilter += agi::format("%s scripts (%s)|%s|", fact->GetEngineName(), fact->GetFilenamePattern(), filter);
catchall += filter + ";";
}
fnfilter += from_wx(_("All Files")) + " (*.*)|*.*";
diff --git a/src/auto4_lua.cpp b/src/auto4_lua.cpp
index 4ee7dae6f..2d3569963 100644
--- a/src/auto4_lua.cpp
+++ b/src/auto4_lua.cpp
@@ -50,17 +50,17 @@
#include "video_controller.h"
#include "utils.h"
+#include
#include
#include
#include
-#include
#include
+#include
#include
#include
#include
#include
-#include
#include
#include
#include
@@ -475,7 +475,7 @@ namespace {
// don't thread this, as there's no point in it and it seems to break on wx 2.8.3, for some reason
if (lua_pcall(L, 0, 0, 0)) {
// error occurred, assumed to be on top of Lua stack
- description = str(boost::format("Error initialising Lua script \"%s\":\n\n%s") % GetPrettyFilename().string() % get_string_or_default(L, -1));
+ description = agi::format("Error initialising Lua script \"%s\":\n\n%s", GetPrettyFilename().string(), get_string_or_default(L, -1));
lua_pop(L, 1);
return;
}
@@ -655,7 +655,7 @@ namespace {
, cmd_type(cmd::COMMAND_NORMAL)
{
lua_getfield(L, LUA_REGISTRYINDEX, "filename");
- cmd_name = str(boost::format("automation/lua/%s/%s") % check_string(L, -1) % check_string(L, 1));
+ cmd_name = agi::format("automation/lua/%s/%s", check_string(L, -1), check_string(L, 1));
if (!lua_isfunction(L, 3))
error(L, "The macro processing function must be a function");
diff --git a/src/command/edit.cpp b/src/command/edit.cpp
index 288a2dfd7..196cc79d3 100644
--- a/src/command/edit.cpp
+++ b/src/command/edit.cpp
@@ -50,12 +50,12 @@
#include "../video_controller.h"
#include
+#include
#include
#include
#include
#include
-#include
#include
#include
#include
@@ -358,7 +358,7 @@ void show_color_picker(const agi::Context *c, agi::Color (AssStyle::*field), con
for (auto& line : lines) {
int shift = line.second.set_tag(tag, new_color.GetAssOverrideFormatted(), norm_sel_start, sel_start);
if (new_color.a != line.first.a) {
- shift += line.second.set_tag(alpha, str(boost::format("&H%02X&") % (int)new_color.a), norm_sel_start, sel_start + shift);
+ shift += line.second.set_tag(alpha, agi::format("&H%02X&", (int)new_color.a), norm_sel_start, sel_start + shift);
line.first.a = new_color.a;
}
diff --git a/src/command/video.cpp b/src/command/video.cpp
index 49e4b2be0..115aa6c86 100644
--- a/src/command/video.cpp
+++ b/src/command/video.cpp
@@ -50,6 +50,7 @@
#include "../video_display.h"
#include "../video_frame.h"
+#include
#include
#include
#include
@@ -58,7 +59,6 @@
#include
#include
#include
-#include
#include
#include
@@ -487,7 +487,7 @@ static void save_snapshot(agi::Context *c, bool raw) {
int session_shot_count = 1;
std::string path;
do {
- path = str(boost::format("%s_%03d_%d.png") % basepath.string() % session_shot_count++ % c->videoController->GetFrameN());
+ path = agi::format("%s_%03d_%d.png", basepath.string(), session_shot_count++, c->videoController->GetFrameN());
} while (agi::fs::FileExists(path));
get_image(c, raw).SaveFile(to_wx(path), wxBITMAP_TYPE_PNG);
diff --git a/src/crash_writer.cpp b/src/crash_writer.cpp
index 336301f70..ab521be5f 100644
--- a/src/crash_writer.cpp
+++ b/src/crash_writer.cpp
@@ -18,10 +18,10 @@
#include "version.h"
+#include
#include
#include
-#include
#include
#include
@@ -41,8 +41,8 @@ public:
if (!fp.good()) return;
fp << util::strftime("--- %y-%m-%d %H:%M:%S ------------------\n");
- fp << boost::format("VER - %s\n") % GetAegisubLongVersionString();
- fp << boost::format("FTL - Beginning stack dump for \"%s\": \n") % cause;
+ fp << agi::format("VER - %s\n", GetAegisubLongVersionString());
+ fp << agi::format("FTL - Beginning stack dump for \"%s\": \n", cause);
}
~StackWalker() {
@@ -55,9 +55,9 @@ public:
void OnStackFrame(wxStackFrame const& frame) override final {
if (!fp.good()) return;
- fp << boost::format("%03u - %p: %s") % frame.GetLevel() % frame.GetAddress() % frame.GetName().utf8_str().data();
+ fp << agi::format("%03u - %p: %s", frame.GetLevel(), frame.GetAddress(), frame.GetName().utf8_str().data());
if (frame.HasSourceLocation())
- fp << boost::format(" on %s:%u") % frame.GetFileName().utf8_str().data() % frame.GetLine();
+ fp << agi::format(" on %s:%u", frame.GetFileName().utf8_str().data(), frame.GetLine());
fp << "\n";
}
@@ -83,8 +83,8 @@ void Write(std::string const& error) {
boost::filesystem::ofstream file(crashlog_path, std::ios::app);
if (file.is_open()) {
file << util::strftime("--- %y-%m-%d %H:%M:%S ------------------\n");
- file << boost::format("VER - %s\n") % GetAegisubLongVersionString();
- file << boost::format("EXC - Aegisub has crashed with unhandled exception \"%s\".\n") % error;
+ file << agi::format("VER - %s\n", GetAegisubLongVersionString());
+ file << agi::format("EXC - Aegisub has crashed with unhandled exception \"%s\".\n", error);
file << "----------------------------------------\n\n";
file.close();
}
diff --git a/src/crash_writer_minidump.cpp b/src/crash_writer_minidump.cpp
index 526df912f..5481273cd 100644
--- a/src/crash_writer_minidump.cpp
+++ b/src/crash_writer_minidump.cpp
@@ -18,13 +18,13 @@
#include "version.h"
+#include
#include
#include
#include
#include
#include
-#include
#include
#include
#include
@@ -143,10 +143,9 @@ void Write(std::string const& error) {
boost::filesystem::ofstream file(crashlog_path, std::ios::app);
if (file.is_open()) {
file << agi::util::strftime("--- %y-%m-%d %H:%M:%S ------------------\n");
- file << boost::format("VER - %s\n") % GetAegisubLongVersionString();
- file << boost::format("EXC - Aegisub has crashed with unhandled exception \"%s\".\n") % error;
+ agi::format(file, "VER - %s\n", GetAegisubLongVersionString());
+ agi::format(file, "EXC - Aegisub has crashed with unhandled exception \"%s\".\n", error);
file << "----------------------------------------\n\n";
- file.close();
}
}
}
diff --git a/src/dialog_version_check.cpp b/src/dialog_version_check.cpp
index 3339d4d37..8aef014f0 100644
--- a/src/dialog_version_check.cpp
+++ b/src/dialog_version_check.cpp
@@ -40,6 +40,7 @@
#include
#include
+#include
#include
#include
@@ -47,7 +48,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -287,21 +287,20 @@ void DoCheck(bool interactive) {
if (!stream)
throw VersionCheckError(from_wx(_("Could not connect to updates server.")));
- stream << boost::format(
+ stream << agi::format(
"GET %s?rev=%d&rel=%d&os=%s&lang=%s&aegilang=%s HTTP/1.0\r\n"
"User-Agent: Aegisub %s\r\n"
"Host: %s\r\n"
"Accept: */*\r\n"
- "Connection: close\r\n\r\n")
- % UPDATE_CHECKER_BASE_URL
- % GetSVNRevision()
- % (GetIsOfficialRelease() ? 1 : 0)
- % GetOSShortName()
- % GetSystemLanguage()
- % GetAegisubLanguage()
- % GetAegisubLongVersionString()
- % UPDATE_CHECKER_SERVER
- ;
+ "Connection: close\r\n\r\n"
+ , UPDATE_CHECKER_BASE_URL
+ , GetSVNRevision()
+ , (GetIsOfficialRelease() ? 1 : 0)
+ , GetOSShortName()
+ , GetSystemLanguage()
+ , GetAegisubLanguage()
+ , GetAegisubLongVersionString()
+ , UPDATE_CHECKER_SERVER);
std::string http_version;
stream >> http_version;
diff --git a/src/main.cpp b/src/main.cpp
index 4ee7b3ede..357f2eb30 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -55,6 +55,7 @@
#include "version.h"
#include
+#include
#include
#include
#include
@@ -62,7 +63,6 @@
#include
#include
-#include
#include
#include
#include
@@ -378,7 +378,7 @@ static void UnhandledExeception(bool stackWalk, agi::Context *c) {
agi::fs::CreateDirectory(path);
auto filename = c->subsController->Filename().stem();
- filename.replace_extension(str(boost::format("%s.ass") % agi::util::strftime("%Y-%m-%d-%H-%M-%S")));
+ filename.replace_extension(agi::format("%s.ass", agi::util::strftime("%Y-%m-%d-%H-%M-%S")));
path /= filename;
c->subsController->Save(path);
diff --git a/src/mkv_wrap.cpp b/src/mkv_wrap.cpp
index 1fa1cfab7..78aee3f6d 100644
--- a/src/mkv_wrap.cpp
+++ b/src/mkv_wrap.cpp
@@ -42,11 +42,11 @@
#include "MatroskaParser.h"
#include
+#include
#include
#include
#include
-#include
#include
#include
#include
@@ -143,18 +143,18 @@ static void read_subtitles(agi::ProgressSink *ps, MatroskaFile *file, MkvStdIO *
subList.emplace_back(
boost::lexical_cast(str_range(readBuf, first)),
- str(boost::format("Dialogue: %d,%s,%s,%s")
- % boost::lexical_cast(str_range(first + 1, second))
- % subStart.GetAssFormated()
- % subEnd.GetAssFormated()
- % str_range(second + 1, readBufEnd)));
+ agi::format("Dialogue: %d,%s,%s,%s"
+ , boost::lexical_cast(str_range(first + 1, second))
+ , subStart.GetAssFormated()
+ , subEnd.GetAssFormated()
+ , str_range(second + 1, readBufEnd)));
}
// Process SRT
else {
- auto line = str(boost::format("Dialogue: 0,%s,%s,Default,,0,0,0,,%s")
- % subStart.GetAssFormated()
- % subEnd.GetAssFormated()
- % str_range(readBuf, readBufEnd));
+ auto line = agi::format("Dialogue: 0,%s,%s,Default,,0,0,0,,%s"
+ , subStart.GetAssFormated()
+ , subEnd.GetAssFormated()
+ , str_range(readBuf, readBufEnd));
boost::replace_all(line, "\r\n", "\\N");
boost::replace_all(line, "\r", "\\N");
boost::replace_all(line, "\n", "\\N");
@@ -191,7 +191,7 @@ void MatroskaWrapper::GetSubtitles(agi::fs::path const& filename, AssFile *targe
std::string CodecID(trackInfo->CodecID);
if (CodecID == "S_TEXT/SSA" || CodecID == "S_TEXT/ASS" || CodecID == "S_TEXT/UTF8") {
tracksFound.push_back(track);
- tracksNames.emplace_back(str(boost::format("%d (%s %s)") % track % CodecID % trackInfo->Language));
+ tracksNames.emplace_back(agi::format("%d (%s %s)", track, CodecID, trackInfo->Language));
if (trackInfo->Name) {
tracksNames.back() += ": ";
tracksNames.back() += trackInfo->Name;
diff --git a/src/spellchecker_hunspell.cpp b/src/spellchecker_hunspell.cpp
index 17000db49..53ee66f84 100644
--- a/src/spellchecker_hunspell.cpp
+++ b/src/spellchecker_hunspell.cpp
@@ -24,6 +24,7 @@
#include "options.h"
#include
+#include
#include
#include
#include
@@ -31,7 +32,6 @@
#include
#include
-#include
#include
#include
@@ -177,8 +177,8 @@ std::vector HunspellSpellChecker::GetLanguageList() {
}
static bool check_path(agi::fs::path const& path, std::string const& language, agi::fs::path& aff, agi::fs::path& dic) {
- aff = path/str(boost::format("%s.aff") % language);
- dic = path/str(boost::format("%s.dic") % language);
+ aff = path/agi::format("%s.aff", language);
+ dic = path/agi::format("%s.dic", language);
return agi::fs::FileExists(aff) && agi::fs::FileExists(dic);
}
@@ -204,7 +204,7 @@ void HunspellSpellChecker::OnLanguageChanged() {
conv = agi::make_unique("utf-8", hunspell->get_dic_encoding());
rconv = agi::make_unique(hunspell->get_dic_encoding(), "utf-8");
- userDicPath = config::path->Decode("?user/dictionaries")/str(boost::format("user_%s.dic") % language);
+ userDicPath = config::path->Decode("?user/dictionaries")/agi::format("user_%s.dic", language);
ReadUserDictionary();
for (auto const& word : customWords) {
diff --git a/src/string_codec.cpp b/src/string_codec.cpp
index 6e19c7fbb..6ad7c7ca7 100644
--- a/src/string_codec.cpp
+++ b/src/string_codec.cpp
@@ -37,15 +37,14 @@
#include "string_codec.h"
-#include
+#include
std::string inline_string_encode(const std::string &input) {
std::string output;
output.reserve(input.size());
- auto format = boost::format("#%02X");
for (char c : input) {
if (c <= 0x1F || c == 0x23 || c == 0x2C || c == 0x3A || c == 0x7C)
- output += str(format % (int)(unsigned char)c);
+ output += agi::format("#%02X", (unsigned char)c);
else
output += c;
}
diff --git a/src/subs_controller.cpp b/src/subs_controller.cpp
index 5f0a80f0f..358811ba2 100644
--- a/src/subs_controller.cpp
+++ b/src/subs_controller.cpp
@@ -31,11 +31,11 @@
#include "subtitle_format.h"
#include "text_selection_controller.h"
+#include
#include
#include
#include
-#include
#include
namespace {
@@ -277,7 +277,7 @@ agi::fs::path SubsController::AutoSave() {
if (name.empty())
name = "Untitled";
- path /= str(boost::format("%s.%s.AUTOSAVE.ass") % name.string() % agi::util::strftime("%Y-%m-%d-%H-%M-%S"));
+ path /= agi::format("%s.%s.AUTOSAVE.ass", name.string(), agi::util::strftime("%Y-%m-%d-%H-%M-%S"));
SubtitleFormat::GetWriter(path)->WriteFile(context->ass.get(), path, 0);
autosaved_commit_id = commit_id;
diff --git a/src/subtitle_format_encore.cpp b/src/subtitle_format_encore.cpp
index 59d23be27..865dda902 100644
--- a/src/subtitle_format_encore.cpp
+++ b/src/subtitle_format_encore.cpp
@@ -38,7 +38,7 @@
#include "ass_file.h"
#include "text_file_writer.h"
-#include
+#include
EncoreSubtitleFormat::EncoreSubtitleFormat()
: SubtitleFormat("Adobe Encore")
@@ -70,5 +70,5 @@ void EncoreSubtitleFormat::WriteFile(const AssFile *src, agi::fs::path const& fi
int i = 0;
TextFileWriter file(filename, "UTF-8");
for (auto const& current : copy.Events)
- file.WriteLineToFile(str(boost::format("%i %s %s %s") % ++i % ft.ToSMPTE(current.Start) % ft.ToSMPTE(current.End) % current.Text));
+ file.WriteLineToFile(agi::format("%i %s %s %s", ++i, ft.ToSMPTE(current.Start), ft.ToSMPTE(current.End), current.Text));
}
diff --git a/src/subtitle_format_microdvd.cpp b/src/subtitle_format_microdvd.cpp
index af8f4bcf6..d2e981bc1 100644
--- a/src/subtitle_format_microdvd.cpp
+++ b/src/subtitle_format_microdvd.cpp
@@ -41,11 +41,11 @@
#include "text_file_reader.h"
#include "text_file_writer.h"
+#include
#include
#include
#include
-#include
#include
#include
@@ -135,13 +135,13 @@ void MicroDVDSubtitleFormat::WriteFile(const AssFile *src, agi::fs::path const&
// Write FPS line
if (!fps.IsVFR())
- file.WriteLineToFile(str(boost::format("{1}{1}%.6f") % fps.FPS()));
+ file.WriteLineToFile(agi::format("{1}{1}%.6f", fps.FPS()));
// Write lines
for (auto const& current : copy.Events) {
int start = fps.FrameAtTime(current.Start, agi::vfr::START);
int end = fps.FrameAtTime(current.End, agi::vfr::END);
- file.WriteLineToFile(str(boost::format("{%i}{%i}%s") % start % end % boost::replace_all_copy(current.Text.get(), "\\N", "|")));
+ file.WriteLineToFile(agi::format("{%i}{%i}%s", start, end, boost::replace_all_copy(current.Text.get(), "\\N", "|")));
}
}
diff --git a/src/subtitle_format_srt.cpp b/src/subtitle_format_srt.cpp
index ac89d0744..2b8817d35 100644
--- a/src/subtitle_format_srt.cpp
+++ b/src/subtitle_format_srt.cpp
@@ -41,13 +41,13 @@
#include "text_file_reader.h"
#include "text_file_writer.h"
+#include
#include
#include
#include
#include
#include
-#include
#include
#include