%% options copyright owner = Dirk Krause copyright year = 2011-xxxx license = bsd %% header #include "dkwxtrace.h" $!trace-include /** Worker thread for wxdkct. */ class DkWxTraceThread : public wxThread { protected: /** Conversion option set. */ DKCT_OPTION_SET dkcto; /** Communication object between main thread and worker thread. */ DkWxCommunicator *pComm; /** Localized text messages. */ wxChar const * const *sTexts; /** Localized dkChar messages. */ dkChar const * const *msg; /** Directory to process. */ wxChar const *sDirectory; /** Application helper. */ DkWxAppHelper *pHelper; /** Application structure. */ dk3_app_t *app; /** Encoding used for wxChar. */ int wxe; /** Encoding used for dkChar. */ int dke; /** Run for one file. @param fn File name. @param sufi Suffix index. */ void runForFile(dkChar const *fn, int sufi); /** Check one file, run if necessary. @param fn File name. @param sufi Suffix index. */ void checkAndRunFile(dkChar const *fn, int sufi); /** Run for directory. @param dirname Directory name. */ void runForDirectory(wxChar const *dirname); public: /** Constructor @param comm Communication object. @param texts Localized messages texts. @param ms Localized dkChar message texts. @param directory Directory to process. @param ah Application helper. @param o Conversion option set. @param we Encoding for wxChar. @param de Encoding for dkChar. */ DkWxTraceThread( DkWxCommunicator *comm, wxChar const * const *texts, dkChar const * const *ms, wxChar const *directory, DkWxAppHelper *ah, DKCT_OPTION_SET *o, int we, int de ); /** Thread function. @return A pointer which is ignored. */ virtual void *Entry(); /** Function executed at the end of thread, does nothing. */ virtual void OnExit(); }; %% module #include "dkwxtrace.h" $!trace-include /** wxChar keywords used in this module. */ static wxChar const wxdkct_trace_thread_string_colon[] = { wxT(":") }; /** Keywords used in this module. */ static dkChar const * const dkwxtrthr_kw[] = { /* 0 */ dkT("."), NULL }; static void dkwxtrthr_check_current_directory(DKCT_SRC *psrc, dkChar const *fn) { dkChar curdir[DK3_MAX_PATH]; dkChar fndir[DK3_MAX_PATH]; dkChar *ptr; $? "+ dkwxtrthr_check_current_directory" if(dk3str_len(fn) < DK3_SIZEOF(fndir,dkChar)) { dk3str_cpy(fndir, fn); ptr = dk3str_rchr(fndir, DK3_CHAR_SEP); if(ptr) { *ptr = DK3_CHAR_0; } if(dk3str_cmp(dkwxtrthr_kw[0], fndir) == 0) { psrc->curdi = 1; } else { if(dk3sf_getcwd_app(curdir,DK3_SIZEOF(curdir,dkChar),psrc->app)) { if(dk3str_cmp(curdir, fndir) == 0) { psrc->curdi = 1; } } } } $? "- dkwxtrthr_check_current_directory %d", psrc->curdi } DkWxTraceThread::DkWxTraceThread( DkWxCommunicator *comm, wxChar const * const *texts, dkChar const * const *ms, wxChar const *directory, DkWxAppHelper *ah, DKCT_OPTION_SET *o, int we, int de ) : wxThread(wxTHREAD_DETACHED) { $? "+ DkWxTraceThread::DkWxTraceThread" pComm = comm; wxe = we; dke = de; sTexts = texts; msg = ms; sDirectory = directory; pHelper = ah; app = pHelper->getApp(); dk3mem_cpy((void *)(&dkcto),(void *)o,sizeof(DKCT_OPTION_SET)); $? "- DkWxTraceThread::DkWxTraceThread" } static wxChar const testfilename[] = { wxT("Test") }; void DkWxTraceThread::runForFile(dkChar const *fn, int sufi) { char shn[DK3_MAX_PATH]; /* Short file name. */ dkChar const *pstart; /* Start of short file name. */ DKCT_SRC *psrc; /* Source structure. */ int ie; /* Input encoding. */ int ok = 0; $? "+ runForFile" pstart = dk3str_rchr(fn, DK3_CHAR_SEP); if(pstart) { pstart++; } else { pstart = fn; } ie = dk3app_get_encoding(app); if(dk3str_to_c8p_app(shn, sizeof(shn), pstart, ie, app)) { $? ". conv ok" pComm->addDkText(fn); pComm->addWxText(wxdkct_trace_thread_string_colon); pComm->nl(); psrc = dkct_tr_new(&dkcto, shn, sufi, app, fn); if(psrc) { $? ". psrc ok" (psrc->dkcto).deben = 1; psrc->msg = msg; psrc->pComm = pComm; dkwxtrthr_check_current_directory(psrc, fn); if(dkct_tr_read(psrc, fn, sufi)) { $? ". read ok" if(dkct_tr_check(psrc, fn, sufi)) { $? ". check ok" if(dkct_tr_write(psrc, fn, sufi)) { $? ". write ok" ok = 1; } } } dkct_tr_delete(psrc); psrc = NULL; } else { /* ERROR: Memory! */ pComm->addWxText(sTexts[63]); pComm->nl(); } $? ". before addWxText" pComm->addWxText(sTexts[(ok) ? 56 : 57]); $? ". after addWxText" pComm->nl(); pComm->nl(); } else { $? "! name conversion failed" /* ERROR: Can not convert file name to 8-bit characters plain! */ pComm->addWxText(sTexts[61]); pComm->addDkText(fn); pComm->addWxText(sTexts[62]); pComm->nl(); } $? "- runForFile" } void DkWxTraceThread::checkAndRunFile(dkChar const *fn, int sufi) { dkChar b1[DK3_MAX_PATH]; dkChar *xsu; dkChar const *pstart; dkChar const * const *lfdsu; $? "+ checkAndRunFile" int must_run = 1; if(dkcto.mak) { $? ". make mode, check" /* Check whether we really need to run */ if(dk3str_len(fn) < DK3_SIZEOF(b1,dkChar)) { dk3str_cpy(b1, fn); lfdsu = (dkct_str_get_dest_suffixes())[sufi]; xsu = dk3str_get_suffix(b1); if(xsu) { must_run = 0; while(*lfdsu) { *xsu = dkT('\0'); if((dk3str_len(b1) + dk3str_len(*lfdsu)) < DK3_SIZEOF(b1,dkChar)) { dk3str_cat(b1, *lfdsu); if(dk3sf_must_rebuild(b1,fn)) { must_run = 1; } } else { must_run = 1; } lfdsu++; } } } } if(must_run) { $? ". must run" runForFile(fn, sufi); } else { /* Up to date. */ pstart = dk3str_rchr(fn, DK3_CHAR_SEP); if(pstart) { pstart++; } else { pstart = fn; } pComm->addDkText(pstart); pComm->addWxText(wxdkct_trace_thread_string_colon); pComm->nl(); pComm->addWxText(sTexts[55]); pComm->nl(); pComm->nl(); } $? "- checkAndRunFile" } void DkWxTraceThread::runForDirectory(wxChar const *dirname) { dkChar bu[DK3_MAX_PATH]; wxChar fnb[DK3_MAX_PATH]; dk3_dir_t *dir; dkChar const *en; dkChar const *su; dk3_stat_t const *es; dk3_um_t nFiles; dk3_um_t cFile; dk3_um_t promille; int ai; int cc; $? "+ runForDirectory \"%ls\"", dirname cFile = DK3_UM_0; cc = 1; if(dk3wxs_to_dkstr(bu, DK3_SIZEOF(bu,dkChar), dke, dirname, wxe)) { $? ". conversion ok" dir = dk3dir_open_app(bu, app); if(dir) { $? ". dir opened" nFiles = dk3dir_get_number_of_files(dir); if(!(nFiles)) nFiles++; while(cc) { $? ". start of loop" cc = 0; if(dk3dir_get_next_file(dir)) { $? ". yet another file" cc = 1; if(cFile > nFiles) cFile = nFiles; promille = ((dk3_um_t)1000UL * cFile) / nFiles; en = dk3dir_get_fullname(dir); es = dk3dir_get_stat(dir); if((en) && (es)) { $? ". file name and stat ok" if(dk3wxs_from_dkstr(fnb, DK3_SIZEOF(fnb,wxChar), wxe, en, dke)) { pComm->setUpdates(fnb, promille); } switch((es->ft) & (~(DK3_FT_SYMLINK))) { case DK3_FT_REGULAR: { $? ". regular file" su = dk3str_get_suffix(en); if(su) { #if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 0); #else ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 1); #endif if(ai >= 0) { checkAndRunFile(en, ai); } } } break; } } cFile++; } if(!(pComm->getCanContinue())) { cc = 0; } } dk3dir_close(dir); } else { $? "! failed to open directory" /* ERROR: Failed to open directory! */ pComm->addWxText(sTexts[59]); pComm->addWxText(dirname); pComm->addWxText(sTexts[60]); pComm->nl(); } } else { $? "! conversion failed" /* ERROR: Filename conversion failed! */ pComm->addWxText(sTexts[58]); pComm->nl(); } $? "- runForDirectory" } void * DkWxTraceThread::Entry() { $? "+ Entry" #if 0 /* Simple test thread witout practical use. */ int i = 0; int cc = 1; int numbreak = -1; do { this->Sleep(100); i++; if(i >= 100) { cc = 0; } pComm->setUpdates(testfilename, (10*i)); if(pComm->getCanContinue() == 0) { if(numbreak == -1) { numbreak = i; } else { if(i >= numbreak + 15) { cc = 0; } } } pComm->addWxText(wxT("Test mit einer ganz ganz ganz ganz langen Zeile\n")); } while(cc); pComm->setRunning(0); #else /* Start message */ pComm->addWxText(sTexts[54]); if(sDirectory) { pComm->addWxText(sDirectory); } else { pComm->addWxText(sTexts[25]); } pComm->nl(); runForDirectory((sDirectory) ? sDirectory : sTexts[25]); /* Signal finished. */ pComm->setRunning(0); #endif $? "- Entry" return NULL; } void DkWxTraceThread::OnExit() { }