summaryrefslogtreecommitdiffstats
path: root/core/mp_msg.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-07-31 21:40:30 +0200
committerwm4 <wm4@nowhere>2013-07-31 21:46:40 +0200
commit88d79fc00df39dc0180de86c758697f5ab3e56cb (patch)
tree5764f1067cae79dad6a01dccfb241db894b67683 /core/mp_msg.c
parentd1de1e090f91a254f066505ee5811feda4d93dde (diff)
downloadmpv-88d79fc00df39dc0180de86c758697f5ab3e56cb.tar.bz2
mpv-88d79fc00df39dc0180de86c758697f5ab3e56cb.tar.xz
mp_msg: introduce new log functions and macros
This has two goals: 1. Getting rid of global variables to make the core library-safe. 2. Getting rid of all the MSGT_* constants and the inconsistent prefixes spread throughout the source code. Both goals are not immediately reached with this commit. It's a huge transition that will take time. There are over >2500 mp_msg calls in the source, which all have to be replaced for this to work. The inconsistent prefixes are in particular annoying. Lots of code manually prefixes messages, e.g. mp_msg(MSGT_VO, MSGL_V, "[vo] ..."). Sometimes the prefixes don't even follow this convention (for example vo_direct3d.c uses "<vo_direct3d>" as prefix). This commit allows automatically adding prefixes on request, so consistency will hopefully improve. For now, this commit adds unused stuff, and behavior should not change. In mplayer.c, move the GetCpuCaps() call, because that used mp_msg() before mp_msg_init() was run.
Diffstat (limited to 'core/mp_msg.c')
-rw-r--r--core/mp_msg.c251
1 files changed, 193 insertions, 58 deletions
diff --git a/core/mp_msg.c b/core/mp_msg.c
index 86a544316e..e9348dbf59 100644
--- a/core/mp_msg.c
+++ b/core/mp_msg.c
@@ -21,8 +21,12 @@
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
+#include <assert.h>
+
+#include "talloc.h"
#include "config.h"
+#include "core/mpv_global.h"
#include "osdep/getch2.h"
#include "osdep/io.h"
@@ -39,6 +43,25 @@
bool mp_msg_stdout_in_use = 0;
+struct mp_log_root {
+ /* This should, at some point, contain all mp_msg related state, instead
+ * of having global variables (at least as long as we don't want to
+ * control the terminal, which is global anyway). But for now, there is
+ * not much. */
+ struct mpv_global *global;
+};
+
+struct mp_log {
+ struct mp_log_root *root;
+ const char *prefix;
+ const char *verbose_prefix;
+ int legacy_mod;
+};
+
+// should not exist
+static bool initialized;
+static struct mp_log *legacy_logs[MSGT_MAX];
+
/* maximum message length of mp_msg */
#define MSGSIZE_MAX 6144
@@ -74,7 +97,7 @@ static int mp_msg_docolor(void) {
return mp_msg_cancolor && mp_msg_color;
}
-void mp_msg_init(void){
+static void mp_msg_do_init(void){
#ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO cinfo;
DWORD cmode = 0;
@@ -121,6 +144,11 @@ int mp_msg_test(int mod, int lev)
return lev <= (mp_msg_levels[mod] == -2 ? mp_msg_level_all + verbose : mp_msg_levels[mod]);
}
+bool mp_msg_test_log(struct mp_log *log, int lev)
+{
+ return mp_msg_test(log->legacy_mod, lev);
+}
+
static void set_msg_color(FILE* stream, int lev)
{
static const int v_colors[10] = {9, 1, 3, 3, -1, -1, 2, 8, 8, 8};
@@ -153,78 +181,30 @@ static void set_msg_color(FILE* stream, int lev)
}
}
-static void print_msg_module(FILE* stream, int mod)
+static void print_msg_module(FILE* stream, struct mp_log *log)
{
- static const char *module_text[MSGT_MAX] = {
- "GLOBAL",
- "CPLAYER",
- "GPLAYER",
- "VIDEOOUT",
- "AUDIOOUT",
- "DEMUXER",
- "DS",
- "DEMUX",
- "HEADER",
- "AVSYNC",
- "AUTOQ",
- "CFGPARSER",
- "DECAUDIO",
- "DECVIDEO",
- "SEEK",
- "WIN32",
- "OPEN",
- "DVD",
- "PARSEES",
- "LIRC",
- "STREAM",
- "CACHE",
- "MENCODER",
- "XACODEC",
- "TV",
- "OSDEP",
- "SPUDEC",
- "PLAYTREE",
- "INPUT",
- "VFILTER",
- "OSD",
- "NETWORK",
- "CPUDETECT",
- "CODECCFG",
- "SWS",
- "VOBSUB",
- "SUBREADER",
- "AFILTER",
- "NETST",
- "MUXER",
- "OSDMENU",
- "IDENTIFY",
- "RADIO",
- "ASS",
- "LOADER",
- "STATUSLINE",
- };
+ int mod = log->legacy_mod;
int c2 = (mod + 1) % 15 + 1;
- if (!mp_msg_module)
- return;
#ifdef _WIN32
HANDLE *wstream = stream == stderr ? hSTDERR : hSTDOUT;
if (mp_msg_docolor())
SetConsoleTextAttribute(wstream, ansi2win32[c2&7] | FOREGROUND_INTENSITY);
- fprintf(stream, "%9s", module_text[mod]);
+ fprintf(stream, "%9s", log->verbose_prefix);
if (mp_msg_docolor())
SetConsoleTextAttribute(wstream, stdoutAttrs);
#else
if (mp_msg_docolor())
fprintf(stream, "\033[%d;3%dm", c2 >> 3, c2 & 7);
- fprintf(stream, "%9s", module_text[mod]);
+ fprintf(stream, "%9s", log->verbose_prefix);
if (mp_msg_docolor())
fprintf(stream, "\033[0;37m");
#endif
fprintf(stream, ": ");
}
-void mp_msg_va(int mod, int lev, const char *format, va_list va)
+static void mp_msg_log_va(struct mp_log *log, int lev, const char *format,
+ va_list va)
{
char tmp[MSGSIZE_MAX];
FILE *stream =
@@ -233,7 +213,7 @@ void mp_msg_va(int mod, int lev, const char *format, va_list va)
// indicates if last line printed was a status line
static int statusline;
- if (!mp_msg_test(mod, lev)) return; // do not display
+ if (!mp_msg_test_log(log, lev)) return; // do not display
vsnprintf(tmp, MSGSIZE_MAX, format, va);
tmp[MSGSIZE_MAX-2] = '\n';
tmp[MSGSIZE_MAX-1] = 0;
@@ -245,9 +225,17 @@ void mp_msg_va(int mod, int lev, const char *format, va_list va)
fprintf(stderr, "\n");
statusline = lev == MSGL_STATUS;
- if (header)
- print_msg_module(stream, mod);
set_msg_color(stream, lev);
+ if (header) {
+ if (mp_msg_module) {
+ print_msg_module(stream, log);
+ set_msg_color(stream, lev);
+ } else if (lev >= MSGL_V || verbose) {
+ fprintf(stream, "[%s] ", log->verbose_prefix);
+ } else if (log->prefix) {
+ fprintf(stream, "[%s] ", log->prefix);
+ }
+ }
size_t len = strlen(tmp);
header = len && (tmp[len-1] == '\n' || tmp[len-1] == '\r');
@@ -266,6 +254,13 @@ void mp_msg_va(int mod, int lev, const char *format, va_list va)
fflush(stream);
}
+void mp_msg_va(int mod, int lev, const char *format, va_list va)
+{
+ assert(initialized);
+ assert(mod >= 0 && mod < MSGT_MAX);
+ mp_msg_log_va(legacy_logs[mod], lev, format, va);
+}
+
void mp_msg(int mod, int lev, const char *format, ...)
{
va_list va;
@@ -334,3 +329,143 @@ void mp_tmsg(int mod, int lev, const char *format, ...)
mp_msg_va(mod, lev, mp_gtext(format), va);
va_end(va);
}
+
+// legacy names
+static const char *module_text[MSGT_MAX] = {
+ "global",
+ "cplayer",
+ "gplayer",
+ "vo",
+ "ao",
+ "demuxer",
+ "ds",
+ "demux",
+ "header",
+ "avsync",
+ "autoq",
+ "cfgparser",
+ "decaudio",
+ "decvideo",
+ "seek",
+ "win32",
+ "open",
+ "dvd",
+ "parsees",
+ "lirc",
+ "stream",
+ "cache",
+ "mencoder",
+ "xacodec",
+ "tv",
+ "osdep",
+ "spudec",
+ "playtree",
+ "input",
+ "vf",
+ "osd",
+ "network",
+ "cpudetect",
+ "codeccfg",
+ "sws",
+ "vobsub",
+ "subreader",
+ "af",
+ "netst",
+ "muxer",
+ "osdmenu",
+ "identify",
+ "radio",
+ "ass",
+ "loader",
+ "statusline",
+ "teletext",
+};
+
+// Create a new log context, which uses talloc_ctx as talloc parent, and parent
+// as logical parent.
+// The name is the prefix put before the output. It's usually prefixed by the
+// parent's name. If the name starts with "/", the parent's name is not
+// prefixed (except in verbose mode), and if it starts with "!", the name is
+// printed at all (except in verbose mode).
+struct mp_log *mp_log_new(void *talloc_ctx, struct mp_log *parent,
+ const char *name)
+{
+ assert(parent);
+ assert(name);
+ struct mp_log *log = talloc_zero(talloc_ctx, struct mp_log);
+ log->root = parent->root;
+ if (name[0] == '!') {
+ name = &name[1];
+ } else if (name[0] == '/') {
+ name = &name[1];
+ log->prefix = talloc_strdup(log, name);
+ } else {
+ log->prefix = parent->prefix
+ ? talloc_asprintf(log, "%s/%s", parent->prefix, name)
+ : talloc_strdup(log, name);
+ }
+ log->verbose_prefix = parent->prefix
+ ? talloc_asprintf(log, "%s/%s", parent->prefix, name)
+ : talloc_strdup(log, name);
+ if (log->prefix && !log->prefix[0])
+ log->prefix = NULL;
+ if (!log->verbose_prefix[0])
+ log->verbose_prefix = "global";
+ log->legacy_mod = parent->legacy_mod;
+ for (int n = 0; n < MSGT_MAX; n++) {
+ if (module_text[n] && strcmp(name, module_text[n]) == 0) {
+ log->legacy_mod = n;
+ break;
+ }
+ }
+ return log;
+}
+
+void mp_msg_init(struct mpv_global *global)
+{
+ assert(!initialized);
+ assert(!global->log);
+
+ struct mp_log_root *root = talloc_zero(NULL, struct mp_log_root);
+ root->global = global;
+
+ struct mp_log dummy = { .root = root };
+ struct mp_log *log = mp_log_new(root, &dummy, "");
+ for (int n = 0; n < MSGT_MAX; n++) {
+ char name[80];
+ snprintf(name, sizeof(name), "!%s", module_text[n]);
+ legacy_logs[n] = mp_log_new(root, log, name);
+ }
+ mp_msg_do_init();
+
+ global->log = log;
+ initialized = true;
+}
+
+struct mpv_global *mp_log_get_global(struct mp_log *log)
+{
+ return log->root->global;
+}
+
+void mp_msg_uninit(struct mpv_global *global)
+{
+ talloc_free(global->log->root);
+ global->log = NULL;
+ initialized = false;
+}
+
+void mp_msg_log(struct mp_log *log, int lev, const char *format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ mp_msg_log_va(log, lev, format, va);
+ va_end(va);
+}
+
+void mp_tmsg_log(struct mp_log *log, int lev, const char *format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ mp_msg_log_va(log, lev, mp_gtext(format), va);
+ va_end(va);
+}