/* 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: dkt-sort.ctr */ /* Copyright (C) 2011-2013, 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 dkt-sort.c The dkt-sort module. */ #line 10 "dkt-sort.ctr" /** @file dkt-sort.c The "dkt sort" command. -b Ignore leading blanks. -c Ignore case -n Sort by leading signed integer (numeric). -u Sort by leading unsigned integer. -f Sort by leading floating point number. -s Lines without leading int for floating point numbers are printed before lines with values found. -w Normalize lines (whitespace sequences replaced by space). -m Merge equal lines. -r Reverse search order. -i ie Input encoding. -p Same as -i plain. */ #include "dk3all.h" #include "dkt.h" #line 36 "dkt-sort.ctr" /** Sort job structure. */ typedef struct { dk3_app_t *app; /**< Application. */ dkChar const * const *msg; /**< Localized messages. */ dkChar const * const *kwnl; /**< Keywords not localized. */ dk3_option_set_t *opt; /**< Option set. */ dk3_sto_t *sto; /**< Storage to keep lines. */ dk3_sto_it_t *sit; /**< Storage iterator. */ dkChar *b1; /**< First buffer. */ dkChar *b2; /**< Buffer for normalization. */ size_t linesz; /**< Line size. */ int exval; /**< Exit status code. */ int enc_s; /**< Encoding on stdin. */ int enc_f; /**< Encoding on files. */ int c_sort; /**< Sort criteria for storage. */ int c_merg; /**< Sort criteria for merging. */ int o_sort; /**< Simple sort criteria. */ int o_merg; /**< Option: Merge. */ int o_norm; /**< Option: Normalize. */ int o_igbl; /**< Option: Ignore leading blanks. */ } DKT_SORT_J; /** Information about one stored line. */ typedef struct { dkChar const *ori; /**< Original line as found. */ dkChar const *nrm; /**< Normalized version. */ dkChar const *stt; /**< Start of text in ori. */ char hv; /**< Flag: Have value. */ union { double d; /**< Double value. */ dk3_im_t i; /**< Signed integer value. */ dk3_um_t u; /**< Unsigned integer value. */ } v; /**< Value for sorting. */ } DKT_SORT_L; /** Configuration file options. */ static dkChar const * const dkt_sort_long_opt[] = { dkT("stdin-encoding"), dkT("file-encoding"), dkT("reset"), dkT("line-size"), NULL }; /** Data for the option set. */ static dk3_option_t const dkt_sort_options[] = { { dkT('R'), dkT("reset"), 0 }, { dkT('i'), dkT("input-encoding"), 1 }, { dkT('p'), dkT("plain"), 0 }, { dkT('l'), dkT("line-size"), 1 }, { dkT('b'), dkT("ignore-leading-blanks"), 0 }, { dkT('c'), dkT("ignore-case"), 0 }, { dkT('n'), dkT("integer"), 0 }, { dkT('u'), dkT("unsigned"), 0 }, { dkT('f'), dkT("float"), 0 }, { dkT('w'), dkT("normalize-text"), 0 }, { dkT('m'), dkT("merge"), 0 }, { dkT('e'), dkT("merge-exact"), 0 }, { dkT('r'), dkT("reverse"), 0 }, { dkT('s'), dkT("missing-value-first"), 0}, }; /** Number of options in the dkt_sort_options array. */ static size_t const dkt_sort_szoptions = sizeof(dkt_sort_options)/sizeof(dk3_option_t); /** Compare two sort line structures. @param l Left structure. @param r Right structure. @param cr Comparison criteria. @return Comparison result. */ static int dkt_sort_compare(void *l, void *r, int cr) { int back = 0; int mycr = 0; /* My criteria. */ DKT_SORT_L *pl = NULL; /* Left object. */ DKT_SORT_L *pr = NULL; /* Right object. */ #line 133 "dkt-sort.ctr" if(l) { if(r) { pl = (DKT_SORT_L *)l; pr = (DKT_SORT_L *)r; mycr = cr & DKT_SORT_CRITERIA_MASK; switch(mycr) { case 1: case 2: case 3: { #line 139 "dkt-sort.ctr" if(pl->hv) { if(pr->hv) { switch(mycr) { case 1: { #line 143 "dkt-sort.ctr" if((pl->v).i > (pr->v).i) { back = 1; } else { if((pl->v).i < (pr->v).i) { back = -1; } } } break; case 2: { #line 152 "dkt-sort.ctr" if((pl->v).u > (pr->v).u) { back = 1; } else { if((pl->v).u < (pr->v).u) { back = -1; } } } break; case 3: { #line 161 "dkt-sort.ctr" if((pl->v).d > (pr->v).d) { back = 1; } else { if((pl->v).d < (pr->v).d) { back = -1; } } } break; } } else { back = -1; if(cr & DKT_SORT_NOVALUE_FIRST) { back = 1; } } } else { if(pr->hv) { back = 1; if(cr & DKT_SORT_NOVALUE_FIRST) { back = -1; } } } } break; } if(back == 0) { if(cr & DKT_SORT_NORMALIZE) { #line 184 "dkt-sort.ctr" if(pl->nrm) { if(pr->nrm) { #line 186 "dkt-sort.ctr" if(cr & DKT_SORT_CASEINS) { back = dk3str_casecmp(pl->nrm, pr->nrm); } else { back = dk3str_cmp(pl->nrm, pr->nrm); } } else { back = 1; } } else { if(pr->nrm) { back = -1; } else { #line 196 "dkt-sort.ctr" } } } } if(back == 0) { if(cr & DKT_SORT_IGNORE_LWHS) { #line 202 "dkt-sort.ctr" if(pl->stt) { if(pr->stt) { #line 204 "dkt-sort.ctr" if(cr & DKT_SORT_CASEINS) { back = dk3str_casecmp(pl->stt, pr->stt); } else { back = dk3str_cmp(pl->stt, pr->stt); } } else { back = 1; } } else { if(pr->stt) { back = -1; } else { #line 214 "dkt-sort.ctr" } } } } if(back == 0) { if(cr & DKT_SORT_EXACT) { #line 220 "dkt-sort.ctr" if(pl->ori) { if(pr->ori) { #line 222 "dkt-sort.ctr" if(cr & DKT_SORT_CASEINS) { back = dk3str_casecmp(pl->ori, pr->ori); } else { back = dk3str_cmp(pl->ori, pr->ori); } } else { back = 1; } } else { if(pr->ori) { back = -1; } else { #line 232 "dkt-sort.ctr" } } } } #line 236 "dkt-sort.ctr" if(back > 0) { back = 1; } else { if(back < 0) { back = -1; } } } else { back = 1; } } else { if(r) { back = -1; } else { #line 243 "dkt-sort.ctr" } } if(cr & DKT_SORT_INVERT) { #line 246 "dkt-sort.ctr" back = 0 - back; } #line 248 "dkt-sort.ctr" return back; } /** Delete a line information structure. @param lp Structure to delete. */ static void dkt_sort_line_delete(DKT_SORT_L *lp) { #line 261 "dkt-sort.ctr" if(lp) { dk3_release(lp->ori) dk3_release(lp->nrm) lp->stt = NULL; lp->hv = '\0'; dk3_delete(lp); } #line 268 "dkt-sort.ctr" } /** Create a line information structure. @param j Job structure. @param ori Original line. @param nrm Normalized line. @return Pointer to new structure on success, NULL on error. */ DKT_SORT_L * dkt_sort_line_new(DKT_SORT_J *j, dkChar const *ori, dkChar const *nrm) { DKT_SORT_L *back = NULL; int ok = 0; /* Flag: Conversion ok. */ dk3_im_t im = DK3_MAX_INT_0; /* Value for line. */ dk3_um_t um = DK3_MAX_UINT_0; /* Value for line. */ double db = 0.0; /* Value for line. */ back = dk3_new_app(DKT_SORT_L,1,j->app); if(back) { back->ori = NULL; back->nrm = NULL; back->stt = NULL; back->hv = '\0'; back->ori = dk3str_dup_app(ori, j->app); if(back->ori) { if(nrm) { back->nrm = dk3str_dup_app(nrm, j->app); if(back->nrm) { ok = 1; } } else { ok = 1; } } if(ok) { if(j->o_igbl) { back->stt = dk3str_start(back->ori, NULL); } switch(j->o_sort) { case DKT_SORT_INTEGER: { if(dk3ma_intmax_from_string(&im, back->ori)) { (back->v).i = im; #line 311 "dkt-sort.ctr" back->hv = 'y'; } else { #line 313 "dkt-sort.ctr" } } break; case DKT_SORT_UNSIGNED: { if(dk3ma_uintmax_from_string(&um, back->ori)) { (back->v).u = um; #line 318 "dkt-sort.ctr" back->hv = 'y'; } else { #line 320 "dkt-sort.ctr" } } break; case DKT_SORT_DOUBLE: { if(dk3sf_sscanf3(back->ori, (j->kwnl)[1], &db) == 1) { (back->v).d = db; #line 325 "dkt-sort.ctr" back->hv = 'y'; } else { #line 327 "dkt-sort.ctr" } } break; } } else { dkt_sort_line_delete(back); back = NULL; } } return back; } /** Initialize job structure. @param j Job structure. */ static void dkt_sort_job_init(DKT_SORT_J *j) { j->opt = NULL; j->exval = DKT_RESULT_ERR_UNSPECIFIC; j->linesz = DKT_SORT_LINE_SIZE; j->enc_s = dk3app_get_input_stdin_encoding(j->app); j->enc_f = dk3app_get_input_file_encoding(j->app); j->c_sort = 0; j->c_merg = 0; j->o_merg = 0; j->o_sort = 0; j->o_norm = 0; j->o_igbl = 0; j->sto = NULL; j->sit = NULL; } /** Reset job structure (--reset or -R option). @param j Job structure. */ static void dkt_sort_job_reset(DKT_SORT_J *j) { j->linesz = DKT_SORT_LINE_SIZE; j->enc_s = dk3app_get_default_stdin_encoding(j->app); j->enc_f = dk3app_get_default_file_encoding(j->app); } /** Clean up job structure. @param j Job structure. */ static void dkt_sort_job_cleanup(DKT_SORT_J *j) { DKT_SORT_L *lp = NULL; if(j->sit) { dk3sto_it_reset(j->sit); while((lp = (DKT_SORT_L *)dk3sto_it_next(j->sit)) != NULL) { dkt_sort_line_delete(lp); } dk3sto_it_close(j->sit); } j->sit = NULL; if(j->sto) { dk3sto_close(j->sto); } j->sto = NULL; if(j->opt) { dk3opt_close(j->opt); j->opt = NULL; } } /** Set line size. @param j Job structure. @param t Text containing the new line size. @return 1 on success, 0 on error. */ static int dkt_sort_set_linesize(DKT_SORT_J *j, dkChar const *t) { int back = 0; unsigned u = 0; /* Used for conversion. */ size_t s = 0; /* New size. */ if(dk3sf_sscanf3(t, (j->kwnl)[0], &u) == 1) { s = (size_t)u; if((unsigned)s == u) { back = u; j->linesz = s; } } return back; } /** Process one key/value pair. @param jv Pointer to job structure casted to void *. @param k Key. @param v Value. @return 1 to indicate success. */ static int dkt_sort_conf_line(void *jv, dkChar const *k, dkChar const *v) { int back = 0; DKT_SORT_J *j; #line 441 "dkt-sort.ctr" j = (DKT_SORT_J *)jv; switch(dk3str_array_index(dkt_sort_long_opt, k, 0)) { case 0: { if(v) { #line 445 "dkt-sort.ctr" back = dkt_tool_set_encoding( j->app, &(j->enc_s), v, dk3app_get_input_stdin_encoding(j->app) ); } } break; case 1: { #line 452 "dkt-sort.ctr" if(v) { back = dkt_tool_set_encoding( j->app, &(j->enc_f), v, dk3app_get_input_file_encoding(j->app) ); } } break; case 2: { #line 460 "dkt-sort.ctr" back = 1; dkt_sort_job_reset(j); } break; case 3: { if(v) { back = dkt_sort_set_linesize(j, v); } } break; } #line 469 "dkt-sort.ctr" return back; } /** Process the command line arguments. @param j Job structure. @return 1 on success, 0 on error. */ static int dkt_sort_process_arguments(DKT_SORT_J *j) { int back = 0; int xargc = 0; /* Number of cmd line args. */ dkChar const * const *xargv = NULL; /* Cmd line args array. */ xargc = dk3app_get_argc(j->app); xargv = dk3app_get_argv(j->app); xargv++; xargv++; xargc--; xargc--; j->opt = dk3opt_open_app( dkt_sort_options, dkt_sort_szoptions, 0x00, NULL, xargc, xargv, j->app ); if(j->opt) { if(0 == dk3opt_get_error_code(j->opt)) { back = 1; if(dk3opt_is_set(j->opt, dkT('R'))) { dkt_sort_job_reset(j); } if(dk3opt_is_set(j->opt, dkT('n'))) { j->o_sort = j->c_sort = DKT_SORT_INTEGER; if(dk3opt_is_set(j->opt, dkT('u')) || dk3opt_is_set(j->opt, dkT('f'))) { back = 0; /* ERROR: Options -n -u -f are exclusive! */ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 2); } } else { if(dk3opt_is_set(j->opt, dkT('u'))) { j->o_sort = j->c_sort = DKT_SORT_UNSIGNED; if(dk3opt_is_set(j->opt, dkT('f'))) { back = 0; /* ERROR: Options -n -u -f are exclusive! */ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 2); } } else { if(dk3opt_is_set(j->opt, dkT('f'))) { j->o_sort = j->c_sort = DKT_SORT_DOUBLE; } } } j->c_sort |= DKT_SORT_EXACT; if(dk3opt_is_set(j->opt, dkT('s'))) { j->c_sort |= DKT_SORT_NOVALUE_FIRST; } if(dk3opt_is_set(j->opt, dkT('c'))) { j->c_sort |= DKT_SORT_CASEINS; } if(dk3opt_is_set(j->opt, dkT('r'))) { j->c_sort |= DKT_SORT_INVERT; } if(dk3opt_is_set(j->opt, dkT('w'))) { j->c_sort |= DKT_SORT_NORMALIZE; j->o_norm = 1; if(dk3opt_is_set(j->opt, dkT('b'))) { back = 0; /* ERROR: -w and -b are exlusive! */ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 3); } } else { if(dk3opt_is_set(j->opt, dkT('b'))) { j->c_sort |= DKT_SORT_IGNORE_LWHS; j->o_igbl = 1; } } j->c_merg = j->c_sort; /* Same options for merge as for sort. */ if(dk3opt_is_set(j->opt, dkT('e'))) { j->c_sort |= DKT_SORT_MERGE; j->c_merg |= DKT_SORT_MERGE; j->o_merg = 1; if(dk3opt_is_set(j->opt, dkT('m'))) { back = 0; /* ERROR: -e and -m are exclusive! */ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 4); } } else { if(dk3opt_is_set(j->opt, dkT('m'))) { j->c_sort |= DKT_SORT_MERGE; j->c_merg |= DKT_SORT_MERGE; j->o_merg = 1; if((j->c_merg) & (DKT_SORT_NORMALIZE | DKT_SORT_IGNORE_LWHS)) { #line 566 "dkt-sort.ctr" j->c_merg &= (~(DKT_SORT_EXACT)); } } } } } return back; } /** Handler function for one line. @param vj Job structure casted to void *. @param il Input line to process. @return 1=OK, 0=error, can continue, -1=error, abort processing. */ static int dkt_sort_line_handler(void *vj, dkChar *il) { int back = 0; int must_add = 1; /* Flag: Must add line. */ DKT_SORT_J *j = NULL; /* Job structure. */ DKT_SORT_L ltest; DKT_SORT_L *lnew = NULL; /* New line structure. */ dk3_im_t im = DK3_MAX_INT_0; /* Line value. */ dk3_um_t um = DK3_MAX_UINT_0; /* Line value. */ double db = 0.0; /* Line value. */ #line 595 "dkt-sort.ctr" j = (DKT_SORT_J *)vj; dk3str_delnl(il); /* Create normalized version. */ if(j->o_norm) { #line 599 "dkt-sort.ctr" dk3str_cpy(j->b2, il); dk3str_normalize(j->b2, NULL, dkT(' ')); } /* Check for merging whether or not to add this line. */ if(j->o_merg) { #line 604 "dkt-sort.ctr" ltest.ori = il; ltest.nrm = NULL; if(j->o_norm) { ltest.nrm = j->b2; } ltest.stt = NULL; if(j->o_igbl) { ltest.stt = dk3str_start(il, NULL); } ltest.hv = '\0'; switch(j->o_sort) { case DKT_SORT_INTEGER: { if(dk3ma_intmax_from_string(&im, il)) { ltest.v.i = im; #line 612 "dkt-sort.ctr" ltest.hv = 'y'; } else { #line 614 "dkt-sort.ctr" } } break; case DKT_SORT_UNSIGNED: { if(dk3ma_uintmax_from_string(&um, il)) { ltest.v.u = um; #line 619 "dkt-sort.ctr" ltest.hv = 'y'; } else { #line 621 "dkt-sort.ctr" } } break; case DKT_SORT_DOUBLE: { if(dk3sf_sscanf3(il, (j->kwnl)[1], &db) == 1) { ltest.v.d = db; #line 626 "dkt-sort.ctr" ltest.hv = 'y'; } else { #line 628 "dkt-sort.ctr" } } break; } lnew = (DKT_SORT_L *)dk3sto_it_find_like( j->sit, (void *)(<est), j->c_merg ); if(lnew) { #line 635 "dkt-sort.ctr" must_add = 0; } } /* Attept to add the line. */ if(must_add) { #line 640 "dkt-sort.ctr" lnew = dkt_sort_line_new(j, il, ((j->o_norm) ? (j->b2) : NULL)); if(lnew) { if(dk3sto_add(j->sto, (void *)lnew)) { back = 1; } else { dkt_sort_line_delete(lnew); back = -1; } } else { back = -1; } } else { back = 1; } #line 654 "dkt-sort.ctr" return back; } /** Process file names specified as command line arguments. @param j Job structure. @param nfn Number of file names. @return 1 on success, 0 on error. */ static int dkt_sort_process_files(DKT_SORT_J *j, int nfn) { int back = 1; int i = 0; /* Index of current file name. */ int res = 0; /* Line processing result. */ dkChar const *fn = NULL; /* File name. */ dk3_dir_t *fne = NULL; /* File name expander. */ dkChar const *en = NULL; /* Full file name. */ dkChar bu[DK3_MAX_PATH]; /* File name buffer. */ for(i = 0; i < nfn; i++) { fn = dk3opt_get_arg(j->opt, i); if(fn) { if(dk3str_len(fn) < DK3_SIZEOF(bu,dkChar)) { dk3str_cpy(bu, fn); dk3str_correct_filename(bu); if(dk3sf_must_expand(bu)) { fne = dk3dir_fne_open_app(bu, j->app); if(fne) { if(dk3dir_get_number_of_files(fne) > 0) { while(dk3dir_get_next_file(fne)) { en = dk3dir_get_fullname(fne); if(en) { res = dk3stream_process_filename_lines_app( (void *)j, dkt_sort_line_handler, en, j->b1, j->linesz, dk3app_get_encoding(j->app), j->enc_f, j->app ); if(res < 0) { back = 0; } } } } else { back = 0; /* ERROR: No matching file name */ dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, fn); } dk3dir_close(fne); } } else { res = dk3stream_process_filename_lines_app( (void *)j, dkt_sort_line_handler, bu, j->b1, j->linesz, dk3app_get_encoding(j->app), j->enc_f, j->app ); if(res < 1) { back = 0; } } } else { back = 0; /* ERROR: File name too long */ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn); } } else { /* BUG */ } } return back; } /** Process data from standard input. @param j Job structure. @return 1 on success, 0 on error. */ static int dkt_sort_process_stdin(DKT_SORT_J *j) { int back = 0; back = dk3app_process_stdin_lines( j->app, (void *)j, dkt_sort_line_handler, j->b1, j->linesz, j->enc_s ); return back; } /** Get input data. @param j Job structure. @return 1 on success, 0 on error. */ static int dkt_sort_get_with_buffers(DKT_SORT_J *j) { int back = 0; int nfn = 0; /* Number of file names. */ #line 772 "dkt-sort.ctr" nfn = dk3opt_get_num_args(j->opt); if(nfn) { back = dkt_sort_process_files(j, nfn); } else { back = dkt_sort_process_stdin(j); } #line 778 "dkt-sort.ctr" return back; } /** Use allocated buffers to process input. @param j Job structure. @return 1 on success, 0 on error. */ static int dkt_sort_get_with_allocated_buffers(DKT_SORT_J *j) { int back = 0; dkChar *b1 = NULL; /* Allocated buffer 1. */ dkChar *b2 = NULL; /* Allocated buffer 2. */ b1 = dk3_new_app(dkChar,j->linesz,j->app); if(b1) { b2 = dk3_new_app(dkChar,j->linesz,j->app); if(b2) { j->b1 = b1; j->b2 = b2; back = dkt_sort_get_with_buffers(j); j->b1 = NULL; j->b2 = NULL; dk3_delete(b2); } dk3_delete(b1); } return back; } /** Use builtin buffers to process input. @param j Job structure. @return 1 on success, 0 on error. */ static int dkt_sort_get_with_builtin_buffers(DKT_SORT_J *j) { int back = 0; dkChar b1[DKT_SORT_LINE_SIZE]; /* Buffer 1. */ dkChar b2[DKT_SORT_LINE_SIZE]; /* Buffer 2. */ size_t oldsz = 0; /* Line size. */ j->b1 = b1; j->b2 = b2; oldsz = j->linesz; j->linesz = DKT_SORT_LINE_SIZE; back = dkt_sort_get_with_buffers(j); j->linesz = oldsz; j->b1 = NULL; j->b2 = NULL; return back; } /** Read input from named files or from standard input. @param j Job structure. @return 1 on success, 0 on error. */ static int dkt_sort_get_input(DKT_SORT_J *j) { int back = 0; if(j->linesz > DKT_SORT_LINE_SIZE) { back = dkt_sort_get_with_allocated_buffers(j); } else { back = dkt_sort_get_with_builtin_buffers(j); } return back; } /** Input was read successfully, now produce output. @param j Job structure. */ static void dkt_sort_produce_output(DKT_SORT_J *j) { DKT_SORT_L *lp = NULL; /* Current line to process. */ dkChar const *ptr = NULL; /* Line text. */ register int initialized = 0; /* Flag: stdout initialized. */ dk3sto_it_reset(j->sit); while((lp = (DKT_SORT_L *)dk3sto_it_next(j->sit)) != NULL) { if(!initialized) { dk3sf_initialize_stdout(); initialized = 1; } ptr = lp->ori; if(j->o_merg) { if((j->c_merg) & DKT_SORT_NORMALIZE) { if(!((j->c_merg) & DKT_SORT_EXACT)) { if(lp->nrm) { ptr = lp->nrm; } } } else { if((j->c_merg) & DKT_SORT_IGNORE_LWHS) { if(!((j->c_merg) & DKT_SORT_EXACT)) { if(lp->stt) { ptr = lp->stt; } } } } } if(ptr) { dk3sf_fputs(ptr, stdout); dk3sf_fputc(dkT('\n'), stdout); } } } /** Create storage and iterator to save input lines. @param j Job structure. @return 1 on success, 0 on error. */ static int dkt_sort_create_storage(DKT_SORT_J *j) { int back = 0; j->sto = dk3sto_open_app(j->app); if(j->sto) { dk3sto_set_comp(j->sto, dkt_sort_compare, j->c_sort); j->sit = dk3sto_it_open(j->sto); if(j->sit) { back = 1; } } return back; } int dkt_sort( dk3_app_t *app, dkChar const *sn, dkChar const * const *msg, dkChar const * const *kwnl ) { int back = DKT_RESULT_ERR_UNSPECIFIC; DKT_SORT_J j; #line 934 "dkt-sort.ctr" j.app = app; j.msg = msg; j.kwnl = kwnl; dkt_sort_job_init(&j); dkt_tool_read_conf(app, sn, (void *)(&j), dkt_sort_conf_line); if(dkt_sort_process_arguments(&j)) { if(dkt_sort_create_storage(&j)) { if(dkt_sort_get_input(&j)) { dkt_sort_produce_output(&j); } } } dkt_sort_job_cleanup(&j); #line 946 "dkt-sort.ctr" return back; } /* vim: set ai sw=2 : */