summaryrefslogtreecommitdiff
path: root/support/dktools/dk-sort.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk-sort.c
Initial commit
Diffstat (limited to 'support/dktools/dk-sort.c')
-rw-r--r--support/dktools/dk-sort.c1855
1 files changed, 1855 insertions, 0 deletions
diff --git a/support/dktools/dk-sort.c b/support/dktools/dk-sort.c
new file mode 100644
index 0000000000..87a55cda5c
--- /dev/null
+++ b/support/dktools/dk-sort.c
@@ -0,0 +1,1855 @@
+/*
+ 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-sort.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.
+*/
+
+/** @file dk-sort.c The dk-sort module.
+*/
+
+
+#line 8 "dk-sort.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_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
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fput.h"
+#include "dk4mpl.h"
+#include "dk4maiddbl.h"
+#if 0
+#include "dk4maidhmu.h"
+#include "dk4maiddmu.h"
+#include "dk4maiddmi.h"
+#endif
+#include "dk4maidddu.h"
+#include "dk4maidhdu.h"
+#include "dk4maidddi.h"
+#include "dk4maodd.h"
+#include "dk4enc.h"
+#include "dk4strd.h"
+#include "dk4strda.h"
+#include "dk4tspdk.h"
+#include "dk4fopda.h"
+#include "dk4pathd.h"
+#include "dk4filed.h"
+
+
+
+
+
+#line 69 "dk-sort.ctr"
+
+
+
+/** Structure to store one line, optionally with evaluation result.
+*/
+typedef struct {
+ dkChar *line; /**< Text line. */
+ dkChar *fts; /**< File type suffix. */
+ union {
+ dk4_um_t u; /**< Unsigned number at start of line. */
+ dk4_im_t i; /**< Signed number at start of line. */
+ double d; /**< Floating point number at start of line. */
+ } value; /**< Value at start of line. */
+ char h; /**< Flag: Have value. */
+} dk_sort_line_t;
+
+
+/** Default help text, shown if help file is not found.
+*/
+static const dkChar * const dk_sort_help_text[] = {
+dkT(""),
+dkT("Sort text line by line"),
+dkT(""),
+dkT("dk-sort [<options>] [<file(s)>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-i <encoding>\t--input-encoding=<encoding>\tExpected input encoding."),
+dkT("-c\t\t--case-insensitive\t\tCase-insensitive comparisons."),
+dkT("-b\t\t--ignore-leading-blanks\t\tIgnore leading whitespaces."),
+dkT("-w\t\t--normalize\t\t\tNormalize text lines."),
+dkT("-e\t\t--suppress-empty-lines\t\tSuppress output for empty lines."),
+dkT("-t\t\t--file-type\t\t\tSort by file type."),
+dkT("-s <size>\t--skip-words=<size>\t\tNumber of words to skip."),
+dkT("-n\t\t--number\t\t\tLeading signed integer values."),
+dkT("-u\t\t--unsigned\t\t\tLeading unsigned integer values."),
+dkT("-x\t\t--hex\t\t\t\tLeading hexadecimal numbers."),
+dkT("-f\t\t--float\t\t\t\tLeading floating point numbers."),
+dkT("-v\t\t--value-lines-first\t\tLines containing numbers first."),
+dkT("-m\t\t--merge-equal-lines\t\tMerge equal lines."),
+dkT("-r\t\t--reverse\t\t\tReverse output order."),
+dkT("-l <size>\t--line-size=<size>\t\tLine buffer sizes."),
+dkT("-R\t\t--reset\t\t\t\tIgnore preferences values."),
+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 121 "dk-sort.ctr"
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_sort_license_text[] = {
+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 252 "dk-sort.ctr"
+};
+
+
+
+/** Command line options.
+*/
+static const dk4_option_specification_t dk_sort_options[] = {
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE },
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+ { dkT('c'), dkT("case-insensitive"), DK4_OPT_ARG_NONE },
+ { dkT('b'), dkT("ignore-leading-blanks"), DK4_OPT_ARG_NONE },
+ { dkT('w'), dkT("normalize"), DK4_OPT_ARG_NONE },
+ { dkT('t'), dkT("file-type"), DK4_OPT_ARG_NONE },
+ { dkT('s'), dkT("skip-words"), DK4_OPT_ARG_SIZE },
+ { dkT('n'), dkT("number"), DK4_OPT_ARG_NONE },
+ { dkT('u'), dkT("unsigned"), DK4_OPT_ARG_NONE },
+ { dkT('x'), dkT("hex"), DK4_OPT_ARG_NONE },
+ { dkT('f'), dkT("float"), DK4_OPT_ARG_NONE },
+ { dkT('v'), dkT("value-lines-first"), DK4_OPT_ARG_NONE },
+ { dkT('m'), dkT("merge-equal-lines"), DK4_OPT_ARG_NONE },
+ { dkT('r'), dkT("reverse"), DK4_OPT_ARG_NONE },
+ { dkT('l'), dkT("line-size"), DK4_OPT_ARG_SIZE },
+ { dkT('e'), dkT("suppress-empty-lines"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Number of elements in the dk_sort_options array.
+*/
+static const size_t dk_sort_sz_options =
+sizeof(dk_sort_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Constant text strings used by the module, not localized.
+*/
+static const dkChar * const dk_sort_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-sort.txt"),
+
+/* 2 */
+dkT("dk-sort.str"),
+
+/* 3 */
+dkT("stdin"),
+
+/* 4 */
+dkT("rb"),
+
+/* 5 */
+dkT("\\"),
+
+/* 6 */
+dkT("line.size"),
+
+NULL
+
+
+#line 319 "dk-sort.ctr"
+};
+
+
+
+/** Text strings used by program, localized versions used if found.
+*/
+static const dkChar * const dk_sort_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore previous signal handlers!"),
+
+/* 2 */
+dkT("Encoding error!"),
+
+/* 3 */
+dkT("Decoding error!"),
+
+/* 4 */
+dkT("Processing error!"),
+
+/* 5 */
+dkT("Encoding error!\n\tByte: "),
+
+/* 6 */
+dkT("Decoding error!\n\tByte: "),
+
+/* 7 */
+dkT("Processing error!\n\tByte: "),
+
+/* 8 */
+dkT(",\n\tCharacter: "),
+
+/* 9 */
+dkT(",\n\tPosition in line: "),
+
+/* 10 */
+dkT("."),
+
+/* 11 */
+dkT("Options -u, -x, and -f are mutually exclusive!"),
+
+/* 12 */
+dkT("Illegal input encoding: \""),
+
+/* 13 */
+dkT("\"!"),
+
+/* 14 */
+dkT("Failed to initialize text stream processing!"),
+
+NULL
+
+
+#line 364 "dk-sort.ctr"
+};
+
+
+
+/** Default buffer to use if sizes up to 1024 are specified.
+*/
+static dkChar input_line_buffer[1024];
+
+
+
+/** Input buffer really to use.
+*/
+static dkChar *ibptr = input_line_buffer;
+
+
+
+/** Allocated input buffer address for line sizes larger than 1024.
+*/
+static dkChar *allocated_buffer = NULL;
+
+
+
+/** Localized message texts.
+*/
+static const dkChar * const *dk_sort_msg = dk_sort_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Line storage.
+*/
+static dk4_sto_t *lsto = NULL;
+
+
+
+/** Iterator to traverse line storage.
+*/
+static dk4_sto_it_t *lsti = NULL;
+
+
+
+/** Number of strings in dk_sort_msg array.
+*/
+static size_t dk_sort_sz_msg =
+sizeof(dk_sort_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Size of ibptr buffer.
+*/
+static size_t ibsz = DK4_SIZEOF(input_line_buffer,dkChar);
+
+
+
+/** Number of words to skip when processing file names.
+*/
+static size_t skip_words = 0;
+
+
+
+/** Flag: Case-insensitive comparison.
+*/
+static int case_insensitive = 0;
+
+
+
+/** How to handle blanks:
+ 0 leave as is,
+ 1 remove leading and trailing blanks,
+ 2 normalize lines.
+*/
+static int handle_blanks = 0;
+
+
+
+/** How to handle leading values:
+ 0 do not use numeric values,
+ 1 use signed integers
+ 2 use unsigned integers
+ 3 use unsigned integers, specified in hexadecimal notation
+ 4 use floating point numbers.
+*/
+static int handle_values = 0;
+
+
+
+/** Flag: Sort files type file type suffix.
+*/
+static int handle_file_type = 0;
+
+
+
+/** Flag: Show lines containing values before lines not containing
+ a value. Default is to show lines without a value first.
+*/
+static int value_first = 0;
+
+
+
+/** Flag: Merge equal lines.
+*/
+static int merge = 0;
+
+
+
+/** Flag: Reverse search order.
+*/
+static int reversed = 0;
+
+
+
+/** Flag: Suppress empty lines.
+*/
+static int suppress_empty = 0;
+
+
+/** Expected input encoding.
+*/
+static int input_encoding = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Flag: Already reported decoding errors.
+*/
+static int dk_sort_had_decoding_errors = 0;
+
+
+
+/** Flag: Already reported encoding errors.
+*/
+static int dk_sort_had_encoding_errors = 0;
+
+
+
+/** Flag: Already reported processing errors.
+*/
+static int dk_sort_had_proc_errors = 0;
+
+
+
+/** Exit status code returned by the main function.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+#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_sort_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Delete a storage node.
+ @param ptr Node to delete.
+*/
+static
+void
+dk_sort_delete_node(dk_sort_line_t *ptr)
+{
+
+
+#line 644 "dk-sort.ctr"
+ if (NULL != ptr) {
+ dk4mem_release(ptr->line);
+ dk4mem_free(ptr);
+ }
+
+
+#line 649 "dk-sort.ctr"
+}
+
+
+
+/** Create storage node for a text line.
+ @param line Text line to store.
+ @return Pointer to new node on success, NULL on error.
+*/
+static
+dk_sort_line_t *
+dk_sort_new_node(dkChar *line)
+{
+ dk_sort_line_t *back = NULL;
+ dkChar *lines = NULL; /* Start of line */
+ const dkChar *endptr = NULL; /* First text after value */
+ double d; /* Evaluation double */
+ dk4_um_t u; /* Evaluation unsigned */
+ dk4_im_t i; /* Evaluation integer */
+
+
+#line 668 "dk-sort.ctr"
+ /* Normalize or remove leading and trailing whitespace if required.
+ */
+ if (NULL != line) {
+ dk4str_delnl(line);
+ if (0 < handle_blanks) {
+ lines = dk4str_start(line, NULL);
+ if (NULL != lines) {
+ line = lines;
+ switch (handle_blanks) {
+ case 1: {
+ dk4str_rtwh(line, NULL);
+ } break;
+ case 2: {
+ dk4str_normalize(line, NULL);
+ } break;
+ }
+ } else {
+ *line = dkT('\0');
+ }
+ }
+ }
+ if ((0 != suppress_empty) && (NULL != line)) {
+ lines = dk4str_start(line, NULL);
+ if (NULL == lines) {
+ line = NULL;
+ }
+ }
+
+ /* Create node.
+ */
+ if (NULL != line) {
+ back = dk4mem_new_app(dk_sort_line_t,1,app);
+ if (NULL != back) {
+ back->fts = NULL;
+ back->h = 0x00;
+ back->line = dk4str_dup_app(line, app);
+ if (NULL != back->line) {
+ if (0 != handle_file_type) {
+ back->fts = dk4path_get_suffix(back->line, NULL);
+ }
+ } else {
+ dk_sort_delete_node(back);
+ back = NULL;
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory, already reported */
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory, already reported */
+ }
+ }
+
+ /* Evaluate node if necessary.
+ */
+ if (NULL != back) {
+ switch (handle_values) {
+ case 4: {
+ d = 0.0;
+ if (0 != dk4ma_input_dk_double(&d, line, &endptr, 2, NULL)) {
+ (back->value).d = d;
+ back->h = 0x01;
+ }
+ } break;
+ case 3: {
+ u = (dk4_um_t)0UL;
+ if (0 != dk4ma_input_dk_hex_dk4_um_t(&u, line, &endptr, 2, NULL)) {
+ (back->value).u = u;
+ back->h = 0x01;
+ }
+ } break;
+ case 2: {
+ u = (dk4_um_t)0UL;
+ if (0 != dk4ma_input_dk_dec_dk4_um_t(&u, line, &endptr, 2, NULL)) {
+ (back->value).u = u;
+ back->h = 0x01;
+ }
+ } break;
+ case 1: {
+ i = (dk4_im_t)0L;
+ if (0 != dk4ma_input_dk_dec_dk4_im_t(&i, line, &endptr, 2, NULL)) {
+ (back->value).i = i;
+ back->h = 0x01;
+ }
+ } break;
+ }
+ }
+
+
+#line 755 "dk-sort.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk_sort_is_dot_file(const dkChar *fn)
+{
+ const dkChar *fns = NULL;
+ const dkChar *ptr = NULL;
+ int back = 0;
+
+
+#line 768 "dk-sort.ctr"
+ ptr = fn;
+ while (dkT('\0') != *ptr) {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ if (dkT('\\') == *ptr) { fns = ptr; }
+#else
+ if (dkT('/') == *ptr) { fns = ptr; }
+#endif
+ ptr++;
+ }
+ if (NULL == fns) { fns = fn; }
+ else { fns++; }
+
+
+#line 780 "dk-sort.ctr"
+ if (dkT('.') == *fns) {
+ back = 1;
+ }
+#if DK4_ON_WINDOWS
+ if (dkT('_') == *fns) {
+ back = 1;
+ }
+#endif
+
+
+#line 789 "dk-sort.ctr"
+ return back;
+}
+
+
+
+/** Compare two storage nodes.
+ @param l Left node.
+ @param r Right node.
+ @param cr Comparison criteria, ignored here.
+ @return Comparison result.
+*/
+static
+int
+dk_sort_compare_nodes(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ dk_sort_line_t *pl;
+ dk_sort_line_t *pr;
+ const dkChar *fnleft;
+ const dkChar *fnright;
+
+
+#line 810 "dk-sort.ctr"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (dk_sort_line_t *)l;
+ pr = (dk_sort_line_t *)r;
+
+ /* Check file type suffix if required.
+ */
+ if (0 != handle_file_type) {
+ fnleft = dk4str_skip(pl->line, skip_words);
+ fnright = dk4str_skip(pr->line, skip_words);
+ if (NULL != fnleft) {
+
+#line 821 "dk-sort.ctr"
+ if (NULL != fnright) {
+
+#line 822 "dk-sort.ctr"
+ if (0 != dk4file_is_directory(fnleft, NULL)) {
+ if (0 == dk4file_is_directory(fnright, NULL)) {
+ back = -1;
+ }
+ } else {
+ if (0 != dk4file_is_directory(fnright, NULL)) {
+ back = 1;
+ }
+ }
+ if (0 == back) {
+ if (0 != dk_sort_is_dot_file(fnleft)) {
+ if (0 == dk_sort_is_dot_file(fnright)) {
+ back = -1;
+ }
+ } else {
+ if (0 != dk_sort_is_dot_file(fnright)) {
+ back = 1;
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != fnright) {
+ back = -1;
+ }
+ }
+ if (0 == back) {
+ if (NULL != pl->fts) {
+ if (NULL != pr->fts) {
+ back = dk4str_pathcmp(pl->fts, pr->fts);
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ if (0 == back) {
+ back = dk4str_cmp(pl->fts, pr->fts);
+ }
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != pr->fts) {
+ back = -1;
+ }
+ }
+ }
+ }
+
+ /* Check evaluation if required.
+ */
+ if (0 == back) {
+ if (0 != handle_values) {
+ if (0x00 != pl->h) {
+ if (0x00 != pr->h) { /* both values */
+ switch (handle_values) {
+ case 4: {
+ if ((pl->value).d < (pr->value).d) {
+ back = -1;
+ } else {
+ if ((pl->value).d > (pr->value).d) {
+ back = 1;
+ }
+ }
+ } break;
+ case 2: case 3: {
+ if ((pl->value).u < (pr->value).u) {
+ back = -1;
+ } else {
+ if ((pl->value).u > (pr->value).u) {
+ back = 1;
+ }
+ }
+ } break;
+ case 1: {
+ if ((pl->value).i < (pr->value).i) {
+ back = -1;
+ } else {
+ if ((pl->value).i > (pr->value).i) {
+ back = 1;
+ }
+ }
+ } break;
+ }
+ } else { /* only left value */
+ back = ((0 != value_first) ? -1 : 1);
+ }
+ } else {
+ if (0x00 != pr->h) { /* only right value */
+ back = ((0 != value_first) ? 1 : -1);
+ }
+ }
+ }
+ }
+
+ /* String comparison
+ */
+ if (0 == back) {
+ if (0 != case_insensitive) {
+ back = dk4str_casecmp(pl->line, pr->line);
+ if (0 == back) {
+ back = dk4str_cmp(pl->line, pr->line);
+ }
+ } else {
+ back = dk4str_cmp(pl->line, pr->line);
+ }
+ }
+
+ /* Reverse order if necessary.
+ */
+ if (0 != reversed) { back = -1 * back; }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+
+#line 940 "dk-sort.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk_sort_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk_sort_line_t *nptr;
+ int back = DK4_TSP_RES_OK;
+
+
+#line 957 "dk-sort.ctr"
+ nptr = dk_sort_new_node(line);
+ if (NULL != nptr) {
+ if (0 == dk4sto_add(lsto, nptr, NULL)) {
+ dk_sort_delete_node(nptr);
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ back = DK4_TSP_RES_FATAL;
+ exval = EXIT_FAILURE;
+ }
+ }
+
+#line 966 "dk-sort.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
+dk_sort_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;
+ 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,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_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, i1, 8, 9, 10, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, i2);
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+ dk4app_set_log_source_file(app, oldlogname);
+}
+
+
+
+/** Report errors from line processing.
+ @param er_en Error report for encoding/decoding errors.
+ @param en_pr Error report for processing errors.
+ @param fn File name for error message.
+*/
+static
+void
+dk_sort_report_errors(
+ dk4_er_t *er_en,
+ dk4_er_t *er_pr,
+ const dkChar *fn
+)
+{
+
+
+#line 1037 "dk-sort.ctr"
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED : {
+ switch (dk_sort_had_decoding_errors) {
+ case 0: case 1: case 2: {
+ dk_sort_report_with_position(
+ 6, 3,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ } break;
+ }
+ if (3 > dk_sort_had_decoding_errors) { dk_sort_had_decoding_errors++; }
+ } break;
+ case DK4_E_ENCODING_FAILED : {
+ switch (dk_sort_had_encoding_errors) {
+ case 0: case 1: case 2: {
+ dk_sort_report_with_position(
+ 5, 2,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ } break;
+ }
+ if (3 > dk_sort_had_encoding_errors) { dk_sort_had_encoding_errors++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (dk_sort_had_proc_errors) {
+ case 0: case 1: case 2: {
+ dk_sort_report_with_position(
+ 7, 4,
+ er_pr->dt.fpos.byteno, er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno, er_pr->dt.fpos.charinline,
+ fn
+ );
+ } break;
+ }
+ if (3 > dk_sort_had_proc_errors) { dk_sort_had_proc_errors++; }
+ }
+ }
+
+
+#line 1083 "dk-sort.ctr"
+}
+
+
+
+/** Process one input file opened in binary mode.
+ @param fipo File to process.
+ @param filename File name.
+*/
+static
+void
+dk_sort_process_file(FILE *fipo, const dkChar *filename)
+{
+ dk4_tspdk_t tsp;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ dk4_er_t er;
+ int res;
+ int cc;
+ int c;
+ unsigned char ub;
+
+
+#line 1104 "dk-sort.ctr"
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ dk4error_init(&er);
+ res = dk4tspdk_setup_line(
+ &tsp, NULL,
+ dk_sort_line_handler,
+ ibptr, ibsz,
+ dk4app_get_encoding(app), input_encoding,
+ &er
+ );
+ if (0 != res) {
+ cc = 1;
+ do {
+ if (dk_sort_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tsp, ub)) {
+ case DK4_TSP_RES_FATAL : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == cc) {
+ switch (dk4tspdk_finish(&tsp)) {
+ case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Failed to initialize text stream processor */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 14);
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1161 "dk-sort.ctr"
+}
+
+
+
+/** Process standard input.
+*/
+static
+void
+dk_sort_process_stdin(void)
+{
+#if DK4_ON_WINDOWS
+ int oldmode;
+#endif
+
+
+#line 1175 "dk-sort.ctr"
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_sort_process_file(stdin, dk_sort_kwnl[3]);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+
+
+#line 1183 "dk-sort.ctr"
+}
+
+
+
+static
+void
+dk_sort_process_one_file_name(const dkChar *fn)
+{
+ FILE *fipo;
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+
+
+#line 1194 "dk-sort.ctr"
+ fipo = dk4fopen_app(fn, dk_sort_kwnl[4], tests, app);
+ if (NULL != fipo) {
+ dk_sort_process_file(fipo, fn);
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file, already reported */
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1203 "dk-sort.ctr"
+}
+
+
+
+#if DK4_ON_WINDOWS
+static
+void
+dk_sort_expand_one_file_name(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf; /* Short file name */
+ const dkChar *pth; /* Path */
+ int any_file_found = 0; /* Flag: Any file found */
+ int can_continue;
+
+
+#line 1219 "dk-sort.ctr"
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ can_continue = 1;
+ while ((0 != can_continue) && (NULL != (shf = dk4dir_next_file(fne)))) {
+ any_file_found = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_sort_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_sort_process_one_file_name(buf);
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ }
+ else
+ {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ dk_sort_process_one_file_name(shf);
+ }
+ can_continue = dk_sort_can_continue();
+ if (EXIT_FAILURE == exval) { can_continue = 0; }
+ }
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to open file name expander (already reported) */
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1265 "dk-sort.ctr"
+}
+#endif
+
+
+
+/** Process either the files specified on the command line
+ or standard input otherwise.
+*/
+static
+void
+dk_sort_process_files(void)
+{
+ const dkChar *fn; /* Current file to process */
+ int xargc; /* Number of command line arguments */
+ int i; /* Current file index */
+
+
+#line 1281 "dk-sort.ctr"
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ for (
+ i = 0;
+ ((i < xargc) && (0 != dk_sort_can_continue()) && (EXIT_SUCCESS == exval));
+ i++
+ )
+ {
+ fn = dk4app_get_argv(app, i);
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(fn)) {
+ dk_sort_expand_one_file_name(fn);
+ } else {
+#endif
+ dk_sort_process_one_file_name(fn);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+ }
+ } else {
+ dk_sort_process_stdin();
+ }
+
+
+#line 1306 "dk-sort.ctr"
+}
+
+
+
+/** Write stored text lines to standard output.
+*/
+static
+void
+dk_sort_write_output(void)
+{
+ dk_sort_line_t *nptr;
+ const dkChar *prevtext;
+ int printthis;
+
+
+#line 1320 "dk-sort.ctr"
+ if ((0 != dk_sort_can_continue()) && (EXIT_SUCCESS == exval)) {
+ dk4sto_it_reset(lsti);
+ prevtext = NULL;
+ do {
+ if ((0 != dk_sort_can_continue()) && (EXIT_SUCCESS == exval)) {
+ nptr = (dk_sort_line_t *)dk4sto_it_next(lsti);
+ if (NULL != nptr) {
+ printthis = 1;
+ if (0 != merge) {
+ if (NULL != prevtext) {
+ if (0 == dk4str_cmp(prevtext, nptr->line)) {
+ printthis = 0;
+ }
+ }
+ prevtext = nptr->line;
+ }
+ if (0 != printthis) {
+ if (0 == dk4fputs(nptr->line, stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ nptr = NULL;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ nptr = NULL;
+ }
+ }
+ }
+ } else {
+ nptr = NULL;
+ }
+ } while (NULL != nptr);
+ }
+
+
+#line 1353 "dk-sort.ctr"
+}
+
+
+
+/** Run after setting signal handlers.
+*/
+static
+void
+dk_sort_normal_run(void)
+{
+ dkChar buf[32]; /* Input encoding name */
+ dk4_er_t er; /* Error report */
+ dk_sort_line_t *nopt; /* Current node */
+ size_t myll = 1024; /* Line length */
+ size_t nskip = 0;
+ int options_error = 0; /* Flag: Error in options */
+ int res = 0; /* Operations result */
+
+
+#line 1371 "dk-sort.ctr"
+ /* Process command line options
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ case_insensitive = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ handle_blanks = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('w'), NULL)) {
+ handle_blanks = 2;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ handle_file_type = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&nskip, app, dkT('s'), NULL)) {
+ skip_words = nskip;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+ handle_values = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('u'), NULL)) {
+ handle_values = 2;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) {
+ handle_values = 3;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('f'), NULL)) {
+ if ((2 != handle_values) && (3 != handle_values)) {
+ handle_values = 4;
+ } else {
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 11);
+ options_error = 1;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ value_first = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('m'), NULL)) {
+ merge = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) {
+ reversed = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('e'), NULL)) {
+ suppress_empty = 1;
+ }
+ if (0 < dk4app_get_argc(app)) {
+ input_encoding = dk4app_get_file_in_encoding(app);
+ } else {
+ input_encoding = dk4app_get_stdin_encoding(app);
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, dkT('i'), NULL
+ );
+ if (0 != res) {
+ res = dk4enc_find(&input_encoding, NULL, buf, NULL);
+ if (0 == res) {
+ dk4app_log_3(app,dk_sort_msg,dk_sort_sz_msg,DK4_LL_ERROR,12,13,buf);
+ options_error = 1;
+ }
+ }
+ }
+ res = 0;
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ res = dk4app_opt_get_size_short(&myll, app, dkT('l'), NULL);
+ }
+ if (0 == res) {
+ if (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ res = dk4app_pref_get_size(&myll, app, dk_sort_kwnl[6], 0);
+ }
+ }
+ if ((0 != res) && (DK4_SIZEOF(input_line_buffer,dkChar) < myll)) {
+ allocated_buffer = dk4mem_new_app(dkChar,myll,app);
+ if (NULL != allocated_buffer) {
+ ibptr = allocated_buffer;
+ ibsz = myll;
+ } else {
+ /* ERROR: Memory allocation failed, already reported */
+ options_error = 1;
+ }
+ }
+
+ /* Processing part.
+ */
+ if (0 == options_error) {
+ dk4error_init(&er);
+ lsto = dk4sto_open(&er);
+ if (NULL != lsto) {
+ dk4sto_set_comp(lsto, dk_sort_compare_nodes, 0);
+ lsti = dk4sto_it_open(lsto, &er);
+ if (NULL != lsti) {
+ exval = EXIT_SUCCESS;
+ dk_sort_process_files();
+ dk_sort_write_output();
+ dk4sto_it_reset(lsti);
+ do {
+ nopt = (dk_sort_line_t *)dk4sto_it_next(lsti);
+ if (NULL != nopt) {
+ dk_sort_delete_node(nopt);
+ }
+ } while (NULL != nopt);
+ dk4sto_it_close(lsti);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ dk4sto_close(lsto);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+
+ /* Cleanup: release dynamically allocated memory for input line buffer.
+ */
+ if (NULL != allocated_buffer) {
+ dk4mem_free(allocated_buffer); allocated_buffer = NULL; ibsz = 1024;
+ }
+
+
+#line 1491 "dk-sort.ctr"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_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;
+
+
+#line 1514 "dk-sort.ctr"
+#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_sort_msg, dk_sort_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_sort_msg, dk_sort_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_sort_msg, dk_sort_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_sort_msg, dk_sort_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_sort_msg, dk_sort_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_sort_msg, dk_sort_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_sort_msg, dk_sort_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_sort_msg, dk_sort_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_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_sort_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_sort_msg, dk_sort_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_sort_msg, dk_sort_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_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+
+
+#line 1615 "dk-sort.ctr"
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_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;
+
+
+#line 1630 "dk-sort.ctr"
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_sort_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+
+
+#line 1642 "dk-sort.ctr"
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_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;
+
+
+#line 1657 "dk-sort.ctr"
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_sort_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+
+
+#line 1669 "dk-sort.ctr"
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_run_with_signal_handlers(void)
+{
+ dk_sort_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
+{
+
+
+#line 1697 "dk-sort.ctr"
+
+
+#line 1698 "dk-sort.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_sort_options, dk_sort_sz_options,
+ dk_sort_kwnl[0], DKT_VERSION_DK,
+ dk_sort_kwnl[1], dk_sort_help_text, dk_sort_license_text
+ );
+ if (NULL != app) {
+ dk_sort_sz_msg = dk4app_string_table_size(dk_sort_kw_def);
+ dk_sort_msg = dk4app_string_table(app, dk_sort_kwnl[2], dk_sort_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+
+
+#line 1710 "dk-sort.ctr"
+ dk_sort_run_with_signal_handlers();
+ } else {
+
+
+#line 1713 "dk-sort.ctr"
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 1725 "dk-sort.ctr"
+
+
+#line 1726 "dk-sort.ctr"
+ return exval;
+}
+