638d63feaa13172d3df2e7cde302c38f34a77d2d
[vg.git] / vg_log.c
1 #ifndef VG_LOG_C
2 #include <stdarg.h>
3 #include <string.h>
4 #include <malloc.h>
5 #include "vg_stdint.h"
6 #include "vg_platform.h"
7 #include "vg_log.h"
8
9 #ifndef _WIN32
10 #include <execinfo.h>
11 #endif
12
13 static void _vg_log_append_line( const char *str ){
14 if( vg_log.log_line_count < vg_list_size( vg_log.log ) )
15 vg_log.log_line_count ++;
16
17 char *dest = vg_log.log[ vg_log.log_line_current ++ ];
18 vg_strncpy( str, dest, vg_list_size(vg_log.log[0]), k_strncpy_allow_cutoff );
19
20 if( vg_log.log_line_current >= vg_list_size( vg_log.log ) )
21 vg_log.log_line_current = 0;
22 }
23
24 static void _vg_logx_va( FILE *file,
25 const char *location, const char *prefix,
26 const char *colour,
27 const char *fmt, va_list args )
28 {
29
30 /* @model.h:2000 info| dwahjdiawdjaiwdwadwa djaidjwa\n
31 * | djwaidwaj waodawh a\n
32 * | dwajdkiawjdiw
33 */
34
35 #ifdef VG_GAME
36 SDL_AtomicLock( &log_print_sl );
37 #endif
38
39 char buffer[4096];
40
41 vsnprintf( buffer, vg_list_size(buffer), fmt, args );
42
43 const char *line = buffer;
44 char logline[96];
45
46 for( u32 i=0; i<vg_list_size(buffer); i++ ){
47 char c = buffer[i];
48
49 if( c == '\0' || c == '\n' ){
50 buffer[i] = '\0';
51
52 const char *line_prefix = "",
53 *line_location = "";
54
55 if( line == buffer ) {
56 line_prefix = prefix;
57 line_location = location;
58 }
59
60 snprintf( logline, 96, "%s%7s" KNRM "|%s %s",
61 colour, line_prefix, colour, line );
62 _vg_log_append_line( logline );
63
64 if( location ){
65 #ifdef VG_GAME
66 const char *thread_colours[] = {
67 KGRN, KMAG, KCYN, KYEL, KBLU
68 };
69
70 const char *colour = thread_colours[
71 (vg_thread_purpose() % vg_list_size( thread_colours ))];
72
73 fprintf( file, "%s[%u]"KNRM"%.32s",
74 colour, vg_thread_purpose(), line_location );
75 #else
76 fprintf( file, KNRM "%.32s", line_location );
77 #endif
78 }
79
80 fputs( logline, file );
81 fputc( '\n', file );
82 fputs( KNRM, file );
83
84 if( c == '\0' ) break;
85 if( buffer[i+1] == '\0' ) break;
86 line = buffer+i+1;
87 }
88 }
89
90 #ifdef VG_GAME
91 SDL_AtomicUnlock( &log_print_sl );
92 #endif
93 }
94
95 static void vg_logx( FILE *file,
96 const char *location, const char *prefix,
97 const char *colour,
98 const char *fmt, ... ){
99
100 va_list args;
101 va_start( args, fmt );
102 _vg_logx_va( file,
103 #ifdef VG_LOG_SOURCE_INFO
104 location,
105 #else
106 NULL,
107 #endif
108 prefix, colour, fmt, args );
109 va_end( args );
110 }
111
112 static void vg_print_backtrace(void){
113 #ifndef _WIN32
114
115 void *array[20];
116 char **strings;
117 int size, i;
118
119 size = backtrace( array, 20 );
120 strings = backtrace_symbols( array, size );
121
122 if( strings != NULL ){
123 vg_error( "---------------- gnu backtrace -------------\n" );
124
125 for( int i=0; i<size; i++ )
126 vg_info( "%s\n", strings[i] );
127
128 vg_error( "---------------- gnu backtrace -------------\n" );
129 }
130
131 free( strings );
132
133 #endif
134 }
135
136 #endif /* VG_LOG_C */