summaryrefslogtreecommitdiff
path: root/support/dktools/dk-lines.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-09-20 03:03:26 +0000
committerNorbert Preining <norbert@preining.info>2020-09-20 03:03:26 +0000
commit1f457376b478257b88d4a857f5ec1b6155442dd7 (patch)
tree2a06a60551dea362cf8cb0cb0ba66c78608717c4 /support/dktools/dk-lines.c
parentac690ca29ad5bf8a5203a65fd6252f7b564f4727 (diff)
CTAN sync 202009200303
Diffstat (limited to 'support/dktools/dk-lines.c')
-rw-r--r--support/dktools/dk-lines.c2769
1 files changed, 2769 insertions, 0 deletions
diff --git a/support/dktools/dk-lines.c b/support/dktools/dk-lines.c
new file mode 100644
index 0000000000..1f0f162341
--- /dev/null
+++ b/support/dktools/dk-lines.c
@@ -0,0 +1,2769 @@
+/*
+Copyright (C) 2017-2020, Dirk Krause
+SPDX-License-Identifier: BSD-3-Clause
+*/
+
+/*
+ WARNING: This file was generated by the dkct program (see
+ http://dktools.sourceforge.net/ for details).
+ 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-lines.ctr
+*/
+
+
+#line 9 "dk-lines.ctr"
+
+/** @file dk-lines.c The dk-lines program.
+ The dk_lines_help_text array below shows details.
+
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#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
+
+#ifndef DK4UNUSED_H_INCLUDED
+#include "dk4unused.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4ENC_H_INCLUDED
+#include "dk4enc.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4STRDA_H_INCLUDED
+#include "dk4strda.h"
+#endif
+
+#ifndef DK4DIR_H_INCLUDED
+#include "dk4dir.h"
+#endif
+
+#ifndef DK4PATHD_H_INCLUDED
+#include "dk4pathd.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4AOPT_H_INCLUDED
+#include "dk4aopt.h"
+#endif
+
+#ifndef DK4MEMA_H_INCLUDED
+#include "dk4mema.h"
+#endif
+
+#ifndef DK4VERS_H_INCLUDED
+#include "dk4vers.h"
+#endif
+
+#ifndef DK4MAADU_H_INCLUDED
+#include "dk4maadu.h"
+#endif
+
+#ifndef DK4MAIDDDU_H_INCLUDED
+#include "dk4maidddu.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4FPUT_H_INCLUDED
+#include "dk4fput.h"
+#endif
+
+#ifndef DK4TSPDK_H_INCLUDED
+#include "dk4tspdk.h"
+#endif
+
+#ifndef DK4FOPD_H_INCLUDED
+#include "dk4fopd.h"
+#endif
+
+#ifndef DK4FOPDA_H_INCLUDED
+#include "dk4fopda.h"
+#endif
+
+#ifndef DK4ISADM_H_INCLUDED
+#include "dk4isadm.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEDK_H_INCLUDED
+#include "dk4timedk.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4WMAIN_H_INCLUDED
+#include "dk4wmain.h"
+#endif
+
+
+
+
+#line 168 "dk-lines.ctr"
+
+
+
+#ifndef DK_LINES_BUFFER_SIZE
+/** Text buffer size.
+*/
+#define DK_LINES_BUFFER_SIZE 4096
+#endif
+
+
+
+/** Ring buffer element.
+*/
+typedef struct {
+ dkChar *str; /**< Line text. */
+ dk4_um_t lineno; /**< Line number. */
+ size_t buflen; /**< Length of str buffer (number of dkChar). */
+} rbe_t;
+
+
+
+/** Range specification types.
+*/
+enum {
+ RANGE_NONE_NONE = 0 , /**< No ranges specified. */
+ RANGE_NONE_POS , /**< No start, positive end. */
+ RANGE_NONE_NEG , /**< No start, negative end. */
+ RANGE_POS_NONE , /**< Positive start, no end. */
+ RANGE_POS_POS , /**< Positive start, positive end. */
+ RANGE_POS_NEG , /**< Positive start, negative end. */
+ RANGE_NEG_NONE , /**< Negative start, no end. */
+ RANGE_NEG_POS , /**< Negative start, positive end. */
+ RANGE_NEG_NEG , /**< Negative start, negative end. */
+};
+
+
+
+/** Input line buffer.
+*/
+static dkChar default_input_line_buffer[DK_LINES_BUFFER_SIZE];
+
+
+
+/** Buffer to store current date and time.
+*/
+static dkChar date_buffer[64];
+
+
+
+/** Default text, used if help text file is not found.
+*/
+static const dkChar * const dk_lines_help_text[] = {
+dkT(""),
+dkT("Select lines from text"),
+dkT(""),
+dkT("dk-lines [<options>] [<files>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-i encoding Expected input encoding, one from: plain, ascii, ansi, utf-8,"),
+dkT(" utf-16, utf-16le, utf-16be, c32, c32le, c32be."),
+dkT("-f string Show lines lexicographically equal or larger than string."),
+dkT("-t string Show lines lexicographically equal or smaller than string."),
+dkT("-l spec Specification of line numbers in format <start>/<end> (inclusive)"),
+dkT(" to pass through, applied after -f and -t processing. Examples:"),
+dkT(" 5 (5 and following), 5/8 (5, 6, 7, 8), /8 (1...8), 5/-3 (5 and"),
+dkT(" following except final 2 lines), -5 (final 5 lines), -5/-3 (3 lines"),
+dkT(" before the final 2 lines), /-3 (all lines except the final 2),"),
+dkT(" 5/-3 (5 and following except final 2 lines),"),
+dkT(" -5/8 (final 5 lines but not above line 8)."),
+dkT("-v Verbose mode: Error message on SIGPIPE."),
+dkT("--help Show this short help text. --manual *** SHOW FULL MANUAL. ***"),
+dkT("--version Show version information. --license Show license information."),
+dkT(""),
+dkT("http://sourceforge.net/p/dktools/wiki/dk-lines/"),
+dkT(""),
+NULL
+
+
+#line 245 "dk-lines.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_lines_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://sourceforge.net/p/dktools/wiki/Home/"),
+dkT("\t\tfor 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("1. Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("2. 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("3. Neither the name of the copyright holder nor the names of its"),
+dkT(" contributors may be used to endorse or promote products derived from"),
+dkT(" this software without specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT("IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES"),
+dkT("(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR"),
+dkT("SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER"),
+dkT("CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT("LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT("OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT("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 378 "dk-lines.ctr"
+};
+
+
+
+/** Constant texts used by program, not localized.
+*/
+static const dkChar * const dk_lines_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-lines.txt"),
+
+/* 2 */
+dkT("dk-lines.str"),
+
+/* 3 */
+dkT("line-size"),
+
+/* 4 */
+dkT("today"),
+
+/* 5 */
+dkT("/"),
+
+/* 6 */
+dkT("rb"),
+
+/* 7 */
+dkT("<stdin>"),
+
+NULL
+
+
+#line 422 "dk-lines.ctr"
+};
+
+
+
+/** Constant texts used by program, replaced by localized texts
+ if available.
+*/
+static const dkChar * const dk_lines_kw_def[] = {
+/* 0 */
+dkT("Failed to set up masked signal set for SIGPIPE!"),
+
+/* 1 */
+dkT("Failed to set up masked signal set for SIGINT!"),
+
+/* 2 */
+dkT("Failed to set up masked signal set for SIGTERM!"),
+
+/* 3 */
+dkT("Failed to restore SIGTERM settings!"),
+
+/* 4 */
+dkT("Failed to restore SIGTERM settings!"),
+
+/* 5 */
+dkT("Failed to restore SIGPIPE settings!"),
+
+/* 6 */
+dkT("Illegal line number 0!"),
+
+/* 7 */
+dkT("Number too large: \""),
+
+/* 8 */
+dkT("\"!"),
+
+/* 9 */
+dkT("Not a number: \""),
+
+/* 10 */
+dkT("\"!"),
+
+/* 11 */
+dkT("Start line number larger than end number!"),
+
+/* 12 */
+dkT("Invalid line range specification (empty string)!"),
+
+/* 13 */
+dkT("Missing line range specification!"),
+
+/* 14 */
+dkT("Illegal input encoding: \""),
+
+/* 15 */
+dkT("\"!"),
+
+/* 16 */
+dkT("Missing input encoding!"),
+
+/* 17 */
+dkT("Invalid line size 0!"),
+
+/* 18 */
+dkT("Missing line size specification!"),
+
+/* 19 */
+dkT("Can not use --today with both --from and --to!"),
+
+/* 20 */
+dkT("Input line too long!"),
+
+/* 21 */
+dkT("Too many lines, overflow in line number!"),
+
+/* 22 */
+dkT("Overflow in line range calculation!"),
+
+/* 23 */
+dkT("End line number is 1 (should not happen, bug)!"),
+
+/* 24 */
+dkT("End line number too large, numeric overflow!"),
+
+/* 25 */
+dkT("Start line number too large, numeric overflow!"),
+
+/* 26 */
+dkT("Ring buffer size is 0 (should not happen, bug)!"),
+
+/* 27 */
+dkT("Failed to obtain file name (should not happen, bug)!"),
+
+/* 28 */
+dkT("Program stopped by SIGPIPE!"),
+
+/* 29 */
+dkT("I/O errors while writing output!"),
+
+/* 30 */
+dkT("Program stopped by interrupt!"),
+
+/* 31 */
+dkT("Encoding error!"),
+
+/* 32 */
+dkT("Decoding error!"),
+
+/* 33 */
+dkT("Processing error!"),
+
+/* 34 */
+dkT("Encoding error!\n\tByte: "),
+
+/* 35 */
+dkT("Decoding error!\n\tByte: "),
+
+/* 36 */
+dkT("Processing error!\n\tByte: "),
+
+/* 37 */
+dkT(",\n\tCharacter: "),
+
+/* 38 */
+dkT(",\n\tPosition in line: "),
+
+/* 39 */
+dkT("."),
+
+NULL
+
+
+#line 562 "dk-lines.ctr"
+};
+
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t dk_lines_options[] = {
+
+ /* Input encoding.
+ */
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+
+ /* Only lines matching start text or lexicagraphically after text.
+ */
+ { dkT('f'), dkT("from"), DK4_OPT_ARG_STRING },
+
+ /* Only lines matching end text or lexicographically before text.
+ */
+ { dkT('t'), dkT("to"), DK4_OPT_ARG_STRING },
+
+ /* Line number selection _after_ applying from and to rules.
+ First line is line 1, final line is line -1.
+ dk-lines -l 5/8 Lines 5, 6, 7 and 8
+ dk-lines -l 5 Lines 5, ...
+ dk-lines -l /8 Lines 1, ... 8
+ dk-lines -l -8/-5 8 before last ... 5 before last
+ dk-lines -l -8 Final 8 lines
+ dk-lines -l /-5 Skip final 5 lines
+ dk-lines -l -8/125 Final 8 lines but not above line 125
+ dk-lines -l 125/-8 Lines from 125 but skip final 8 lines
+ dk-lines without -l option All lines
+ */
+ { dkT('l'), dkT("lines"), DK4_OPT_ARG_STRING },
+
+ /* Verbose flag (write notification on SIGPIPE).
+ */
+ { dkT('v'), dkT("verbose"), DK4_OPT_ARG_NONE },
+
+ /* Treat multiple files as one stream.
+ */
+ { dkT('o'), dkT("one-stream"), DK4_OPT_ARG_NONE },
+
+ /* Line buffer size.
+ */
+ { dkT('\0'), dkT("line-size"), DK4_OPT_ARG_SIZE },
+
+ /** Use current date to filter lines.
+ */
+ { dkT('\0'), dkT("today"), DK4_OPT_ARG_NONE }
+};
+
+
+#if DK4_ON_WINDOWS
+
+/** File name separator.
+*/
+static const dkChar fnsep[] = {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+dkT("\\")
+#else
+dkT("/")
+#endif
+};
+
+#endif
+
+
+
+/** Ring buffer used for negative line numbers.
+*/
+static rbe_t *pribu = NULL;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+/** Pointer to localized messages array.
+*/
+static const dkChar * const *msgs = dk_lines_kw_def;
+
+
+
+/** Start range.
+*/
+static const dkChar *t_from = NULL;
+
+
+
+/** End of range.
+*/
+static const dkChar *t_to = NULL;
+
+
+/** Input line buffer to use.
+*/
+static dkChar *ilb = default_input_line_buffer;
+
+
+
+/** Start line number.
+*/
+static dk4_um_t l_start = (dk4_um_t)0UL;
+
+
+
+/** End line number.
+*/
+static dk4_um_t l_end = (dk4_um_t)0UL;
+
+
+
+/** Current line number.
+*/
+static dk4_um_t lineno = (dk4_um_t)0UL;
+
+
+
+/** Length of --from text.
+*/
+static size_t sz_t_from = 0;
+
+
+
+/** Length of --to text.
+*/
+static size_t sz_t_to = 0;
+
+
+
+/** Ring buffer size (number of elements).
+*/
+static size_t sz_ribu = 0;
+
+
+
+/** Current position in ring buffer.
+*/
+static size_t pos_ribu = 0;
+
+
+
+/** Size of input line buffer.
+*/
+static size_t sz_ilb = DK4_SIZEOF(default_input_line_buffer,dkChar);
+
+
+
+/** Number of usable elements in the dk_lines_kw_def array and in msg.
+*/
+static size_t sz_msg = (sizeof(dk_lines_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Number of elements in the dk_lines_options array.
+*/
+static const size_t dk_lines_sz_options =
+sizeof(dk_lines_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Line handling type.
+*/
+static int l_type = RANGE_NONE_NONE;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Write errors.
+*/
+static int had_write_error = 0;
+
+
+
+/** Expected input encoding when reading from file.
+*/
+static int eie_file =
+#if DK4_ON_WINDOWS
+ DK4_FILE_ENCODING_WIN1252
+#else
+ DK4_FILE_ENCODING_PLAIN
+#endif
+;
+
+
+
+/** Expected input encoding on standard input.
+*/
+static int eie_stdin =
+#if DK4_ON_WINDOWS
+ DK4_FILE_ENCODING_WIN1252
+#else
+ DK4_FILE_ENCODING_PLAIN
+#endif
+;
+
+
+
+/** Verbose flag (report SIGPIPE or unusual large line buffer size).
+*/
+static int verbose = 0;
+
+
+
+/** Flag: At least one cyle in the ring buffer was completed.
+*/
+static int cycle_completed = 0;
+
+
+
+/** Flag: Treat multiple files as one stream.
+*/
+static int one_stream = 0;
+
+
+
+/** Number of decoding errors already reported.
+*/
+static int num_r_decoding_e = 0;
+
+
+
+/** Maximum number of decoding errors to report unless verbose output required.
+*/
+static const int max_r_decoding_e = 3;
+
+
+
+/** Number of encoding errors already reported.
+*/
+static int num_r_encoding_e = 0;
+
+
+
+/** Maximum number of encoding errors to report unless verbose output required.
+*/
+static const int max_r_encoding_e = 3;
+
+
+
+/** Number of processing errors already reported.
+*/
+static int num_r_processing_e = 0;
+
+
+
+/** Maximum number of processing errors to report unless
+ verbose output required.
+*/
+static const int max_r_processing_e = 3;
+
+
+
+#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;
+
+
+
+/** Special function to pass a volatile pointer.
+ Some C compiler does not handle direct assignments to volatile variables
+ correctly.
+ @param ptr Address of volatile variable.
+ @return Same address.
+*/
+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 DK4_ARG_UNUSED(signo) )
+{
+ DK4_UNUSED_ARG(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 DK4_ARG_UNUSED(signo) )
+{
+ DK4_UNUSED_ARG(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 DK4_ARG_UNUSED(signo) )
+{
+ DK4_UNUSED_ARG(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(
+#ifdef SIGPIPE
+int check_pipe
+#else
+int DK4_ARG_UNUSED(check_pipe)
+#endif
+)
+{
+ int back = 1;
+#ifndef SIGPIPE
+ DK4_UNUSED_ARG(check_pipe)
+#else
+ 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;
+}
+
+
+
+/** Retrieve value from text.
+ @param pdest Address of result variable to fill.
+ @param vtxt Text containing the value.
+ @param pback Address of success variable to reset on error.
+*/
+static
+void
+retrieve_number(dk4_um_t *pdest, const dkChar *vtxt, int *pback)
+{
+ dk4_er_t er;
+ dk4_um_t u = (dk4_um_t)0UL;
+ const dkChar *pe = NULL;
+
+
+#line 955 "dk-lines.ctr"
+ dk4error_init(&er);
+ if (0 != dk4ma_input_dk_dec_dk4_um_t(&u, vtxt, &pe, 1, &er)) {
+ if ((dk4_um_t)0UL < u) {
+ *pdest = u;
+ }
+ else {
+
+#line 961 "dk-lines.ctr"
+ *pback = 0;
+ /* ERROR: Illegal line number 0 */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 6);
+ }
+ }
+ else {
+ *pback = 0;
+ switch (er.ec) {
+ case DK4_E_MATH_OVERFLOW : {
+
+#line 970 "dk-lines.ctr"
+ /* ERROR: Number too large */
+ dk4app_log_3(app, msgs, sz_msg, DK4_LL_ERROR, 7, 8, vtxt);
+ } break;
+ default : {
+
+#line 974 "dk-lines.ctr"
+ /* ERROR: Not a number */
+ dk4app_log_3(app, msgs, sz_msg, DK4_LL_ERROR, 9, 10, vtxt);
+ } break;
+ }
+ }
+
+
+#line 980 "dk-lines.ctr"
+}
+
+
+
+#if TRACE_DEBUG
+
+static
+void
+trace_type_start_end(int t, unsigned long s, unsigned long e)
+{
+
+
+#line 991 "dk-lines.ctr"
+}
+
+#endif
+
+
+
+/** Process line number range.
+ @param ps Text containing start line number.
+ @param pe Text containing end line number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_line_range_items(const dkChar *ps, const dkChar *pe)
+{
+ int back = 1;
+
+
+#line 1008 "dk-lines.ctr"
+
+ /* Retrieve pure data from texts
+ */
+ if (NULL != ps) {
+
+#line 1012 "dk-lines.ctr"
+ if (NULL != pe) {
+
+#line 1013 "dk-lines.ctr"
+ if (dkT('-') != *ps) {
+
+#line 1014 "dk-lines.ctr"
+ if (dkT('-') != *pe) {
+
+#line 1015 "dk-lines.ctr"
+ l_type = RANGE_POS_POS;
+ retrieve_number(&l_start, ps, &back);
+ retrieve_number(&l_end, pe, &back);
+ if (l_start > l_end) {
+
+#line 1019 "dk-lines.ctr"
+ back = 0;
+ /* ERROR: start line number larger than end */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 11);
+ }
+ }
+ else {
+
+#line 1025 "dk-lines.ctr"
+ pe++;
+ l_type = RANGE_POS_NEG;
+ retrieve_number(&l_start, ps, &back);
+ retrieve_number(&l_end, pe, &back);
+ }
+ }
+ else {
+
+#line 1032 "dk-lines.ctr"
+ ps++;
+ if (dkT('-') != *pe) {
+
+#line 1034 "dk-lines.ctr"
+ l_type = RANGE_NEG_POS;
+ retrieve_number(&l_start, ps, &back);
+ retrieve_number(&l_end, pe, &back);
+ }
+ else {
+
+#line 1039 "dk-lines.ctr"
+ pe++;
+ l_type = RANGE_NEG_NEG;
+ retrieve_number(&l_start, ps, &back);
+ retrieve_number(&l_end, pe, &back);
+ if (l_end > l_start) {
+
+#line 1044 "dk-lines.ctr"
+ back = 0;
+ /* ERROR: End line number larger than start */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 11);
+ }
+ }
+ }
+ }
+ else {
+
+#line 1052 "dk-lines.ctr"
+ if (dkT('-') != *ps) {
+
+#line 1053 "dk-lines.ctr"
+ l_type = RANGE_POS_NONE;
+ retrieve_number(&l_start, ps, &back);
+ }
+ else {
+
+#line 1057 "dk-lines.ctr"
+ ps++;
+ l_type = RANGE_NEG_NONE;
+ retrieve_number(&l_start, ps, &back);
+ }
+ }
+ }
+ else {
+
+#line 1064 "dk-lines.ctr"
+ if (NULL != pe) {
+
+#line 1065 "dk-lines.ctr"
+ if (dkT('-') != *pe) {
+
+#line 1066 "dk-lines.ctr"
+ l_type = RANGE_NONE_POS;
+ retrieve_number(&l_end, pe, &back);
+ }
+ else {
+
+#line 1070 "dk-lines.ctr"
+ pe++;
+ l_type = RANGE_NONE_NEG;
+ retrieve_number(&l_end, pe, &back);
+ }
+ }
+ else {
+
+#line 1076 "dk-lines.ctr"
+ }
+ }
+
+ /* Corrections for full ranges
+ */
+ if (0 != back) {
+
+
+#line 1083 "dk-lines.ctr"
+
+
+#line 1084 "dk-lines.ctr"
+ switch (l_type) {
+ case RANGE_NONE_NEG : {
+ if ((dk4_um_t)1UL == l_end) {
+ l_type = RANGE_NONE_NONE;
+ l_end = (dk4_um_t)0UL;
+
+
+#line 1090 "dk-lines.ctr"
+ }
+ } break;
+ case RANGE_POS_NEG : {
+ if ((dk4_um_t)1UL == l_end) {
+ l_type = RANGE_POS_NONE;
+ l_end = (dk4_um_t)0UL;
+
+
+#line 1097 "dk-lines.ctr"
+ if ((dk4_um_t)1UL == l_start) {
+ l_type = RANGE_NONE_NONE;
+ l_start = (dk4_um_t)0UL;
+
+
+#line 1101 "dk-lines.ctr"
+ }
+ }
+ else {
+ if ((dk4_um_t)1UL == l_start) {
+ l_type = RANGE_NONE_NEG;
+ l_start = (dk4_um_t)0UL;
+
+
+#line 1108 "dk-lines.ctr"
+ }
+ }
+ } break;
+ case RANGE_NEG_NEG : {
+ if ((dk4_um_t)1UL == l_end) {
+ l_type = RANGE_NEG_NONE;
+ l_end = (dk4_um_t)0UL;
+
+
+#line 1116 "dk-lines.ctr"
+ }
+ } break;
+ case RANGE_POS_NONE : {
+ if ((dk4_um_t)1UL == l_start) {
+ l_start = (dk4_um_t)0UL;
+ l_type = RANGE_NONE_NONE;
+
+
+#line 1123 "dk-lines.ctr"
+ }
+ } break;
+ case RANGE_POS_POS : {
+ if ((dk4_um_t)1UL == l_start) {
+ l_start = (dk4_um_t)0UL;
+ l_type = RANGE_NONE_POS;
+
+
+#line 1130 "dk-lines.ctr"
+ }
+ } break;
+ default : {
+ /* Empty by intent */
+
+
+#line 1135 "dk-lines.ctr"
+ } break;
+ }
+ }
+
+
+#line 1139 "dk-lines.ctr"
+ return back;
+}
+
+
+
+/** Process line number range.
+ @param range Text containing the line number range.
+*/
+static
+int
+process_line_range(const dkChar *range)
+{
+ dkChar buf[64*sizeof(dk4_um_t)];
+ dkChar *p1 = NULL;
+ dkChar *p2 = NULL;
+ int back = 0;
+
+
+#line 1156 "dk-lines.ctr"
+ back = dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), range, NULL);
+ if (0 != back) {
+ p1 = dk4str_start(buf, NULL);
+ if (NULL != p1) {
+
+#line 1160 "dk-lines.ctr"
+ p2 = dk4str_chr(p1, dkT('/'));
+ if (NULL != p2) {
+
+#line 1162 "dk-lines.ctr"
+ *(p2++) = dkT('\0');
+ p2 = dk4str_start(p2, NULL);
+
+#line 1164 "dk-lines.ctr"
+ p1 = dk4str_start(p1, NULL);
+
+#line 1165 "dk-lines.ctr"
+ }
+
+#line 1166 "dk-lines.ctr"
+ back = process_line_range_items(p1, p2);
+ }
+ else {
+
+#line 1169 "dk-lines.ctr"
+ /* ERROR: Empty string */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 12);
+ back = 0;
+ }
+ }
+
+
+#line 1175 "dk-lines.ctr"
+ return back;
+}
+
+
+
+/** Retrieve configuration from command line arguments.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_command_line_arguments(void)
+{
+ dk4_time_t timer = (dk4_time_t)0UL;
+ const dkChar *ptr = NULL;
+ size_t sz = 0;
+ int back = 1;
+ int res = 0;
+ int iec = 0;
+
+
+#line 1194 "dk-lines.ctr"
+
+ /* --verbose
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ verbose = 1;
+ }
+
+ /* --one-stream
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('o'), NULL)) {
+ one_stream = 1;
+ }
+
+ /* --from
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('f'), NULL)) {
+ t_from = dk4app_opt_get_string_ptr_short(app, dkT('f'), NULL);
+ sz_t_from = dk4str_len(t_from);
+ }
+
+ /* --to
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ t_to = dk4app_opt_get_string_ptr_short(app, dkT('t'), NULL);
+ sz_t_to = dk4str_len(t_to);
+ }
+
+ /* --lines
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ ptr = dk4app_opt_get_string_ptr_short(app, dkT('l'), NULL);
+ if (NULL != ptr) {
+ back = process_line_range(ptr);
+ }
+ else {
+
+#line 1229 "dk-lines.ctr"
+ /* ERROR: Failed to retrieve line range argument */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 13);
+ back = 0;
+ }
+ }
+
+ /* --input-encoding
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ ptr = dk4app_opt_get_string_ptr_short(app, dkT('i'), NULL);
+ if (NULL != ptr) {
+ res = dk4enc_find(&iec, NULL, ptr, NULL);
+ if (0 != res) {
+ eie_stdin = iec;
+ eie_file = iec;
+ }
+ else {
+ /* ERROR: Illegal input encoding */
+ dk4app_log_3(app, msgs, sz_msg, DK4_LL_ERROR, 14, 15, ptr);
+ }
+ }
+ else {
+ back = 0;
+ /* ERROR: Failed to retrieve input encoding */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 16);
+ }
+ }
+
+ /* --line-size
+ */
+ if (0 != dk4app_opt_is_set_long(app, dk_lines_kwnl[3], NULL)) {
+ if (0 != dk4app_opt_get_size_long(&sz, app, dk_lines_kwnl[3], NULL)) {
+ if (0 < sz) {
+ if (DK4_SIZEOF(default_input_line_buffer,dkChar) < sz) {
+ sz_ilb = sz;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1267 "dk-lines.ctr"
+ }
+#endif
+ }
+ else {
+
+#line 1271 "dk-lines.ctr"
+ /* ERROR: Line size 0 */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 17);
+ back = 0;
+ }
+ }
+ else {
+
+#line 1277 "dk-lines.ctr"
+ /* ERROR: Failed to retrieve line size */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 18);
+ back = 0;
+ }
+ }
+
+ /* --today
+ */
+ if (0 != dk4app_opt_is_set_long(app, dk_lines_kwnl[4], NULL)) {
+ if ((NULL == t_from) || (NULL == t_to)) {
+ dk4time_get(&timer);
+ res = dk4time_as_text(
+ date_buffer, DK4_SIZEOF(date_buffer,dkChar), &timer, NULL
+ );
+ if (0 != res) {
+ date_buffer[10] = dkT('\0');
+ if (NULL == t_from) {
+ t_from = date_buffer;
+ sz_t_from = dk4str_len(t_from);
+ }
+ if (NULL == t_to ) {
+ t_to = date_buffer;
+ sz_t_to = dk4str_len(t_to);
+ }
+ }
+ }
+ else {
+ /* ERROR: --today used with --from and --to */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 19);
+ }
+ }
+
+
+#line 1309 "dk-lines.ctr"
+ return back;
+}
+
+
+
+/** Report an error with position.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Current byte number.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number within line.
+ @param fn File name processed.
+*/
+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,
+ const dkChar *fn
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))+16];
+ dkChar b2[8*(1+sizeof(dk4_um_t))+16];
+ dkChar b3[8*(1+sizeof(dk4_um_t))+16];
+ const dkChar *oldlogname = NULL;
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ const size_t szb3 = DK4_SIZEOF(b3,dkChar);
+ const size_t szb2 = DK4_SIZEOF(b2,dkChar);
+ const size_t szb1 = DK4_SIZEOF(b1,dkChar);
+ int allbuffersok = 0;
+
+ oldlogname = dk4app_get_log_source_file(app);
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3, szb3, cil, 0, NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2, szb2, cno, 0, NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1, szb1, bno, 0, NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, msgs, sz_msg, DK4_LL_ERROR, i1, 37, 38, 39, b1, b2, b3
+ );
+ }
+ else {
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, i2);
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+ dk4app_set_log_source_file(app, oldlogname);
+}
+
+
+
+static
+void
+report_errors_from_tsp(
+ dk4_er_t *er_en,
+ dk4_er_t *er_pr,
+ const dkChar *fn
+)
+{
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED : {
+ if ((0 != verbose) || (max_r_decoding_e > num_r_decoding_e)) {
+ report_with_position(
+ 35, 32,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ num_r_decoding_e++;
+ if (num_r_decoding_e > max_r_decoding_e) {
+ num_r_decoding_e = max_r_decoding_e;
+ }
+ }
+ } break;
+ case DK4_E_ENCODING_FAILED : {
+ if ((0 != verbose) || (max_r_encoding_e > num_r_encoding_e)) {
+ report_with_position(
+ 34, 31,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ num_r_encoding_e++;
+ if (num_r_encoding_e > max_r_encoding_e) {
+ num_r_encoding_e = max_r_encoding_e;
+ }
+ }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ if ((0 != verbose) || (max_r_processing_e > num_r_processing_e)) {
+ report_with_position(
+ 36, 33,
+ er_pr->dt.fpos.byteno, er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno, er_pr->dt.fpos.charinline,
+ fn
+ );
+ num_r_processing_e++;
+ if (num_r_processing_e > max_r_processing_e) {
+ num_r_processing_e = max_r_processing_e;
+ }
+ }
+ }
+ }
+}
+
+
+
+static
+int
+write_text_line(const dkChar *line, dk4_er_t *erp)
+{
+ int back = DK4_TSP_RES_OK;
+ if (0 == dk4fputs(line, stdout, erp)) {
+ had_write_error = 1;
+ back = DK4_TSP_RES_ERROR;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, erp)) {
+ had_write_error = 1;
+ back = DK4_TSP_RES_ERROR;
+ }
+ return back;
+}
+
+
+
+/** Add new line to ring buffer, write line stored previously.
+ @param line New line to add.
+ @param erp Error report.
+ @return DK4_TSP_RES_OK on success, DK4_TSP_RES_ERROR on error.
+*/
+static
+int
+ribu_add_and_print(const dkChar *line, dk4_er_t *erp)
+{
+ dkChar *ptr;
+ size_t sz;
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1461 "dk-lines.ctr"
+ sz = dk4str_len(line);
+ if ((SIZE_MAX) > sz) {
+ if ((NULL != pribu) && (0 < sz_ribu)) {
+ if (NULL != pribu[pos_ribu].str) {
+
+
+#line 1466 "dk-lines.ctr"
+
+
+#line 1467 "dk-lines.ctr"
+ if (0 != cycle_completed) {
+ back = write_text_line(pribu[pos_ribu].str, erp);
+ }
+ if (sz > pribu[pos_ribu].buflen) {
+
+#line 1471 "dk-lines.ctr"
+ ptr = dk4str_dup_app(line, app);
+ if (NULL != ptr) {
+ dk4mem_free(pribu[pos_ribu].str);
+ pribu[pos_ribu].str = ptr;
+ pribu[pos_ribu].buflen = sz;
+ }
+ else {
+ back = DK4_TSP_RES_ERROR;
+ dk4error_set_simple_error_code(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED
+ );
+ /* ERROR: Memory allocation failed */
+ }
+ }
+ else {
+
+#line 1486 "dk-lines.ctr"
+ (void)dk4str_cpy_s(
+ pribu[pos_ribu].str, (1 + pribu[pos_ribu].buflen),
+ line, NULL
+ );
+ }
+ }
+ else {
+
+#line 1493 "dk-lines.ctr"
+ pribu[pos_ribu].str = dk4str_dup_app(line, app);
+ pribu[pos_ribu].buflen = sz;
+ if (NULL == pribu[pos_ribu].str) {
+ back = DK4_TSP_RES_ERROR;
+ dk4error_set_simple_error_code(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED
+ );
+ pribu[pos_ribu].buflen = 0;
+ /* ERROR: Memory allocation failed */
+ }
+ }
+
+
+#line 1505 "dk-lines.ctr"
+
+
+#line 1506 "dk-lines.ctr"
+ pribu[pos_ribu].lineno = lineno;
+ pos_ribu++;
+ if (pos_ribu >= sz_ribu) {
+ pos_ribu = 0;
+ cycle_completed = 1;
+ }
+
+#line 1512 "dk-lines.ctr"
+ }
+ else {
+ back = DK4_TSP_RES_ERROR;
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ /* ERROR: No ring buffer */
+ }
+ }
+ else {
+ back = DK4_TSP_RES_ERROR;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ /* ERROR: Line too long */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 20);
+ }
+
+
+#line 1526 "dk-lines.ctr"
+ return back;
+}
+
+
+
+/** Add new line to ring buffer, do not print line previously stored.
+ @param line New line to add.
+ @param erp Error report.
+ @return DK4_TSP_RES_OK on success, DK4_TSP_RES_ERROR on error.
+*/
+static
+int
+ribu_add_silently(const dkChar *line, dk4_er_t *erp)
+{
+ dkChar *ptr;
+ size_t sz;
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1544 "dk-lines.ctr"
+
+ sz = dk4str_len(line);
+ if ((SIZE_MAX) > sz) {
+ if ((NULL != pribu) && (0 < sz_ribu)) {
+
+#line 1548 "dk-lines.ctr"
+ if (NULL != pribu[pos_ribu].str) {
+
+#line 1549 "dk-lines.ctr"
+
+
+#line 1550 "dk-lines.ctr"
+
+
+#line 1551 "dk-lines.ctr"
+
+
+#line 1552 "dk-lines.ctr"
+
+
+#line 1553 "dk-lines.ctr"
+ if (sz > pribu[pos_ribu].buflen) {
+
+#line 1554 "dk-lines.ctr"
+ ptr = dk4str_dup_app(line, app);
+ if (NULL != ptr) {
+
+#line 1556 "dk-lines.ctr"
+ dk4mem_free(pribu[pos_ribu].str);
+ pribu[pos_ribu].str = ptr;
+ pribu[pos_ribu].buflen = sz;
+ }
+ else {
+
+#line 1561 "dk-lines.ctr"
+ dk4mem_release(pribu[pos_ribu].str);
+ pribu[pos_ribu].buflen = 0;
+ pribu[pos_ribu].lineno = (dk4_um_t)0UL;
+ back = DK4_TSP_RES_ERROR;
+ dk4error_set_simple_error_code(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED
+ );
+ /* ERROR: Memory allocation failed */
+ }
+ }
+ else {
+
+#line 1572 "dk-lines.ctr"
+ (void)dk4str_cpy_s(
+ pribu[pos_ribu].str, (1 + pribu[pos_ribu].buflen),
+ line, NULL
+ );
+ }
+ }
+ else {
+
+#line 1579 "dk-lines.ctr"
+ pribu[pos_ribu].str = dk4str_dup_app(line, app);
+ pribu[pos_ribu].buflen = sz;
+ if (NULL == pribu[pos_ribu].str) {
+
+#line 1582 "dk-lines.ctr"
+ back = DK4_TSP_RES_ERROR;
+ dk4error_set_simple_error_code(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED
+ );
+ pribu[pos_ribu].buflen = 0;
+ /* ERROR: Memory allocation failed */
+ }
+ }
+
+
+#line 1591 "dk-lines.ctr"
+
+
+#line 1592 "dk-lines.ctr"
+ pribu[pos_ribu].lineno = lineno;
+ pos_ribu++;
+ if (pos_ribu >= sz_ribu) {
+ pos_ribu = 0;
+ }
+ }
+ else {
+
+#line 1599 "dk-lines.ctr"
+ back = DK4_TSP_RES_ERROR;
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ /* ERROR: No ring buffer */
+ }
+ }
+ else {
+ back = DK4_TSP_RES_ERROR;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ /* ERROR: Line too long */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 20);
+ }
+
+
+#line 1611 "dk-lines.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk_lines_line_handler(
+ void *DK4_ARG_UNUSED(obj),
+ dkChar *line,
+ dk4_um_t xlineno,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ size_t sz = 0;
+ int back = DK4_TSP_RES_OK;
+ int ok = 1;
+
+ DK4_UNUSED_ARG(obj)
+
+
+#line 1632 "dk-lines.ctr"
+ dk4app_set_log_source_line(app, xlineno);
+ dk4str_delnl(line);
+
+
+#line 1635 "dk-lines.ctr"
+ if ((NULL != t_from) && (0 < sz_t_from)) {
+#if VERSION_BEFORE_2017_11_20
+ sz = dk4str_len(line);
+ if (sz < sz_t_from) {
+ ok = 0;
+ }
+ else {
+ if (0 > dk4str_ncmp(line, t_from, sz_t_from)) { ok = 0; }
+ }
+#endif
+ if (0 > dk4str_cmp(line, t_from)) { ok = 0; }
+ }
+ if ((0 != ok) && (NULL != t_to) && (0 < sz_t_to)) {
+#if VERSION_BEFORE_2017_11_20
+ if (0 == sz) { sz = dk4str_len(line); }
+ if (sz < sz_t_to) {
+ if (0 < dk4str_ncmp(line, t_to, sz)) { ok = 0; }
+ }
+ else {
+ if (0 < dk4str_ncmp(line, t_to, sz_t_to)) { ok = 0; }
+ }
+#endif
+ sz = dk4str_len(line);
+ if (sz < sz_t_to) {
+ if (0 < dk4str_cmp(line, t_to)) { ok = 0; }
+ }
+ else {
+ if (0 < dk4str_ncmp(line, t_to, sz_t_to)) { ok = 0; }
+ }
+ }
+ if (0 != ok) {
+ dk4error_init(&er);
+ lineno = dk4ma_um_add(lineno, (dk4_um_t)1UL, &er);
+ if (DK4_E_NONE == er.ec) {
+
+
+#line 1670 "dk-lines.ctr"
+ switch (l_type) {
+ case RANGE_NONE_NONE : {
+ back = write_text_line(line, erp);
+ } break;
+ case RANGE_NONE_POS : {
+ if (lineno <= l_end) {
+ back = write_text_line(line, erp);
+ }
+ } break;
+ case RANGE_NONE_NEG : {
+ back = ribu_add_and_print(line, erp);
+ } break;
+ case RANGE_POS_NONE : {
+ if (l_start <= lineno) {
+ back = write_text_line(line, erp);
+ }
+ } break;
+ case RANGE_POS_POS : {
+ if ((l_start <= lineno) && (lineno <= l_end)) {
+ back = write_text_line(line, erp);
+ }
+ } break;
+ case RANGE_POS_NEG : {
+ if (l_start <= lineno) {
+ back = ribu_add_and_print(line, erp);
+ }
+ } break;
+ case RANGE_NEG_NONE : {
+ back = ribu_add_silently(line, erp);
+ } break;
+ case RANGE_NEG_POS : {
+ back = ribu_add_silently(line, erp);
+ } break;
+ case RANGE_NEG_NEG : {
+ back = ribu_add_silently(line, erp);
+ } break;
+ }
+ }
+ else {
+ back = DK4_TSP_RES_ERROR;
+ dk4error_copy(erp, &er);
+ /* ERROR: Overflow in line number */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 21);
+ }
+ }
+
+
+
+#line 1717 "dk-lines.ctr"
+ return back;
+}
+
+
+
+/** Flush the ring buffer after finishing file or stream.
+*/
+static
+void
+flush_ring_buffer(void)
+{
+ dk4_er_t er;
+ dk4_um_t umax;
+ size_t i;
+ size_t idx;
+ size_t max;
+
+ switch (l_type) {
+ case RANGE_NONE_NONE : {
+ /* Empty by intent, ring buffer not used */
+ } break;
+ case RANGE_NONE_POS : {
+ /* Empty by intent, ring buffer not used */
+ } break;
+ case RANGE_NONE_NEG : case RANGE_POS_NEG : {
+ /* Empty by intent, lines of interest already printed */
+ } break;
+ case RANGE_POS_NONE : {
+ /* Empty by intent, ring buffer not used */
+ } break;
+ case RANGE_POS_POS : {
+ /* Empty by intent, ring buffer not used */
+ } break;
+ case RANGE_NEG_NONE : {
+ idx = pos_ribu;
+ for (i = 0; i < sz_ribu; i++) {
+
+
+#line 1754 "dk-lines.ctr"
+ if (NULL != pribu[idx].str) {
+
+#line 1755 "dk-lines.ctr"
+
+
+#line 1756 "dk-lines.ctr"
+ if (0 == dk4fputs(pribu[idx].str, stdout, NULL)) {
+ had_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ had_write_error = 1;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1765 "dk-lines.ctr"
+ }
+#endif
+ idx++; if (idx >= sz_ribu) { idx = 0; }
+ }
+ } break;
+ case RANGE_NEG_POS : {
+ idx = pos_ribu;
+ for (i = 0; i < sz_ribu; i++) {
+ if ((NULL != pribu[idx].str) && (pribu[idx].lineno <= l_end)) {
+ if (0 == dk4fputs(pribu[idx].str, stdout, NULL)) {
+ had_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ had_write_error = 1;
+ }
+ }
+ idx++; if (idx >= sz_ribu) { idx = 0; }
+ }
+ } break;
+ case RANGE_NEG_NEG : {
+ dk4error_init(&er);
+ umax = dk4ma_um_add(
+ dk4ma_um_sub(l_start, l_end, &er),
+ (dk4_um_t)1UL,
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ if ((dk4_um_t)(SIZE_MAX) >= umax) {
+ max = (size_t)umax;
+ idx = pos_ribu;
+ for (i = 0; i < max; i++) {
+ if (NULL != pribu[idx].str) {
+ if (0 == dk4fputs(pribu[idx].str, stdout, NULL)) {
+ had_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ had_write_error = 1;
+ }
+ }
+ idx++; if (idx >= sz_ribu) { idx = 0; }
+ }
+ }
+ else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Overflow in line range calculation */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 22);
+ }
+ }
+ else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Overflow in line range calculation */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 22);
+ }
+ } break;
+ }
+}
+
+
+
+/** Process file contents.
+ @param fipo File, opened for binary read access.
+ @param fn File name (for diagnostics).
+ @param eie Expected input encoding.
+*/
+static
+void
+run_for_file_with_name(FILE *fipo, const dkChar *fn, int eie)
+{
+ dk4_tspdk_t tsp; /* Text stream processor */
+ dk4_er_t er_en; /* Error report for enc/decoding */
+ dk4_er_t er_pr; /* Error report for processing */
+ dk4_er_t er; /* General error report */
+ const dkChar *oldlogname = NULL; /* Old source file */
+ dk4_um_t oldlogline = 0UL; /* Old source line */
+ size_t i; /* Traverse ring buffer elements */
+ int c; /* Current character retrieved */
+ int res; /* Operation result */
+ int cc; /* Flag: Can continue */
+ unsigned char uc; /* Byte added to processor */
+
+
+#line 1845 "dk-lines.ctr"
+
+ oldlogname = dk4app_get_log_source_file(app);
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ /* Initialize handling of one file
+ */
+ if (0 == one_stream) {
+ lineno = (dk4_um_t)0UL;
+ pos_ribu = 0;
+ if (NULL != pribu) {
+ for (i = 0; i < sz_ribu; i++) {
+ pribu[i].str = NULL;
+ pribu[i].lineno = (dk4_um_t)0UL;
+ pribu[i].buflen = 0;
+ }
+ }
+ }
+
+ /* Process file contents in loop
+ */
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ dk4error_init(&er);
+ res = dk4tspdk_setup_line(
+ &tsp, NULL, dk_lines_line_handler, ilb, sz_ilb,
+ dk4app_get_encoding(app), eie, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while(1 == cc) {
+ cc = -1;
+ if (0 != sig_can_continue(1)) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ cc = 1;
+ uc = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tsp, uc)) {
+ case DK4_TSP_RES_FATAL : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ report_errors_from_tsp(&er_en, &er_pr, fn);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ report_errors_from_tsp(&er_en, &er_pr, fn);
+ } break;
+ }
+ }
+ else {
+ cc = 0;
+ }
+ }
+ }
+ /* Flush data from text processor
+ */
+ if (0 == cc) {
+ switch (dk4tspdk_finish(&tsp)) {
+ case DK4_TSP_RES_FATAL : case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ report_errors_from_tsp(&er_en, &er_pr, fn);
+ } break;
+ }
+ }
+ }
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+
+ /* Flush data from ring buffer
+ */
+ if (0 == one_stream) {
+ flush_ring_buffer();
+ }
+
+ /* Clean up resources
+ */
+ if (0 == one_stream) {
+ cycle_completed = 0;
+ if (NULL != pribu) {
+ for (i = 0; i < sz_ribu; i++) {
+ dk4mem_release(pribu[i].str);
+ pribu[i].lineno = (dk4_um_t)0UL;
+ pribu[i].buflen = 0;
+ }
+ }
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+ dk4app_set_log_source_file(app, oldlogname);
+
+
+#line 1936 "dk-lines.ctr"
+}
+
+
+
+/** Open and process a file.
+ @param fn File name to process.
+*/
+static
+void
+run_for_filename(const dkChar *fn)
+{
+ const dkChar *oldlogname = NULL;
+ FILE *fipo = NULL;
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int tests = DK4_FOPEN_SC_USER;
+
+
+#line 1952 "dk-lines.ctr"
+ oldlogname = dk4app_get_log_source_file(app);
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ if (dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+
+
+#line 1958 "dk-lines.ctr"
+ fipo = dk4fopen_app(fn, dk_lines_kwnl[6], tests, app);
+ if (NULL != fipo) {
+ run_for_file_with_name(fipo, fn, eie_file);
+ fclose(fipo);
+ }
+ else {
+ exval = EXIT_FAILURE;
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+ dk4app_set_log_source_file(app, oldlogname);
+
+
+#line 1969 "dk-lines.ctr"
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+static
+void
+expand_filename_and_run(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int any_file_found = 0;
+ int cc;
+ int ok;
+
+
+#line 1988 "dk-lines.ctr"
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ pth = dk4dir_get_path(fne);
+ cc = 1;
+ while (1 == cc) {
+ if (0 != sig_can_continue(1)) {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+
+#line 1996 "dk-lines.ctr"
+ any_file_found = 1;
+ if (NULL != pth) {
+
+#line 1998 "dk-lines.ctr"
+ ok = 1;
+ if (0 == dk4str_cpy_s(buf, szbuf, pth, NULL)) {
+ ok = 0;
+ }
+ if(0 != dk4str_cat_s(buf, szbuf, fnsep, NULL)) {
+ ok = 0;
+ }
+ if(0 != dk4str_cat_s(buf, szbuf, shf, NULL)) {
+ ok = 0;
+ }
+ if (1 == ok) {
+
+#line 2009 "dk-lines.ctr"
+ run_for_filename(buf);
+ }
+ else {
+
+#line 2012 "dk-lines.ctr"
+ /* ERROR: Path too long */
+ exval = EXIT_FAILURE;
+ dk4app_log_base3(app,DK4_LL_ERROR,100,105,pattern);
+ }
+ }
+ else {
+
+#line 2018 "dk-lines.ctr"
+ run_for_filename(shf);
+ }
+ }
+ else {
+ cc = 0;
+ }
+ }
+ else {
+ cc = -1;
+ }
+ }
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ exval = EXIT_FAILURE;
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ }
+ }
+ else {
+
+#line 2036 "dk-lines.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to open file name expander (already reported) */
+ }
+
+
+#line 2040 "dk-lines.ctr"
+}
+
+#endif
+
+
+
+/** Allocate ring buffer used for negative line numbers.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+allocate_ring_buffer(void)
+{
+ size_t i;
+ int back = 1;
+
+
+#line 2056 "dk-lines.ctr"
+ switch (l_type) {
+ case RANGE_NONE_NEG : case RANGE_POS_NEG : case RANGE_NEG_NONE :
+ case RANGE_NEG_POS : case RANGE_NEG_NEG : {
+
+#line 2059 "dk-lines.ctr"
+ back = 0;
+ switch (l_type) {
+ case RANGE_NONE_NEG : case RANGE_POS_NEG : {
+ if ((dk4_um_t)(SIZE_MAX) >= l_end) {
+ if ((dk4_um_t)1UL < l_end) {
+ sz_ribu = (size_t)(l_end - (dk4_um_t)1UL);
+ }
+ else {
+
+#line 2067 "dk-lines.ctr"
+ /* BUG: l_end is 1, should not happen */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 23);
+ }
+ }
+ else {
+
+#line 2072 "dk-lines.ctr"
+ /* ERROR: Numeric overflow */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 24);
+ }
+ } break;
+ default : {
+ if ((dk4_um_t)(SIZE_MAX) >= l_start) {
+ sz_ribu = (size_t)l_start;
+ }
+ else {
+
+#line 2081 "dk-lines.ctr"
+ /* ERROR: Numeric overflow */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 25);
+ }
+ } break;
+ }
+ if (0 < sz_ribu) {
+
+#line 2087 "dk-lines.ctr"
+ pribu = dk4mem_new_app(rbe_t,sz_ribu,app);
+ if (NULL != pribu) {
+
+#line 2089 "dk-lines.ctr"
+ back = 1;
+ for (i = 0; i < sz_ribu; i++) {
+ pribu[i].str = NULL;
+ pribu[i].lineno = (dk4_um_t)0UL;
+ pribu[i].buflen = 0;
+ }
+ }
+ else {
+
+#line 2097 "dk-lines.ctr"
+ /* ERROR: Memory allocation failed (already reported) */
+ }
+ }
+ else {
+
+#line 2101 "dk-lines.ctr"
+ /* Invalid ring buffer size */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 26);
+ }
+ } break;
+ default : {
+
+#line 2106 "dk-lines.ctr"
+ /* Empty by intent */
+ } break;
+ }
+
+
+#line 2110 "dk-lines.ctr"
+ return back;
+}
+
+
+
+/** Allocate ring buffer if necessary and process input.
+*/
+static
+void
+run_for_input(void)
+{
+ const dkChar *fnptr;
+ size_t xi;
+ int argc;
+ int i;
+
+
+#line 2126 "dk-lines.ctr"
+ if (0 != allocate_ring_buffer()) {
+ /*
+ Initialize handling of one large data stream
+ */
+ if (0 != one_stream) {
+ lineno = (dk4_um_t)0UL;
+ pos_ribu = 0;
+ if (NULL != pribu) {
+ for (xi = 0; xi < sz_ribu; xi++) {
+ pribu[xi].str = NULL;
+ pribu[xi].lineno = (dk4_um_t)0UL;
+ pribu[xi].buflen = 0;
+ }
+ }
+ }
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+
+#line 2143 "dk-lines.ctr"
+ for (i = 0; ((i < argc) && (0 != sig_can_continue(1))); i++) {
+ fnptr = dk4app_get_argv(app, i);
+ if (NULL != fnptr) {
+
+#line 2146 "dk-lines.ctr"
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(fnptr)) {
+ expand_filename_and_run(fnptr);
+ }
+ else {
+#endif
+ run_for_filename(fnptr);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+ else {
+
+#line 2158 "dk-lines.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Did not obtain file name */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 27);
+ }
+ }
+ }
+ else {
+
+#line 2165 "dk-lines.ctr"
+ run_for_file_with_name(stdin, dk_lines_kwnl[7], eie_stdin);
+ }
+ /* Flush ring buffer and clean up resources for large data stream
+ */
+ if (0 != one_stream) {
+ /*
+ Flush ring buffer
+ */
+ flush_ring_buffer();
+ /*
+ Release ring buffer resources
+ */
+ cycle_completed = 0;
+ if (NULL != pribu) {
+ for (xi = 0; xi < sz_ribu; xi++) {
+ dk4mem_release(pribu[xi].str);
+ pribu[xi].lineno = (dk4_um_t)0UL;
+ pribu[xi].buflen = 0;
+ }
+ }
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2189 "dk-lines.ctr"
+ }
+#endif
+ if (NULL != pribu) {
+ dk4mem_free(pribu);
+ }
+
+
+#line 2195 "dk-lines.ctr"
+}
+
+
+
+/** Run the functionality.
+*/
+static
+void
+run_the_functions(void)
+{
+ dkChar *mybuf = NULL;
+
+
+#line 2207 "dk-lines.ctr"
+
+
+#line 2208 "dk-lines.ctr"
+ if (0 != process_command_line_arguments()) {
+ /*
+ If a line buffer larger than default is required,
+ allocate the buffer and run
+ */
+ if (DK4_SIZEOF(default_input_line_buffer,dkChar) < sz_ilb) {
+ mybuf = dk4mem_new_app(dkChar,sz_ilb,app);
+ if (NULL != mybuf) {
+ ilb = mybuf;
+ run_for_input();
+ dk4mem_free(mybuf);
+ }
+ else {
+
+#line 2221 "dk-lines.ctr"
+ exval = EXIT_FAILURE;
+ }
+ }
+ /* Otherwise run with default buffer
+ */
+ else {
+ run_for_input();
+ }
+ }
+ else {
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 2234 "dk-lines.ctr"
+}
+
+
+#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)) {
+
+#line 2263 "dk-lines.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+
+#line 2268 "dk-lines.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+
+#line 2273 "dk-lines.ctr"
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, msgs, 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)) {
+
+#line 2285 "dk-lines.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+
+#line 2290 "dk-lines.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+
+#line 2295 "dk-lines.ctr"
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 1);
+ 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)) {
+
+#line 2306 "dk-lines.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 2);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+
+#line 2311 "dk-lines.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 2);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+
+#line 2316 "dk-lines.ctr"
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 2);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ run_the_functions();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+
+#line 2327 "dk-lines.ctr"
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 3);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+
+#line 2336 "dk-lines.ctr"
+ /* ERROR: Failed to restore old SIGINT settings */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 4);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+
+#line 2346 "dk-lines.ctr"
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 5);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) {
+
+#line 2356 "dk-lines.ctr"
+ 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 2437 "dk-lines.ctr"
+
+
+#line 2438 "dk-lines.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_lines_options, dk_lines_sz_options,
+ dk_lines_kwnl[0], DKT_VERSION_DK,
+ dk_lines_kwnl[1], dk_lines_help_text, dk_lines_license_text
+ );
+ if (NULL != app) {
+ sz_msg = dk4app_string_table_size(dk_lines_kw_def);
+ msgs = dk4app_string_table(app, dk_lines_kwnl[2], dk_lines_kw_def);
+ eie_file = dk4app_get_file_in_encoding(app);
+ eie_stdin = dk4app_get_stdin_encoding(app);
+ if (0 != dk4app_can_run_normally(app)) {
+ 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) {
+
+#line 2460 "dk-lines.ctr"
+ /* ERROR: Stopped by SIGPIPE */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 28);
+ }
+ exval = EXIT_FAILURE;
+ }
+ else {
+ if (0 != had_write_error) {
+
+#line 2467 "dk-lines.ctr"
+ /* ERROR: Had write error */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 29);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+
+#line 2473 "dk-lines.ctr"
+ /* ERROR: Stopped by interrupt */
+ dk4app_log_1(app, msgs, sz_msg, DK4_LL_ERROR, 30);
+ }
+ }
+ else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 2489 "dk-lines.ctr"
+
+
+#line 2490 "dk-lines.ctr"
+ exit(exval); return exval;
+}
+
+/* vim: set ai sw=4 ts=4 : */