File: jc_fwprint.c

package info (click to toggle)
libjodycode 4.1.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 3,676 kB
  • sloc: ansic: 2,820; makefile: 372; sh: 160; xml: 37
file content (105 lines) | stat: -rw-r--r-- 2,360 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* libjodycode: easy wide single-string fprintf()
 *
 * Copyright (C) 2014-2026 by Jody Bruchon <jody@jodybruchon.com>
 * Released under The MIT License
 */

#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "likely_unlikely.h"
#include "libjodycode.h"

#ifdef ON_WINDOWS
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <io.h>
 static int jc_out_mode = _O_TEXT;
 static int jc_err_mode = _O_TEXT;
#endif  /* ON_WINDOWS */


#ifdef ON_WINDOWS
/* Set jc_fwprint output modes for stdout/stderr to TEXT, BINARY, or UTF-16
 * 0: no change
 * 1: set to text mode
 * 2: set to binary (UTF-8) mode
 * 3: set to UTF-16 mode
 * 4: set to UTF-16 mode for terminals, otherwise set to binary mode
 */
void jc_set_output_modes(const int out, const int err)
{
	switch (out) {
		default:
		case 0:
			break;
		case 1:
			jc_out_mode = _O_TEXT;
			break;
		case 2:
			jc_out_mode = _O_BINARY;
			break;
		case 3:
			jc_out_mode = _O_U16TEXT;
			break;
		case 4:
			if (!_isatty(_fileno(stdout))) jc_out_mode = _O_BINARY;
			else jc_out_mode = _O_U16TEXT;
			break;
	}

	switch (err) {
		default:
		case 0:
			break;
		case 1:
			jc_err_mode = _O_TEXT;
			break;
		case 2:
			jc_err_mode = _O_BINARY;
			break;
		case 3:
			jc_err_mode = _O_U16TEXT;
			break;
		case 4:
			if (!_isatty(_fileno(stderr))) jc_err_mode = _O_BINARY;
			else jc_err_mode = _O_U16TEXT;
			break;
	}

	return;
}
#endif /* ON_WINDOWS */


/* Print a string that is wide on Windows but normal on POSIX */
int jc_fwprint(FILE * const restrict stream, const char * const restrict str, const int cr)
{
#ifdef UNICODE
	int retval;
	int stream_mode;
	JC_WCHAR_T *wstr;

	stream_mode = (stream == stderr) ? jc_err_mode : jc_out_mode;

	if (stream_mode == _O_U16TEXT) {
		/* Convert to wide string and send to wide console output */
		if (jc_string_to_wstring(str, &wstr) != 0) return JC_EALLOC;
		fflush(stream);
		_setmode(_fileno(stream), stream_mode);
		if (cr == 2) retval = fwprintf(stream, L"%ls%C", wstr, 0);
		else retval = fwprintf(stream, L"%ls%ls", wstr, cr == 1 ? L"\n" : L"");
		fflush(stream);
		_setmode(_fileno(stream), _O_TEXT);
		free(wstr);
		return retval;
	} else {
#endif
		if (cr == 2) return fprintf(stream, "%s%c", str, 0);
		else return fprintf(stream, "%s%s", str, cr == 1 ? "\n" : "");
#ifdef UNICODE
	}
#endif
}