/* 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: dk4wxpref.cpt */ /* 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 dk4wxpref.cpp The dk4wxpref module. */ #line 160 "dk4wxpref.cpt" #include "dk4wxpref.h" #include "dk4strd.h" #include "dk4strx.h" #include "dk4recwx.h" #include "dk4mem.h" #include "dk4mpl.h" #include "dk4tspdk.h" #include "dk4fs.h" #line 173 "dk4wxpref.cpt" /** Preference reading helper structure. */ typedef struct { dk4_sto_t *spref; /**< Preference storage. */ dk4_sto_it_t *ipref; /**< Preferences iterator. */ const dkChar *nameApp; /**< Application name. */ const dkChar *nameGrp; /**< Application group name. */ const dkChar *nameLog; /**< Users login name. */ const dkChar *nameHost; /**< Host name. */ const dkChar *language; /**< Users language. */ const dkChar *region; /**< Users region. */ wxChar *wx1; /**< One wxChar buffer. */ wxChar *wx2; /**< Other wxChar buffer. */ size_t szwx; /**< Size of wxChar buffers. */ int encWx; /**< Encoding for wxChar. */ int encDk; /**< Encoding for dkChar. */ int compat; /**< Flag: Compatible mode. */ int insc; /**< Flag: In scope. */ int lasc; /**< Flag: Previous line was scope. */ } dk4_wx_pref_rd_t; /** Constant keywords used by the module, not localized. */ static const dkChar * const dk4wxpref_kw_dk[] = { /* 0 */ dkT("dk3pref.conf"), /* 1 */ dkT("dk4pref.conf"), /* 2 */ dkT("*"), NULL #line 213 "dk4wxpref.cpt" }; /** Names for scope settings. */ static const dkChar * const dk4wxpref_scope_names[] = { /* 0 */ dkT("user"), /* 1 */ dkT("application"), /* 2 */ dkT("application-group"), /* 3 */ dkT("host"), /* 4 */ dkT("windows"), /* 5 */ dkT("non-windows"), /* 6 */ dkT("language"), /* 7 */ dkT("region"), NULL #line 254 "dk4wxpref.cpt" }; void dk4wxpref_close(dk4_wx_pref_t *ptr) { if (NULL != ptr) { dk4mem_release(ptr->name); dk4mem_release(ptr->value); dk4mem_free(ptr); } } dk4_wx_pref_t * dk4wxpref_open(const wxChar *name, const wxChar *value, dk4_er_t *erp) { dk4_wx_pref_t *back = NULL; if ((NULL != name) && (NULL != value)) { back = dk4mem_new(dk4_wx_pref_t,1,erp); if (NULL != back) { back->name = back->value = NULL; back->name = dk4strx_dup(name, erp); back->value = dk4strx_dup(value, erp); if ((NULL == back->name) || (NULL == back->value)) { dk4wxpref_close(back); back = NULL; } else { dk4error_set_simple_error_code(erp, DK4_E_MEMORY_ALLOCATION_FAILED); } } else { dk4error_set_simple_error_code(erp, DK4_E_MEMORY_ALLOCATION_FAILED); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } int dk4wxpref_compare(const void *l, const void *r, int cr) { const dk4_wx_pref_t *lptr; const dk4_wx_pref_t *rptr; int back = 0; if (NULL != l) { if (NULL != r) { lptr = (const dk4_wx_pref_t *)l; switch (cr) { case 1: { if (NULL != lptr->name) { back = dk4strx_cmp(lptr->name, (const wxChar *)r); } else back = -1; } break; default: { rptr = (const dk4_wx_pref_t *)r; if (NULL != lptr->name) { if (NULL != rptr->name) { back = dk4strx_cmp(lptr->name, rptr->name); } else back = 1; } else { if (NULL != rptr->name) back = -1; } } break; } if (-1 > back) back = -1; if ( 1 < back) back = 1; } else back = 1; } else { if (NULL != r) back = -1; } return back; } #if DK4_HAVE_COMPATDKTOOLS3 /** Modify version 3 preference names to version 4 names. I.e. /a/b/c -> a.b.c @param pstr String to modify. */ static void dk4wxpref_modify_compatible(dkChar *pstr) { if (dkT('/') == *pstr) { dk4str_cpy_to_left(pstr, &(pstr[1])); } while (dkT('\0') != *pstr) { if (dkT('/') == *pstr) { *pstr = dkT('.'); } pstr++; } } #endif /** Test one scope entry. @param rd Reader object. @param scn Scope part name. @return 1 if test succeeded, 0 otherwise. */ static int dk4wxpref_check_one_scope_entry(dk4_wx_pref_rd_t *rd, dkChar *scn) { dkChar *scv = NULL; int back = 1; scn = dk4str_start(scn, NULL); if (NULL != scn) { scv = dk4str_chr(scn, dkT('=')); if (NULL != scv) { *(scv++) = dkT('\0'); scv = dk4str_start(scv, NULL); } dk4str_normalize(scn, NULL); if (NULL != scv) { dk4str_normalize(scv, NULL); } back = 0; switch (dk4str_array_index(dk4wxpref_scope_names, scn, 0)) { case 0: { /* user */ if (NULL != scv) { if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) { back = 1; } else { if (NULL != rd->nameLog) { #if DK4_HAVE_CASE_INSENSITIVE_USERNAMES if (0 == dk4str_casecmp(rd->nameLog, scv)) #else if (0 == dk4str_cmp(rd->nameLog, scv)) #endif { back = 1; } } } } } break; case 1: { /* application */ if (NULL != scv) { if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) { back = 1; } else { if (NULL != rd->nameApp) { if (0 == dk4str_cmp(rd->nameApp, scv)) { back = 1; } } } } } break; case 2: { /* application group */ if (NULL != scv) { if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) { back = 1; } else { if (NULL != rd->nameGrp) { if (0 == dk4str_cmp(rd->nameGrp, scv)) { back = 1; } } } } } break; case 3: { /* host */ if (NULL != scv) { if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) { back = 1; } else { if (NULL != rd->nameHost) { if (0 == dk4str_casecmp(rd->nameHost, scv)) { back = 1; } } } } } break; case 4: { /* windows */ if (NULL != scv) { if (0 != dk4str_is_on(scv)) { #if DK4_ON_WINDOWS back = 1; #endif } else { #if !(DK4_ON_WINDOWS) back = 1; #endif } } else { #if DK4_ON_WINDOWS back = 1; #endif } } break; case 5: { /* non-windows */ if (NULL != scv) { if (0 != dk4str_is_on(scv)) { #if !(DK4_ON_WINDOWS) back = 1; #endif } else { #if DK4_ON_WINDOWS back = 1; #endif } } else { #if !(DK4_ON_WINDOWS) back = 1; #endif } } break; case 6: { /* language */ if (NULL != scv) { if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) { back = 1; } else { if (NULL != rd->language) { if (0 == dk4str_casecmp(rd->language, scv)) { back = 1; } } } } } break; case 7: { /* region */ if (NULL != scv) { if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) { back = 1; } else { if (NULL != rd->region) { if (0 == dk4str_casecmp(rd->region, scv)) { back = 1; } } } } } break; } } return back; } /** Process one input line. @param obj Preferences 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 dk4wxpref_line_handler( void *obj, dkChar *line, dk4_um_t lineno, dk4_er_t *erp ) { dk4_wx_pref_rd_t *rd; /* Reader object */ dk4_wx_pref_t *pptr; /* New pref */ dkChar *p1; /* Pref name */ dkChar *p2; /* Pref value */ wxChar *nv; /* New value */ int isneg; /* Flag: Not in scope */ int ok; /* Flag: Tests passed */ int res; /* Operation result */ int back = DK4_TSP_RES_OK; /* Function result */ rd = (dk4_wx_pref_rd_t *)obj; dk4str_delnl(line); p1 = dk4str_start(line, NULL); if (NULL != p1) { if (dkT('#') != *p1) { if (dkT('[') == *p1) { #line 537 "dk4wxpref.cpt" if (0 == rd->lasc) { rd->insc = 0; } p2 = dk4str_chr(p1, dkT(']')); if (NULL != p2) { *p2 = dkT('\0'); } p1++; if (dkT('-') == *p1) { isneg = 1; p1++; } else { isneg = 0; } ok = 1; while (NULL != p1) { p2 = dk4str_chr(p1, dkT(',')); if (NULL != p2) { *(p2++) = dkT('\0'); p2 = dk4str_start(p2, NULL); } if (0 == dk4wxpref_check_one_scope_entry(rd, p1)) { ok = 0; } p1 = p2; } if (1 == ok) { if (0 != isneg) { rd->insc = 0; } else { rd->insc = 1; } } rd->lasc = 1; } else { #line 563 "dk4wxpref.cpt" if (rd->insc) { p2 = dk4str_chr(p1, dkT('=')); if (NULL != p2) { *(p2++) = dkT('\0'); p2 = dk4str_start(p2, NULL); } if ((NULL != p1) && (NULL != p2)) { dk4str_normalize(p1, NULL); dk4str_rtwh(p2, NULL); #if DK4_HAVE_COMPATDKTOOLS3 if (0 != rd->compat) { dk4wxpref_modify_compatible(p1); } #endif res = dk4recwx_dkchar_to_wxchar( rd->wx1, rd->szwx, rd->encWx, p1, rd->encDk, NULL ); if (0 < res) { res = dk4recwx_dkchar_to_wxchar( rd->wx2, rd->szwx, rd->encWx, p2, rd->encDk, NULL ); if (0 < res) { pptr = (dk4_wx_pref_t *)dk4sto_it_find_like( rd->ipref, rd->wx1, 1 ); if (NULL != pptr) { nv = dk4strx_dup(rd->wx2, NULL); if (NULL != nv) { dk4mem_release(pptr->value); pptr->value = nv; } } else { pptr = dk4wxpref_open(rd->wx1, rd->wx2, NULL); if (NULL != pptr) { if (0 == dk4sto_add(rd->spref, pptr, NULL)) { dk4wxpref_close(pptr); } } } } } } } rd->lasc = 0; } } else { #line 609 "dk4wxpref.cpt" } } else { #line 611 "dk4wxpref.cpt" } return back; } /** Use one file. @param spref Preferences storage. @param ipref Iterator for preferences storage. @param nameApp Application name. @param nameGrp Application group name. @param nameLog Users login name. @param nameHost Host name. @param language Language. @param region Region. @param fn File name. @param encWx Encoding for wxChar strings. @param encDk Encoding for dkChar strings. @param encFile Expected encoding for files. @param compat Flag: In compatibility mode. */ static void dk4wxpref_one_file( dk4_sto_t *spref, dk4_sto_it_t *ipref, const dkChar *nameApp, const dkChar *nameGrp, const dkChar *nameLog, const dkChar *nameHost, const dkChar *language, const dkChar *region, const dkChar *fn, int encWx, int encDk, int encFile, int compat ) { char ib[4096]; /* Input buffer for stream read */ wxChar wx1[1024]; /* Buffer for conversion */ wxChar wx2[DK4_SIZEOF(wx1,wxChar)]; /* too */ dkChar il[1024]; /* Input line */ dk4_wx_pref_rd_t rd; /* Reader object */ dk4_er_t er; /* Error report */ dk4_tspdk_t tsp; /* Text stream processing */ dk4_stream_t *istrm; /* Input stream */ size_t szil = DK4_SIZEOF(il,dkChar); /* Buffer size */ size_t szwx = DK4_SIZEOF(wx1,wxChar); /* Buffer size */ size_t rb; /* Bytes read */ int res; /* Operation result */ int cc; /* Flag: Can continue */ dk4error_init(&er); istrm = dk4stream_open_file_reader(fn, &er); if (NULL != istrm) { rd.spref = spref; rd.ipref = ipref; rd.nameApp = nameApp; rd.nameGrp = nameGrp; rd.nameLog = nameLog; rd.nameHost = nameHost; rd.language = language; rd.region = region; rd.compat = compat; rd.encWx = encWx; rd.encDk = encDk; rd.insc = 1; rd.lasc = 0; rd.wx1 = wx1; rd.wx2 = wx2; rd.szwx = szwx; res = dk4tspdk_setup_line( &tsp, &rd, (dk4_dk_line_handler_t *)dk4wxpref_line_handler, il, szil, encDk, encFile, &er ); if (0 != res) { cc = 1; while (1 == cc) { cc = 0; rb = sizeof(ib); if (0 != dk4stream_read(ib, &rb, istrm, &er)) { if (0 < rb) { cc = 1; res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb); if (DK4_TSP_RES_FATAL == res) { cc = -1; } } } } if (0 == cc) { #if VERSION_BEFORE_20150821 res = dk4tspdk_finish(&tsp); #else (void)dk4tspdk_finish(&tsp); #endif } } dk4stream_close(istrm, NULL); } } void dk4wxpref_one_pass( dk4_sto_t *spref, dk4_sto_it_t *ipref, const dkChar *nameApp, const dkChar *nameGrp, const dkChar *nameLog, const dkChar *nameHost, const dkChar *language, const dkChar *region, const dkChar *dirHome, const dkChar *dirEtc, const dkChar *dirShare, int encWx, int encDk, int encFile, int pn ) { dkChar fnb[DK4_MAX_PATH]; dk4_er_t er; size_t szfnb = DK4_SIZEOF(fnb,dkChar); int res; #if DK4_HAVE_COMPATDKTOOLS3 dk4error_init(&er); res = dk4fs_config_compat_one( fnb, szfnb, dk4wxpref_kw_dk[0], dirShare, dirEtc, dirHome, nameApp, nameGrp, pn, 1, 1, &er ); if (0 != res) { dk4wxpref_one_file( spref, ipref, nameApp, nameGrp, nameLog, nameHost, language, region, fnb, encWx, encDk, encFile, 1 ); } #endif dk4error_init(&er); res = dk4fs_config_one( fnb, szfnb, dk4wxpref_kw_dk[1], dirShare, dirEtc, dirHome, nameApp, nameGrp, pn, 1, &er ); if (0 != res) { dk4wxpref_one_file( spref, ipref, nameApp, nameGrp, nameLog, nameHost, language, region, fnb, encWx, encDk, encFile, 0 ); } }