%% options copyright owner = Dirk Krause copyright year = 2016-xxxx license = bsd %% header /** @file dk4papea.h Paper sizes for applications. */ #ifndef DK4PAPER_H_INCLUDED #include "dk4paper.h" #endif #ifndef DK4APP_H_INCLUDED #include "dk4app.h" #endif #ifdef __cplusplus extern "C" { #endif /** Get paper sizes collection. If the function returns a valid pointer, use dk4papersize_coll_close() to release the paper size collection when done with it. @param app Application structure. @return Valid pointer on success, NULL on error. */ dk4_paper_size_collection_t * dk4app_get_paper_sizes(dk4_app_t *app); /** Get one paper size. On success, call dk4mem_free() to release the paper size when done with it. The paper size is returned with values only, empty name. @param app Application structure. @param psname Name of paper size to search for. @return Valid pointer to paper size on success, NULL on error. */ dk4_paper_size_t * dk4app_get_paper_size(dk4_app_t *app, const dkChar *psname); #ifdef __cplusplus } #endif /* vim: set ai sw=4 ts=4 : */ %% module #include "dk4papea.h" #include "dk4strd.h" #include "dk4mem.h" #include "dk4maiddbl.h" #include "dk4tspdk.h" #include "dk4fs.h" #include "dk4mpl.h" #include "dk4strm.h" #include "dk4strmr.h" $!trace-include /** Object passed as pointer to the reader function */ typedef struct { dk4_paper_size_collection_t *pscptr; dk4_app_t *app; } reader_obj_t; /** Names of files to read. */ static const dkChar * const conf_file_names[] = { dkT("dk4paper.conf"), #if DK4_HAVE_COMPATDKTOOLS3 dkT("dk3paper.conf"), #endif NULL }; /** Process one input line. @param obj Reader object. @param line Current line to process. @param lineno Line number. @param erp Error report, may be NULL. @return DK4_TSP_RES_OK if processing succeeded, DK4_TSP_RES_ERROR on errors (can continue), DK4_TSP_RES_FATAL on fatal errors (can not continue). */ static int dk4papersize_line_handler( void *obj, dkChar *line, dk4_um_t lineno, dk4_er_t *erp ) { double val[6]; /* w, h, i, o, t, b */ dkChar *tok[16]; /* tokens from the value side */ dk4_paper_size_collection_t *pscptr; /* collection of paper sizes */ dk4_paper_size_t *ps; /* paper size to modify */ dkChar *pls; /* line start (size name) */ dkChar *pval; /* value side of line */ const dkChar *ep; /* end pointer after double value */ dk4_app_t *app; /* application structure */ reader_obj_t *rdo; /* reader object */ size_t ntok; /* number of tokens in value side */ size_t i; /* index for traversal */ int back = DK4_TSP_RES_OK; $? "+ dk4papersize_line_handler \"%!ds\"", line /* Retrieve components from obj pointer */ rdo = (reader_obj_t *)obj; pscptr = rdo->pscptr; app = rdo->app; dk4app_set_log_source_line(app, lineno); /* Find start of line */ pls = dk4str_start(line, NULL); if (NULL == pls) { $? ". empty line" goto finished; } /* Ignore comment lines */ if (dkT('#') == *pls) { $? ". comment line" goto finished; } /* Line must by key = values */ pval = dk4str_chr(pls, dkT('=')); if (NULL == pval) { $? "! no = found" /* ERROR: Syntax */ dk4app_log_base1(app, DK4_LL_WARNING, 159); back = DK4_TSP_RES_ERROR; goto finished; } $? ". found =" *(pval++) = dkT('\0'); dk4str_rtwh(pls, NULL); if (0 == dk4str_len(pls)) { $? "! 0 name length" /* ERROR: Syntax */ dk4app_log_base1(app, DK4_LL_WARNING, 159); back = DK4_TSP_RES_ERROR; goto finished; } $? ". name length ok" pval = dk4str_start(pval, NULL); if (NULL == pval) { $? "! pval" /* ERROR: Syntax */ dk4app_log_base1(app, DK4_LL_WARNING, 159); back = DK4_TSP_RES_ERROR; goto finished; } $? ". pval" /* Tokenize string */ ntok = dk4str_tokenize(tok, 16, pval, NULL, NULL); if ((2 > ntok) || (6 < ntok)) { $? "! wrong number of tokens" /* ERROR: Syntax */ dk4app_log_base1(app, DK4_LL_WARNING, 159); back = DK4_TSP_RES_ERROR; goto finished; } $? ". number of tokens ok" /* Initialize values */ for (i = 0; i < 6; i++) { val[i] = 0.0; } /* Process tokens to values */ for (i = 0; i < ntok; i++) { ep = NULL; $? ". token=\"%!ds\"", tok[i] if (0 == dk4ma_input_dk_double(&(val[i]), tok[i], &ep, 1, NULL)) { /* ERROR: Syntax */ dk4app_log_base1(app, DK4_LL_WARNING, 159); back = DK4_TSP_RES_ERROR; $? "! token=\"%!ds\"", tok[i] goto finished; } } /* Modify existing or create new papersize */ ps = (dk4_paper_size_t *)dk4sto_it_find_like(pscptr->i_ps, pls, 1); if (NULL == ps) { $? ". must create new paper size" ps = dk4papersize_new(pls, NULL); if (NULL != ps) { $? ". paper size created" if (0 == dk4sto_add(pscptr->s_ps, ps, NULL)) { dk4papersize_delete(ps); $? "! failed to add" ps = NULL; } } #if TRACE_DEBUG else { $? "! memory" } #endif } if (NULL == ps) { $? "! no paper size to set up" /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_WARNING, 90); back = DK4_TSP_RES_ERROR; goto finished; } $? ". paper size available" ps->w = val[0]; ps->h = val[1]; ps->i = val[2]; ps->o = val[3]; ps->t = val[4]; ps->b = val[5]; finished: $? "- dk4papersize_line_handler %d", back return back; } /** Apply contents of one configuration file to paper size collection. @param pscptr Paper size collection to modify. @param fn File name. @param app Application structure. */ static void dk4app_apply_paper_size_file( dk4_paper_size_collection_t *pscptr, const dkChar *fn, dk4_app_t *app ) { char ib[4096]; /* Byte buffer */ dkChar il[1024]; /* Text line buffer */ dk4_tspdk_t tsp; /* Text stream processor */ dk4_er_t er; /* Error report */ reader_obj_t rdo; /* Passed to text proc */ const dkChar *oldsourcefile = NULL; /* Saved source file name */ dk4_stream_t *istrm = NULL; /* Input stream */ dk4_um_t oldsourceline = (dk4_um_t)0UL; /* Saved source line */ size_t rb = 0; /* Number of bytes read */ int cc = 1; /* Flag: Can continue */ int res = 0; /* Operation result */ $? "+ dk4app_apply_paper_size_file \"%!ds\"", fn /* Save current file name and file line for logging */ oldsourcefile = dk4app_get_log_source_file(app); oldsourceline = dk4app_get_log_source_line(app); /* We will process the specified input file, so set file name for logging */ dk4app_set_log_source_file(app, fn); dk4app_set_log_source_line(app, (dk4_um_t)0UL); /* Open stream for read access */ dk4error_init(&er); istrm = dk4stream_open_file_reader(fn, &er); if (NULL == istrm) { $? "! failed to open file" goto finished; } $? ". file opened" /* Set up reader object */ rdo.pscptr = pscptr; rdo.app = app; /* Set up text processor */ res = dk4tspdk_setup_line( &tsp, &rdo, dk4papersize_line_handler, il, DK4_SIZEOF(il,dkChar), app->encoding, app->enc_in_file, &er ); if (0 == res) { $? "! failed to init tsp" goto finished; } $? ". tsp initialized" /* Read and process contents from stream */ res = DK4_TSP_RES_OK; do { $? ". start of loop" cc = 0; rb = sizeof(ib); if (0 != dk4stream_read(ib, &rb, istrm, &er)) { $? ". read ok" if (0 < rb) { $? ". bytes found" res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb); if (DK4_TSP_RES_FATAL != res) { $? ". byte processing ok" cc = 1; } } #if TRACE_DEBUG else { $? ". 0 read" } #endif } #if TRACE_DEBUG else { $? "! read failed" } #endif $? ". end of loop cc=%d", cc } while (1 == cc); if (DK4_TSP_RES_FATAL != res) { dk4tspdk_finish(&tsp); } finished: /* Close input stream */ if (NULL != istrm) { dk4stream_close(istrm, NULL); } /* Restore file name and file line for logging */ dk4app_set_log_source_file(app, oldsourcefile); dk4app_set_log_source_line(app, oldsourceline); $? "- dk4app_apply_paper_size_file" } dk4_paper_size_collection_t * dk4app_get_paper_sizes(dk4_app_t *app) { dkChar fnb[DK4_MAX_PATH]; /* File name buffer */ dk4_er_t er; /* Error result */ const dkChar *msg[3]; dk4_paper_size_collection_t *back = NULL; /* Function result */ const size_t szfnb = DK4_SIZEOF(fnb,dkChar); /* Size */ int res; /* Operation result */ int i; /* Index for traversal */ $? "+ dk4app_get_paper_sizes" /* Check app pointer */ if (NULL == app) { $? "! invalid app pointer" goto finished; } /* Allocate new size collection with default sizes */ back = dk4papersize_coll_open(NULL); if (NULL == back) { $? "! memory" /* ERROR: Memory */ dk4app_log_base1(app, DK4_LL_WARNING, 90); goto finished; } /* Find all configuration files and apply contents. */ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) { if ((NULL != app->msg_debug) && (36 < app->sz_msg_debug)) { msg[0] = (app->msg_debug)[36]; dk4app_log_msg(app, DK4_LL_DEBUG, msg, 1); } } for (i = 0; i <= DK4_FS_CONF_MAX; i++) { $? ". pass %u", (unsigned)i #if DK4_HAVE_COMPATDKTOOLS3 #if VERSION_BEFORE_2017_03_09 dk4error_init(&er); res = dk4fs_config_compat_one( fnb, szfnb, conf_file_names[1], app->dir_share, app->dir_etc, app->user_home, app->prog_name, app->group_name, i, 1, 1, &er ); if (0 != res) { $? ". dk3paper.conf" dk4app_apply_paper_size_file(back, fnb, app); } #else dk4error_init(&er); res = dk4fs_config_construct_compat_one( fnb, szfnb, conf_file_names[1], app->dir_share, app->dir_etc, app->user_home, app->prog_name, app->group_name, i, 1, &er ); if (0 != res) { res = dk4fs_attempt_file_name(fnb, szfnb, 1, &er); if (0 != res) { if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) { if ((NULL != app->msg_debug) && (30 < app->sz_msg_debug)) { msg[0] = (app->msg_debug)[30]; msg[1] = fnb; dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2); } } dk4app_apply_paper_size_file(back, fnb, app); } else { if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) { if ((NULL != app->msg_debug) && (31 < app->sz_msg_debug)) { msg[0] = (app->msg_debug)[31]; msg[1] = fnb; dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2); } } } } #endif #endif #if VERSION_BEFORE_2017_03_09 dk4error_init(&er); res = dk4fs_config_one( fnb, szfnb, conf_file_names[0], app->dir_share, app->dir_etc, app->user_home, app->prog_name, app->group_name, i, 1, &er ); if (0 != res) { $? ". dk4paper.conf" dk4app_apply_paper_size_file(back, fnb, app); } #else dk4error_init(&er); res = dk4fs_config_construct_compat_one( fnb, szfnb, conf_file_names[0], app->dir_share, app->dir_etc, app->user_home, app->prog_name, app->group_name, i, 0, &er ); if (0 != res) { res = dk4fs_attempt_file_name(fnb, szfnb, 1, &er); if (0 != res) { if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) { if ((NULL != app->msg_debug) && (30 < app->sz_msg_debug)) { msg[0] = (app->msg_debug)[30]; msg[1] = fnb; dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2); } } dk4app_apply_paper_size_file(back, fnb, app); } else { if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) { if ((NULL != app->msg_debug) && (31 < app->sz_msg_debug)) { msg[0] = (app->msg_debug)[31]; msg[1] = fnb; dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2); } } } } else { } #endif } finished: $? "- dk4app_get_paper_sizes %d", TR_IPTR(back) return back; } dk4_paper_size_t * dk4app_get_paper_size(dk4_app_t *app, const dkChar *psname) { dk4_paper_size_collection_t *coll = NULL; /* Paper sizes collection */ dk4_paper_size_t *back = NULL; /* Function result */ dk4_paper_size_t *tmp = NULL; /* Temporary found paper size */ $? "+ dk4app_get_paper_size \"%!ds\"", TR_STR(psname) /* Check arguments */ if ((NULL == app) || (NULL == psname)) { goto finished; } /* Retrieve paper size collection */ coll = dk4app_get_paper_sizes(app); if (NULL == coll) { goto finished; } tmp = (dk4_paper_size_t *)dk4sto_it_find_like(coll->i_ps, psname, 1); if (NULL == tmp) { goto finished; } back = dk4mem_new(dk4_paper_size_t,1,NULL); if (NULL == back) { goto finished; } back->name = NULL; back->w = tmp->w; back->h = tmp->h; back->i = tmp->i; back->o = tmp->o; back->t = tmp->t; back->b = tmp->b; finished: if (NULL != coll) { dk4papersize_coll_close(coll); } $? "- dk4app_get_paper_size %d", TR_IPTR(back) return back; } /* vim: set ai sw=4 ts=4 : */