Replace boost::format with agi::format

boost::format is slow to compile, slow to run, and has an unpleasant
interface.
This commit is contained in:
Thomas Goyne 2014-05-28 15:19:05 -07:00
parent 8ba286c544
commit b43788fa7f
42 changed files with 616 additions and 171 deletions

View File

@ -54,6 +54,7 @@
<ClInclude Include="$(SrcDir)include\libaegisub\dispatch.h" />
<ClInclude Include="$(SrcDir)include\libaegisub\exception.h" />
<ClInclude Include="$(SrcDir)include\libaegisub\file_mapping.h" />
<ClInclude Include="$(SrcDir)include\libaegisub\format.h" />
<ClInclude Include="$(SrcDir)include\libaegisub\fs.h" />
<ClInclude Include="$(SrcDir)include\libaegisub\fs_fwd.h" />
<ClInclude Include="$(SrcDir)include\libaegisub\hotkey.h" />
@ -104,6 +105,7 @@
<ClCompile Include="$(SrcDir)common\color.cpp" />
<ClCompile Include="$(SrcDir)common\dispatch.cpp" />
<ClCompile Include="$(SrcDir)common\file_mapping.cpp" />
<ClCompile Include="$(SrcDir)common\format.cpp" />
<ClCompile Include="$(SrcDir)common\fs.cpp" />
<ClCompile Include="$(SrcDir)common\hotkey.cpp" />
<ClCompile Include="$(SrcDir)common\io.cpp" />

View File

@ -170,6 +170,9 @@
<ClInclude Include="$(SrcDir)include\libaegisub\file_mapping.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="$(SrcDir)include\libaegisub\format.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="$(SrcDir)include\libaegisub\character_count.h">
<Filter>Header Files</Filter>
</ClInclude>

View File

@ -16,7 +16,7 @@
#include "parser.h"
#include <boost/format.hpp>
#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 {

View File

@ -0,0 +1,324 @@
// Copyright (c) 2014, Thomas Goyne <plorkyeran@aegisub.org>
//
// 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 <boost/interprocess/streams/vectorstream.hpp>
#include <boost/io/ios_state.hpp>
#include <cassert>
#include <type_traits>
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<typename In, typename Out, bool = std::is_convertible<In, Out>::value>
struct runtime_cast_helper {
static Out cast(In const&) { throw std::bad_cast(); }
};
template<typename In, typename Out>
struct runtime_cast_helper<In, Out, true> {
static Out cast(In const& value) {
return static_cast<Out>(value);
}
};
template<typename Out, typename In>
Out runtime_cast(In const& value) {
return runtime_cast_helper<In, Out>::cast(value);
}
template<typename T>
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<size_t>(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<typename T>
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<int>(value);
read_width = false;
return;
}
if (read_precision) {
precision = runtime_cast<int>(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<char>(value);
break;
case 'd': case 'i':
out.setf(std::ios::dec, std::ios::basefield);
out << runtime_cast<intmax_t>(value);
break;
case 'o':
out.setf(std::ios::oct, std::ios::basefield);
out << runtime_cast<intmax_t>(value);
break;
case 'x':
out.setf(std::ios::hex, std::ios::basefield);
out << runtime_cast<intmax_t>(value);
break;
case 'u':
out.setf(std::ios::dec, std::ios::basefield);
out << runtime_cast<uintmax_t>(value);
break;
case 'e':
out.setf(std::ios::scientific, std::ios::floatfield);
out.setf(std::ios::dec, std::ios::basefield);
out << runtime_cast<double>(value);
break;
case 'f':
out.setf(std::ios::fixed, std::ios::floatfield);
out << runtime_cast<double>(value);
break;
case 'g':
out.setf(std::ios::dec, std::ios::basefield);
out.flags(out.flags() & ~std::ios::floatfield);
out << runtime_cast<double>(value);
break;
case 'p':
out.setf(std::ios::hex, std::ios::basefield);
out << runtime_cast<const void *>(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<typename T, typename... Args>
void format(formatter&& fmt, T&& first, Args&&... rest) {
fmt(first);
format(std::move(fmt), std::forward<Args>(rest)...);
}
} // namespace format_detail
template<typename... Args>
void format(std::ostream& out, const char *fmt, Args&&... args) {
format(format_detail::formatter(out, fmt), std::forward<Args>(args)...);
}
template<typename... Args>
std::string format(const char *fmt, Args&&... args) {
boost::interprocess::basic_vectorstream<std::string> out;
format(out, fmt, std::forward<Args>(args)...);
return out.vector();
}
}

View File

@ -16,11 +16,11 @@
#include "libaegisub/lua/utils.h"
#include "libaegisub/format.h"
#include "libaegisub/log.h"
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/format.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/regex.hpp>
@ -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("<anonymous function at lines %d-%d>") % real_line(ar.linedefined) % real_line(ar.lastlinedefined - 1));
function = agi::format("<anonymous function at lines %d-%d>", 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));
}
}

