1%% options 2 3copyright owner = Dirk Krause 4copyright year = 2015-xxxx 5SPDX-License-Identifier: BSD-3-Clause 6 7 8 9%% header 10 11/** @file 12 File functions for dkChar characters 13 and strings. 14 15 CRT on Windows: Required. 16*/ 17 18#ifndef DK4CONF_H_INCLUDED 19#if DK4_BUILDING_DKTOOLS4 20#include "dk4conf.h" 21#else 22#include <dktools-4/dk4conf.h> 23#endif 24#endif 25 26#ifndef DK4TYPES_H_INCLUDED 27#if DK4_BUILDING_DKTOOLS4 28#include <libdk4base/dk4types.h> 29#else 30#include <dktools-4/dk4types.h> 31#endif 32#endif 33 34#ifndef DK4ERROR_H_INCLUDED 35#if DK4_BUILDING_DKTOOLS4 36#include <libdk4base/dk4error.h> 37#else 38#include <dktools-4/dk4error.h> 39#endif 40#endif 41 42#ifndef STDIO_H_INCLUDED 43#include <stdio.h> 44#define STDIO_H_INCLUDED 1 45#endif 46 47#if DK4_HAVE_ERRNO_H 48#ifndef ERRNO_H_INCLUDED 49#include <errno.h> 50#define ERRNO_H_INCLUDED 1 51#endif 52#endif 53 54#ifdef __cplusplus 55extern "C" { 56#endif 57 58/** On Windows, initialize stdout to write dkChar and write a BOM. 59*/ 60void 61dk4fput_initialize_stdout(void); 62 63/** On Windows, initialize stdout to write dkChar. 64*/ 65void 66dk4fput_initialize_stdout_no_bom(void); 67 68/** On Windows, initialize stderr to write dkChar and write a BOM. 69*/ 70void 71dk4fput_initialize_stderr(void); 72 73/** On Windows, initialize stderr to write dkChar. 74*/ 75void 76dk4fput_initialize_stderr_no_bom(void); 77 78/** On Windows, initialize file to write dkChar and write a BOM. 79 @param fipo File to set up. 80*/ 81void 82dk4fput_initialize_file(FILE *fipo); 83 84/** On Windows, initialize file to write dkChar. 85 @param fipo File to set up. 86*/ 87void 88dk4fput_initialize_file_no_bom(FILE *fipo); 89 90/** On Windows, return to the default file encoding for stdout. 91*/ 92void 93dk4fput_cleanup_stdout(void); 94 95/** On Windows, return to the default file encoding for stderr. 96*/ 97void 98dk4fput_cleanup_stderr(void); 99 100/** Write one character to file. 101 @param c Character to write. 102 @param fipo File to write to. 103 @param erp Error report, may be NULL. 104 @return 1 on success, 0 on error. 105 106 Error codes: 107 - DK4_E_NOT_SUPPORTED<br> 108 if writing wide characters is not supported on the system, 109 - DK4_E_INVALID_ARGUMENTS<br> 110 if fipo is NULL, 111 - DK4_E_WRITE_FAILED<br> 112 with errno value in iDetails1 if the write attempt failed. 113*/ 114int 115dk4fputc(dkChar c, FILE *fipo, dk4_er_t *erp); 116 117/** Write one string to file. 118 @param s String to write. 119 @param fipo File to write to. 120 @param erp Error report, may be NULL. 121 @return 1 on success, 0 on error. 122 123 Error codes: 124 - DK4_E_NOT_SUPPORTED<br> 125 if writing wide character strings is not supported on the system, 126 - DK4_E_INVALID_ARGUMENTS<br> 127 if fipo is NULL, 128 - DK4_E_WRITE_FAILED<br> 129 with errno in iDetails1 if the write attempt failed. 130*/ 131int 132dk4fputs(const dkChar *s, FILE *fipo, dk4_er_t *erp); 133 134#ifdef __cplusplus 135} 136#endif 137 138 139 140%% module 141 142#include "dk4conf.h" 143#include <libdk4c/dk4fput.h> 144 145#if DK4_HAVE_IO_H 146#ifndef IO_H_INCLUDED 147#include <io.h> 148#define IO_H_INCLUDED 1 149#endif 150#endif 151 152#if DK4_HAVE_FCNTL_H 153#ifndef FCNTL_H_INCLUDED 154#include <fcntl.h> 155#define FCNTL_H_INCLUDED 1 156#endif 157#endif 158 159#ifndef DK4REC26_H_INCLUDED 160#include <libdk4c/dk4rec26.h> 161#endif 162 163#include <libdk4base/dk4unused.h> 164 165#if DK4_HAVE_ASSERT_H 166#ifndef ASSERT_H_INCLUDED 167#include <assert.h> 168#define ASSERT_H_INCLUDED 1 169#endif 170#endif 171 172 173$!trace-include 174 175 176 177#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 178 179/** Flag: Standard output initialized to write dkChar. 180*/ 181static int dk4fput_stdout_initialized = 0; 182 183/** Standard output mode at startup (should be restored before exiting). 184*/ 185static int dk4fput_stdout_oldmode = _O_TEXT; 186 187/** Flag: Standard error output initialized to write dkChar. 188*/ 189static int dk4fput_stderr_initialized = 0; 190 191/** Standard error mode at startup (should be restored before exiting). 192*/ 193static int dk4fput_stderr_oldmode = _O_TEXT; 194 195#endif 196 197 198 199void 200dk4fput_initialize_stdout(void) 201{ 202#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 203 if (0 == dk4fput_stdout_initialized) { 204 dk4fput_stdout_oldmode = _setmode(_fileno(stdout), _O_U16TEXT); 205 if (0 == _isatty(_fileno(stdout))) { 206 fputwc((wchar_t)0xFEFF, stdout); 207 } 208 dk4fput_stdout_initialized = 1; 209 } 210#endif 211} 212 213 214 215void 216dk4fput_initialize_stdout_no_bom(void) 217{ 218#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 219 if (0 == dk4fput_stdout_initialized) { 220 dk4fput_stdout_oldmode = _setmode(_fileno(stdout), _O_U16TEXT); 221 dk4fput_stdout_initialized = 1; 222 } 223#endif 224} 225 226 227void 228dk4fput_cleanup_stdout(void) 229{ 230#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 231 if (0 != dk4fput_stdout_initialized) { 232 fflush(stdout); 233 (void)_setmode(_fileno(stdout), dk4fput_stdout_oldmode); 234 } 235#endif 236} 237 238 239 240void 241dk4fput_initialize_stderr(void) 242{ 243#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 244 if (0 == dk4fput_stderr_initialized) { 245 dk4fput_stderr_oldmode = _setmode(_fileno(stderr), _O_U16TEXT); 246 if (0 == _isatty(_fileno(stderr))) { 247 fputwc((wchar_t)0xFEFF, stderr); 248 } 249 dk4fput_stderr_initialized = 1; 250 } 251#endif 252} 253 254 255 256void 257dk4fput_initialize_stderr_no_bom(void) 258{ 259#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 260 if (0 == dk4fput_stderr_initialized) { 261 dk4fput_stderr_oldmode = _setmode(_fileno(stderr), _O_U16TEXT); 262 dk4fput_stderr_initialized = 1; 263 } 264#endif 265} 266 267 268 269void 270dk4fput_cleanup_stderr(void) 271{ 272#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 273 if (0 != dk4fput_stderr_initialized) { 274 fflush(stderr); 275 (void)_setmode(_fileno(stdout), dk4fput_stderr_oldmode); 276 } 277#endif 278} 279 280 281void 282dk4fput_initialize_file( 283#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 284 FILE *fipo 285#else 286 FILE * DK4_ARG_UNUSED(fipo) 287#endif 288) 289{ 290#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 291#if DK4_USE_ASSERT 292 assert(NULL != fipo); 293#endif 294 if (NULL != fipo) { 295 (void)_setmode(_fileno(fipo), _O_U16TEXT); 296 fputwc(0xFEFF, fipo); 297 } 298#else 299 DK4_UNUSED_ARG(fipo) 300#endif 301} 302 303 304 305void 306dk4fput_initialize_file_no_bom( 307#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 308 FILE *fipo 309#else 310 FILE * DK4_ARG_UNUSED(fipo) 311#endif 312) 313{ 314#if _WIN32 && (DK4_CHAR_SIZE > 1) && DK4_HAVE__SETMODE && defined(_MSC_VER) 315#if DK4_USE_ASSERT 316 assert(NULL != fipo); 317#endif 318 if (NULL != fipo) { 319 (void)_setmode(_fileno(fipo), _O_U16TEXT); 320 } 321#else 322 DK4_UNUSED_ARG(fipo) 323#endif 324} 325 326 327 328int 329dk4fputc(dkChar c, FILE *fipo, dk4_er_t *erp) 330{ 331#if DK4_CHAR_SIZE > 1 332#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T 333#if DK4_HAVE_FPUTWC 334 int back = 0; 335 $? "+ dk4fputc (wide) %lx", dk4recode_dk_to_ul(c) 336#if DK4_USE_ASSERT 337 assert(NULL != fipo); 338#endif 339 if (NULL != fipo) { 340 errno = 0; 341 if (WEOF != fputwc(c, fipo)) { 342 back = 1; 343 } else { 344 dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno); 345 } 346 } else { 347 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); 348 } $? "- dk4fputc (wide) %d", back 349 return back; 350#else 351 dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); 352 return 0; 353#endif 354#else 355 dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); 356 return 0; 357#endif 358#else 359 int back = 0; 360#if DK4_USE_ASSERT 361 assert(NULL != fipo); 362#endif 363 if (NULL != fipo) { 364 errno = 0; 365 if (EOF != fputc(c, fipo)) { 366 back = 1; 367 } else { 368 dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno); 369 } 370 } else { 371 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); 372 } 373 return back; 374#endif 375} 376 377 378 379int 380dk4fputs(const dkChar *s, FILE *fipo, dk4_er_t *erp) 381{ 382#if DK4_CHAR_SIZE > 1 383#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T 384#if DK4_HAVE_FPUTWS 385 int back = 0; 386#if DK4_USE_ASSERT 387 assert(NULL != fipo); 388 assert(NULL != s); 389#endif 390 if ((NULL != s) && (NULL != fipo)) { 391 errno = 0; 392 if (WEOF != fputws(s, fipo)) { 393 back = 1; 394 } else { 395 dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno); 396 } 397 } else { 398 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); 399 } 400 return back; 401#else 402 dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); 403 return 0; 404#endif 405#else 406 dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); 407 return 0; 408#endif 409#else 410 int back = 0; 411#if DK4_USE_ASSERT 412 assert(NULL != fipo); 413 assert(NULL != s); 414#endif 415 if ((NULL != s) && (NULL != fipo)) { 416 errno = 0; 417 if (EOF != fputs(s, fipo)) { 418 back = 1; 419 } else { 420 dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno); 421 } 422 } else { 423 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); 424 } 425 return back; 426#endif 427} 428 429