/* Copyright (C) 2011-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk3paper.ctr */ /** @file dk3paper.c The dk3paper module. */ #line 57 "dk3paper.ctr" #include "dk3all.h" #include "dk3paper.h" #line 64 "dk3paper.ctr" /** Built-in named paper sizes, may be overwritten in configuration files. */ static dkChar const * const dk3paper_default_sizes[] = { dkT("A4\t\t=\t595\t842"), dkT("Letter\t\t=\t612\t792"), dkT("a4\t\t=\t595\t842\t56\t28\t14\t14"), dkT("letter\t\t=\t612\t792\t56\t28\t14\t14"), NULL #line 76 "dk3paper.ctr" }; /** File name for configuration file. */ static dkChar const dk3paper_config_file_name[] = { dkT("dk3paper.conf") }; /** Delete named paper size, release memory. @param nps Data to delete. */ static void dk3paper_nps_delete(dk3_named_paper_size_t *nps) { #line 94 "dk3paper.ctr" if(nps->name) { dk3_release(nps->name); } dk3_delete(nps); #line 99 "dk3paper.ctr" } /** Create named paper size structure, allocate memory. @param app Application structure for diagnostics. @param name Paper size name. @return Pointer to new paper size on success, NULL on error. */ static dk3_named_paper_size_t * dk3paper_nps_new(dk3_app_t *app, dkChar const *name) { dk3_named_paper_size_t *back = NULL; #line 114 "dk3paper.ctr" if((app) && (name)) { back = dk3_new_app(dk3_named_paper_size_t,1,app); if(back) { back->name = NULL; (back->size).w = (back->size).h = 0.0; (back->size).i = (back->size).o = (back->size).t = (back->size).b = 0.0; back->name = dk3str_dup_app(name, app); if(!(back->name)) { dk3paper_nps_delete(back); back = NULL; } } } #line 126 "dk3paper.ctr" return back; } /** Compare two named paper sizes by name. @param l Left structure. @param r Right structure. @param cr Comparison criteria (0=size/size, 1=size/name). @return Comparison result. */ static int dk3paper_nps_compare(void const *l, void const *r, int cr) { int back = 0; dk3_named_paper_size_t const *pl; /* Pointer to left structure. */ dk3_named_paper_size_t const *pr; /* Pointer to right structure. */ if(l) { if(r) { pl = (dk3_named_paper_size_t const *)l; switch(cr) { case 1: { /* Compare structure against a name string. */ if(pl->name) { back = dk3str_cmp(pl->name, (dkChar const *)r); } else { back = -1; } } break; default: { /* Compare two structures by name. */ pr = (dk3_named_paper_size_t const *)r; if(pl->name) { if(pr->name) { back = dk3str_cmp(pl->name, pr->name); } else { back = 1; } } else { if(pr->name) { back = -1; } } } break; } } else { back = 1; } } else { if(r) { back = -1; } } if(back < -1) back = -1; if(back > 1) back = 1; return back; } /** Set values in a named paper size. @param np Named paper size. @param v Values array. @param num Number of values (2 or 6). Width and height are mandatory, borders are optional. @return 1 on success, 0 on error. */ static int dk3paper_set_values(dk3_named_paper_size_t *np, double const *v, size_t num) { int back = 0; #line 205 "dk3paper.ctr" (np->size).i = (np->size).o = (np->size).t = (np->size).b = 0.0; (np->size).w = v[0]; (np->size).h = v[1]; if(num > 2) { (np->size).i = v[2]; (np->size).o = v[3]; (np->size).t = v[4]; (np->size).b = v[5]; } /* Indicate success only if all values are reasonable. */ if((np->size).w > 0.0) { if((np->size).h > 0.0) { if((np->size).i >= 0.0) { if((np->size).o >= 0.0) { if((np->size).t >= 0.0) { if((np->size).b >= 0.0) { back = 1; } } } } } } #line 227 "dk3paper.ctr" return back; } /** Handler function for one configuration file line. @param obj Paper size collection. @param il Input line to process. @return 1 for OK, 0 for recoverable error, -1 for abort. */ static int dk3paper_const_line_handler(void *obj, dkChar const *il) { dkChar bu[DK3_PAPER_CONFIG_LINE_SIZE]; /* Private copy. */ dkChar *parts[16]; /* Split number sequence. */ double v[8]; /* Values from text line. */ dk3_paper_size_collection_t *psc; /* Paper size collection. */ dk3_named_paper_size_t *np; /* Paper size to edit. */ dkChar *p1; /* Paper size name. */ dkChar *p2; /* Values for that size. */ size_t nparts; /* Number of values. */ size_t i; /* Traverse all values. */ int back = 1; int res = 0; /* Flag: No reporting necessary. */ #line 253 "dk3paper.ctr" if((obj) && (il)) { #line 254 "dk3paper.ctr" psc = (dk3_paper_size_collection_t *)obj; if(dk3str_len(il) < DK3_SIZEOF(bu,dkChar)) { dk3str_cpy_not_overlapped(bu, il); p1 = dk3str_start(bu, NULL); if(p1) { if(*p1 != dkT('#')) { p2 = dk3str_chr(p1, dkT('=')); if(p2) { *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); if(p2) { dk3str_chomp(p1, NULL); nparts = dk3str_explode(parts, 15, p2, NULL); if((nparts == 2) || (nparts == 6)) { /* Line syntax ok so far. */ res = 1; /* Read double value from all text words. */ for(i = 0; i < nparts; i++) { #if VERSION_BEFORE_20140716 if(dk3sf_sscanf3(parts[i], dkT("%lg"), &(v[i])) != 1) #else /* Bugfix 2014-09-01: If the action fails, the res variable is set to failure, not on success. */ #if VERSION_BEFORE_20140901 /* WRONG*/ if (dk3ma_d_from_string(&(v[i]), parts[i], NULL)) #else /* OK */ if (0 == dk3ma_d_from_string(&(v[i]), parts[i], NULL)) #endif #endif { res = 0; } } if(res) { if(dk3str_len(p1) > 0) { /* Attempt to find existing size for that name. */ np = (dk3_named_paper_size_t *)dk3sto_it_find_like( psc->i_sizes, (void *)p1, 1 ); if(np) { /* Entry exists, reconfigure entry. */ res = dk3paper_set_values(np, v, nparts); } else { /* Create new entry. */ np = dk3paper_nps_new(psc->app, p1); if(np) { if(dk3sto_add(psc->s_sizes, (void *)np)) { res = dk3paper_set_values(np, v, nparts); } else { /* ERROR: Memory */ dk3paper_nps_delete(np); np = NULL; back = 0; } } else { /* ERROR: Memory */ back = 0; } } } else { res = 0; } } } } } } else { res = 1; } } else { res = 1; } if(!(res)) { /* ERROR: Syntax */ dk3str_cpy_not_overlapped(bu, il); dk3str_normalize(bu, NULL, dkT(' ')); dk3app_log_i3(psc->app, DK3_LL_ERROR, 211, 212, bu); } } } #line 338 "dk3paper.ctr" return back; } /** Handler function for one configuration file line. @param obj Paper size collection. @param il Input line to process. @return 1 for OK, 0 for recoverable error, -1 for abort. */ static int dk3paper_line_handler(void *obj, dkChar *il) { int back; back = dk3paper_const_line_handler(obj, il); return back; } dk3_paper_size_collection_t * dk3paper_open_app(dk3_app_t *app) { dkChar bu[DK3_PAPER_CONFIG_LINE_SIZE]; /* Buffer. */ dk3_paper_size_collection_t *back = NULL; dk3_search_t *sr; dkChar const *fn; dkChar const * const *lfdptr; int ok = 0; int res; int de; int se; #line 372 "dk3paper.ctr" if(app) { back = dk3_new_app(dk3_paper_size_collection_t,1,app); if(back) { #line 375 "dk3paper.ctr" back->app = app; back->s_sizes = NULL; back->i_sizes = NULL; back->s_sizes = dk3sto_open_app(app); if(back->s_sizes) { #line 379 "dk3paper.ctr" dk3sto_set_comp(back->s_sizes, dk3paper_nps_compare, 0); back->i_sizes = dk3sto_it_open(back->s_sizes); if(back->i_sizes) { #line 382 "dk3paper.ctr" ok = 1; /* Read built-in lines. */ lfdptr = dk3paper_default_sizes; while(*lfdptr) { #line 388 "dk3paper.ctr" if(!dk3paper_const_line_handler((void *)back, *lfdptr)) { ok = 0; #line 390 "dk3paper.ctr" } lfdptr++; } /* Read configuration files. */ sr = dk3app_find_config_file(app, dk3paper_config_file_name, 0); if(sr) { #line 398 "dk3paper.ctr" dk3search_reset(sr); se = dk3app_get_encoding(app); de = dk3app_get_input_file_encoding(app); while((fn = dk3search_next(sr)) != NULL) { #line 403 "dk3paper.ctr" res = dk3stream_process_filename_lines_app( (void *)back, dk3paper_line_handler, fn, bu, DK3_SIZEOF(bu,dkChar), se, de, app ); if(!(res)) { ok = 0; } } dk3search_close(sr); } else { #line 413 "dk3paper.ctr" } } else { #line 415 "dk3paper.ctr" } } else { #line 417 "dk3paper.ctr" } if(!(ok)) { dk3paper_close(back); back = NULL; } } else { #line 422 "dk3paper.ctr" } } #line 424 "dk3paper.ctr" return back; } void dk3paper_close(dk3_paper_size_collection_t *psc) { dk3_named_paper_size_t *nps; /* Current size to release. */ #line 434 "dk3paper.ctr" if(psc) { if(psc->s_sizes) { if(psc->i_sizes) { dk3sto_it_reset(psc->i_sizes); while((nps = (dk3_named_paper_size_t *)dk3sto_it_next(psc->i_sizes)) != NULL ) { dk3paper_nps_delete(nps); } dk3sto_it_close(psc->i_sizes); } dk3sto_close(psc->s_sizes); } psc->s_sizes = NULL; psc->app = NULL; dk3_delete(psc); } #line 452 "dk3paper.ctr" } dk3_paper_size_t const * dk3paper_find(dk3_paper_size_collection_t *psc, dkChar const *psn) { dk3_paper_size_t const *back = NULL; dk3_named_paper_size_t *nps; /* Named size. */ #line 461 "dk3paper.ctr" if((psc) && (psn)) { nps = (dk3_named_paper_size_t *)dk3sto_it_find_like( psc->i_sizes, (void *)psn, 1 ); if(nps) { #line 466 "dk3paper.ctr" back = (dk3_paper_size_t const *)(&(nps->size)); } } #line 469 "dk3paper.ctr" return back; } void dk3paper_reset(dk3_paper_size_collection_t *psc) { if(psc) { if(psc->i_sizes) { dk3sto_it_reset(psc->i_sizes); } } } dk3_named_paper_size_t const * dk3paper_next(dk3_paper_size_collection_t *psc) { dk3_named_paper_size_t const *back = NULL; if(psc) { if(psc->i_sizes) { back = (dk3_named_paper_size_t const *)dk3sto_it_next(psc->i_sizes); } } return back; }