diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk-sort.c |
Initial commit
Diffstat (limited to 'support/dktools/dk-sort.c')
-rw-r--r-- | support/dktools/dk-sort.c | 1855 |
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; +} + |