/camera/imageviewer

To get this branch, use:
bzr branch http://darksoft.org/webbzr/camera/imageviewer

« back to all changes in this revision

Viewing changes to cameralink/ds_log.c

  • Committer: Suren A. Chilingaryan
  • Date: 2011-02-13 01:34:55 UTC
  • Revision ID: csa@dside.dyndns.org-20110213013455-7999955h7v4uf9m8
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <errno.h>
 
5
#include <time.h>
 
6
#include <stdarg.h>
 
7
 
 
8
#include <glib.h>
 
9
 
 
10
#include "ds_log.h"
 
11
 
 
12
#undef DS_LOG_SUPPORT_THREADS
 
13
 
 
14
#define DS_MAX_LOG_STRING 1024
 
15
#define DS_MAX_FORMAT_CHARS 32
 
16
 
 
17
static int ds_log_time = 0;
 
18
static int ds_log_thread = 0;
 
19
static int ds_log_level = ((G_LOG_LEVEL_DEBUG<<1) - 1)&G_LOG_LEVEL_MASK;
 
20
 
 
21
static int ds_log_exception_message = 1;
 
22
static int ds_exception_level = G_LOG_LEVEL_ERROR|G_LOG_LEVEL_CRITICAL;
 
23
static DSExceptionHandler ds_exception_handler = NULL;
 
24
 
 
25
static char printf_integer_keys[] = "diouxX";
 
26
static char printf_accepted_flags[] = "#0- +'I*$123456789.hlLqjzt";
 
27
 
 
28
#ifdef DS_LOG_SUPPORT_THREADS
 
29
GStaticMutex ds_log_mutex = G_STATIC_MUTEX_INIT;
 
30
#endif /* DS_LOG_SUPPORT_THREADS */
 
31
 
 
32
/*
 
33
static void ds_log_handler_dummy(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) {
 
34
}
 
35
*/
 
36
 
 
37
static void ds_log_handler_stderr(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) {
 
38
    fprintf(stderr, "%s\n", message);
 
39
}
 
40
 
 
41
 
 
42
//static void (*ds_log_handler)(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) = ds_log_handler_stderr;
 
43
 
 
44
 
 
45
void ds_log_set_handler(GLogFunc handler, gpointer arg) {
 
46
    g_log_set_default_handler(handler?handler:g_log_default_handler, arg);
 
47
}
 
48
 
 
49
void ds_log_set_level(GLogLevelFlags log_level) {
 
50
    ds_log_level = ((log_level<<1) - 1)&G_LOG_LEVEL_MASK;
 
51
}
 
52
 
 
53
void ds_configure_logger(GLogLevelFlags log_level, const char *sink) {
 
54
    ds_log_set_level(log_level);
 
55
        // Ignoring at the moment
 
56
    ds_log_set_handler(ds_log_handler_stderr, NULL);
 
57
}
 
58
 
 
59
void ds_log_enable_timestamps() {
 
60
    ds_log_time = 1;
 
61
}
 
62
 
 
63
void ds_log_enable_threads() {
 
64
    ds_log_thread = 1;
 
65
}
 
66
 
 
67
void ds_log_configure_exception_handler(GLogLevelFlags log_level, DSExceptionHandler handler, int log_exception_message) {
 
68
    ds_exception_level = log_level;
 
69
    ds_exception_handler = handler;
 
70
    ds_log_exception_message = log_exception_message;
 
71
}
 
72
 
 
73
/*
 
74
void ds_log_set_domain_level(const gchar *log_domain, GLogLevelFlags log_level) {
 
75
    ds_log_level = ((log_level<<1) - 1)&G_LOG_LEVEL_MASK;
 
76
    //g_log_set_handler(log_domain,  (~ds_log_level&G_LOG_LEVEL_MASK), &ds_log_handler_dummy);
 
77
}
 
78
 
 
79
void ds_log_set_domain_handler(const gchar *log_domain, GLogFunc handler, gpointer arg) {
 
80
    guint id;
 
81
 
 
82
    id = g_log_set_handler(log_domain, G_LOG_LEVEL_MASK, handler, arg);
 
83
 
 
84
    // assuming current implementation using sequential uid numbers starting from 1, the handler should not be set directly after that
 
85
    if (id > 1) g_log_remove_handler(log_domain, id - 1);
 
86
}
 
87
 
 
88
int ds_configure_domain_logger(GLogLevelFlags log_level, const char *sink) {
 
89
    ds_log_set_level(log_domain, log_level);
 
90
        // Ignoring at the moment
 
91
    ds_log_set_handler(log_domain, ds_log_handler_stderr, NULL);
 
92
}
 
93
*/
 
