Coverage Report

Created: 2026-10-17 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jq/src/util.h
Line
Count
Source
1
#ifndef UTIL_H
2
#define UTIL_H
3
4
#ifdef WIN32
5
/* For WriteConsoleW() below */
6
#include <windows.h>
7
#include <io.h>
8
#include <limits.h>
9
#include <processenv.h>
10
#include <shellapi.h>
11
#include <stdlib.h>
12
#include <wchar.h>
13
#include <wtypes.h>
14
#endif
15
16
#include "jv.h"
17
18
jv expand_path(jv);
19
jv get_home(void);
20
jv jq_realpath(jv);
21
22
/*
23
 * The Windows console does not do UTF-8.  Bytes written to it, with
24
 * fwrite() or with WriteFile() alike, are decoded with the console's
25
 * output code page, so anything but ASCII comes out as mojibake unless
26
 * the user happened to run `chcp 65001` first.  The wide character
27
 * console API is code page independent, so convert to UTF-16 and use
28
 * WriteConsoleW() instead.  We must not call SetConsoleOutputCP(): the
29
 * code page belongs to the console rather than to us, so changing it
30
 * also changes the shell we were started from (see #1121 and #1184).
31
 *
32
 * Only a console needs this; a file or a pipe wants the UTF-8 bytes.
33
 * The is_tty flag alone cannot tell the two apart, as it is computed
34
 * once, from stdout, and passed along even for writes to stderr, so
35
 * ask the handle we are about to write to.
36
 */
37
38
0
static void priv_fwrite(const char *s, size_t len, FILE *fout, int is_tty) {
39
#ifdef WIN32
40
  if (is_tty && len > 0 && len <= INT_MAX / sizeof(wchar_t)) {
41
    HANDLE h = (HANDLE)_get_osfhandle(fileno(fout));
42
    DWORD mode;
43
    if (GetConsoleMode(h, &mode)) {
44
      int wlen = MultiByteToWideChar(CP_UTF8, 0, s, (int)len, NULL, 0);
45
      wchar_t *ws = wlen > 0 ? malloc(wlen * sizeof(*ws)) : NULL;
46
      if (ws != NULL) {
47
        wlen = MultiByteToWideChar(CP_UTF8, 0, s, (int)len, ws, wlen);
48
        fflush(fout); /* keep our order with stdio writes to this stream */
49
        for (int done = 0; done < wlen;) {
50
          DWORD written;
51
          /* WriteConsoleW() may write fewer characters than asked for. */
52
          if (!WriteConsoleW(h, ws + done, wlen - done, &written, NULL) ||
53
              written == 0)
54
            break;
55
          done += written;
56
        }
57
        free(ws);
58
        return;
59
      }
60
    }
61
  }
62
#endif
63
0
  fwrite(s, 1, len, fout);
64
0
}
Unexecuted instantiation: jv.c:priv_fwrite
Unexecuted instantiation: util.c:priv_fwrite
Unexecuted instantiation: jv_print.c:priv_fwrite
Unexecuted instantiation: linker.c:priv_fwrite
Unexecuted instantiation: locfile.c:priv_fwrite
Unexecuted instantiation: builtin.c:priv_fwrite
Unexecuted instantiation: compile.c:priv_fwrite
65
66
const void *_jq_memmem(const void *haystack, size_t haystacklen,
67
                       const void *needle, size_t needlelen);
68
69
#ifndef MIN
70
#define MIN(a,b) \
71
1
  ({ __typeof__ (a) _a = (a); \
72
1
   __typeof__ (b) _b = (b); \
73
1
   _a < _b ? _a : _b; })
74
#endif
75
#ifndef MAX
76
#define MAX(a,b) \
77
0
  ({ __typeof__ (a) _a = (a); \
78
0
   __typeof__ (b) _b = (b); \
79
0
   _a > _b ? _a : _b; })
80
#endif
81
82
#include <time.h>
83
84
#ifndef HAVE_STRPTIME
85
char* strptime(const char *buf, const char *fmt, struct tm *tm);
86
#endif
87
88
#endif /* UTIL_H */