summaryrefslogtreecommitdiff
path: root/support/dktools/dk-cat.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk-cat.c
Initial commit
Diffstat (limited to 'support/dktools/dk-cat.c')
-rw-r--r--support/dktools/dk-cat.c2433
1 files changed, 2433 insertions, 0 deletions
diff --git a/support/dktools/dk-cat.c b/support/dktools/dk-cat.c
new file mode 100644
index 0000000000..63b35118ff
--- /dev/null
+++ b/support/dktools/dk-cat.c
@@ -0,0 +1,2433 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-cat.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 10 "dk-cat.ctr"
+
+/** @file dk-cat.c The dk-cat program.
+ The dk_cat_help_text array below shows details.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4strm.h"
+#include "dk4strmf.h"
+#include "dk4strmo32.h"
+#include "dk4istty.h"
+#include "dk4fopda.h"
+#include "dk4tsp32.h"
+#include "dk4tspdk.h"
+#include "dk4mao8d.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+#include "dk4fput.h"
+#include "dk4maodd.h"
+#include "dk4mpl.h"
+#include "dk4isadm.h"
+
+
+
+
+
+#line 94 "dk-cat.ctr"
+
+
+
+#ifndef DK_CAT_INPUT_BUFFER_SIZE
+/** Input buffer size.
+*/
+#define DK_CAT_INPUT_BUFFER_SIZE 4096
+#endif
+
+
+
+/** Default text, used if help text file is not found.
+*/
+static const dkChar * const dk_cat_help_text[] = {
+dkT(""),
+dkT("Show text files"),
+dkT(""),
+dkT("dk-cat [<options>] [<files>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-c <bool> Enable CR/NL -n Write line numbers"),
+dkT("-i <encoding> Expected input encoding -w Normalize text lines"),
+dkT("-o <encoding> Output encoding -p No unneccessary decoding/encoding"),
+dkT("--help Show this short help text. --manual *** SHOW FULL MANUAL. ***"),
+dkT("--version Show version information. --license Show license information."),
+dkT("--verbose Error message on SIGPIPE"),
+dkT("--line-number-width=<int> Minimum line number width."),
+dkT(""),
+dkT("Encoding names: plain (ASCII text), ascii (synonym for plain), ansi, utf-8,"),
+dkT("utf-16, utf-16le (little-endian) utf-16be (big-endian),"),
+dkT("c32 (32 bit characters), c32le, c32be."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 130 "dk-cat.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_cat_license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 262 "dk-cat.ctr"
+};
+
+
+
+/** Constant texts used by program, not localized.
+*/
+static const dkChar * const dk_cat_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-cat.txt"),
+
+/* 2 */
+dkT("dk-cat.str"),
+
+/* 3 */
+dkT("line-number-width"),
+
+/* 4 */
+dkT("stdin"),
+
+/* 5 */
+dkT("\\"),
+
+/* 6 */
+dkT("verbose"),
+
+NULL
+
+
+#line 299 "dk-cat.ctr"
+};
+
+
+
+/** Constant texts used by program, replaced by localized texts
+ if available.
+*/
+static const dkChar * const dk_cat_kw_def[] = {
+/* 0 */
+dkT("Decoding error!\n\tByte: "),
+
+/* 1 */
+dkT("Another decoding error!"),
+
+/* 2 */
+dkT("Further decoding errors!"),
+
+/* 3 */
+dkT("Encoding error!\n\tByte: "),
+
+/* 4 */
+dkT("Another encoding error!"),
+
+/* 5 */
+dkT("Further encoding errors!"),
+
+/* 6 */
+dkT("Processing error!\n\tByte: "),
+
+/* 7 */
+dkT("Another processing error!"),
+
+/* 8 */
+dkT("Further processing errors!"),
+
+/* 9 */
+dkT(",\n\tCharacter: "),
+
+/* 10 */
+dkT(",\n\tPosition in line: "),
+
+/* 11 */
+dkT("Decoding error!"),
+
+/* 12 */
+dkT("Encoding error!"),
+
+/* 13 */
+dkT("Processing error!"),
+
+/* 14 */
+dkT("."),
+
+/* 15 */
+dkT("Illegal input encoding: \""),
+
+/* 16 */
+dkT("\"!"),
+
+/* 17 */
+dkT("Illegal output encoding: \""),
+
+/* 18 */
+dkT("\"!"),
+
+/* 19 */
+dkT("Line number width must be larger than 0!"),
+
+/* 20 */
+dkT("Failed to write text to output!"),
+
+/* 21 */
+dkT("Numeric conversion failed (should not happen, probably bug in program)!"),
+
+/* 22 */
+dkT("Failed to set up signal handlers!"),
+
+/* 23 */
+dkT("Failed to restore signal handlers!"),
+
+/* 24 */
+dkT("Signal received: SIGPIPE!"),
+
+/* 25 */
+dkT("Signal received: SIGINT!"),
+
+NULL
+
+
+#line 377 "dk-cat.ctr"
+};
+
+
+
+/** Message texts, uses localized texts if possible.
+*/
+static const dkChar * const *msg = dk_cat_kw_def;
+
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t dk_cat_options[] = {
+
+ /* Flag: Line end consists of carriage return and newline.
+ */
+ { dkT('c'), dkT("crnl"), DK4_OPT_ARG_BOOL },
+
+ /* Show line numbers.
+ */
+ { dkT('n'), dkT("line-numbers"), DK4_OPT_ARG_NONE },
+
+ /* Number of digits for line numbers.
+ */
+ { dkT('\0'), dkT("line-number-width"), DK4_OPT_ARG_SIZE },
+
+ /* Flag: Normalize text lines.
+ */
+ { dkT('w'), dkT("normalize"), DK4_OPT_ARG_NONE },
+
+ /* Expected input encoding.
+ */
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+
+ /* Output encoding to produce.
+ */
+ { dkT('o'), dkT("output-encoding"), DK4_OPT_ARG_STRING },
+
+ /* Pass-through UTF-8 data.
+ */
+ { dkT('p'), dkT("pass-through"), DK4_OPT_ARG_NONE },
+
+ /* Verbose output.
+ */
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+
+};
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of elements in the dk_cat_options array.
+*/
+static const size_t dk_cat_sz_options =
+sizeof(dk_cat_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of usable elements in the dk_cat_kw_def array and in msg.
+*/
+static size_t sz_msg = (sizeof(dk_cat_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+/** Name of current input file processed.
+*/
+static const dkChar *input_file_name = NULL;
+
+
+/** Flag: Output already initialized.
+*/
+static int output_initialized = 0;
+
+
+#if DK4_ON_WINDOWS
+/** Original mode for stdout.
+*/
+static int old_output_mode = 0;
+#endif
+
+
+/** Flag: Use stream instead output to stdout.
+*/
+static int use_stream = 1;
+
+
+/** System output encoding.
+*/
+static int oenc_sys = DK4_FILE_ENCODING_ASCII;
+
+
+/** Default output encoding on the system.
+*/
+static int oenc_def = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Output encoding specified on command line.
+*/
+static int oenc = DK4_FILE_ENCODING_ASCII;
+
+
+/** System setting whether or not to write a BOM.
+*/
+static int obom_sys = 0;
+
+
+/** Flag: Write BOM. -1=auto, 0=no, 1=yes.
+*/
+static int obom = -1;
+
+
+/** Default CR/NL sequence setting.
+*/
+static int crnl_def = DK4_HAVE_LINE_END_CR_NL;
+
+
+/** CR/NL sequence setting from options if available.
+*/
+static int crnl = DK4_HAVE_LINE_END_CR_NL;
+
+
+/** Input encoding specified on the command line.
+*/
+static int ienc_def = DK4_FILE_ENCODING_ASCII;
+
+
+/** Flag: Show line numbers (from options).
+*/
+static int line_numbers = 0;
+
+
+/** Current line number.
+*/
+static dk4_um_t line_number = (dk4_um_t)1UL;
+
+
+/** Flag: Previous character was carriage return.
+*/
+static int previous_was_cr = 0;
+
+
+/** Flag: Previous character was not a whitespace.
+*/
+static int previous_was_text = 0;
+
+
+/** Flag: Previous character was a newline.
+*/
+static int previous_was_nl = 0;
+
+
+/** Flag: We already had text in this line.
+*/
+static int text_in_line = 0;
+
+
+/** Flag: We had any output for this file.
+*/
+static int there_was_text = 0;
+
+
+/** Flag: Line number was already printed for current line.
+*/
+static int line_number_printed = 0;
+
+
+/** Line number width.
+*/
+static size_t line_number_width = 5;
+
+
+/** Flag: Normalize lines.
+*/
+static int normalize_lines = 0;
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+/** Flag: Already reported encoding errors for this file.
+*/
+static int had_encoding_error = 0;
+
+/** Flag: Already reported decoding errors for this file.
+*/
+static int had_decoding_error = 0;
+
+/** Flag: Already reported processing errors for this file.
+*/
+static int had_processing_error = 0;
+
+/** Flag: Had error while writing to stdout.
+*/
+static int had_write_error = 0;
+
+/** Flag: Verbose output (report SIGPIPE).
+*/
+static int verbose = 0;
+
+
+/** Output stream.
+*/
+static dk4_stream_t *output_stream = NULL;
+
+
+
+/*
+ We can output to stdout using dk4fputc() if all the conditions
+ below are true:
+ - output encoding is system output encoding and
+ - CR/NL setting is system CR/NL setting and
+ - BOM settings is ``automatic'' or is system BOM setting.
+
+ Otherwise we set stdout in binary mode (on Windows only)
+ and use a dk4_stream_t to process 32 bit characters.
+*/
+
+/** Initialize settings from application.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+initialize_from_app(void)
+{
+ dkChar buf[32];
+ int res = 0; /* Operation result */
+ int back = 1;
+
+
+#line 711 "dk-cat.ctr"
+
+ /* String tables and defaults.
+ */
+
+
+#line 715 "dk-cat.ctr"
+ oenc_sys = dk4app_get_stdout_encoding(app);
+ oenc_def = oenc_sys;
+ ienc_def = dk4app_get_stdin_encoding(app);
+
+
+#line 719 "dk-cat.ctr"
+ if (0 < dk4app_get_argc(app)) {
+ ienc_def = dk4app_get_file_in_encoding(app);
+
+
+#line 722 "dk-cat.ctr"
+ }
+
+ /* Set verbose flag if -v was used.
+ */
+ if (0 != dk4app_opt_is_set_long(app, dk_cat_kwnl[6], NULL)) {
+ verbose = 1;
+ }
+
+ /* Output encoding to produce (-o)
+ */
+
+
+#line 733 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('o'), NULL)) {
+
+#line 734 "dk-cat.ctr"
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, dkT('o'), NULL
+ );
+ if (0 != res) {
+
+#line 738 "dk-cat.ctr"
+ res = dk4enc_find(&oenc_def, &obom, buf, NULL);
+ if (0 == res) {
+
+#line 740 "dk-cat.ctr"
+ /* ERROR: Illegal output encoding */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 17, 18, buf);
+ back = 0;
+ }
+ } else {
+
+#line 745 "dk-cat.ctr"
+ /* ERROR: BUG, No option argument */
+ back = 0;
+ }
+ }
+
+ /* Expected input encoding (-i)
+ */
+
+
+#line 753 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+
+#line 754 "dk-cat.ctr"
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, dkT('i'), NULL
+ );
+ if (0 != res) {
+
+#line 758 "dk-cat.ctr"
+ res = dk4enc_find(&ienc_def, NULL, buf, NULL);
+ if (0 == res) {
+
+#line 760 "dk-cat.ctr"
+ /* ERROR: Illegal input encoding */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 15, 16, buf);
+ back = 0;
+ }
+ } else {
+
+#line 765 "dk-cat.ctr"
+ /* ERROR: BUG, No option argument */
+ back = 0;
+ }
+ }
+
+ /* CR/NL (-c)
+ */
+
+
+#line 773 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+
+#line 774 "dk-cat.ctr"
+ if (0 == dk4app_opt_get_bool_short(&crnl, app, dkT('c'), NULL)) {
+ /* ERROR: BUG, No option argument */
+ back = 0;
+
+#line 777 "dk-cat.ctr"
+ }
+ }
+
+ /* Line numbers (-n)
+ */
+
+
+#line 783 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+
+#line 784 "dk-cat.ctr"
+ line_numbers = 1;
+ }
+
+ /* Line number width (--line-number-width)
+ */
+
+
+#line 790 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_long(app, dk_cat_kwnl[3], NULL)) {
+
+#line 791 "dk-cat.ctr"
+ if (0 == dk4app_opt_get_size_long(&line_number_width, app, dk_cat_kwnl[3], NULL)) {
+ /* ERROR: BUG, No option argument */
+ back = 0;
+
+#line 794 "dk-cat.ctr"
+ } else {
+ if (0 == line_number_width) {
+
+#line 796 "dk-cat.ctr"
+ /* ERROR: Illegal line number width */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 19);
+ back = 0;
+ }
+ }
+ }
+
+ /* Normalize text (-w)
+ */
+
+
+#line 806 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('w'), NULL)) {
+
+#line 807 "dk-cat.ctr"
+ normalize_lines = 1;
+ }
+
+
+
+#line 811 "dk-cat.ctr"
+ switch (oenc_sys) {
+ case DK4_FILE_ENCODING_ASCII :
+ case DK4_FILE_ENCODING_ANSI :
+ case DK4_FILE_ENCODING_UTF8 :
+ {
+ obom_sys = 0;
+ } break;
+ default :
+ {
+ if (0 == dk4istty(1, NULL)) {
+ obom_sys = 1;
+ }
+ } break;
+ }
+ oenc = oenc_def;
+
+
+
+#line 828 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Check whether we can write to standard output directly.
+*/
+static
+void
+decide_for_output_type(void)
+{
+ if (oenc_def == oenc_sys) {
+ if (crnl == crnl_def) {
+ if ((-1 == obom) || (obom_sys == obom)) {
+ use_stream = 0;
+ }
+ }
+ }
+}
+
+
+
+/** Initialize output structures before writing first output.
+*/
+static
+void
+initialize_output(void)
+{
+ dk4_er_t er;
+
+
+#line 858 "dk-cat.ctr"
+ if (0 == output_initialized) {
+ output_initialized = 1;
+ if (0 != use_stream) {
+ dk4error_init(&er);
+#if DK4_ON_WINDOWS
+
+
+#line 864 "dk-cat.ctr"
+ old_output_mode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+ output_stream = dk4stream_open_for_file(
+ stdout, DK4_STREAM_WRITE, 0, 4096, &er
+ );
+ if (NULL != output_stream) {
+ dk4stream_set_output_encoding(output_stream, oenc);
+ switch (obom) {
+ case 1: {
+ if(0 == dk4stream_c32_putc(output_stream, dkC32(0xFEFF), NULL)) {
+ /* ERROR: Failed to write BOM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ } break;
+ case -1: {
+ if (1 == obom_sys) {
+ if(0 == dk4stream_c32_putc(output_stream,dkC32(0xFEFF),NULL)) {
+ /* ERROR: Failed to write BOM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to create stream */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else {
+ dk4fput_initialize_stdout();
+ }
+ }
+
+#line 897 "dk-cat.ctr"
+}
+
+
+
+/** Close stream, or set mode for stdout back to original mode.
+*/
+static
+void
+cleanup_output(void)
+{
+ dk4_er_t er;
+
+
+#line 909 "dk-cat.ctr"
+ if (0 != output_initialized) {
+ if (0 != use_stream) {
+ if (NULL != output_stream) {
+ /* Close output stream.
+ */
+ dk4error_init(&er);
+ if (0 == dk4stream_close(output_stream, &er)) {
+ /* ERROR: Closing the stream failed */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ }
+#if DK4_ON_WINDOWS
+ /* Set stdout to original mode.
+ */
+
+
+#line 925 "dk-cat.ctr"
+ _setmode(_fileno(stdout), old_output_mode);
+#endif
+ } else {
+ dk4fput_cleanup_stdout();
+ }
+ }
+
+#line 931 "dk-cat.ctr"
+}
+
+
+
+/** Report an error with position in source line.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ const dkChar *oldlogname = NULL;
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogname = dk4app_get_log_source_file(app);
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, input_file_name);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, msg, sz_msg, DK4_LL_ERROR, i1, 9, 10, 14, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, msg, sz_msg, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_file(app, oldlogname);
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+
+/** Report an error occured while writing 32 bit character to
+ output stream.
+ @param erp Error information returned by dk4stream_c32_putc().
+ @param pos Position information.
+*/
+static
+void
+error_while_writing_c32(dk4_er_t *erp, dk4_text_stream_position_t *pos)
+{
+ dk4_um_t bytes = (dk4_um_t)0UL;
+ dk4_um_t lineno = (dk4_um_t)0UL;
+ dk4_um_t chars = (dk4_um_t)0UL;
+ dk4_um_t charil = (dk4_um_t)0UL;
+ switch (erp->ec) {
+ case DK4_E_ENCODING_FAILED : {
+ if (NULL != pos) {
+ bytes = pos->bytes;
+ lineno = pos->lineno;
+ chars = pos->chars;
+ charil = pos->charil;
+ }
+ if ((dk4_um_t)0UL < bytes) { bytes = bytes - (dk4_um_t)1UL; }
+ if ((dk4_um_t)0UL < chars) { chars = chars - (dk4_um_t)1UL; }
+ if ((dk4_um_t)0UL < charil) { charil = charil - (dk4_um_t)1UL; }
+ report_with_position(3, 12, bytes, lineno, chars, charil);
+ } break;
+ default: {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ } break;
+ }
+}
+
+
+
+/** Write one 32 bit character to output.
+ If the character is a newline, convert to carriage return and
+ newline sequence if required by crnl settings.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_real_output(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = DK4_TSP_RES_OK;
+ dk4_sig_atomic_t shp;
+
+
+
+#line 1049 "dk-cat.ctr"
+ initialize_output();
+ if (0 != use_stream) {
+ if (NULL != output_stream) {
+ dk4error_init(&er);
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 == shp) {
+ if ((dkC32(0x0A) == c) && (0 != crnl)) {
+ if (0 == dk4stream_c32_putc(output_stream, dkC32(0x0D), &er)) {
+ /* ERROR: Failed to write output character */
+ error_while_writing_c32(&er, pos);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ if (0 == dk4stream_c32_putc(output_stream, c, &er)) {
+ /* ERROR: Failed to write output character */
+ error_while_writing_c32(&er, pos);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ } else {
+ /* ERROR: Failed to create output stream (already reported) */
+ back = DK4_TSP_RES_FATAL;
+ }
+ } else {
+ }
+ if (dkC32(0x0A) == c) {
+ previous_was_nl = 1;
+ } else {
+ previous_was_nl = 0;
+ }
+ there_was_text = 1;
+
+
+#line 1085 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Check whether a character is the first character in a line,
+ write line number if necessary and write the character.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_after_normalize(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ char buf[8*(1+sizeof(dk4_um_t))];
+ char *ptr = NULL;
+ size_t i = 0;
+ int res = 0;
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1118 "dk-cat.ctr"
+ if (0 != line_numbers) {
+ if (0 == line_number_printed) {
+ line_number_printed = 1;
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), line_number, 0, NULL
+ );
+ if (0 != res) {
+ /* Spaces before line number.
+ */
+ i = dk4str8_len(buf);
+ while (i < line_number_width) {
+ switch (c32_real_output(obj, dkC32(0x20), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ i++;
+ }
+ /* Line number
+ */
+ ptr = buf;
+ while ('\0' != *ptr) {
+ res = c32_real_output(
+ obj, (dk4_c32_t)((unsigned char)(*(ptr++))), pos, erp
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ /* Trailing space after line number
+ */
+ switch (c32_real_output(obj, dkC32(0x20), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to convert line number. */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 21);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ switch (c32_real_output(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ back = c32_real_output(obj, c, pos, erp);
+ }
+
+#line 1190 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Normalize the text if required and pass characters downwards.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_after_cr_nl(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1218 "dk-cat.ctr"
+ if (0 != normalize_lines) {
+ if ((dkC32(0x09) == c) || (dkC32(0x20) == c) || (dkC32(0x0D) == c)) {
+ previous_was_text = 0;
+ } else {
+ if (dkC32(0x0A) == c) {
+ previous_was_text = 0;
+ back = c32_after_normalize(obj, c, pos, erp);
+ text_in_line = 0;
+ } else {
+ if ((0 == previous_was_text) && (0 != text_in_line)) {
+ back = c32_after_normalize(obj, dkC32(0x20), pos, erp);
+ }
+ switch (c32_after_normalize(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ previous_was_text = 1;
+ text_in_line = 1;
+ }
+ }
+ } else {
+ back = c32_after_normalize(obj, c, pos, erp);
+ }
+
+#line 1247 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_handler(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1274 "dk-cat.ctr"
+ dk4app_set_log_source_line(app, line_number);
+ if (dkC32(0x0D) == c) {
+
+#line 1276 "dk-cat.ctr"
+ if (0 != previous_was_cr) {
+ back = c32_after_cr_nl(obj, dkC32(0x0D), pos, erp);
+ }
+ previous_was_cr = 1;
+ } else {
+ if (dkC32(0x0A) == c) {
+
+#line 1282 "dk-cat.ctr"
+ back = c32_after_cr_nl(obj, c, pos, erp);
+ line_number++;
+ dk4app_set_log_source_line(app, line_number);
+ line_number_printed = 0;
+ text_in_line = 0;
+ } else {
+
+#line 1288 "dk-cat.ctr"
+ if (0 != previous_was_cr) {
+ back = c32_after_cr_nl(obj, dkC32(0x0D), pos, erp);
+ }
+ switch (c32_after_cr_nl(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ previous_was_cr = 0;
+ }
+
+#line 1304 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Write one dkChar to output (for a newline write a carriage
+ return, newline sequence if required).
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_real_output(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = DK4_TSP_RES_OK;
+ dk4_sig_atomic_t shp;
+
+
+#line 1335 "dk-cat.ctr"
+ initialize_output();
+ dk4error_init(&er);
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 == shp) {
+ if (0 == dk4fputc(c, stdout, &er)) {
+ /* ERROR while writing to standard output */
+#if 0
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+#endif
+ had_write_error = 0;
+ back = DK4_TSP_RES_FATAL;
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (dkT('\n') == c) {
+ previous_was_nl = 1;
+ } else {
+ previous_was_nl = 0;
+ }
+ there_was_text = 1;
+
+
+#line 1360 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Pass character downwards to dkc_real_output().
+ If the character is the first in the line, prepend line
+ number if required.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_after_normalize(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ char buf[8*(1+sizeof(dk4_um_t))];
+ char *ptr = NULL;
+ size_t i = 0;
+ int res = 0;
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1394 "dk-cat.ctr"
+ if (0 != line_numbers) {
+ if (0 == line_number_printed) {
+ line_number_printed = 1;
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), line_number, 0, NULL
+ );
+ if (0 != res) {
+ /* Spaces before line number.
+ */
+ i = dk4str8_len(buf);
+ while (i < line_number_width) {
+ switch (dkc_real_output(obj, dkT(' '), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ i++;
+ }
+ /* Line number
+ */
+ ptr = buf;
+ while ('\0' != *ptr) {
+ res = dkc_real_output(
+ obj, (dkChar)((unsigned char)(*(ptr++))), pos, erp
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ /* Trailing space after line number
+ */
+ switch (dkc_real_output(obj, dkT(' '), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to convert line number. */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 21);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ switch (dkc_real_output(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ back = dkc_real_output(obj, c, pos, erp);
+ }
+
+#line 1466 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Normalize text if required and pass characters downwards.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_after_cr_nl(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1494 "dk-cat.ctr"
+ if (0 != normalize_lines) {
+ if ((dkT('\t') == c) || (dkT(' ') == c) || (dkT('\r') == c)) {
+ previous_was_text = 0;
+ } else {
+ if (dkT('\n') == c) {
+ previous_was_text = 0;
+ back = dkc_after_normalize(obj, c, pos, erp);
+ text_in_line = 0;
+ } else {
+ if ((0 == previous_was_text) && (0 != text_in_line)) {
+ back = dkc_after_normalize(obj, dkT(' '), pos, erp);
+ }
+ switch (dkc_after_normalize(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ previous_was_text = 1;
+ text_in_line = 1;
+ }
+ }
+ } else {
+ back = dkc_after_normalize(obj, c, pos, erp);
+ }
+
+#line 1523 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_handler(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1551 "dk-cat.ctr"
+ dk4app_set_log_source_line(app, line_number);
+ if (dkT('\r') == c) {
+ if (0 != previous_was_cr) {
+ back = dkc_after_cr_nl(obj, dkT('\r'), pos, erp);
+ }
+ previous_was_cr = 1;
+ } else {
+ if (dkT('\n') == c) {
+ back = dkc_after_cr_nl(obj, c, pos, erp);
+ line_number++;
+ dk4app_set_log_source_line(app, line_number);
+ line_number_printed = 0;
+ text_in_line = 0;
+ } else {
+ if (0 != previous_was_cr) {
+ back = dkc_after_cr_nl(obj, dkT('\r'), pos, erp);
+ }
+ switch (dkc_after_cr_nl(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ previous_was_cr = 0;
+ }
+
+
+#line 1582 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Initialize variables like line number and others for one file.
+*/
+static
+void
+initialize_for_one_file(void)
+{
+
+
+#line 1594 "dk-cat.ctr"
+ line_number = (dk4_um_t)1UL;
+ previous_was_cr = 0;
+ previous_was_nl = 0;
+ previous_was_text = 0;
+ line_number_printed = 0;
+ there_was_text = 0;
+ had_encoding_error = 0;
+ had_decoding_error = 0;
+ had_processing_error = 0;
+ text_in_line = 0;
+
+
+#line 1605 "dk-cat.ctr"
+}
+
+
+
+/** Report errors indicated by text processing.
+ @param er_en Error report for decoding and encoding errors.
+ @param er_pr Error report for processing errors.
+*/
+static
+void
+report_errors(dk4_er_t *er_en, dk4_er_t *er_pr)
+{
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (had_decoding_error) {
+ case 0: case 1: {
+ report_with_position(
+ ((0 == had_decoding_error) ? 0 : 1), 11,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ } break;
+ }
+ if (3 > had_decoding_error) { had_decoding_error++; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (had_encoding_error) {
+ case 0: case 1: {
+ report_with_position(
+ ((0 == had_encoding_error) ? 3 : 4), 12,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ } break;
+ }
+ if (3 > had_encoding_error) { had_encoding_error++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (had_processing_error) {
+ case 0: case 1: {
+ report_with_position(
+ ((0 == had_processing_error) ? 6 : 7), 13,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ } break;
+ }
+ if (3 > had_processing_error) { had_processing_error++; }
+ }
+ }
+}
+
+
+
+/** Process one input file.
+ @param fipo File to process.
+*/
+static
+void
+process_one_file(FILE *fipo)
+{
+ dk4_tsp32_t tsp32;
+ dk4_tspdk_t tspdk;
+ dk4_er_t er;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+#if VERSION_1
+ size_t sz;
+#endif
+ int res;
+ int cc;
+ int c;
+ unsigned char ub;
+
+
+
+#line 1696 "dk-cat.ctr"
+ cc = 1;
+ initialize_for_one_file();
+ dk4error_init(&er);
+ if (0 != use_stream) {
+
+#line 1700 "dk-cat.ctr"
+ res = dk4tsp32_setup_char(
+ &tsp32, NULL, c32_handler, ienc_def, &er
+ );
+ if (0 != res) {
+
+#line 1704 "dk-cat.ctr"
+ do {
+ if (0 != sig_can_continue(0)) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tsp32_add_one_byte(&tsp32, ub)) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == cc) {
+
+#line 1733 "dk-cat.ctr"
+ res = dk4tsp32_finish(&tsp32);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+
+#line 1736 "dk-cat.ctr"
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+
+#line 1741 "dk-cat.ctr"
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ if (0 != sig_can_continue(0)) {
+ if ((0 != there_was_text) && (0 == previous_was_nl)) {
+ res = c32_real_output(NULL, dkC32(0x0A), NULL, NULL);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+
+#line 1752 "dk-cat.ctr"
+ exval = EXIT_FAILURE;
+ } break;
+ case DK4_TSP_RES_FATAL: {
+
+#line 1755 "dk-cat.ctr"
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ }
+ }
+ } else {
+
+#line 1761 "dk-cat.ctr"
+ /* BUG, Should not happen */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1765 "dk-cat.ctr"
+ res = dk4tspdk_setup_char(
+ &tspdk, NULL, dkc_handler, oenc_sys, ienc_def, &er
+ );
+ if (0 != res) {
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+
+
+#line 1771 "dk-cat.ctr"
+ dk4tspdk_enable_utf8_pass_through(&tspdk, 1);
+ }
+ do {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tspdk, ub)) {
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } }
+ } while (1 == cc);
+ if (0 == cc) {
+ res = dk4tspdk_finish(&tspdk);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ if ((0 != there_was_text) && (0 == previous_was_nl)) {
+ res = dkc_real_output(NULL, dkT('\n'), NULL, NULL);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ }
+ }
+ }
+
+
+#line 1826 "dk-cat.ctr"
+}
+
+
+
+/** Process one input file specified by name.
+ @param filename Name of input file to process.
+*/
+static
+void
+process_one_file_name(const dkChar *filename)
+{
+ dk4_er_t er;
+ FILE *fipo = NULL;
+ const dkChar *oldsourcefile;
+ dk4_um_t oldsourceline;
+ int tests = DK4_FOPEN_SC_USER;
+
+
+#line 1843 "dk-cat.ctr"
+ dk4error_init(&er);
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, filename);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+#if 0
+ /* File is opened for reading only.
+ */
+ if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+#endif
+ if (0 != sig_can_continue(1)) {
+ fipo = dk4fopen_app(filename, dkT("rb"), tests, app);
+ if (NULL != fipo) {
+ input_file_name = filename;
+ process_one_file(fipo);
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file (already reported) */
+ exval = EXIT_FAILURE;
+ }
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+
+
+#line 1867 "dk-cat.ctr"
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+static
+void
+expand_and_process(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf; /* Short file name */
+ const dkChar *pth; /* Path */
+ int any_file_found = 0; /* Flag: Any file found */
+ int can_continue;
+
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ can_continue = 1;
+ while ((0 != can_continue) && (NULL != (shf = dk4dir_next_file(fne)))) {
+ any_file_found = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_cat_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ process_one_file_name(buf);
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ }
+ else
+ {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ process_one_file_name(shf);
+ }
+ can_continue = sig_can_continue(1);
+ }
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to open file name expander (already reported) */
+ exval = EXIT_FAILURE;
+ }
+}
+
+#endif
+
+
+
+/** Process all input files specified on command line or standard
+ input if no file name is found.
+*/
+static
+void
+process_files(void)
+{
+ int argc;
+ int i;
+ const dkChar *fn;
+#if DK4_ON_WINDOWS
+ int oldmode;
+#endif
+
+
+#line 1948 "dk-cat.ctr"
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+
+#line 1950 "dk-cat.ctr"
+ for (i = 0; ((i < argc) && (0 != sig_can_continue(1))); i++) {
+ fn = dk4app_get_argv(app, i);
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(fn)) {
+ expand_and_process(fn);
+ } else {
+#endif
+ process_one_file_name(fn);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+ }
+ } else {
+
+#line 1965 "dk-cat.ctr"
+#if DK4_ON_WINDOWS
+
+
+#line 1967 "dk-cat.ctr"
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ input_file_name = dk_cat_kwnl[4];
+ process_one_file(stdin);
+#if DK4_ON_WINDOWS
+
+
+#line 1973 "dk-cat.ctr"
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+
+
+#line 1977 "dk-cat.ctr"
+}
+
+
+
+static
+void
+run_the_functions(void)
+{
+ process_files();
+ fflush(stdout);
+ cleanup_output();
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+ struct sigaction oterm;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ run_the_functions();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 23);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 23);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 23);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ run_the_functions();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ run_the_functions();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+ run_the_functions();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_sig_atomic_t shp;
+
+
+#line 2191 "dk-cat.ctr"
+
+
+#line 2192 "dk-cat.ctr"
+ app = dk4app_open_cmd(
+ argc, argv, dk_cat_options, dk_cat_sz_options,
+ dk_cat_kwnl[0], DKT_VERSION_DK,
+ dk_cat_kwnl[1], dk_cat_help_text, dk_cat_license_text
+ );
+ if (NULL != app) {
+ sz_msg = dk4app_string_table_size(dk_cat_kw_def);
+ msg = dk4app_string_table(app, dk_cat_kwnl[2], dk_cat_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ if (0 != initialize_from_app()) {
+ decide_for_output_type();
+ exval = EXIT_SUCCESS;
+ run_with_signals();
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 != shp) {
+ if (0 != verbose) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 24);
+ }
+ exval = EXIT_FAILURE;
+ } else {
+ if (0 != had_write_error) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 25);
+ }
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+
+
+#line 2233 "dk-cat.ctr"
+
+
+#line 2234 "dk-cat.ctr"
+ exit(exval); return exval;
+}
+