26 #define LELY_UTIL_DIAG_INLINE extern inline
41 #pragma comment(lib, "wtsapi32.lib")
43 #elif _POSIX_C_SOURCE >= 200809L && !defined(__NEWLIB__)
48 #ifndef LELY_DIALOG_DIAG_TIMEOUT
49 #define LELY_DIALOG_DIAG_TIMEOUT 10
56 static void *diag_handle;
58 static void *diag_at_handle;
68 assert(!end || end >= begin);
70 const char *cp = begin;
71 while ((!end || cp < end) && *cp) {
74 if ((!end || cp < end) && *cp ==
'\n')
107 int r = snprintf(s, n,
"%s:", at->
filename);
111 r =
MIN((
size_t)r, n);
115 r = snprintf(s, n,
"%d:", at->
line);
119 r =
MIN((
size_t)r, n);
123 r = snprintf(s, n,
"%d:", at->
column);
142 *phandler = diag_handler;
144 *phandle = diag_handle;
150 diag_handler = handler;
151 diag_handle = handle;
158 *phandler = diag_at_handler;
160 *phandle = diag_at_handle;
166 diag_at_handler = handler;
167 diag_at_handle = handle;
174 va_start(ap, format);
175 vdiag(severity, errc, format, ap);
183 diag_handler(diag_handle, severity, errc, format, ap);
188 const char *format, ...)
191 va_start(ap, format);
192 vdiag_at(severity, errc, at, format, ap);
198 const char *format, va_list ap)
201 diag_at_handler(diag_at_handle, severity, errc, at, format, ap);
206 const char *format, ...)
209 va_start(ap, format);
210 vdiag_if(severity, errc, at, format, ap);
216 const char *format, va_list ap)
219 vdiag_at(severity, errc, at, format, ap);
224 const char *format, va_list ap)
231 const struct floc *at,
const char *format, va_list ap)
244 fprintf(stderr,
"%s\n", s);
259 const char *format, va_list ap)
261 const char *cmd = handle;
264 fprintf(stderr,
"%s: ", cmd);
274 const char *format, va_list ap)
281 const struct floc *at,
const char *format, va_list ap)
294 const char *format, va_list ap)
301 const struct floc *at,
const char *format, va_list ap)
303 LPSTR pTitle = (LPSTR)(handle ? handle :
"");
305 DWORD Style = MB_OK | MB_SETFOREGROUND | MB_TOPMOST;
308 case DIAG_INFO: Style |= MB_ICONINFORMATION;
break;
311 case DIAG_FATAL: Style |= MB_ICONERROR;
break;
316 char *pMessage = NULL;
319 WTSSendMessageA(WTS_CURRENT_SERVER_HANDLE,
320 WTSGetActiveConsoleSessionId(), pTitle,
321 strlen(pTitle), pMessage, strlen(pMessage),
322 Style, LELY_DIALOG_DIAG_TIMEOUT, &dwResponse,
336 const char *format, va_list ap)
343 const struct floc *at,
const char *format, va_list ap)
347 if (time(&timer) != -1) {
350 struct tm *timeptr = NULL;
351 if (localtime_s(&tm, &timer))
353 #elif defined(_POSIX_C_SOURCE)
355 struct tm *timeptr = localtime_r(&timer, &tm);
357 struct tm *timeptr = localtime(&timer);
362 if (strftime(buf,
sizeof(buf),
363 "%a, %d %b %Y %H:%M:%S %z", timeptr)
366 fprintf(stderr,
"%s: ", buf);
378 const char *format, va_list ap)
385 const struct floc *at,
const char *format, va_list ap)
387 #if _POSIX_C_SOURCE >= 200809L && !defined(__NEWLIB__)
390 int priority = LOG_USER;
392 case DIAG_DEBUG: priority |= LOG_DEBUG;
break;
393 case DIAG_INFO: priority |= LOG_INFO;
break;
396 case DIAG_FATAL: priority |= LOG_EMERG;
break;
402 syslog(priority,
"%s", s);
415 const char *format, va_list ap)
422 const char *format, va_list ap)
429 const struct floc *at,
const char *format, va_list ap)
442 r =
MIN((
size_t)r, n);
445 r = snprintf(s, n,
" ");
449 r =
MIN((
size_t)r, n);
455 case DIAG_DEBUG: r = snprintf(s, n,
"debug: ");
break;
457 case DIAG_WARNING: r = snprintf(s, n,
"warning: ");
break;
458 case DIAG_ERROR: r = snprintf(s, n,
"error: ");
break;
459 case DIAG_FATAL: r = snprintf(s, n,
"fatal: ");
break;
460 default: r = 0;
break;
465 r =
MIN((
size_t)r, n);
469 if (format && *format) {
470 r = vsnprintf(s, n, format, ap);
474 r =
MIN((
size_t)r, n);
478 r = snprintf(s, n,
": ");
482 r =
MIN((
size_t)r, n);
489 const char *errstr =
errc2str(errc);
491 r = snprintf(s, n,
"%s", errstr);
503 const struct floc *at,
const char *format, va_list ap)
514 char *s = malloc(n + 1);
541 const char *cmd = path;
545 while (cmd >= path && *cmd !=
'\\')
547 while (cmd >= path && *cmd !=
'/')
void syslog_diag_handler(void *handle, enum diag_severity severity, int errc, const char *format, va_list ap)
The diag() handler used for the system logging facilities.
void daemon_diag_at_handler(void *handle, enum diag_severity severity, int errc, const struct floc *at, const char *format, va_list ap)
The diag_at() handler for daemons.
void diag_set_handler(diag_handler_t *handler, void *handle)
Sets the handler function for diag().
int vsnprintf_diag(char *s, size_t n, enum diag_severity severity, int errc, const char *format, va_list ap)
Prints a diagnostic message to a string buffer.
size_t floc_lex(struct floc *at, const char *begin, const char *end)
Increments a file location by reading characters from a memory buffer.
int vasprintf_diag_at(char **ps, enum diag_severity severity, int errc, const struct floc *at, const char *format, va_list ap)
Equivalent to vsnprintf_diag_at(), except that it allocates a string large enough to hold the output,...
void cmd_diag_handler(void *handle, enum diag_severity severity, int errc, const char *format, va_list ap)
The diag() handler used for command-line programs.
void vdiag(enum diag_severity severity, int errc, const char *format, va_list ap)
Emits a diagnostic message.
void vdiag_at(enum diag_severity severity, int errc, const struct floc *at, const char *format, va_list ap)
Emits a diagnostic message occurring at a location in a text file.
const char * cmdname(const char *path)
Extracts the command name from a path.
void default_diag_at_handler(void *handle, enum diag_severity severity, int errc, const struct floc *at, const char *format, va_list ap)
The default diag_at() handler.
void diag_at_set_handler(diag_at_handler_t *handler, void *handle)
Sets the handler function for diag_at().
int vasprintf_diag(char **ps, enum diag_severity severity, int errc, const char *format, va_list ap)
Equivalent to vsnprintf_diag(), except that it allocates a string large enough to hold the output,...
void diag_if(enum diag_severity severity, int errc, const struct floc *at, const char *format,...)
Emits a diagnostic message occurring at a location in a text file.
void diag_at_get_handler(diag_at_handler_t **phandler, void **phandle)
Retrieves the handler function for diag_at().
void vdiag_if(enum diag_severity severity, int errc, const struct floc *at, const char *format, va_list ap)
Emits a diagnostic message occurring at a location in a text file.
int snprintf_floc(char *s, size_t n, const struct floc *at)
Prints a file location to a string buffer.
void daemon_diag_handler(void *handle, enum diag_severity severity, int errc, const char *format, va_list ap)
The diag() handler for daemons.
void diag_at(enum diag_severity severity, int errc, const struct floc *at, const char *format,...)
Emits a diagnostic message occurring at a location in a text file.
void log_diag_at_handler(void *handle, enum diag_severity severity, int errc, const struct floc *at, const char *format, va_list ap)
The diag_at() handler used for log-files.
void diag(enum diag_severity severity, int errc, const char *format,...)
Emits a diagnostic message.
void log_diag_handler(void *handle, enum diag_severity severity, int errc, const char *format, va_list ap)
The diag() handler for log files.
int vsnprintf_diag_at(char *s, size_t n, enum diag_severity severity, int errc, const struct floc *at, const char *format, va_list ap)
Prints a diagnostic message occurring at a location in a text file to a string buffer.
void diag_get_handler(diag_handler_t **phandler, void **phandle)
Retrieves the handler function for diag().
void default_diag_handler(void *handle, enum diag_severity severity, int errc, const char *format, va_list ap)
The default diag() handler.
void syslog_diag_at_handler(void *handle, enum diag_severity severity, int errc, const struct floc *at, const char *format, va_list ap)
The diag_at() handler used for the system logging facilities.
This header file is part of the utilities library; it contains the diagnostic declarations.
void dialog_diag_at_handler(void *handle, enum diag_severity severity, int errc, const struct floc *at, const char *format, va_list ap)
The diag_at() handler for dialog boxes.
void diag_at_handler_t(void *handle, enum diag_severity severity, int errc, const struct floc *at, const char *format, va_list ap)
The function type of a handler for diag_at().
diag_severity
The severity of a diagnostic message.
@ DIAG_DEBUG
A debug message.
@ DIAG_INFO
An informational message.
@ DIAG_FATAL
A fatal error, which SHOULD result in program termination.
void diag_handler_t(void *handle, enum diag_severity severity, int errc, const char *format, va_list ap)
The function type of a handler for diag().
void dialog_diag_handler(void *handle, enum diag_severity severity, int errc, const char *format, va_list ap)
The diag() handler for dialog boxes.
const char * errc2str(int errc)
Returns a string describing a native error code.
#define MIN(a, b)
Returns the minimum of a and b.
This is the internal header file of the utilities library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdio....
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
This header file is part of the C11 and POSIX compatibility library; it includes <string....
A location in a text file.
int line
The line number (starting from 1).
int column
The column number (starting from 1).
const char * filename
The name of the file.