1 /* vim:expandtab:ts=2 sw=2:
2 */
3 /*  Grafx2 - The Ultimate 256-color bitmap paint program
4 
5 	Copyright owned by various GrafX2 authors, see COPYRIGHT.txt for details.
6 
7     Grafx2 is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     as published by the Free Software Foundation; version 2
10     of the License.
11 
12     Grafx2 is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with Grafx2; if not, see <http://www.gnu.org/licenses/>
19 */
20 
21 #if defined(_MSC_VER)
22 #include <windows.h>
23 #if _MSC_VER < 1900
24 #define snprintf _snprintf
25 #endif
26 #endif
27 #if defined(USE_SDL2)
28 #include <SDL.h>
29 #endif
30 #include <stdio.h>
31 #include <string.h>
32 #include "gfx2log.h"
33 
34 GFX2_Log_priority_T GFX2_verbosity_level = GFX2_INFO;
35 
GFX2_Log(GFX2_Log_priority_T priority,const char * fmt,...)36 extern void GFX2_Log(GFX2_Log_priority_T priority, const char * fmt, ...)
37 {
38   va_list ap;
39 
40   va_start(ap, fmt);
41   GFX2_LogV(priority, fmt, ap);
42   va_end(ap);
43 }
44 
GFX2_LogV(GFX2_Log_priority_T priority,const char * fmt,va_list ap)45 extern void GFX2_LogV(GFX2_Log_priority_T priority, const char * fmt, va_list ap)
46 {
47 #if !defined(_DEBUG)
48   if ((unsigned)GFX2_verbosity_level < (unsigned)priority)
49     return;
50 #endif
51 #if defined(USE_SDL2)
52   {
53     int sdl_priority;
54     switch(priority)
55     {
56       case GFX2_ERROR:
57         sdl_priority = SDL_LOG_PRIORITY_ERROR;
58         break;
59       case GFX2_WARNING:
60         sdl_priority = SDL_LOG_PRIORITY_WARN;
61         break;
62       case GFX2_INFO:
63         sdl_priority = SDL_LOG_PRIORITY_INFO;
64         break;
65       case GFX2_DEBUG:
66         sdl_priority = SDL_LOG_PRIORITY_DEBUG;
67         break;
68       default:
69         sdl_priority = SDL_LOG_PRIORITY_CRITICAL; // unknown
70     }
71     SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, sdl_priority, fmt, ap);
72   }
73 #else
74   vfprintf((unsigned)priority >= GFX2_INFO ? stdout : stderr, fmt, ap);
75 #endif
76 #if defined(_MSC_VER) && defined(_DEBUG) && !defined(USE_SDL2)
77   {
78     char message[1024];
79     vsnprintf(message, sizeof(message), fmt, ap);
80     OutputDebugStringA(message);
81   }
82 #endif
83 }
84 
GFX2_LogHexDump(GFX2_Log_priority_T priority,const char * header,const byte * data,long offset,long count)85 extern void GFX2_LogHexDump(GFX2_Log_priority_T priority, const char * header, const byte * data, long offset, long count)
86 {
87   char line[128];
88   long i;
89   int previous_allzero_count = 0;
90   while (count > 0)
91   {
92     int p = 0, r;
93     int allzero = 1;
94     for (i = 0; i < count && i < 16; i++)
95     {
96       if (data[offset+i] != 0)
97       {
98         allzero = 0;
99         break;
100       }
101     }
102     if (previous_allzero_count && allzero)
103     {
104       // prints a single "*" for multiple line of 00's
105       if (previous_allzero_count == 1)
106         GFX2_Log(priority, "*\n");
107     }
108     else
109     {
110       r = snprintf(line + p, sizeof(line) - p, "%s%06lX:", header, offset);
111       if (r < 0)
112         return;
113       p += r;
114       for (i = 0; i < count && i < 16; i++)
115       {
116         r = snprintf(line + p, sizeof(line) - p, " %02x", data[offset+i]);
117         if (r < 0)
118           return;
119         p += r;
120         if (i == 7)
121           line[p++] = ' ';
122       }
123       if (i < 16)
124       {
125         if (i < 7)
126           line[p++] = ' ';
127         memset(line + p, ' ', 3 * (16 - i));
128         p += 3 * (16 - i);
129       }
130       line[p++] = ' ';
131       line[p++] = '|';
132       for (i = 0; i < count && i < 16; i++)
133         line[p++] = data[offset+i]>=32 && data[offset+i]<127 ? data[offset+i] : '.';
134       line[p++] = '\0';
135       GFX2_Log(priority, "%s\n", line);
136     }
137     if (allzero)
138       previous_allzero_count++;
139     else
140       previous_allzero_count = 0;
141     count -= i;
142     offset += i;
143   }
144   // print the ending offset if there was "*"
145   if (previous_allzero_count > 1)
146     GFX2_Log(priority, "%s%06lX\n", header, offset);
147 }
148