94
 
 
95
void _ds_gen_message(int msglen, /* the buffer should be one byte longer for null termination */
 
96
            char *msg,
 
97
            const char *file, 
 
98
            const char *func,
 
99
            int line, 
 
100
            const gchar *service,
 
101
            const gchar *module, 
 
102
            void *ptr, 
 
103
            gchar *prefix,
 
104
            int err, 
 
105
            gchar *format, 
 
106
            va_list ap) {
 
107
    struct tm t;
 
108
    struct tm gm;
 
109
    long offset;
 
110
    int hoffset, moffset;
 
111
    GTimeVal ts;
 
112
    const char *errmsg;
 
113
    int flag, pos = 0;
 
114
    size_t length, prefixlength;
 
115
    gchar *prefixptr, *ppos;
 
116
 
 
117
    char subformat[DS_MAX_FORMAT_CHARS + 1] = "";
 
118
 
 
119
 
 
120
    if (ds_log_time) {
 
121
        g_get_current_time(&ts);
 
122
        
 
123
        if  ((localtime_r(&ts.tv_sec, &t))&&(!gmtime_r(&ts.tv_sec, &gm))) {
 
124
            offset = (t.tm_sec - gm.tm_sec) + 60*((t.tm_min - gm.tm_min) + 60*(t.tm_hour - gm.tm_hour));
 
125
            if ((t.tm_mday != gm.tm_mday)||(t.tm_mon != gm.tm_mon)||(t.tm_year != gm.tm_year)) {
 
126
                if (t.tm_year > gm.tm_year) offset += 86400;
 
127
                else if (t.tm_year < gm.tm_year) offset -= 86400;
 
128
                else if (t.tm_mon > gm.tm_mon) offset += 86400;
 
129
                else if (t.tm_mon < gm.tm_mon) offset -= 86400;
 
130
                else if (t.tm_mday > gm.tm_mday) offset += 86400;
 
131
                else offset -= 86400;
 
132
            }   
 
133
    
 
134
            g_snprintf(msg + pos, msglen - pos + 1, 
 
135
                "%04u-%02u-%02uT%02u:%02u:%02u.%07lu",
 
136
                t.tm_year+1900,t.tm_mon+1,t.tm_mday,
 
137
                t.tm_hour,t.tm_min,t.tm_sec,
 
138
                ts.tv_usec*10
 
139
            );
 
140
            
 
141
            pos += strlen(msg + pos);
 
142
 
 
143
            if ((offset==0)&&(pos < msglen)) msg[pos++] = 'Z';
 
144
            else {
 
145
                hoffset=offset/3600;
 
146
                moffset=abs(offset/60-hoffset*60);
 
147
                g_snprintf(msg + pos, msglen - pos + 1, "%+03i:%02u", hoffset, moffset);
 
148
                pos += strlen(msg + pos);
 
149
            }
 
150
        } else {
 
151
            g_snprintf(msg + pos, msglen - pos + 1, 
 
152
                "%04u-%02u-%02uT%02u:%02u:%02u.%07uZ",
 
153
                0,0,0,
 
154
                0,0,0,
 
155
                0
 
156
            );
 
157
            pos += strlen(msg + pos);
 
158
        }
 
159
        if (pos < msglen) msg[pos++] = ' ';
 
160
    }
 
161
 
 
162
    flag = 0;
 
163
    if (service) {
 
164
        if (ds_log_thread) g_snprintf(msg + pos, msglen - pos + 1, "%s(%p)", service, g_thread_self());
 
165
        else g_snprintf(msg + pos, msglen - pos + 1, "%s", service);
 
166
        pos += strlen(msg + pos);
 
167
    }
 
168
    
 
169
    if (module) {
 
170
        if ((flag)&&(pos < msglen)) msg[pos++] = '/';
 
171
 
 
172
        if (ptr) g_snprintf(msg + pos, msglen - pos + 1, "%s(%p): ", module, ptr);
 
173
        else g_snprintf(msg + pos, msglen - pos + 1, "%s: ", module);
 
174
 
 
175
        pos += strlen(msg + pos);
 
176
    } else if ((flag)&&(pos < msglen)) msg[pos++] = '/';
 
177
    
 
178
 
 
179
    if (err < 0) {
 
180
#if (defined(_WIN32)||defined(_WIN64))
 
181
        err = GetLastError(); 
 
182
#else
 
183
        err = errno;
 
184
#endif /* WIN */
 
185
    }
 
186
 
 
187
    if (prefix) {
 
188
        prefixptr = prefix;
 
189
        for (ppos = strchr(prefix, '%');ppos;) {
 
190
            length = strspn(ppos + 1, printf_accepted_flags) + 1;
 
191
            if ((length < DS_MAX_FORMAT_CHARS)&&((ppos[length]=='s')||(strspn(ppos+length, printf_integer_keys)>0))) {
 
192
                prefixlength = (ppos - prefixptr);
 
193
                if (prefixlength) {
 
194
                    if ((msglen - pos) > prefixlength) g_strlcpy(msg + pos, prefixptr, prefixlength + 1);
 
195
                    else g_strlcpy(msg + pos, prefixptr, msglen - pos + 1);
 
196
                    pos += strlen(msg + pos);
 
197
                }
 
198
 
 
199
                if (ppos[length]=='s') g_vsnprintf(msg + pos, msglen - pos + 1, format, ap);
 
200
                else {
 
201
                    strncpy(subformat, ppos, length + 1); subformat[length + 1] = 0;
 
202
                    g_snprintf(msg + pos, msglen - pos + 1, subformat, err);
 
203
                }
 
204
                pos += strlen(msg + pos);
 
205
                    
 
206
                prefixptr = ppos + length + 1;
 
207
                ppos = strchr(prefixptr, '%');
 
208
            } else if (ppos[length]) {
 
209
                ppos = strchr(ppos + length + 1, '%');
 
210
            } else {
 
211
                break;
 
212
            }
 
213
        }
 
214
        
 
215
        if (*prefixptr) {
 
216
            g_strlcpy(msg + pos, prefixptr, msglen - pos + 1);
 
217
            pos += strlen(msg + pos);
 
218
        }
 
219
    } else {    
 
220
        if (err) {
 
221
#if (defined(_WIN32)||defined(_WIN64))
 
222
            errmsg = NULL;
 
223
#else
 
224
            errmsg = g_strerror(err);
 
225
#endif /* WIN */
 
226
 
 
227
            if (errmsg) g_snprintf(msg + pos, msglen - pos + 1, "Error %i(%s): ", err, errmsg);
 
228
            else g_snprintf(msg + pos, msglen - pos + 1, "Error %i: ", err);
 
229
 
 
230
            pos += strlen(msg + pos);
 
231
        }
 
232
 
 
233
        if (format) {
 
234
            g_vsnprintf(msg + pos, msglen - pos + 1, format, ap);
 
235
 
 
236
            pos += strlen(msg + pos);
 
237
        }
 
238
    }
 
239
    
 
240
    if (file) {
 
241
        if (func) g_snprintf(msg + pos, msglen - pos + 1, " <%s:%s:%u>", file, func, line);
 
242
        else g_snprintf(msg + pos, msglen - pos + 1, " <%s:%u>", file, line);
 
243
        pos += strlen(msg + pos);
 
244
    }
 
245
    
 
246
//    if (pos < msglen) msg[pos++] = '\n';
 
247
    msg[pos] = 0;
 
248
}
 