View File

@ -18,12 +18,13 @@
#include <libaegisub/access.h>
#include <libaegisub/format.h>
#include <libaegisub/format_path.h>
#include <libaegisub/fs.h>
#include <libaegisub/log.h>
#include <libaegisub/util.h>
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
#include <windows.h>
@ -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())));
}
}

View File

@ -34,7 +34,7 @@
#include "ass_export_filter.h"
#include <boost/format.hpp>
#include <libaegisub/format.h>
static FilterList& filters() {
static FilterList instance;
@ -53,7 +53,7 @@ void AssExportFilterChain::Register(std::unique_ptr<AssExportFilter> 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;

View File

@ -18,7 +18,8 @@
#include "ass_dialogue.h"
#include <boost/format.hpp>
#include <libaegisub/format.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/trim.hpp>
@ -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) {

View File

@ -38,12 +38,12 @@
#include "utils.h"
#include <libaegisub/color.h>
#include <libaegisub/format.h>
#include <libaegisub/make_unique.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/format.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <functional>
@ -128,7 +128,7 @@ template<> void AssOverrideParameter::Set<std::string>(std::string new_value) {
template<> void AssOverrideParameter::Set<int>(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));
}

View File

@ -37,10 +37,10 @@
#include "subtitle_format.h"
#include "utils.h"
#include <libaegisub/format.h>
#include <libaegisub/split.h>
#include <boost/algorithm/string/trim.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <wx/intl.h>
@ -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) {

View File

@ -23,12 +23,12 @@
#include "utils.h"
#include <libaegisub/format.h>
#include <libaegisub/util.h>
#include <algorithm>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/format.hpp>
#include <boost/range/adaptor/filtered.hpp>
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 {

View File

@ -20,12 +20,12 @@
#include "options.h"
#include <libaegisub/file_mapping.h>
#include <libaegisub/format.h>
#include <libaegisub/fs.h>
#include <libaegisub/path.h>
#include <libaegisub/make_unique.h>
#include <boost/filesystem/path.hpp>
#include <boost/format.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include <thread>
@ -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<agi::temp_file_mapping>(cache_dir / filename, num_samples * bytes_per_sample);
decoder = std::thread([&] {

View File

@ -39,13 +39,13 @@
#include "subs_controller.h"
#include <libaegisub/dispatch.h>
#include <libaegisub/format.h>
#include <libaegisub/fs.h>
#include <libaegisub/path.h>
#include <libaegisub/make_unique.h>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
#include <future>
@ -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")) + " (*.*)|*.*";

View File

@ -50,17 +50,17 @@
#include "video_controller.h"
#include "utils.h"
#include <libaegisub/format.h>
#include <libaegisub/lua/modules.h>
#include <libaegisub/lua/script_reader.h>
#include <libaegisub/lua/utils.h>
#include <libaegisub/path.h>
#include <libaegisub/make_unique.h>
#include <libaegisub/path.h>
#include <algorithm>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/format.hpp>
#include <boost/scope_exit.hpp>
#include <cassert>
#include <mutex>
@ -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");

View File

@ -50,12 +50,12 @@
#include "../video_controller.h"
#include <libaegisub/address_of_adaptor.h>
#include <libaegisub/format.h>
#include <libaegisub/of_type_adaptor.h>
#include <libaegisub/make_unique.h>
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/indirected.hpp>
@ -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;
}

View File

@ -50,6 +50,7 @@
#include "../video_display.h"
#include "../video_frame.h"
#include <libaegisub/format.h>
#include <libaegisub/fs.h>
#include <libaegisub/path.h>
#include <libaegisub/make_unique.h>
@ -58,7 +59,6 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/format.hpp>
#include <wx/msgdlg.h>
#include <wx/textdlg.h>
@ -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);

View File

@ -18,10 +18,10 @@
#include "version.h"
#include <libaegisub/format.h>
#include <libaegisub/util.h>
#include <boost/filesystem/fstream.hpp>
#include <boost/format.hpp>
#include <wx/string.h>
#include <wx/stackwalk.h>
@ -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();
}

View File

@ -18,13 +18,13 @@
#include "version.h"
#include <libaegisub/format.h>
#include <libaegisub/fs.h>
#include <libaegisub/make_unique.h>
#include <libaegisub/util.h>
#include <atomic>
#include <boost/filesystem/fstream.hpp>
#include <boost/format.hpp>
#include <condition_variable>
#include <mutex>
#include <thread>
@ -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();
}
}
}

