Merge svn changes up to r29455
[mplayer.git] / mp_msg.c
blob7314dd25afc91741d76604af8c1c1dc1efdee32b
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <string.h>
6 #include "config.h"
8 #ifdef CONFIG_ICONV
9 #include <iconv.h>
10 #include <errno.h>
11 /**
12 * \brief gets the name of the system's terminal character set
13 * \return a malloced string indicating the system charset
15 * Be warned that this function on many systems is in no way thread-safe
16 * since it modifies global data
18 char* get_term_charset(void);
19 #endif
21 #include "mp_msg.h"
23 /* maximum message length of mp_msg */
24 #define MSGSIZE_MAX 3072
26 int mp_msg_levels[MSGT_MAX]; // verbose level of this module. initialized to -2
27 int mp_msg_level_all = MSGL_STATUS;
28 int verbose = 0;
29 int mp_msg_color = 0;
30 int mp_msg_module = 0;
31 #ifdef CONFIG_ICONV
32 char *mp_msg_charset = NULL;
33 static char *old_charset = NULL;
34 static iconv_t msgiconv;
35 #endif
37 const char* filename_recode(const char* filename)
39 #if !defined(CONFIG_ICONV) || !defined(MSG_CHARSET)
40 return filename;
41 #else
42 static iconv_t inv_msgiconv = (iconv_t)(-1);
43 static char recoded_filename[MSGSIZE_MAX];
44 size_t filename_len, max_path;
45 char* precoded;
46 if (!mp_msg_charset ||
47 !strcasecmp(mp_msg_charset, MSG_CHARSET) ||
48 !strcasecmp(mp_msg_charset, "noconv"))
49 return filename;
50 if (inv_msgiconv == (iconv_t)(-1)) {
51 inv_msgiconv = iconv_open(MSG_CHARSET, mp_msg_charset);
52 if (inv_msgiconv == (iconv_t)(-1))
53 return filename;
55 filename_len = strlen(filename);
56 max_path = MSGSIZE_MAX - 4;
57 precoded = recoded_filename;
58 if (iconv(inv_msgiconv, &filename, &filename_len,
59 &precoded, &max_path) == (size_t)(-1) && errno == E2BIG) {
60 precoded[0] = precoded[1] = precoded[2] = '.';
61 precoded += 3;
63 *precoded = '\0';
64 return recoded_filename;
65 #endif
68 void mp_msg_init(void){
69 int i;
70 char *env = getenv("MPLAYER_VERBOSE");
71 if (env)
72 verbose = atoi(env);
73 for(i=0;i<MSGT_MAX;i++) mp_msg_levels[i] = -2;
74 mp_msg_levels[MSGT_IDENTIFY] = -1; // no -identify output by default
75 #ifdef CONFIG_ICONV
76 mp_msg_charset = getenv("MPLAYER_CHARSET");
77 if (!mp_msg_charset)
78 mp_msg_charset = get_term_charset();
79 #endif
82 int mp_msg_test(int mod, int lev)
84 return lev <= (mp_msg_levels[mod] == -2 ? mp_msg_level_all + verbose : mp_msg_levels[mod]);
87 static void set_msg_color(FILE* stream, int lev)
89 static const unsigned char v_colors[10] = {9, 1, 3, 15, 7, 2, 2, 8, 8, 8};
90 int c = v_colors[lev];
91 #ifdef MP_ANNOY_ME
92 /* that's only a silly color test */
94 int c;
95 static int flag = 1;
96 if (flag)
97 for(c = 0; c < 24; c++)
98 printf("\033[%d;3%dm*** COLOR TEST %d ***\n", c>7, c&7, c);
99 flag = 0;
101 #endif
102 if (mp_msg_color)
103 fprintf(stream, "\033[%d;3%dm", c >> 3, c & 7);
106 static void print_msg_module(FILE* stream, int mod)
108 static const char *module_text[MSGT_MAX] = {
109 "GLOBAL",
110 "CPLAYER",
111 "GPLAYER",
112 "VIDEOOUT",
113 "AUDIOOUT",
114 "DEMUXER",
115 "DS",
116 "DEMUX",
117 "HEADER",
118 "AVSYNC",
119 "AUTOQ",
120 "CFGPARSER",
121 "DECAUDIO",
122 "DECVIDEO",
123 "SEEK",
124 "WIN32",
125 "OPEN",
126 "DVD",
127 "PARSEES",
128 "LIRC",
129 "STREAM",
130 "CACHE",
131 "MENCODER",
132 "XACODEC",
133 "TV",
134 "OSDEP",
135 "SPUDEC",
136 "PLAYTREE",
137 "INPUT",
138 "VFILTER",
139 "OSD",
140 "NETWORK",
141 "CPUDETECT",
142 "CODECCFG",
143 "SWS",
144 "VOBSUB",
145 "SUBREADER",
146 "AFILTER",
147 "NETST",
148 "MUXER",
149 "OSDMENU",
150 "IDENTIFY",
151 "RADIO",
152 "ASS",
153 "LOADER",
154 "STATUSLINE",
156 int c2 = (mod + 1) % 15 + 1;
158 if (!mp_msg_module)
159 return;
160 if (mp_msg_color)
161 fprintf(stream, "\033[%d;3%dm", c2 >> 3, c2 & 7);
162 fprintf(stream, "%9s", module_text[mod]);
163 if (mp_msg_color)
164 fprintf(stream, "\033[0;37m");
165 fprintf(stream, ": ");
168 void mp_msg_va(int mod, int lev, const char *format, va_list va)
170 char tmp[MSGSIZE_MAX];
171 FILE *stream = lev <= MSGL_WARN ? stderr : stdout;
172 static int header = 1;
174 if (!mp_msg_test(mod, lev)) return; // do not display
175 vsnprintf(tmp, MSGSIZE_MAX, format, va);
176 tmp[MSGSIZE_MAX-2] = '\n';
177 tmp[MSGSIZE_MAX-1] = 0;
179 #if defined(CONFIG_ICONV) && defined(MSG_CHARSET)
180 if (mp_msg_charset && strcasecmp(mp_msg_charset, "noconv")) {
181 char tmp2[MSGSIZE_MAX];
182 size_t inlen = strlen(tmp), outlen = MSGSIZE_MAX;
183 char *in = tmp, *out = tmp2;
184 if (!old_charset || strcmp(old_charset, mp_msg_charset)) {
185 if (old_charset) {
186 free(old_charset);
187 iconv_close(msgiconv);
189 msgiconv = iconv_open(mp_msg_charset, MSG_CHARSET);
190 old_charset = strdup(mp_msg_charset);
192 if (msgiconv == (iconv_t)(-1)) {
193 fprintf(stderr,"iconv: conversion from %s to %s unsupported\n"
194 ,MSG_CHARSET,mp_msg_charset);
195 }else{
196 memset(tmp2, 0, MSGSIZE_MAX);
197 while (iconv(msgiconv, &in, &inlen, &out, &outlen) == -1) {
198 if (!inlen || !outlen)
199 break;
200 *out++ = *in++;
201 outlen--; inlen--;
203 strncpy(tmp, tmp2, MSGSIZE_MAX);
204 tmp[MSGSIZE_MAX-1] = 0;
205 tmp[MSGSIZE_MAX-2] = '\n';
208 #endif
210 if (header)
211 print_msg_module(stream, mod);
212 set_msg_color(stream, lev);
213 header = tmp[strlen(tmp)-1] == '\n' || tmp[strlen(tmp)-1] == '\r';
215 fprintf(stream, "%s", tmp);
216 fflush(stream);
219 void mp_msg(int mod, int lev, const char *format, ...)
221 va_list va;
222 va_start(va, format);
223 mp_msg_va(mod, lev, format, va);
224 va_end(va);
228 char *mp_gtext(const char *string)
230 return string;