249
 
 
250
int _ds_log_message(int condition, 
 
251
            const gchar *log_domain, 
 
252
            GLogLevelFlags log_levels, 
 
253
            const char *file, 
 
254
            const char *func,
 
255
            int line, 
 
256
            const gchar *service,
 
257
            const gchar *module, 
 
258
            void *ptr, 
 
259
            gchar *prefix,
 
260
            int err, 
 
261
            gchar *format, 
 
262
            ...) {
 
263
 
 
264
    va_list ap;
 
265
    char msg[DS_MAX_LOG_STRING + 1] = "";
 
266
    
 
267
    if (condition) return 0;
 
268
    if ((ds_log_level&log_levels)==0) return 1;
 
269
 
 
270
    va_start(ap, format);
 
271
    _ds_gen_message(DS_MAX_LOG_STRING, msg, file, func, line, service, module, ptr, prefix, err, format, ap);
 
272
    va_end(ap);
 
273
 
 
274
    if (log_levels&DS_LOG_CLEAN_MESSAGE) {
 
275
        if (prefix) g_free(prefix);
 
276
        else if (format) g_free(format);
 
277
    }
 
278
 
 
279
    if ((!ds_exception_handler)||(log_levels&ds_exception_level==0)||(ds_log_exception_message)) {
 
280
#ifdef DS_LOG_SUPPORT_THREADS
 
281
        g_static_mutex_lock(g_log_mutex);
 
282
#endif /* DS_LOG_SUPPORT_THREADS */
 
283
        g_log(log_domain, log_levels&DS_LOG_LEVEL_MASK, msg);
 
284
#ifdef DS_LOG_SUPPORT_THREADS
 
285
        g_static_mutex_unlock(g_log_mutex);
 
286
#endif /* DS_LOG_SUPPORT_THREADS */
 
287
    }
 
288
 
 
289
    if ((ds_exception_handler)&&(log_levels&ds_exception_level)) {
 
290
        ds_exception_handler(err, msg);
 
291
    } 
 
292
    
 
293
    if (log_levels&DS_LOG_FATAL_MESSAGE) {
 
294
        if (file) g_error(" Program stops at %s:%u. Bye\n", file, line);
 
295
        else g_error(" Program stops. Bye\n");
 
296
        exit(1);
 
297
    }
 
298
    
 
299
    return 1;
 
300
}
 
301
 
 
302