%% options copyright owner = Dirk Krause copyright year = 2015-xxxx license = bsd %% header /** @file File functions for dkChar characters and strings. CRT on Windows: Required. */ #ifndef DK4CONF_H_INCLUDED #include "dk4conf.h" #endif #ifndef DK4TYPES_H_INCLUDED #include "dk4types.h" #endif #ifndef DK4ERROR_H_INCLUDED #include "dk4error.h" #endif #ifndef STDIO_H_INCLUDED #include #define STDIO_H_INCLUDED 1 #endif #if DK4_HAVE_ERRNO_H #ifndef ERRNO_H_INCLUDED #include #define ERRNO_H_INCLUDED 1 #endif #endif #ifdef __cplusplus extern "C" { #endif /** On Windows, initialize stdout to write dkChar and write a BOM. */ void dk4fput_initialize_stdout(void); /** On Windows, initialize stdout to write dkChar. */ void dk4fput_initialize_stdout_no_bom(void); /** On Windows, initialize stderr to write dkChar and write a BOM. */ void dk4fput_initialize_stderr(void); /** On Windows, initialize stderr to write dkChar. */ void dk4fput_initialize_stderr_no_bom(void); /** On Windows, initialize file to write dkChar and write a BOM. @param fipo File to set up. */ void dk4fput_initialize_file(FILE *fipo); /** On Windows, initialize file to write dkChar. @param fipo File to set up. */ void dk4fput_initialize_file_no_bom(FILE *fipo); /** On Windows, return to the default file encoding for stdout. */ void dk4fput_cleanup_stdout(void); /** On Windows, return to the default file encoding for stderr. */ void dk4fput_cleanup_stderr(void); /** Write one character to file. @param c Character to write. @param fipo File to write to. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_NOT_SUPPORTED
if writing wide characters is not supported on the system, - DK4_E_INVALID_ARGUMENTS
if fipo is NULL, - DK4_E_WRITE_FAILED
with errno value in iDetails1 if the write attempt failed. */ int dk4fputc(dkChar c, FILE *fipo, dk4_er_t *erp); /** Write one string to file. @param s String to write. @param fipo File to write to. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_NOT_SUPPORTED
if writing wide character strings is not supported on the system, - DK4_E_INVALID_ARGUMENTS
if fipo is NULL, - DK4_E_WRITE_FAILED
with errno in iDetails1 if the write attempt failed. */ int dk4fputs(const dkChar *s, FILE *fipo, dk4_er_t *erp); #ifdef __cplusplus } #endif %% module #include "dk4fput.h" #if DK4_HAVE_IO_H #ifndef IO_H_INCLUDED #include #define IO_H_INCLUDED 1 #endif #endif #if DK4_HAVE_FCNTL_H #ifndef FCNTL_H_INCLUDED #include #define FCNTL_H_INCLUDED 1 #endif #endif $!trace-include #if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1) /** Flag: Standard output initialized to write dkChar. */ static int dk4fput_stdout_initialized = 0; /** Standard output mode at startup (should be restored before exiting). */ static int dk4fput_stdout_oldmode = _O_TEXT; /** Flag: Standard error output initialized to write dkChar. */ static int dk4fput_stderr_initialized = 0; /** Standard error mode at startup (should be restored before exiting). */ static int dk4fput_stderr_oldmode = _O_TEXT; #endif void dk4fput_initialize_stdout(void) { #if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1) if (0 == dk4fput_stdout_initialized) { dk4fput_stdout_oldmode = _setmode(_fileno(stdout), _O_U16TEXT); if (0 == _isatty(_fileno(stdout))) { fputwc((wchar_t)0xFEFF, stdout); } dk4fput_stdout_initialized = 1; } #endif } void dk4fput_initialize_stdout_no_bom(void) { #if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1) if (0 == dk4fput_stdout_initialized) { dk4fput_stdout_oldmode = _setmode(_fileno(stdout), _O_U16TEXT); dk4fput_stdout_initialized = 1; } #endif } void dk4fput_cleanup_stdout(void) { #if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1) if (0 != dk4fput_stdout_initialized) { fflush(stdout); (void)_setmode(_fileno(stdout), dk4fput_stdout_oldmode); } #endif } void dk4fput_initialize_stderr(void) { #if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1) if (0 == dk4fput_stderr_initialized) { dk4fput_stderr_oldmode = _setmode(_fileno(stderr), _O_U16TEXT); if (0 == _isatty(_fileno(stderr))) { fputwc((wchar_t)0xFEFF, stderr); } dk4fput_stderr_initialized = 1; } #endif } void dk4fput_initialize_stderr_no_bom(void) { #if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1) if (0 == dk4fput_stderr_initialized) { dk4fput_stderr_oldmode = _setmode(_fileno(stderr), _O_U16TEXT); dk4fput_stderr_initialized = 1; } #endif } void dk4fput_cleanup_stderr(void) { #if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1) if (0 != dk4fput_stderr_initialized) { fflush(stderr); (void)_setmode(_fileno(stdout), dk4fput_stderr_oldmode); } #endif } void dk4fput_initialize_file(FILE *fipo) { #if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1) if (NULL != fipo) { (void)_setmode(_fileno(fipo), _O_U16TEXT); fputwc(0xFEFF, fipo); } #endif } void dk4fput_initialize_file_no_bom(FILE *fipo) { #if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1) if (NULL != fipo) { (void)_setmode(_fileno(fipo), _O_U16TEXT); } #endif } int dk4fputc(dkChar c, FILE *fipo, dk4_er_t *erp) { #if DK4_CHAR_SIZE > 1 #if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T #if DK4_HAVE_FPUTWC int back = 0; $? "+ dk4fputc (wide) %lx", (unsigned long)c if (NULL != fipo) { errno = 0; if (WEOF != fputwc(c, fipo)) { back = 1; } else { dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } $? "- dk4fputc (wide) %d", back return back; #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return 0; #endif #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return 0; #endif #else int back = 0; if (NULL != fipo) { errno = 0; if (EOF != fputc(c, fipo)) { back = 1; } else { dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; #endif } int dk4fputs(const dkChar *s, FILE *fipo, dk4_er_t *erp) { #if DK4_CHAR_SIZE > 1 #if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T #if DK4_HAVE_FPUTWS int back = 0; if ((NULL != s) && (NULL != fipo)) { errno = 0; if (WEOF != fputws(s, fipo)) { back = 1; } else { dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return 0; #endif #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return 0; #endif #else int back = 0; if ((NULL != s) && (NULL != fipo)) { errno = 0; if (EOF != fputs(s, fipo)) { back = 1; } else { dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; #endif }