forked from mia/Aegisub
Fix a pile of actual memory leaks
Originally committed to SVN as r4575.
This commit is contained in:
parent
cbf201ab86
commit
2b47f34e76
8 changed files with 80 additions and 88 deletions
|
@ -21,6 +21,8 @@
|
|||
#include "charset_ucd.h"
|
||||
|
||||
#ifndef LAGI_PRE
|
||||
#include <memory>
|
||||
|
||||
#include "../../universalchardet/nsCharSetProber.h"
|
||||
#endif
|
||||
|
||||
|
@ -31,8 +33,7 @@ namespace agi {
|
|||
|
||||
UCDetect::UCDetect(const std::string &file): nsUniversalDetector(NS_FILTER_ALL) {
|
||||
{
|
||||
std::ifstream *fp;
|
||||
fp = io::Open(file);
|
||||
std::auto_ptr<std::ifstream> fp(io::Open(file));
|
||||
|
||||
while (!mDone && !fp->eof()) {
|
||||
char buf[512];
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
|
@ -40,99 +42,84 @@ std::auto_ptr<LogSink> log(new LogSink());
|
|||
/// Keep this ordered the same as Severity
|
||||
const char *Severity_ID = "EAWID";
|
||||
|
||||
SinkMessage::SinkMessage(const char *section, Severity severity, const char *file,
|
||||
const char *func, int line, agi_timeval tv):
|
||||
section(section),
|
||||
severity(severity),
|
||||
file(file),
|
||||
func(func),
|
||||
line(line),
|
||||
tv(tv) {
|
||||
SinkMessage::SinkMessage(const char *section, Severity severity,
|
||||
const char *file, const char *func, int line,
|
||||
agi_timeval tv)
|
||||
: section(section)
|
||||
, severity(severity)
|
||||
, file(file)
|
||||
, func(func)
|
||||
, line(line)
|
||||
, tv(tv)
|
||||
, message(NULL)
|
||||
, len(0)
|
||||
{
|
||||
}
|
||||
|
||||
SinkMessage::~SinkMessage() {
|
||||
///@todo Memory cleanup
|
||||
delete message;
|
||||
}
|
||||
|
||||
|
||||
LogSink::LogSink(): emit(0) {
|
||||
sink = new Sink();
|
||||
LogSink::LogSink() {
|
||||
}
|
||||
|
||||
LogSink::~LogSink() {
|
||||
/// @todo This needs to flush all log data to disk on quit.
|
||||
if (emit) {
|
||||
for (int i = emitters.size()-1; i >= 0; i--) {
|
||||
delete emitters[i];
|
||||
}
|
||||
}
|
||||
agi::util::delete_clear(sink);
|
||||
}
|
||||
|
||||
|
||||
void LogSink::log(SinkMessage *sm) {
|
||||
sink->push_back(sm);
|
||||
sink.push_back(sm);
|
||||
|
||||
if (emit) {
|
||||
for (int i = emitters.size()-1; i >= 0; i--) {
|
||||
emitters[i]->log(sm);
|
||||
}
|
||||
}
|
||||
std::for_each(
|
||||
emitters.begin(),
|
||||
emitters.end(),
|
||||
std::bind2nd(std::mem_fun(&Emitter::log), sm));
|
||||
}
|
||||
|
||||
|
||||
Emitter::~Emitter() {
|
||||
void LogSink::Subscribe(Emitter *em) {
|
||||
emitters.push_back(em);
|
||||
}
|
||||
|
||||
|
||||
Emitter::Emitter() {
|
||||
void LogSink::Unsubscribe(Emitter *em) {
|
||||
emitters.erase(std::remove(emitters.begin(), emitters.end(), em), emitters.end());
|
||||
}
|
||||
|
||||
|
||||
int LogSink::Subscribe(Emitter &em) {
|
||||
emitters.push_back(&em);
|
||||
emit = 1;
|
||||
/// @todo This won't work since removing it will cause the id's to change,
|
||||
/// it's good enough while this is being written.
|
||||
return emitters.size();
|
||||
}
|
||||
|
||||
|
||||
void LogSink::Unsubscribe(const int &id) {
|
||||
emitters.erase((emitters.begin()-1)+id);
|
||||
if (emitters.size() == 0)
|
||||
emit = 0;
|
||||
}
|
||||
|
||||
|
||||
Message::Message(const char *section,
|
||||
Severity severity,
|
||||
const char *file,
|
||||
const char *func,
|
||||
int line):
|
||||
len(1024) {
|
||||
buf = new char[len];
|
||||
msg = new std::ostrstream(buf, len);
|
||||
int line)
|
||||
: len(1024)
|
||||
, buf(new char[len])
|
||||
, msg(buf, len)
|
||||
{
|
||||
agi_timeval tv;
|
||||
util::time_log(tv);
|
||||
sm = new SinkMessage(section, severity, file, func, line, tv);
|
||||
}
|
||||
|
||||
|
||||
Message::~Message() {
|
||||
sm->message = msg->str();
|
||||
sm->len = msg->pcount();
|
||||
sm->message = msg.str();
|
||||
sm->len = msg.pcount();
|
||||
agi::log::log->log(sm);
|
||||
delete msg;
|
||||
}
|
||||
|
||||
Emitter::Emitter() {
|
||||
}
|
||||
|
||||
Emitter::~Emitter() {
|
||||
Disable();
|
||||
}
|
||||
|
||||
void Emitter::Enable() {
|
||||
id = agi::log::log->Subscribe(*(this));
|
||||
agi::log::log->Subscribe(this);
|
||||
}
|
||||
|
||||
|
||||
void Emitter::Disable() {
|
||||
agi::log::log->Unsubscribe(id);
|
||||
agi::log::log->Unsubscribe(this);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "libaegisub/cajun/reader.h"
|
||||
#include "libaegisub/cajun/writer.h"
|
||||
|
@ -55,10 +56,10 @@ void Options::ConfigNext(std::istream& stream) {
|
|||
}
|
||||
|
||||
void Options::ConfigUser() {
|
||||
std::istream *stream;
|
||||
std::auto_ptr<std::istream> stream;
|
||||
|
||||
try {
|
||||
stream = agi::io::Open(config_file);
|
||||
stream.reset(agi::io::Open(config_file));
|
||||
} catch (const acs::AcsNotFound&) {
|
||||
return;
|
||||
}
|
||||
|
@ -66,7 +67,6 @@ void Options::ConfigUser() {
|
|||
/// @todo Handle other errors such as parsing and notifying the user.
|
||||
LoadConfig(*stream);
|
||||
config_loaded = true;
|
||||
delete stream;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -77,11 +77,11 @@ struct SinkMessage {
|
|||
/// @param file File name
|
||||
/// @param func Function name
|
||||
/// @param line Source line
|
||||
/// @param tv Log time
|
||||
/// @param tv Log time
|
||||
SinkMessage(const char *section, Severity severity, const char *file,
|
||||
const char *func, int line, agi_timeval tv);
|
||||
|
||||
// Destructor
|
||||
/// Destructor
|
||||
~SinkMessage();
|
||||
|
||||
const char *section; ///< Section info eg "video/open" "video/seek" etc
|
||||
|
@ -105,14 +105,11 @@ class LogSink {
|
|||
int64_t size;
|
||||
|
||||
/// Log sink
|
||||
Sink *sink;
|
||||
Sink sink;
|
||||
|
||||
/// List of function pointers to emitters
|
||||
std::vector<Emitter*> emitters;
|
||||
|
||||
/// Whether to enable emitters
|
||||
bool emit;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
LogSink();
|
||||
|
@ -124,24 +121,20 @@ public:
|
|||
void log(SinkMessage *sm);
|
||||
|
||||
/// @brief Subscribe an emitter.
|
||||
/// @param Function pointer to an emitter
|
||||
/// @return ID for this Emitter
|
||||
int Subscribe(Emitter &em);
|
||||
/// @param em Emitter to add
|
||||
void Subscribe(Emitter *em);
|
||||
|
||||
/// @brief Unsubscribe an emitter.
|
||||
/// @param id ID to remove.
|
||||
void Unsubscribe(const int &id);
|
||||
/// @param em Emitter to remove
|
||||
void Unsubscribe(Emitter *em);
|
||||
|
||||
/// @brief @get the complete (current) log.
|
||||
/// @return Const pointer to internal sink.
|
||||
const Sink* GetSink() { return sink; }
|
||||
const Sink* GetSink() { return &sink; }
|
||||
};
|
||||
|
||||
/// An emitter to produce human readable output for a log sink.
|
||||
class Emitter {
|
||||
/// ID for this emitter
|
||||
int id;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
Emitter();
|
||||
|
@ -162,9 +155,9 @@ public:
|
|||
|
||||
/// Generates a message and submits it to the log sink.
|
||||
class Message {
|
||||
char *buf;
|
||||
const int len;
|
||||
std::ostrstream *msg;
|
||||
char *buf;
|
||||
std::ostrstream msg;
|
||||
SinkMessage *sm;
|
||||
|
||||
public:
|
||||
|
@ -174,7 +167,7 @@ public:
|
|||
const char *func,
|
||||
int line);
|
||||
~Message();
|
||||
std::ostream& stream() { return *(msg); }
|
||||
std::ostream& stream() { return msg; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -34,5 +34,17 @@ namespace agi {
|
|||
void Rename(const std::string& from, const std::string& to);
|
||||
void time_log(agi_timeval &tv);
|
||||
|
||||
struct delete_ptr {
|
||||
template<class T>
|
||||
void operator()(T* ptr) const {
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
template<class T>
|
||||
void delete_clear(T& container) {
|
||||
std::for_each(container.begin(), container.end(), delete_ptr());
|
||||
container.clear();
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace agi
|
||||
|
|
|
@ -37,7 +37,7 @@ void EmitSTDOUT::log(SinkMessage *sm) {
|
|||
// tmtime.tm_mon,
|
||||
// tmtime.tm_mday,
|
||||
|
||||
printf("%c %02d:%02d:%02d %ld <%-25s> [%s:%s:%d] %s\n",
|
||||
printf("%c %02d:%02d:%02d %ld <%-25s> [%s:%s:%d] %.*s\n",
|
||||
Severity_ID[sm->severity],
|
||||
tmtime.tm_hour,
|
||||
tmtime.tm_min,
|
||||
|
@ -47,8 +47,8 @@ void EmitSTDOUT::log(SinkMessage *sm) {
|
|||
sm->file,
|
||||
sm->func,
|
||||
sm->line,
|
||||
strndup(sm->message,
|
||||
sm->len));
|
||||
sm->len,
|
||||
sm->message);
|
||||
}
|
||||
|
||||
} // namespace log
|
||||
|
|
|
@ -30,15 +30,15 @@ namespace agi {
|
|||
namespace log {
|
||||
|
||||
void EmitSTDOUT::log(SinkMessage *sm) {
|
||||
/*
|
||||
tm tmtime;
|
||||
localtime_r(&sm->tv.tv_sec, &tmtime);
|
||||
time_t time = sm->tv.tv_sec;
|
||||
localtime_s(&tmtime, &time);
|
||||
|
||||
// tmtime.tm_year+1900,
|
||||
// tmtime.tm_mon,
|
||||
// tmtime.tm_mday,
|
||||
|
||||
printf("%c %02d:%02d:%02d %ld <%-25s> [%s:%s:%d] %s\n",
|
||||
printf("%c %02d:%02d:%02d %ld <%-25s> [%s:%s:%d] %.*s\n",
|
||||
Severity_ID[sm->severity],
|
||||
tmtime.tm_hour,
|
||||
tmtime.tm_min,
|
||||
|
@ -48,9 +48,8 @@ void EmitSTDOUT::log(SinkMessage *sm) {
|
|||
sm->file,
|
||||
sm->func,
|
||||
sm->line,
|
||||
strndup(sm->message,
|
||||
sm->len));
|
||||
*/
|
||||
sm->len,
|
||||
sm->message);
|
||||
}
|
||||
} // namespace log
|
||||
} // namespace agi
|
||||
|
|
|
@ -144,8 +144,8 @@ void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName) {
|
|||
///
|
||||
bool AegisubApp::OnInit() {
|
||||
#ifdef _DEBUG
|
||||
agi::log::EmitSTDOUT *emit_stdout = new agi::log::EmitSTDOUT();
|
||||
emit_stdout->Enable();
|
||||
agi::log::EmitSTDOUT emit_stdout;
|
||||
emit_stdout.Enable();
|
||||
#endif
|
||||
|
||||
// App name (yeah, this is a little weird to get rid of an odd warning)
|
||||
|
|
Loading…
Reference in a new issue