View File

@ -40,6 +40,7 @@
#include <libaegisub/dispatch.h>
#include <libaegisub/exception.h>
#include <libaegisub/format.h>
#include <libaegisub/line_iterator.h>
#include <libaegisub/scoped_ptr.h>
@ -47,7 +48,6 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/format.hpp>
#include <functional>
#include <mutex>
#include <vector>
@ -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;

View File

@ -55,6 +55,7 @@
#include "version.h"
#include <libaegisub/dispatch.h>
#include <libaegisub/format.h>
#include <libaegisub/fs.h>
#include <libaegisub/io.h>
#include <libaegisub/log.h>
@ -62,7 +63,6 @@
#include <libaegisub/path.h>
#include <libaegisub/util.h>
#include <boost/format.hpp>
#include <boost/interprocess/streams/bufferstream.hpp>
#include <boost/locale.hpp>
#include <locale>
@ -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);

View File

@ -42,11 +42,11 @@
#include "MatroskaParser.h"
#include <libaegisub/file_mapping.h>
#include <libaegisub/format.h>
#include <libaegisub/scoped_ptr.h>
#include <algorithm>
#include <boost/algorithm/string/replace.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/range/irange.hpp>
#include <boost/tokenizer.hpp>
@ -143,18 +143,18 @@ static void read_subtitles(agi::ProgressSink *ps, MatroskaFile *file, MkvStdIO *
subList.emplace_back(
boost::lexical_cast<int>(str_range(readBuf, first)),
str(boost::format("Dialogue: %d,%s,%s,%s")
% boost::lexical_cast<int>(str_range(first + 1, second))
% subStart.GetAssFormated()
% subEnd.GetAssFormated()
% str_range(second + 1, readBufEnd)));
agi::format("Dialogue: %d,%s,%s,%s"
, boost::lexical_cast<int>(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;

View File

@ -24,6 +24,7 @@
#include "options.h"
#include <libaegisub/charset_conv.h>
#include <libaegisub/format.h>
#include <libaegisub/fs.h>
#include <libaegisub/io.h>
#include <libaegisub/line_iterator.h>
@ -31,7 +32,6 @@
#include <libaegisub/path.h>
#include <libaegisub/make_unique.h>
#include <boost/format.hpp>
#include <boost/range/algorithm.hpp>
#include <hunspell/hunspell.hxx>
@ -177,8 +177,8 @@ std::vector<std::string> 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<agi::charset::IconvWrapper>("utf-8", hunspell->get_dic_encoding());
rconv = agi::make_unique<agi::charset::IconvWrapper>(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) {

View File

@ -37,15 +37,14 @@
#include "string_codec.h"
#include <boost/format.hpp>
#include <libaegisub/format.h>
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;
}

View File

@ -31,11 +31,11 @@
#include "subtitle_format.h"
#include "text_selection_controller.h"
#include <libaegisub/format.h>
#include <libaegisub/fs.h>
#include <libaegisub/path.h>
#include <libaegisub/util.h>
#include <boost/format.hpp>
#include <wx/msgdlg.h>
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;

View File

@ -38,7 +38,7 @@
#include "ass_file.h"
#include "text_file_writer.h"
#include <boost/format.hpp>
#include <libaegisub/format.h>
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));
}

View File

@ -41,11 +41,11 @@
#include "text_file_reader.h"
#include "text_file_writer.h"
#include <libaegisub/format.h>
#include <libaegisub/fs.h>
#include <libaegisub/util.h>
#include <boost/algorithm/string/replace.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
@ -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", "|")));
}
}

View File

