/* 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-blks.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-blks.c The dkt-blks module. */ #line 10 "dkt-blks.ctr" #include "dk3all.h" #include "dkt.h" #line 18 "dkt-blks.ctr" /** Job structure for dkt blks. */ 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. */ char *ib; /**< Input buffer. */ char *ob; /**< Output buffer. */ size_t oblgt; /**< Output buffer length. */ size_t obused; /**< Output buffer used. */ int exval; /**< Exit status code. */ int f_oer; /**< Flag: Output error reported. */ } DKT_BLKS_J; /** Options used by dkt blks. */ static dk3_option_t const dkt_blks_options[] = { { dkT('R'), dkT("reset"), 0 }, { dkT('b'), dkT("block-size"), 1 } }; /** Keywords available in configuration file. */ static dkChar const * const dkt_blks_conf_kw[] = { dkT("block-size"), NULL }; /** Number of options in the dkt_blks_options array. */ static size_t const dkt_blks_szoptions = sizeof(dkt_blks_options)/sizeof(dk3_option_t); /** Initialize job structure. @param j Structure to initialize. */ static void dkt_blks_job_init(DKT_BLKS_J *j) { #line 71 "dkt-blks.ctr" j->opt = NULL; j->ib = NULL; j->ob = NULL; j->oblgt = 512; #line 75 "dkt-blks.ctr" j->obused = 0; j->exval = DKT_RESULT_ERR_UNSPECIFIC; j->f_oer = 0; #line 79 "dkt-blks.ctr" } /** Clean up job structure. @param j Job structure to clean up. */ static void dkt_blks_job_cleanup(DKT_BLKS_J *j) { if(j->opt) { dk3opt_close(j->opt); } j->opt = NULL; #line 94 "dkt-blks.ctr" } /** 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_blks_conf_line(void *jv, dkChar const *k, dkChar const *v) { int back = 0; unsigned u = 512; /* Variable for block size. */ DKT_BLKS_J *j = NULL; /* Job structure. */ #line 112 "dkt-blks.ctr" j = (DKT_BLKS_J *)jv; switch(dk3str_array_index(dkt_blks_conf_kw, k, 0)) { case 0: { if(v) { if(dk3sf_sscanf3(v, dkT("%u"), &u) > 0) { j->oblgt = (size_t)u; back = 1; #line 118 "dkt-blks.ctr" } } } break; } #line 122 "dkt-blks.ctr" return back; } /** Process the command line arguments. @param j Job structure. @return 1 on success, 0 on error. */ static int dkt_blks_process_arguments(DKT_BLKS_J *j) { int back = 0; int xargc = 0; /* Number of command line arguments. */ unsigned u = 512; /* Variable for block size. */ dkChar const *arg = NULL; /* Current argument to process. */ dkChar const * const *xargv = NULL; /* Command line arguments array. */ #line 141 "dkt-blks.ctr" xargc = dk3app_get_argc(j->app); xargv = dk3app_get_argv(j->app); xargv++; xargv++; xargc--; xargc--; j->opt = dk3opt_open_app( dkt_blks_options, dkt_blks_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'))) { j->oblgt = 512; #line 158 "dkt-blks.ctr" } if(dk3opt_is_set(j->opt, dkT('b'))) { #line 160 "dkt-blks.ctr" arg = dk3opt_get_short_arg(j->opt, dkT('b')); if(arg) { #line 162 "dkt-blks.ctr" if(dk3sf_sscanf3(arg, dkT("%u"), &u) > 0) { #line 163 "dkt-blks.ctr" j->oblgt = (size_t)u; #line 164 "dkt-blks.ctr" if((unsigned)(j->oblgt) != u) { #line 165 "dkt-blks.ctr" back = 0; j->exval = DKT_RESULT_ERR_OPTION; /* ERROR: Overflow. */ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 15, 16, arg); } } else { #line 171 "dkt-blks.ctr" back = 0; j->exval = DKT_RESULT_ERR_OPTION; /* ERROR: Not a number. */ dk3app_log_i3(j->app, DK3_LL_ERROR, 141, 142, arg); } } else { back = 0; j->exval = DKT_RESULT_ERR_OPTION; } } } else { j->exval = DKT_RESULT_ERR_OPTION; } } else { j->exval = DKT_RESULT_ERR_OPTION; } #line 187 "dkt-blks.ctr" return back; } /** Flush output buffer to standard output. @param j Job structure. */ static void dkt_blks_flush_output(DKT_BLKS_J *j) { #line 200 "dkt-blks.ctr" if(j->obused > 0) { #line 201 "dkt-blks.ctr" if(!dk3sf_write_app(1, j->ob, j->obused, j->app)) { /* ERROR while writing output! */ j->exval = DKT_RESULT_ERR_OUTPUT; if(!(j->f_oer)) { dk3app_log_i1(j->app, DK3_LL_ERROR, 120); } j->f_oer = 0; } } #line 209 "dkt-blks.ctr" } /** Add one character to output buffer, flush if necessary (buffer full). @param j Job structure. @param c Character to add. */ static void dkt_blks_add_char(DKT_BLKS_J *j, char c) { #line 222 "dkt-blks.ctr" (j->ob)[j->obused] = c; j->obused += 1; if(j->obused >= j->oblgt) { dkt_blks_flush_output(j); j->obused = 0; } #line 228 "dkt-blks.ctr" } /** Process one input file. @param j Job structure. @param fipo File pointer to read input file. */ static void dkt_blks_process_file(DKT_BLKS_J *j, FILE *fipo) { size_t rdbytes = 0; /* Bytes read in current pass. */ size_t i = 0; /* Index of current byte to process. */ #line 243 "dkt-blks.ctr" do { rdbytes = dk3sf_fread_app((void *)(j->ib), 1, j->oblgt, fipo, j->app); if(rdbytes > 0) { for(i = 0; i < rdbytes; i++) { dkt_blks_add_char(j, (j->ib)[i]); } } } while(rdbytes > 0); #line 251 "dkt-blks.ctr" } /** Process standard input. @param j Job structure. */ static void dkt_blks_stdin_run(DKT_BLKS_J *j) { size_t rdbytes = 0; /* Number of bytes read from stdin. */ size_t i = 0; /* Index of current byte to process. */ #if DK3_ON_WINDOWS int oldmode; /* Old stdin mode. */ #endif #if DK3_ON_WINDOWS oldmode = _setmode(0, _O_BINARY); #endif #line 271 "dkt-blks.ctr" do { #line 272 "dkt-blks.ctr" rdbytes = dk3sf_read_app(0, j->ib, j->oblgt, j->app); #line 274 "dkt-blks.ctr" if(rdbytes > 0) { for(i = 0; i < rdbytes; i++) { dkt_blks_add_char(j, (j->ib)[i]); } } } while(rdbytes > 0); #if DK3_ON_WINDOWS _setmode(0, oldmode); #endif #line 284 "dkt-blks.ctr" } /** Process one real file name (after correction and expansion). @param j Job structure. @param en Entry name. */ static void dkt_blks_process_one_real_name(DKT_BLKS_J *j, dkChar const *en) { FILE *fipo = NULL; /* File pointer to read input file. */ #line 298 "dkt-blks.ctr" fipo = dk3sf_fopen_app(en, dk3app_not_localized(36), j->app); if(fipo) { dkt_blks_process_file(j, fipo); fclose(fipo); } else { /* ERROR: Failed to open file */ j->exval = DKT_RESULT_ERR_FILENAME; } #line 306 "dkt-blks.ctr" } /** Process all the file names specified on the command line. @param j Job structure. @param nfn Number of file names. */ static void dkt_blks_process_filenames(DKT_BLKS_J *j, int nfn) { dkChar const *arg = NULL; /* Current argument. */ dkChar const *en = NULL; /* File name. */ dkChar fnb[DK3_MAX_PATH]; /* Copy of file name. */ int i = 0; /* Current argument index. */ dk3_dir_t *fne = NULL; /* File name expander. */ #line 324 "dkt-blks.ctr" for(i = 0; i < nfn; i++) { arg = dk3opt_get_arg(j->opt, i); if(arg) { if(dk3str_len(arg) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy(fnb, arg); dk3str_correct_filename(fnb); if(dk3sf_must_expand(fnb)) { fne = dk3dir_fne_open_app(fnb, 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) { dkt_blks_process_one_real_name(j, en); } else { /* BUG */ } } } else { /* ERROR: No such file! */ dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, fnb); j->exval = DKT_RESULT_ERR_FILENAME; } dk3dir_close(fne); } else { /* ERROR: Expander */ j->exval = DKT_RESULT_ERR_MEMORY; } } else { dkt_blks_process_one_real_name(j, fnb); } } else { /* ERROR: Name too long! */ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, arg); j->exval = DKT_RESULT_ERR_FILENAME; } } else { /* BUG */ } } #line 364 "dkt-blks.ctr" } /** Run with buffers. @param j Job structure. */ static void dkt_blks_run_with_buffers(DKT_BLKS_J *j) { int nfn = 0; /* Number of file names. */ #if DK3_ON_WINDOWS int oldmode = _O_TEXT; /* Old stdout mode. */ #endif #line 380 "dkt-blks.ctr" #if DK3_ON_WINDOWS oldmode = _setmode(1, _O_BINARY); #endif nfn = dk3opt_get_num_args(j->opt); if(nfn > 0) { dkt_blks_process_filenames(j, nfn); } else { dkt_blks_stdin_run(j); } if(j->obused) { dkt_blks_flush_output(j); } #if DK3_ON_WINDOWS _setmode(1, oldmode); #endif #line 396 "dkt-blks.ctr" } /** Allocate buffers and run with buffers in dynamic memory. @param j Job structure. */ static void dkt_blks_run_with_allocated_buffers(DKT_BLKS_J *j) { char *ib = NULL; /* Input buffer dynamically allocated. */ char *ob = NULL; /* Output buffer dynamically allocated. */ #line 410 "dkt-blks.ctr" ib = dk3_new_app(char,j->oblgt,j->app); if(ib) { ob = dk3_new_app(char,j->oblgt,j->app); if(ob) { j->ib = ib; j->ob = ob; dkt_blks_run_with_buffers(j); dk3_delete(ob); } else { j->exval = DKT_RESULT_ERR_MEMORY; } dk3_delete(ib); } else { j->exval = DKT_RESULT_ERR_MEMORY; } #line 424 "dkt-blks.ctr" } /** Run with builtin buffers. @param j Job structure. */ static void dkt_blks_run_with_internal_buffers(DKT_BLKS_J *j) { char ib[4096]; /* Builtin input buffer. */ char ob[4096]; /* Builtin output buffer. */ #line 438 "dkt-blks.ctr" j->ib = ib; j->ob = ob; dkt_blks_run_with_buffers(j); #line 440 "dkt-blks.ctr" } /** Run a conversion. @param j Job structure. */ static void dkt_blks_run(DKT_BLKS_J *j) { #line 452 "dkt-blks.ctr" if(j->oblgt > 4096) { dkt_blks_run_with_allocated_buffers(j); } else { dkt_blks_run_with_internal_buffers(j); } #line 457 "dkt-blks.ctr" } int dkt_blocksize( dk3_app_t *app, dkChar const *sn, dkChar const * const *msg, dkChar const * const *kwnl ) { int back = DKT_RESULT_ERR_UNSPECIFIC; DKT_BLKS_J j; /* Job structure. */ #line 472 "dkt-blks.ctr" j.app = app; j.msg = msg; j.kwnl = kwnl; dkt_blks_job_init(&j); dkt_tool_read_conf(app, sn, (void *)(&j), dkt_blks_conf_line); if(dkt_blks_process_arguments(&j)) { j.exval = DKT_RESULT_OK; dkt_blks_run(&j); } back = j.exval; dkt_blks_job_cleanup(&j); #line 482 "dkt-blks.ctr" return back; } /* vim: set ai sw=2 : */