2014-07-09 00:55:20 -04:00
|
|
|
#ifndef UTIL_H
|
|
|
|
|
#define UTIL_H
|
|
|
|
|
|
2015-07-04 13:45:24 -05:00
|
|
|
#ifdef WIN32
|
2026-09-18 20:12:34 +09:00
|
|
|
/* For WriteConsoleW() below */
|
2015-07-04 13:45:24 -05:00
|
|
|
#include <windows.h>
|
|
|
|
|
#include <io.h>
|
2026-09-18 20:12:34 +09:00
|
|
|
#include <limits.h>
|
2015-07-04 13:45:24 -05:00
|
|
|
#include <processenv.h>
|
|
|
|
|
#include <shellapi.h>
|
2026-09-18 20:12:34 +09:00
|
|
|
#include <stdlib.h>
|
2015-07-04 13:45:24 -05:00
|
|
|
#include <wchar.h>
|
|
|
|
|
#include <wtypes.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2014-07-09 00:55:20 -04:00
|
|
|
#include "jv.h"
|
|
|
|
|
|
|
|
|
|
jv expand_path(jv);
|
|
|
|
|
jv get_home(void);
|
|
|
|
|
jv jq_realpath(jv);
|
|
|
|
|
|
2015-06-26 21:24:01 -05:00
|
|
|
/*
|
2026-09-18 20:12:34 +09:00
|
|
|
* The Windows console does not do UTF-8. Bytes written to it, with
|
|
|
|
|
* fwrite() or with WriteFile() alike, are decoded with the console's
|
|
|
|
|
* output code page, so anything but ASCII comes out as mojibake unless
|
|
|
|
|
* the user happened to run `chcp 65001` first. The wide character
|
|
|
|
|
* console API is code page independent, so convert to UTF-16 and use
|
|
|
|
|
* WriteConsoleW() instead. We must not call SetConsoleOutputCP(): the
|
|
|
|
|
* code page belongs to the console rather than to us, so changing it
|
|
|
|
|
* also changes the shell we were started from (see #1121 and #1184).
|
2015-06-26 21:24:01 -05:00
|
|
|
*
|
2026-09-18 20:12:34 +09:00
|
|
|
* Only a console needs this; a file or a pipe wants the UTF-8 bytes.
|
|
|
|
|
* The is_tty flag alone cannot tell the two apart, as it is computed
|
|
|
|
|
* once, from stdout, and passed along even for writes to stderr, so
|
|
|
|
|
* ask the handle we are about to write to.
|
2015-06-26 21:24:01 -05:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static void priv_fwrite(const char *s, size_t len, FILE *fout, int is_tty) {
|
|
|
|
|
#ifdef WIN32
|
2026-09-18 20:12:34 +09:00
|
|
|
if (is_tty && len > 0 && len <= INT_MAX / sizeof(wchar_t)) {
|
|
|
|
|
HANDLE h = (HANDLE)_get_osfhandle(fileno(fout));
|
|
|
|
|
DWORD mode;
|
|
|
|
|
if (GetConsoleMode(h, &mode)) {
|
|
|
|
|
int wlen = MultiByteToWideChar(CP_UTF8, 0, s, (int)len, NULL, 0);
|
|
|
|
|
wchar_t *ws = wlen > 0 ? malloc(wlen * sizeof(*ws)) : NULL;
|
|
|
|
|
if (ws != NULL) {
|
|
|
|
|
wlen = MultiByteToWideChar(CP_UTF8, 0, s, (int)len, ws, wlen);
|
|
|
|
|
fflush(fout); /* keep our order with stdio writes to this stream */
|
|
|
|
|
for (int done = 0; done < wlen;) {
|
|
|
|
|
DWORD written;
|
|
|
|
|
/* WriteConsoleW() may write fewer characters than asked for. */
|
|
|
|
|
if (!WriteConsoleW(h, ws + done, wlen - done, &written, NULL) ||
|
|
|
|
|
written == 0)
|
|
|
|
|
break;
|
|
|
|
|
done += written;
|
|
|
|
|
}
|
|
|
|
|
free(ws);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-06-26 21:24:01 -05:00
|
|
|
#endif
|
2026-09-18 20:12:34 +09:00
|
|
|
fwrite(s, 1, len, fout);
|
2015-06-26 21:24:01 -05:00
|
|
|
}
|
2015-06-22 18:15:51 -05:00
|
|
|
|
2014-07-22 22:44:52 -05:00
|
|
|
const void *_jq_memmem(const void *haystack, size_t haystacklen,
|
|
|
|
|
const void *needle, size_t needlelen);
|
2014-07-09 00:55:20 -04:00
|
|
|
|
|
|
|
|
#ifndef MIN
|
|
|
|
|
#define MIN(a,b) \
|
|
|
|
|
({ __typeof__ (a) _a = (a); \
|
|
|
|
|
__typeof__ (b) _b = (b); \
|
|
|
|
|
_a < _b ? _a : _b; })
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef MAX
|
|
|
|
|
#define MAX(a,b) \
|
|
|
|
|
({ __typeof__ (a) _a = (a); \
|
|
|
|
|
__typeof__ (b) _b = (b); \
|
|
|
|
|
_a > _b ? _a : _b; })
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-08-12 20:18:45 +02:00
|
|
|
#include <time.h>
|
|
|
|
|
|
2024-04-18 01:38:29 +02:00
|
|
|
#ifndef HAVE_STRPTIME
|
2023-08-12 20:18:45 +02:00
|
|
|
char* strptime(const char *buf, const char *fmt, struct tm *tm);
|
|
|
|
|
#endif
|
|
|
|
|
|
2014-07-09 00:55:20 -04:00
|
|
|
#endif /* UTIL_H */
|