@ -41,13 +41,13 @@
#include "text_file_reader.h"
#include "text_file_writer.h"
#include <libaegisub/format.h>
#include <libaegisub/of_type_adaptor.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/format.hpp>
#include <boost/regex.hpp>
#include <map>
@ -200,11 +200,11 @@ public:
// handle the attributes
if (attr_name == "face")
new_attribs.face = str(boost::format("{\\fn%s}") % attr_value);
new_attribs.face = agi::format("{\\fn%s}", attr_value);
else if (attr_name == "size")
new_attribs.size = str(boost::format("{\\fs%s}") % attr_value);
new_attribs.size = agi::format("{\\fs%s}", attr_value);
else if (attr_name == "color")
new_attribs.color = str(boost::format("{\\c%s}") % agi::Color(attr_value).GetAssOverrideFormatted());
new_attribs.color = agi::format("{\\c%s}", agi::Color(attr_value).GetAssOverrideFormatted());
// remove this attribute to prepare for the next
tag_attrs = result.suffix().str();
@ -320,7 +320,7 @@ milliseconds:
std::string WriteSRTTime(AssTime const& ts)
{
return str(boost::format("%02d:%02d:%02d,%03d") % ts.GetTimeHours() % ts.GetTimeMinutes() % ts.GetTimeSeconds() % ts.GetTimeMiliseconds());
return agi::format("%02d:%02d:%02d,%03d", ts.GetTimeHours(), ts.GetTimeMinutes(), ts.GetTimeSeconds(), ts.GetTimeMiliseconds());
}
}
@ -382,11 +382,11 @@ void SRTSubtitleFormat::ReadFile(AssFile *target, agi::fs::path const& filename,
if (regex_search(text_line, timestamp_match, timestamp_regex))
goto found_timestamps;
throw SRTParseError(str(boost::format("Parsing SRT: Expected subtitle index at line %d") % line_num), nullptr);
throw SRTParseError(agi::format("Parsing SRT: Expected subtitle index at line %d", line_num), nullptr);
case STATE_TIMESTAMP:
if (!regex_search(text_line, timestamp_match, timestamp_regex))
throw SRTParseError(str(boost::format("Parsing SRT: Expected timestamp pair at line %d") % line_num), nullptr);
throw SRTParseError(agi::format("Parsing SRT: Expected timestamp pair at line %d", line_num), nullptr);
found_timestamps:
if (line) {
// finalize active line
@ -524,9 +524,9 @@ std::string SRTSubtitleFormat::ConvertTags(const AssDialogue *diag) const {
if (it != tag_states.end()) {
bool temp = tag.Params[0].Get(false);
if (temp && !it->second)
final += str(boost::format("<%c>") % it->first);
final += agi::format("<%c>", it->first);
if (!temp && it->second)
final += str(boost::format("</%c>") % it->first);
final += agi::format("</%c>", it->first);
it->second = temp;
}
}
@ -541,7 +541,7 @@ std::string SRTSubtitleFormat::ConvertTags(const AssDialogue *diag) const {
// Otherwise unclosed overrides might affect lines they shouldn't, see bug #809 for example
for (auto it : tag_states) {
if (it.second)
final += str(boost::format("</%c>") % it.first);
final += agi::format("</%c>", it.first);
}
return final;

View File

@ -24,9 +24,10 @@
#include "text_file_writer.h"
#include "version.h"
#include <libaegisub/format.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/format.hpp>
namespace {
std::string replace_commas(std::string str) {
@ -54,14 +55,14 @@ void SsaSubtitleFormat::WriteFile(const AssFile *src, agi::fs::path const& filen
file.WriteLineToFile("[V4 Styles]");
file.WriteLineToFile("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding");
for (auto const& line : src->Styles)
file.WriteLineToFile(str(boost::format("Style: %s,%s,%g,%s,%s,0,%s,%d,%d,%d,%g,%g,%d,%d,%d,%d,0,%i")
% line.name % line.font % line.fontsize
% line.primary.GetSsaFormatted()
% line.secondary.GetSsaFormatted()
% line.shadow.GetSsaFormatted()
% (line.bold? -1 : 0) % (line.italic ? -1 : 0)
% line.borderstyle % line.outline_w % line.shadow_w % AssStyle::AssToSsa(line.alignment)
% line.Margin[0] % line.Margin[1] % line.Margin[2] % line.encoding));
file.WriteLineToFile(agi::format("Style: %s,%s,%g,%s,%s,0,%s,%d,%d,%d,%g,%g,%d,%d,%d,%d,0,%i"
<