diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk-t2l.c |
Initial commit
Diffstat (limited to 'support/dktools/dk-t2l.c')
-rw-r--r-- | support/dktools/dk-t2l.c | 2026 |
1 files changed, 2026 insertions, 0 deletions
diff --git a/support/dktools/dk-t2l.c b/support/dktools/dk-t2l.c new file mode 100644 index 0000000000..52ae36a00e --- /dev/null +++ b/support/dktools/dk-t2l.c @@ -0,0 +1,2026 @@ +/* + 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-t2l.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 9 "dk-t2l.ctr" + +/** @file dk-th2.c The dk-t2l program. + See dk_t2l_help_text for 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_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 + +#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_ERRNO_H +#ifndef ERRNO_H_INCLUDED +#include <errno.h> +#define ERRNO_H_INCLUDED 1 +#endif +#endif + +#include "dk4types.h" +#include "dk4const.h" +#include "dk4mem.h" +#include "dk4enc.h" +#include "dk4app.h" +#include "dk4aopt.h" +#include "dk4fopda.h" +#include "dk4fput.h" +#include "dk4vers.h" +#include "dk4tsp32.h" +#include "dk4uc2l.h" +#include "dk4maidhdu.h" +#include "dk4maidddu.h" +#include "dk4maodh.h" +#include "dk4maodd.h" +#include "dk4mpl.h" +#include "dk4strd.h" +#include "dk4pathd.h" + +#if DK4_CHAR_SIZE > 1 +#if DK4_CHAR_SIZE == 2 +#include "dk4utf16.h" +#endif +#else +#include "dk4ansi.h" +#include "dk4utf8.h" +#endif + + + + + +#line 105 "dk-t2l.ctr" + + + +/** Default help text, shown if no help text file is found. +*/ +static const dkChar * const dk_t2l_help_text[] = { +dkT(""), +dkT("dk-t2l - Text to LaTeX converter"), +dkT(""), +dkT("dk-t2l [<options>] [<file(s)>]"), +dkT(""), +dkT("Options:"), +dkT("-i <encoding>\t--input-encoding=<encoding>\tExpected input encoding."), +dkT("-e\t\t--echo\t\t\t\tProcess command line arguments."), +dkT("-n\t\t--numeric\t\t\tNumeric values on command line."), +dkT("-h\t\t--hex\t\t\t\tHexadecimal values on cmd line."), +dkT("-r\t\t--recommendations\t\tWrite recommendations for"), +dkT("\t\t\t\t\t\tpackages and font encodings"), +dkT("\t\t\t\t\t\tto use."), +dkT("-l\t\t--line-feed\t\t\tWrite \\\\ sequence for newline."), +dkT("-t\t\t--tabulator\t\t\tWrite LaTeX sequence for"), +dkT("\t\t\t\t\t\ttabulators"), +dkT("\t\t--verbose\t\t\tShow error message on SIGPIPE."), +dkT(""), +dkT("--help\t\t\t\t\t\tShow this short help text."), +dkT("--manual\t\t\t\t\t*** SHOW FULL MANUAL. ***"), +dkT("--version\t\t\t\t\tShow version information."), +dkT("--license\t\t\t\t\tShow license information."), +dkT(""), +dkT("http://dktools.sourceforge.net"), +dkT(""), +NULL + + +#line 138 "dk-t2l.ctr" +}; + + + +/** License text. +*/ +static const dkChar * const dk_t2l_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 270 "dk-t2l.ctr" +}; + + + +/** Constant 8 bit character texts, not localized. +*/ +static const char * const dk_t2l_kw8[] = { +/* 0 */ +"\\(", + +/* 1 */ +"\\)", + +/* 2 */ +"\\\\", + +NULL + + +#line 288 "dk-t2l.ctr" +}; + + + +/** Constant text keywords used by the program, not localized. +*/ +static const dkChar * const dk_t2l_kwnl[] = { +/* 0 */ +dkT("dktools"), + +/* 1 */ +dkT("dk-t2l.txt"), + +/* 2 */ +dkT("dk-t2l.str"), + +/* 3 */ +dkT("rb"), + +/* 4 */ +dkT("stdin"), + +/* 5 */ +dkT("\\"), + +/* 6 */ +dkT("verbose"), + +NULL + + +#line 325 "dk-t2l.ctr" +}; + + + +/** Constant keywords used by the program, replaced by localized texts. +*/ +static const dkChar * const dk_t2l_kw_def[] = { +/* 0 */ +dkT("Failed to set up signal handlers!"), + +/* 1 */ +dkT("Failed to restore signal handlers!"), + +/* 2 */ +dkT("Illegal input encoding name: \""), + +/* 3 */ +dkT("\"!"), + +/* 4 */ +dkT("Not a hexadecimal number: \""), + +/* 5 */ +dkT("\"!"), + +/* 6 */ +dkT("No data found for character 0x"), + +/* 7 */ +dkT("!"), + +/* 8 */ +dkT("No data found for character!"), + +/* 9 */ +dkT("Overflow in line number count!"), + +/* 10 */ +dkT("Failed to setup character by character processing!"), + +/* 11 */ +dkT("Probably incorrect output due to problems with the data files!"), + +/* 12 */ +dkT("Aborted by SIGINT signal!"), + +/* 13 */ +dkT("Aborted by SIGTERM signal!"), + +/* 14 */ +dkT("Received SIGPIPE signal!"), + +/* 15 */ +dkT("Write attempt to standard output failed."), + +/* 16 */ +dkT("Decoding failed!\n\tByte:"), + +/* 17 */ +dkT("Encoding failed!\n\tByte:"), + +/* 18 */ +dkT("Processing failed!\n\tByte:"), + +/* 19 */ +dkT(",\n\tCharacter:"), + +/* 20 */ +dkT(",\n\tPosition in line:"), + +/* 21 */ +dkT("."), + +/* 22 */ +dkT("Decoding failed!"), + +/* 23 */ +dkT("Encoding failed!"), + +/* 24 */ +dkT("Processing failed!"), + +/* 25 */ +dkT("Further decoding failures!"), + +/* 26 */ +dkT("Further encoding failures!"), + +/* 27 */ +dkT("Further processing failures!"), + +/* 28 */ +dkT("Out of range: \""), + +/* 29 */ +dkT("\"!"), + +/* 30 */ +dkT("Not a decimal number: \""), + +/* 31 */ +dkT("\"!"), + +NULL + + +#line 405 "dk-t2l.ctr" +}; + + + +/** Options for the program. +*/ +static const dk4_option_specification_t dk_t2l_options[] = { + + /* Expected input encoding. + */ + { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING }, + + /* Process command line arguments. + */ + { dkT('e'), dkT("echo"), DK4_OPT_ARG_NONE }, + + /* Command line arguments are decimal character numbers. + */ + { dkT('n'), dkT("numeric"), DK4_OPT_ARG_NONE }, + + /* Command line arguments are hexadecimal character numbers. + */ + { dkT('x'), dkT("hex"), DK4_OPT_ARG_NONE }, + + /* Write recommendations about font encodings and packages. + */ + { dkT('r'), dkT("recommendations"), DK4_OPT_ARG_NONE }, + + /* Convert tabulators. + */ + { dkT('t'), dkT("tabulator"), DK4_OPT_ARG_NONE }, + + /* Convert line feeds. + */ + { dkT('l'), dkT("line-feed"), DK4_OPT_ARG_NONE }, + + /* Verbose output. + */ + { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE } +}; + + + +/** Pointer to localized or not localized texts. +*/ +static const dkChar * const *dk_t2l_msg = dk_t2l_kw_def; + + + +/** Application structure. +*/ +static dk4_app_t *app = NULL; + + + +/** Conversion data structure. +*/ +static dk4_uc2l_t *uc2l = NULL; + + + +/** Current line number. +*/ +static dk4_um_t dk_t2l_lineno = (dk4_um_t)1UL; + + + +/** Number of elements in the dk_t2l_options array. +*/ +static const size_t dk_t2l_sz_options = +sizeof(dk_t2l_options)/sizeof(dk4_option_specification_t); + + + +/** Number of elements in dk_t2l_msg array. +*/ +static size_t dk_t2l_sz_msg = +sizeof(dk_t2l_kw_def)/sizeof(DK4_PCDKCHAR) - 1; + + +/** Program exit status. +*/ +static int exval = EXIT_FAILURE; + + + +/** Flag: Error occured while writing to stdout. +*/ +static int output_error = 0; + + + +/** Flag: Verbose output (report SIGPIPE). +*/ +static int verbose = 0; + + + +/** Flag: Echo command line arguments instead of processing files. +*/ +static int dk_t2l_echo = 0; + + + +/** Command line arguments are numeric: + 0 = text, + 1 = decimal, + 2 = hexadecimal. +*/ +static int dk_t2l_numeric = 0; + + + +/** Input encoding expected when processing stdin. +*/ +static int dk_t2l_i_std = DK4_FILE_ENCODING_ASCII; + + + +/** Input encoding expected when processing files. +*/ +static int dk_t2l_i_file = DK4_FILE_ENCODING_ASCII; + + + +/** Number of decoding errors in current file. +*/ +static int dk_t2l_dec_err = 0; + + + +/** Number of encoding errors in current file. +*/ +static int dk_t2l_enc_err = 0; + + + +/** Number of processing errors in current file. +*/ +static int dk_t2l_pro_err = 0; + + + +/** Flag: Previous character was carriage return. +*/ +static int dk_t2l_last_cr = 0; + + + +/** Flag: Previous character was newline. +*/ +static int dk_t2l_last_nl = 0; + + + +/** Flag: Have text in line, newline needed. +*/ +static int dk_t2l_lhtx = 0; + + + +/** Flag: In math mode. +*/ +static int dk_t2l_in_mm = 0; + + + +/** Flag: Find LaTeX sequence also for tabulators. +*/ +static int dk_t2l_tabs = 0; + + + +/** Flag: Write sequence for line feeds. +*/ +static int dk_t2l_linef = 0; + + + +#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; + + + +/** Pass a volatile pointer to an atomic integer. + 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 ptr Address of atomic integer variable. + @return The unmodified pointer. +*/ +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; +} + + + +/** Check whether we can continue. + @return 1 for yes, 0 for no. +*/ +static +int +dk_t2l_can_continue(void) +{ + int back = 1; + if (0 == sig_can_continue(1)) { + back = 0; + } + return back; +} + + + +/** Process command line options. + @return 1 on success, 0 on error. +*/ +static +int +dk_t2l_process_options(void) +{ + const dkChar *oaptr; + int encval = 0; + int bomval = 0; + int back = 1; + + if (0 != dk4app_opt_is_set_long(app, dk_t2l_kwnl[6], NULL)) { + verbose = 1; + } + if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) { + dk_t2l_tabs = 1; + } + if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) { + dk_t2l_linef = 1; + } + if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) { + oaptr = dk4app_opt_get_string_ptr_short(app, dkT('i'), NULL); + if (NULL != oaptr) { + if (0 != dk4enc_find(&encval, &bomval, oaptr, NULL)) { + dk_t2l_i_std = dk_t2l_i_file = encval; + } else { + /* ERROR: Illegal encoding */ + dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 2, 3, oaptr); + back = 0; + } + } else { + +#line 738 "dk-t2l.ctr" + /* ERROR: Failed to obtain option argument, bug! */ + } + } + if (0 != dk4app_opt_is_set_short(app, dkT('e'), NULL)) { + dk_t2l_echo = 1; + } + if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) { + dk_t2l_echo = 1; + dk_t2l_numeric = 1; + } + if (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) { + dk_t2l_echo = 1; + dk_t2l_numeric = 2; + } + uc2l = dk4uc2l_open_from_app(app); + if (NULL == uc2l) { + back = 0; + } + return back; +} + + + +/** Start output page. +*/ +static +void +dk_t2l_output_start_page(void) +{ + /* Hook */ +} + + + +/** Finish output page. +*/ +static +void +dk_t2l_output_finish_page(void) +{ + /* Hook */ +} + + + +/** Start processing of one file. +*/ +static +void +dk_t2l_output_start_file(void) +{ + /* No errors in this file yet. + */ + dk_t2l_dec_err = 0; + dk_t2l_enc_err = 0; + dk_t2l_pro_err = 0; + dk_t2l_last_cr = 0; + dk_t2l_last_nl = 0; + dk_t2l_lhtx = 0; + dk_t2l_lineno = (dk4_um_t)1UL; + dk4app_set_log_source_line(app, dk_t2l_lineno); +} + + + +/** Finish processing of one file. +*/ +static +void +dk_t2l_output_finish_file(void) +{ + +} + + + +static +void +dk_t2l_begin_math_mode(void) +{ + if (0 == dk_t2l_in_mm) { + dk_t2l_in_mm = 1; + if (EOF == fputs(dk_t2l_kw8[0], stdout)) { + output_error = 1; + } + } +} + + + +static +void +dk_t2l_end_math_mode(void) +{ + if (0 != dk_t2l_in_mm) { + dk_t2l_in_mm = 0; + if (EOF == fputs(dk_t2l_kw8[1], stdout)) { + output_error = 1; + } + } +} + + + +/** Handler function after processing CR/NL sequences. + Here we do the real output. + @param c Character to process. + @param pos Current position in file or data stream, may be NULL. + @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 +dk_t2l_c32_after_cr_nl_check( + dk4_c32_t c, + dk4_text_stream_position_t *pos, + dk4_er_t *erp +) +{ + dkChar buf[16*sizeof(dk4_um_t)]; + const char *lseq; + size_t szbuf; + int back = DK4_TSP_RES_OK; + + if (dkC32(0x0A) == c) { + /* + Newline, finish line and write newline to output. + */ + dk_t2l_end_math_mode(); + if (0 != dk_t2l_linef) { + if (EOF == fputs(dk_t2l_kw8[2], stdout)) { output_error = 1; } + } + if (EOF == fputc('\n', stdout)) { output_error = 1; } + } else { + if (0 == dk_t2l_lhtx) { + /* + Start new line. + */ + } + /* + Write character to output. + */ + if ((dkC32(0x09) == c) && (0 == dk_t2l_tabs)) { + dk_t2l_end_math_mode(); + if (EOF == fputc(' ', stdout)) { output_error = 1; } + } else { + lseq = dk4uc2l_find(uc2l, c, 0, app); + if (NULL != lseq) { + dk_t2l_end_math_mode(); + if (EOF == fputs(lseq, stdout)) { output_error = 1; } + } else { + lseq = dk4uc2l_find(uc2l, c, 1, app); + if (NULL != lseq) { + dk_t2l_begin_math_mode(); + if (EOF == fputs(lseq, stdout)) { output_error = 1; } + } else { + /* ERROR, no encoding found */ + szbuf = DK4_SIZEOF(buf,dkChar); + if (0 != dk4ma_write_hex_unsigned(buf, szbuf, (dk4_um_t)c, 8, NULL)) { + dk4app_log_3(app,dk_t2l_msg,dk_t2l_sz_msg,DK4_LL_ERROR,6,7,buf); + } else { + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 8); + } + exval = EXIT_FAILURE; + } + } + } + } + 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 +dk_t2l_c32_handler( + void *obj, + dk4_c32_t c, + dk4_text_stream_position_t *pos, + dk4_er_t *erp +) +{ + int back = DK4_TSP_RES_OK; + if (dkC32(0x0A) == c) { + /* + For a newline clear CR and TXT flag, set NL flag. + */ + back = dk_t2l_c32_after_cr_nl_check(c, pos, erp); + dk_t2l_lineno++; + if ((dk4_um_t)0UL == dk_t2l_lineno) { + /* ERROR: Overflow in line number counting */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 9); + exval = EXIT_FAILURE; + } + dk4app_set_log_source_line(app, dk_t2l_lineno); + dk_t2l_last_cr = 0; + dk_t2l_last_nl = 1; + dk_t2l_lhtx = 0; + } else { + if (dkC32(0x0D) == c) { + /* + For a cr if CR flag is set, pass the cr and set TXT flag, clear nl flag. + Otherwise simply set CR flag. + */ + if (0 != dk_t2l_last_cr) { + back = dk_t2l_c32_after_cr_nl_check(dkC32(0x0D), pos, erp); + dk_t2l_lhtx = 1; + dk_t2l_last_nl = 0; + } else { + dk_t2l_last_cr = 1; + } + } else { + /* + For any other character: + If the CR flag is set, pass cr and current character. + Otherwise pass the current character. + Reset NL and CR flag, set TXT flag. + */ + if (0 != dk_t2l_last_cr) { + back = dk_t2l_c32_after_cr_nl_check(dkC32(0x0D), pos, erp); + switch (dk_t2l_c32_after_cr_nl_check(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 = dk_t2l_c32_after_cr_nl_check(c, pos, erp); + } + dk_t2l_lhtx = 1; + dk_t2l_last_nl = 0; + dk_t2l_last_cr = 0; + } + } + return back; +} + + + +/** 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 +dk_t2l_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))]; + dk4_um_t oldlogline = (dk4_um_t)0UL; + int allbuffersok = 0; + + oldlogline = dk4app_get_log_source_line(app); + 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, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, i1, 19, 20, 21, b1, b2, b3 + ); + } else { + dk4app_log_1( + app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, i2 + ); + } + dk4app_set_log_source_line(app, oldlogline); +} + + + +static +void +dk_t2l_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 (dk_t2l_dec_err) { + case 0: case 1: { + dk_t2l_report_with_position( + 16, 22, + er_en->dt.fpos.byteno, + er_en->dt.fpos.lineno, + er_en->dt.fpos.charno, + er_en->dt.fpos.charinline + ); + } break; + case 2: { + dk4app_log_1( + app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 25 + ); + } break; + } + if (3 > dk_t2l_dec_err) { dk_t2l_dec_err++; } + } break; + case DK4_E_ENCODING_FAILED: { + switch (dk_t2l_enc_err) { + case 0: case 1: { + dk_t2l_report_with_position( + 17, 23, + er_en->dt.fpos.byteno, + er_en->dt.fpos.lineno, + er_en->dt.fpos.charno, + er_en->dt.fpos.charinline + ); + } break; + case 2: { + dk4app_log_1( + app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 26 + ); + } break; + } + if (3 > dk_t2l_enc_err) { dk_t2l_enc_err++; } + } break; + } + } + if (NULL != er_pr) { + if (DK4_E_NONE != er_pr->ec) { + switch (dk_t2l_pro_err) { + case 0: case 1: { + dk_t2l_report_with_position( + 18, 24, + er_pr->dt.fpos.byteno, + er_pr->dt.fpos.lineno, + er_pr->dt.fpos.charno, + er_pr->dt.fpos.charinline + ); + } break; + case 2: { + dk4app_log_1( + app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 27 + ); + } break; + } + if (3 > dk_t2l_pro_err) { dk_t2l_pro_err++; } + } + } +} + + + +static +void +dk_t2l_echo_hex(const dkChar *txt, int argno) +{ + const dkChar *endptr = NULL; + dk4_um_t um = (dk4_um_t)0UL; + int res = 0; + if (dkT('0') == txt[0]) { + if ((dkT('x') == txt[1]) || (dkT('X') == txt[1])) { + txt++; txt++; + } + } + res = dk4ma_input_dk_hex_dk4_um_t( + &um, txt, &endptr, 1, NULL + ); + if (0 != res) { + if ((dk4_um_t)0xFFFFFFFFUL >= um) { + (void)dk_t2l_c32_after_cr_nl_check((dk4_c32_t)um, NULL, NULL); + } else { + dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 28, 29, txt); + } + } else { + /* ERROR: Not a hexadecimal number */ + dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 4, 5, txt); + } +} + + + +static +void +dk_t2l_echo_numeric(const dkChar *txt, int argno) +{ + const dkChar *endptr = NULL; + dk4_um_t um = (dk4_um_t)0UL; + int res = 0; + int ishex = 0; + + if (dkT('0') == txt[0]) { + if ((dkT('x') == txt[1]) || (dkT('X') == txt[1])) { + ishex = 1; + } + } + if (0 == ishex) { + res = dk4ma_input_dk_dec_dk4_um_t( + &um, txt, &endptr, 1, NULL + ); + if (0 != res) { + if ((dk4_um_t)0xFFFFFFFFUL >= um) { + (void)dk_t2l_c32_after_cr_nl_check((dk4_c32_t)um, NULL, NULL); + } else { + dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 28, 29, txt); + } + } else { + /* ERROR: Not a decimal number */ + dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 30, 31, txt); + } + } else { + dk_t2l_echo_hex(&(txt[2]), argno); + } +} + + +#if DK4_CHAR_SIZE > 1 +#if DK4_CHAR_SIZE > 2 + +/** Process one text word from command line, UNICODE character. + @param txt Text word. + @param argno Number of current word. +*/ +static +void +dk_t2l_echo_c32(const dkChar *txt, int argno) +{ + int isfirst = 1; + while (dkC32(0) != *txt) { + if ((1 == isfirst) && (0 != argno)) { + if (EOF == fputc(' ', stdout)) { output_error = 1; } + } + isfirst = 0; + (void)dk_t2l_c32_after_cr_nl_check(*(txt++), NULL, NULL); + } +} + +#else + +/** Process one text word from command line, UTF-16 encoded. + @param txt Text word. + @param argno Number of current word. +*/ +static +void +dk_t2l_echo_utf16(const dkChar *txt, int argno) +{ + dk4_utf16_decoder_t dec; + int cc = 1; + int isfirst = 1; + dk4utf16_init(&dec); + while (1 == cc) { + if (dkC16(0) != *txt) { + switch (dk4utf16_add(&dec, *(txt++))) { + case DK4_EDSTM_ERROR : { + cc = -1; + /* !!!!! ERROR: Decoding */ + exval = EXIT_FAILURE; + } break; + case DK4_EDSTM_FINISHED : { + if ((1 == isfirst) && (0 != argno)) { + if (EOF == fputc(' ', stdout)) { output_error = 1; } + } + isfirst = 0; + (void)dk_t2l_c32_after_cr_nl_check(dk4utf16_get(&dec), NULL, NULL); + } break; + } + } else { + cc = 0; + } + } + if (0 == cc) { + if (0 == dk4utf16_is_empty(&dec)) { + /* !!!!! ERROR: Decoding */ + exval = EXIT_FAILURE; + } + } + /* !!!!! TODO: Implementation */ +} + +#endif +#else + +/** Process one text word from command line, ASCII encoded. + @param txt Text word. + @param argno Number of current word. +*/ +static +void +dk_t2l_echo_ascii(const dkChar *txt, int argno) +{ + dk4_c32_t c32; + int isfirst = 1; + while ('\0' != *txt) { + if ((1 == isfirst) && (0 != argno)) { + if (EOF == fputc(' ', stdout)) { output_error = 1; } + } + isfirst = 0; + c32 = dkC32(0xFF) & ((dk4_c32_t)((unsigned char)(*(txt++)))); + (void)dk_t2l_c32_after_cr_nl_check(c32, NULL, NULL); + } +} + +/** Process one text word from command line, UTF-8 encoded. + @param txt Text word. + @param argno Number of current word. +*/ +static +void +dk_t2l_echo_utf8(const dkChar *txt, int argno) +{ + dk4_utf8_decoder_t dec; + int cc = 1; + int isfirst = 1; + + dk4utf8_init(&dec); + while (1 == cc) { + if ('\0' != *txt) { + switch (dk4utf8_add(&dec, *(txt++))) { + case DK4_EDSTM_ERROR : { + cc = -1; + exval = EXIT_FAILURE; + /* !!!!! ERROR: Decoding */ + } break; + case DK4_EDSTM_FINISHED : { + if ((1 == isfirst) && (0 != argno)) { + if (EOF == fputc(' ', stdout)) { output_error = 1; } + } + isfirst = 0; + (void)dk_t2l_c32_after_cr_nl_check(dk4utf8_get(&dec), NULL, NULL); + } break; + } + } else { + cc = 0; + } + } + if (0 == cc) { + if (0 == dk4utf8_is_empty(&dec)) { + exval = EXIT_FAILURE; + /* !!!!! ERROR: Decoding */ + } + } +} + +/** Process one text word from command line, ANSI encoded. + @param txt Text word. + @param argno Number of current word. +*/ +static +void +dk_t2l_echo_ansi(const dkChar *txt, int argno) +{ + dk4_c32_t c32; + int isfirst = 1; + char c; + while ('\0' != *txt) { + c = *(txt++); + if (0 != dk4ansi_decode(&c32, (unsigned char)c)) { + if ((1 == isfirst) && (0 != argno)) { + if (EOF == fputc(' ', stdout)) { output_error = 1; } + } + isfirst = 0; + (void)dk_t2l_c32_after_cr_nl_check(c32, NULL, NULL); + } else { + /* !!!!! ERROR: Decoding */ + exval = EXIT_FAILURE; + } + } +} + +#endif + + + +/** Process one text word from command line. + @param txt Text word. + @param argno Number of current word. +*/ +static +void +dk_t2l_echo_text(const dkChar *txt, int argno) +{ +#if DK4_CHAR_SIZE > 1 +#if DK4_CHAR_SIZE > 2 + dk_t2l_echo_c32(txt, argno); +#else + dk_t2l_echo_utf16(txt, argno); +#endif +#else + switch (dk4app_get_encoding(app)) { + case DK4_ENCODING_UTF8 : { + dk_t2l_echo_utf8(txt, argno); + } break; + case DK4_ENCODING_ANSI : { + dk_t2l_echo_ansi(txt, argno); + } break; + default : { + dk_t2l_echo_ascii(txt, argno); + } break; + } +#endif + dk_t2l_end_math_mode(); +} + + + +/** Process command line arguments. +*/ +static +void +dk_t2l_process_cmdline(void) +{ + const dkChar *xargv; + int argc; + int i; + /* !!!!! TODO: Implementation */ + dk_t2l_output_start_file(); + argc = dk4app_get_argc(app); + if (0 < argc) { + switch (dk_t2l_numeric) { + case 2: { + for (i = 0; i < argc; i++) { + xargv = dk4app_get_argv(app, i); + if (NULL != xargv) { + dk_t2l_echo_hex(xargv, i); + } + } + dk_t2l_end_math_mode(); + } break; + case 1: { + for (i = 0; i < argc; i++) { + xargv = dk4app_get_argv(app, i); + if (NULL != xargv) { + dk_t2l_echo_numeric(xargv, i); + } + } + dk_t2l_end_math_mode(); + } break; + default: { + for (i = 0; i < argc; i++) { + xargv = dk4app_get_argv(app, i); + if (NULL != xargv) { + dk_t2l_echo_text(xargv, i); + } + } + } break; + } + if (EOF == fputc('\n', stdout)) { output_error = 1; } + } else { + /* !!!!! ERROR: No command line arguments specified */ + } + dk_t2l_output_finish_file(); +} + + + +/** Process an opened file with file name. + @param fipo Opened file. + @param fn File name. + @param ienc_def Expected input encoding. +*/ +static +void +dk_t2l_process_named_file(FILE *fipo, const dkChar *fn, int ienc_def) +{ + dk4_tsp32_t tsp32; + dk4_er_t er; + dk4_er_t er_en; + dk4_er_t er_pr; + const dkChar *oldsourcefile; + dk4_um_t oldsourceline; + int c; + int cc; + int res; + unsigned char ub; + + dk_t2l_in_mm = 0; + oldsourcefile = dk4app_get_log_source_file(app); + oldsourceline = dk4app_get_log_source_line(app); + dk4app_set_log_source_file(app, fn); + dk4app_set_log_source_line(app, (dk4_um_t)0UL); + dk_t2l_output_start_file(); + dk4error_init(&er); + res = dk4tsp32_setup_char( + &tsp32, NULL, dk_t2l_c32_handler, ienc_def, &er + ); + if (0 != res) { + cc = 1; + while (1 == cc) { + if (0 != dk_t2l_can_continue()) { + c = fgetc(fipo); + if (EOF != c) { + ub = (unsigned char)c; + res = dk4tsp32_add_one_byte(&tsp32, ub); + switch (res) { + case DK4_TSP_RES_ERROR: { + exval = EXIT_FAILURE; + dk4tsp32_get_errors(&er_en, &er_pr, &tsp32); + dk_t2l_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); + dk_t2l_report_errors(&er_en, &er_pr); + } break; + default: { + } break; + } + } else { + cc = 0; + } + if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } } + } else { + cc = -1; + } + } + if (0 == cc) { + res = dk4tsp32_finish(&tsp32); + switch (res) { + case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: { + exval = EXIT_FAILURE; + dk4tsp32_get_errors(&er_en, &er_pr, &tsp32); + dk_t2l_report_errors(&er_en, &er_pr); + } break; + } + } + if (0 != dk_t2l_can_continue()) { + /* TODO: Finish current line */ + if (0 != dk_t2l_in_mm) { + dk_t2l_end_math_mode(); + if (EOF == fputc('\n', stdout)) { output_error = 1; } + } else { + if (0 == dk_t2l_last_nl) { + if (EOF == fputc('\n', stdout)) { output_error = 1; } + } + } + } + } else { + /* ERROR: Setup failed, should not happen, bug */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 10); + exval = EXIT_FAILURE; + } + dk_t2l_output_finish_file(); + dk4app_set_log_source_file(app, oldsourcefile); + dk4app_set_log_source_line(app, oldsourceline); +} + + + +/** Process standard input. +*/ +static +void +dk_t2l_process_stdin(void) +{ +#if DK4_ON_WINDOWS + int oldmode; + + oldmode = _setmode(_fileno(stdin), _O_BINARY); +#endif + dk_t2l_process_named_file(stdin, dk_t2l_kwnl[4], dk_t2l_i_std); +#if DK4_ON_WINDOWS + _setmode(_fileno(stdin), oldmode); +#endif +} + + + +/** Process one real file name. + @param infname File name to process. +*/ +static +void +dk_t2l_process_one_file_name(const dkChar *infname) +{ + FILE *fipo = NULL; + int tests = DK4_FOPEN_SC_IS_REGULAR; + fipo = dk4fopen_app(infname, dk_t2l_kwnl[3], tests, app); + if (NULL != fipo) { + dk_t2l_process_named_file(fipo, infname, dk_t2l_i_file); + fclose(fipo); + } else { + exval = EXIT_FAILURE; + } +} + + + +#if DK4_ON_WINDOWS + +/** Expand file name pattern and process the files. + @pattern File name pattern to expand. + @return 1 if files were found, 0 otherwise. +*/ +static +int +dk_t2l_expand_and_process(const dkChar *pattern) +{ + dkChar buf[DK4_MAX_PATH]; + dk4_dir_t *fne; + const dkChar *shf; + const dkChar *pth; + int cc; + int back = 0; + fne = dk4app_fne_open(pattern, app); + if (NULL != fne) { + cc = 1; + while (1 == cc) { + if (0 != dk_t2l_can_continue()) { + shf = dk4dir_next_file(fne); + if (NULL != shf) { + back = 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_t2l_kwnl[5],NULL)) + { + if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) { + dk_t2l_process_one_file_name(buf); + } else { + /* ERROR: Path too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); + exval = EXIT_FAILURE; + } + } + else + { + /* ERROR: Path too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); + exval = EXIT_FAILURE; + } + } else { + /* ERROR: Path too long */ + dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth); + exval = EXIT_FAILURE; + } + } else { + dk_t2l_process_one_file_name(shf); + } + } else { + cc = 0; + } + } else { + cc = -1; + } + } + dk4dir_close(fne); + } else { + exval = EXIT_FAILURE; + } + return back; +} + +#endif + + + +/** Process one file name, check whether expansion is necessary. + @param infname Input file name to process, may be NULL. +*/ +static +void +dk_t2l_process_filename(const dkChar *infname) +{ + if (NULL != infname) { +#if DK4_ON_WINDOWS + if (0 != dk4path_must_expand(infname)) { + if (0 == dk_t2l_expand_and_process(infname)) { + exval = EXIT_FAILURE; + /* ERROR: No such file */ + dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, infname); + } + } else { +#endif + dk_t2l_process_one_file_name(infname); +#if DK4_ON_WINDOWS + } +#endif + } +} + + + +/** Run after installing the signal handlers. +*/ +static +void +dk_t2l_normal_run(void) +{ + int argc; + int i; + if (0 != dk_t2l_process_options()) { + exval = EXIT_SUCCESS; + dk_t2l_output_start_page(); + if (0 != dk_t2l_echo) { + dk_t2l_process_cmdline(); + } else { + argc = dk4app_get_argc(app); + if (0 < argc) { + for (i = 0; ((0 != dk_t2l_can_continue()) && (i < argc)); i++) { + dk_t2l_process_filename(dk4app_get_argv(app, i)); + } + } else { + dk_t2l_process_stdin(); + } + } + dk_t2l_output_finish_page(); + if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) { + dk4uc2l_recommendations(uc2l, stdout); + } + if (0 != dk4uc2l_retrieve_errors(uc2l)) { + +#line 1674 "dk-t2l.ctr" + /* ERROR: Probably incorrect output due to problems */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 11); + exval = EXIT_FAILURE; + } + } + if (NULL != uc2l) { + dk4uc2l_close(uc2l); + uc2l = NULL; + } +} + + + +#if DK4_HAVE_SIGACTION +/** Set signal handlers and run. +*/ +static +void +dk_t2l_run_with_signal_handlers(void) +{ +#ifdef SIGPIPE + struct sigaction opipe; +#endif + struct sigaction oint; +#ifdef SIGPIPE + struct sigaction npipe; +#endif + struct sigaction nint; + struct sigaction oterm; + 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, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0); + goto finished; + } + if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { + /* ERROR: Failed to set up masked signal set for SIGPIPE */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0); + goto finished; + } + if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { + /* ERROR: Failed to set up signal handler for SIGPIPE */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0); + 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, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0); + 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, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0); + goto restore_old_pipe; + } + if (0 != sigaction(SIGINT, &nint, &oint)) { + /* ERROR: Failed to set up signal handler for SIGINT */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0); + 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, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0); + 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, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0); + goto restore_old_int; + } + if (0 != sigaction(SIGTERM, &nterm, &oterm)) { + /* ERROR: Failed to set up signal handler for SIGTERM */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0); + goto restore_old_int; + } + + success = 1; + dk_t2l_normal_run(); + + /* Restore signal handling for SIGTERM. + */ + if (0 != sigaction(SIGTERM, &oterm, NULL)) { + /* ERROR: Failed to restore old SIGTERM settings */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 1); + 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, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 1); + 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, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 1); + 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 +dk_t2l_run_with_signal_handlers(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); + dk_t2l_normal_run(); + sigset(SIGTERM, oldterm); + sigset(SIGINT, oldint); +#ifdef SIGPIPE + sigset(SIGPIPE, oldpipe); +#endif +} +#else +#if DK4_HAVE_SIGNAL +/** Set signal handlers and run. +*/ +static +void +dk_t2l_run_with_signal_handlers(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); + dk_t2l_normal_run(); + signal(SIGTERM, oldterm); + signal(SIGINT, oldint); +#ifdef SIGPIPE + signal(SIGPIPE, oldpipe); +#endif +} +#else +/** Set signal handlers and run. +*/ +static +void +dk_t2l_run_with_signal_handlers(void) +{ + dk_t2l_normal_run(); +} +#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 +{ + int shp; + + +#line 1887 "dk-t2l.ctr" + + +#line 1888 "dk-t2l.ctr" + dk4fput_initialize_stderr(); + app = dk4app_open_cmd( + argc, argv, dk_t2l_options, dk_t2l_sz_options, + dk_t2l_kwnl[0], DKT_VERSION_DK, + dk_t2l_kwnl[1], dk_t2l_help_text, dk_t2l_license_text + ); + if (NULL != app) { + dk_t2l_i_std = dk4app_get_stdin_encoding(app); + dk_t2l_i_file = dk4app_get_file_in_encoding(app); + dk_t2l_sz_msg = dk4app_string_table_size(dk_t2l_kw_def); + dk_t2l_msg = dk4app_string_table(app, dk_t2l_kwnl[2], dk_t2l_kw_def); + if (0 != dk4app_can_run_normally(app)) { + dk_t2l_run_with_signal_handlers(); + } else { + dk4fput_initialize_stdout(); + if (0 != dk4app_help_version_license(app)) { + exval = EXIT_SUCCESS; + } + fflush(stdout); + fflush(stderr); + dk4fput_cleanup_stdout(); + } + if (0 != sig_read_atomic(&sig_had_int )) { + exval = EXIT_FAILURE; + /* ERROR: Interrupted by SIGINT */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 12); + } + if (0 != sig_read_atomic(&sig_had_term)) { + exval = EXIT_FAILURE; + /* ERROR: Interrupted by SIGTERM */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 13); + } +#ifdef SIGPIPE + if (0 != sig_read_atomic(&sig_had_pipe)) { + exval = EXIT_FAILURE; + shp = 1; + /* ERROR: Interrupted by SIGPIPE */ + if (0 != verbose) { + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 14); + } + } else { + shp = 0; + } +#else + shp = 0; +#endif + if ((0 == shp) && (0 != output_error)) { + exval = EXIT_FAILURE; + /* ERROR: Output to stdout failed */ + dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 15); + } + dk4app_close(app); + } + fflush(stdout); + if (0 != sig_read_atomic(&sig_had_int )) { exval = EXIT_FAILURE; } + if (0 != sig_read_atomic(&sig_had_term)) { exval = EXIT_FAILURE; } +#ifdef SIGPIPE + if (0 != sig_read_atomic(&sig_had_pipe)) { exval = EXIT_FAILURE; } +#endif + if (0 != output_error) { exval = EXIT_FAILURE; } + fflush(stderr); + dk4fput_cleanup_stderr(); + + +#line 1951 "dk-t2l.ctr" + + +#line 1952 "dk-t2l.ctr" + exit(exval); return exval; +} + + |