Delete all Trailing spaces in code.
[reactos.git] / rosapps / smartpdf / baseutils / log_util.c
1 /* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
2 The author disclaims copyright to this source code. */
3 #include "log_util.h"
4 #include "str_util.h"
5
6 /* Simple logging. 'slog' stands for "simple logging". I figured that 'log'
7 is a very common name so used something else, but still short as a prefix
8 for API names */
9
10 /* TODO: slogfmt(const char *fmt, ...) */
11
12 /* TODO: extend to more than one file, by keeping a list of file names */
13 const TCHAR * g_cur_fileName = NULL;
14
15 /* initialize logging system, should be called before any logging calls */
16 BOOL slog_init(void)
17 {
18 /* do nothing yet */
19 return TRUE;
20 }
21
22 /* deinitialize logging system. Should be called before the program quits */
23 void slog_deinit(void)
24 {
25 slog_file_log_stop(NULL);
26 }
27
28 /* start logging to a file 'fileName'. From now on until slog_file_log_stop()
29 all slog* logging will also go to a file. If a file of that name already
30 exists, it'll overwrite it. */
31 BOOL slog_file_log_start(const TCHAR *fileName)
32 {
33 if (!fileName) return FALSE;
34 g_cur_fileName = tstr_dup(fileName);
35 DeleteFile(fileName);
36 return TRUE;
37 }
38
39 /* like 'slog_file_log_start' but will create a unique file based on 'fileName'.
40 If a 'fileName' has extension, it'll try the first available
41 '$file-$NNN.$ext' file (e.g. "my-app-log-000.txt") if 'fileName' is "my-app-log.txt"
42 If there is no extension, it'll be '$file-$NNN' */
43 int slog_file_log_unique_start(const TCHAR *fileName)
44 {
45 assert(0); /* not implemented */
46 return FALSE;
47 }
48
49 void slog_file_log_stop(const TCHAR *fileName)
50 {
51 /* 'fileName' is currently unused. The idea is that it should match the
52 name given to slog_file_log_start */
53 if (g_cur_fileName) {
54 free((void*)g_cur_fileName);
55 g_cur_fileName = NULL;
56 }
57 }
58
59 /* log 'txt' to all currently enabled loggers */
60 void slog_str(const char *txt)
61 {
62 DWORD to_write_cb;
63 DWORD written_cb;
64 int f_ok;
65 HANDLE fh;
66
67 if (!txt) return;
68
69 if (!g_cur_fileName) return;
70
71 /* we're using this inefficient way of re-opening the file for each
72 log so that we can also watch this file life using tail-like program */
73 fh = CreateFile(g_cur_fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
74 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
75 if (INVALID_HANDLE_VALUE == fh)
76 return;
77 SetFilePointer(fh, 0, NULL, FILE_END);
78 to_write_cb = (DWORD)strlen(txt);
79 f_ok = WriteFile(fh, (void*)txt, to_write_cb, &written_cb, NULL);
80 assert(f_ok && (written_cb == to_write_cb));
81 CloseHandle(fh);
82 }
83
84 void slog_str_printf(const char *format, ...)
85 {
86 char * tmp;
87 va_list args;
88
89 va_start(args, format);
90 tmp = str_printf_args(format, args);
91 va_end(args);
92 if (!tmp) return;
93 slog_str(tmp);
94 free(tmp);
95 }
96
97 static WCHAR* last_error_as_wstr(void)
98 {
99 WCHAR *msgBuf = NULL;
100 WCHAR *copy;
101 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
102 NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
103 (LPTSTR) &msgBuf, 0, NULL);
104 if (!msgBuf) return NULL;
105 copy = wstr_dup(msgBuf);
106 LocalFree(msgBuf);
107 return copy;
108 }
109
110 void slog_last_error(const char *optional_prefix)
111 {
112 WCHAR *txt = last_error_as_wstr();
113 if (!txt) return;
114 slog_str(optional_prefix);
115 slog_wstr_nl(txt);
116 free(txt);
117 }
118
119 /* TODO: converting by casting isn't always correct but here we don't care much */
120 char *wstr_to_str(const WCHAR *txt)
121 {
122 char *txt_copy, *tmp;
123
124 if (!txt) return NULL;
125
126 txt_copy = (char*)malloc(tstr_len(txt) + 1);
127 if (!txt_copy) return NULL;
128
129 tmp = txt_copy;
130 while (*txt) {
131 *tmp++ = (char)*txt++;
132 }
133 *tmp = 0;
134 return txt_copy;
135 }
136
137 void slog_wstr(const WCHAR *txt)
138 {
139 char *txt_copy;
140
141 txt_copy = wstr_to_str(txt);
142 if (!txt_copy) return;
143 slog_str(txt_copy);
144 free(txt_copy);
145 }
146
147 /* log 'txt' to all currently enabled loggers and add newline */
148 void slog_str_nl(const char *txt)
149 {
150 /* TODO: given the 'reopen the file each time' implementation of
151 slgotxt, this should be optimized */
152 slog_str(txt);
153 slog_str("\n");
154 }
155
156 void slog_wstr_nl(const WCHAR *txt)
157 {
158 slog_wstr(txt);
159 slog_wstr(_T("\n"));
160 }