source: branches/help/WINDOW/AW_root_debug.cxx

Last change on this file was 18665, checked in by westram, 3 years ago
  • change many WARN_TODO triggered warnings into todo markers.
File size: 17.4 KB
Line 
1// =========================================================== //
2//                                                             //
3//   File      : AW_root_debug.cxx                             //
4//   Purpose   :                                               //
5//                                                             //
6//   Coded by Ralf Westram (coder@reallysoft.de) in May 2009   //
7//   Institute of Microbiology (Technical University Munich)   //
8//   http://www.arb-home.de/                                   //
9//                                                             //
10// =========================================================== //
11
12#include "aw_window.hxx"
13#include "aw_Xm.hxx"
14#include "aw_window_Xm.hxx"
15#include "aw_root.hxx"
16#include "aw_msg.hxx"
17
18#include <arbdbt.h>
19#include <arb_strarray.h>
20
21#include <vector>
22#include <iterator>
23#include <string>
24#include <algorithm>
25
26// do includes above (otherwise depends depend on DEBUG)
27
28#if defined(DEBUG)
29// --------------------------------------------------------------------------------
30
31using namespace std;
32
33typedef vector<string> CallbackArray;
34typedef CallbackArray::const_iterator CallbackIter;
35
36static GB_HASH *dontCallHash      = NULp;
37static GB_HASH *alreadyCalledHash = NULp;
38
39static void forgetCalledCallbacks() {
40    if (alreadyCalledHash) GBS_free_hash(alreadyCalledHash);
41    alreadyCalledHash = GBS_create_hash(2500, GB_MIND_CASE);
42}
43
44static void auto_dontcall1(const char *key, long value, void *cl_hash) {
45    if (strncmp(key, "ARB_NT/", 7) == 0) {
46        GB_HASH *autodontCallHash = (GB_HASH*)cl_hash;
47        GBS_write_hash(autodontCallHash, GBS_global_string("ARB_NT_1/%s", key+7), value);
48    }
49}
50static void auto_dontcall2(const char *key, long value, void *) {
51    GBS_write_hash(dontCallHash, key, value);
52}
53
54static void forget_dontCallHash() {
55    if (dontCallHash) {
56        GBS_free_hash(dontCallHash);
57        GBS_free_hash(alreadyCalledHash);
58        dontCallHash = NULp;
59    }
60}
61
62static void build_dontCallHash() {
63    aw_assert(!dontCallHash);
64    dontCallHash = GBS_create_hash(100, GB_MIND_CASE);
65    forgetCalledCallbacks();
66
67    atexit(forget_dontCallHash);
68
69    // avoid program termination/restart/etc.
70    GBS_write_hash(dontCallHash, "ARB_NT/QUIT",                 1);
71    GBS_write_hash(dontCallHash, "quit",                        1);
72    GBS_write_hash(dontCallHash, "new_arb",                     1);
73    GBS_write_hash(dontCallHash, "restart_arb",                 1);
74    GBS_write_hash(dontCallHash, "ARB_EDIT4/QUIT",              1);
75    GBS_write_hash(dontCallHash, "ARB_INTRO/CANCEL",            1);
76    GBS_write_hash(dontCallHash, "NEIGHBOUR_JOINING/CLOSE",     1);
77    GBS_write_hash(dontCallHash, "MERGE_SELECT_DATABASES/QUIT", 1);
78    GBS_write_hash(dontCallHash, "quitnstart",                  1);
79    GBS_write_hash(dontCallHash, "PARS_PROPS/ABORT",            1);
80    GBS_write_hash(dontCallHash, "ARB_PHYLO/QUIT",              1);
81    GBS_write_hash(dontCallHash, "SELECT_ALIGNMENT/ABORT",      1);
82
83    // avoid start of some external programs:
84#if 1
85    GBS_write_hash(dontCallHash, "GDE__User__Start_a_slave_ARB_on_a_foreign_host_/GO",         2);
86    GBS_write_hash(dontCallHash, "NAME_SERVER_ADMIN/REMOVE_SUPERFLUOUS_ENTRIES_IN_NAMES_FILE", 2);
87    GBS_write_hash(dontCallHash, "GDE__Print__Pretty_print_sequences_slow_/GO",                2);
88
89    GBS_write_hash(dontCallHash, "ARB_NT/EDIT_SEQUENCES",             2);
90    GBS_write_hash(dontCallHash, "merge_from",                        2);
91    GBS_write_hash(dontCallHash, "CPR_MAIN/HELP",                     2);
92    GBS_write_hash(dontCallHash, "HELP/BROWSE",                       2);
93    GBS_write_hash(dontCallHash, "mailing_list",                      2);
94    GBS_write_hash(dontCallHash, "bug_report",                        2);
95    GBS_write_hash(dontCallHash, "HELP/EDIT",                         2);
96    GBS_write_hash(dontCallHash, "MACROS/EDIT",                       2);
97    GBS_write_hash(dontCallHash, "MACROS/EXECUTE",                    2);
98    GBS_write_hash(dontCallHash, "NAME_SERVER_ADMIN/EDIT_NAMES_FILE", 2);
99    GBS_write_hash(dontCallHash, "arb_dist",                          2);
100    GBS_write_hash(dontCallHash, "arb_pars",                          2);
101    GBS_write_hash(dontCallHash, "arb_pars_quick",                    2);
102    GBS_write_hash(dontCallHash, "arb_phyl",                          2);
103    GBS_write_hash(dontCallHash, "count_different_chars",             2);
104    GBS_write_hash(dontCallHash, "corr_mutat_analysis",               2);
105    GBS_write_hash(dontCallHash, "export_to_ARB",                     2);
106    GBS_write_hash(dontCallHash, "new2_arb_edit4",                    2);
107    GBS_write_hash(dontCallHash, "new_arb_edit4",                     2);
108    GBS_write_hash(dontCallHash, "primer_design",                     2);
109    GBS_write_hash(dontCallHash, "xterm",                             2);
110    GBS_write_hash(dontCallHash, "SUBMIT_REG/SEND",                   2);
111    GBS_write_hash(dontCallHash, "SUBMIT_BUG/SEND",                   2);
112    GBS_write_hash(dontCallHash, "PRINT_CANVAS/PRINT",                2);
113    GBS_write_hash(dontCallHash, "PT_SERVER_ADMIN/CREATE_TEMPLATE",   2);
114    GBS_write_hash(dontCallHash, "PT_SERVER_ADMIN/EDIT_LOG",          2);
115    GBS_write_hash(dontCallHash, "NAME_SERVER_ADMIN/CREATE_TEMPLATE", 2);
116    GBS_write_hash(dontCallHash, "SELECT_CONFIGURATION/START",        2);
117    GBS_write_hash(dontCallHash, "EXPORT_TREE_AS_XFIG/START_XFIG",    2);
118    GBS_write_hash(dontCallHash, "EXPORT_NDS_OF_MARKED/PRINT",        2);
119    GBS_write_hash(dontCallHash, "ALIGNER_V2/GO",                     2);
120    GBS_write_hash(dontCallHash, "SINA/Start",                        2);
121#endif
122
123    // avoid saving
124    GBS_write_hash(dontCallHash, "save_changes",           3);
125    GBS_write_hash(dontCallHash, "save_props",             3);
126    GBS_write_hash(dontCallHash, "save_alitype_props",     3);
127    GBS_write_hash(dontCallHash, "save_alispecific_props", 3);
128    GBS_write_hash(dontCallHash, "save_DB1",               3);
129    GBS_write_hash(dontCallHash, "SAVE_DB/SAVE",           3);
130    GBS_write_hash(dontCallHash, "ARB_NT/SAVE",            3);
131    GBS_write_hash(dontCallHash, "ARB_NT/SAVE_AS",         3);
132    GBS_write_hash(dontCallHash, "ARB_NT/QUICK_SAVE_AS",   3);
133
134    GBS_write_hash(dontCallHash, "User1_search_1/SAVE",            3);
135    GBS_write_hash(dontCallHash, "User2_search_1/SAVE",            3);
136    GBS_write_hash(dontCallHash, "Probe_search_1/SAVE",            3);
137    GBS_write_hash(dontCallHash, "Primer_local_search_1/SAVE",     3);
138    GBS_write_hash(dontCallHash, "Primer_region_search_1/SAVE",    3);
139    GBS_write_hash(dontCallHash, "Primer_global_search_1/SAVE",    3);
140    GBS_write_hash(dontCallHash, "Signature_local_search_1/SAVE",  3);
141    GBS_write_hash(dontCallHash, "Signature_region_search_1/SAVE", 3);
142    GBS_write_hash(dontCallHash, "Signature_global_search_1/SAVE", 3);
143
144    // avoid confusion by recording, executing or deleting macros
145    GBS_write_hash(dontCallHash, "MACROS/DELETE",       1);
146    GBS_write_hash(dontCallHash, "MACROS/EDIT",         1);
147    GBS_write_hash(dontCallHash, "MACROS/EXECUTE",      1);
148    GBS_write_hash(dontCallHash, "MACROS/macro_record", 1);
149
150#if 1
151    // @@@ crashing - fix later
152    GBS_write_hash(dontCallHash, "ARB_NT/view_probe_group_result", 4);
153    GBS_write_hash(dontCallHash, "PT_SERVER_ADMIN/CHECK_SERVER",   4);
154    GBS_write_hash(dontCallHash, "ARB_EDIT4/SECEDIT",              4);
155    GBS_write_hash(dontCallHash, "sec_edit",                       4);
156    GBS_write_hash(dontCallHash, "ARB_EDIT4/RNA3D",                4);
157    GBS_write_hash(dontCallHash, "rna3d",                          4);
158    GBS_write_hash(dontCallHash, "reload_config",                  4);
159    GBS_write_hash(dontCallHash, "LOAD_OLD_CONFIGURATION/LOAD",    4);
160    GBS_write_hash(dontCallHash, "table_admin",                    4); // disabled in userland atm
161    GBS_write_hash(dontCallHash, "PARS_PROPS/GO",                  4); // has already been executed (designed to run only once)
162    GBS_write_hash(dontCallHash, "ARB_PARSIMONY/POP",              4); // pop does not work correctly in all cases (see #528)
163    GBS_write_hash(dontCallHash, "new_win",                        4); // 2nd editor window (blocked by #429)
164    GBS_write_hash(dontCallHash, "ARB_NT/UNDO",                    4); // doesn't crash, but caused following commands to crash
165#endif
166
167    // do not open 2nd ARB_NT window (to buggy)
168    GBS_write_hash(dontCallHash, "new_window", 4);
169
170#if 1
171    // @@@ test callbacks asking questions again later
172    GBS_write_hash(dontCallHash, "ARB_NT/tree_scale_lengths",                            5);
173    GBS_write_hash(dontCallHash, "CREATE_USER_MASK/CREATE",                              5);
174    GBS_write_hash(dontCallHash, "GDE__Import__Import_sequences_using_Readseq_slow_/GO", 5);
175    GBS_write_hash(dontCallHash, "INFO_OF_ALIGNMENT/DELETE",                             5);
176    GBS_write_hash(dontCallHash, "LOAD_SELECTION_BOX/LOAD",                              5);
177    GBS_write_hash(dontCallHash, "MULTI_PROBE/CREATE_NEW_SEQUENCE",                      5);
178    GBS_write_hash(dontCallHash, "PT_SERVER_ADMIN/KILL_ALL_SERVERS",                     5);
179    GBS_write_hash(dontCallHash, "PT_SERVER_ADMIN/KILL_SERVER",                          5);
180    GBS_write_hash(dontCallHash, "PT_SERVER_ADMIN/UPDATE_SERVER",                        5);
181    GBS_write_hash(dontCallHash, "REALIGN_DNA/REALIGN",                                  5);
182    // GBS_write_hash(dontCallHash, "SPECIES_QUERY/DELETE_LISTED",                          5);
183    GBS_write_hash(dontCallHash, "SPECIES_QUERY/DELETE_LISTED_spec",                     5);
184    GBS_write_hash(dontCallHash, "SPECIES_QUERY/SAVELOAD_CONFIG_spec",                   5);
185    GBS_write_hash(dontCallHash, "SPECIES_SELECTIONS/RENAME",                            5);
186    GBS_write_hash(dontCallHash, "SPECIES_SELECTIONS/STORE_0",                           5);
187    GBS_write_hash(dontCallHash, "del_marked",                                           5);
188    GBS_write_hash(dontCallHash, "create_group",                                         5);
189    GBS_write_hash(dontCallHash, "dcs_threshold",                                        5);
190    GBS_write_hash(dontCallHash, "NAME_SERVER_ADMIN/DELETE_OLD_NAMES_FILE",              5);
191    GBS_write_hash(dontCallHash, "detail_col_stat",                                      5);
192#endif
193
194    // don't call some close-callbacks
195    // (needed when they perform cleanup that makes other callbacks from the same window fail)
196    GBS_write_hash(dontCallHash, "ARB_IMPORT/CLOSE", 6);
197
198    GB_HASH *autodontCallHash = GBS_create_hash(100, GB_MIND_CASE);
199    GBS_hash_do_const_loop(dontCallHash, auto_dontcall1, autodontCallHash);
200    GBS_hash_do_const_loop(autodontCallHash, auto_dontcall2, dontCallHash);
201    GBS_free_hash(autodontCallHash);
202}
203
204class StringVectorArray : public ConstStrArray {
205    CallbackArray array;
206public:
207    StringVectorArray(const CallbackArray& a)
208        : array(a)
209    {
210        reserve(a.size());
211        for (CallbackArray::iterator id = array.begin(); id != array.end(); ++id) {
212            put(id->c_str());
213        }
214    }
215};
216
217inline bool exclude_key(const char *key) {
218    if (strncmp(key, "FILTER_SELECT_", 14) == 0) {
219        if (strstr(key, "/2filter/2filter/2filter/")) {
220            return true;
221        }
222    }
223    else {
224        if (strstr(key, "SAVELOAD_CONFIG")) return true;
225    }
226    return false;
227}
228
229inline bool is_wanted_callback(const char *key) {
230    return
231        GBS_read_hash(alreadyCalledHash, key) == 0 && // dont call twice
232        !exclude_key(key); // skip some problematic  callbacks
233}
234
235static int sortedByCallbackLocation(const char *k0, long v0, const char *k1, long v1) {
236    AW_cb *cbs0 = reinterpret_cast<AW_cb*>(v0);
237    AW_cb *cbs1 = reinterpret_cast<AW_cb*>(v1);
238
239    int cmp       = cbs0->compare(*cbs1);
240    if (!cmp) cmp = strcmp(k0, k1);
241
242    return cmp;
243}
244
245// ------------------------
246//      get_action_ids
247
248static void add_wanted_callbacks(const char *key, long /*val*/, void *cl_callbacks) {
249    if (is_wanted_callback(key)) {
250        CallbackArray *callbacks = reinterpret_cast<CallbackArray*>(cl_callbacks);
251        callbacks->push_back(string(key));
252    }
253}
254
255ConstStrArray *AW_root::get_action_ids() {
256    if (!dontCallHash) build_dontCallHash();
257    CallbackArray callbacks;
258    GBS_hash_do_const_sorted_loop(prvt->action_hash, add_wanted_callbacks, GBS_HCF_sortedByKey, &callbacks);
259    return new StringVectorArray(callbacks);
260}
261
262// --------------------------
263//      callallcallbacks
264
265size_t AW_root::callallcallbacks(int mode) {
266    // mode == -2 -> mark all as called
267    // mode == -1 -> forget called
268    // mode == 0 -> call all in alpha-order
269    // mode == 1 -> call all in reverse alpha-order
270    // mode == 2 -> call all in code-order
271    // mode == 3 -> call all in reverse code-order
272    // mode == 4 -> call all in random order
273    // mode & 8 -> repeat until no uncalled callbacks left
274
275    size_t count     = GBS_hash_elements(prvt->action_hash);
276    size_t callCount = 0;
277
278    aw_message(GBS_global_string("Found %zi callbacks", count));
279
280    if (!dontCallHash) build_dontCallHash();
281
282    if (mode>0 && (mode&8)) {
283        aw_message("Calling callbacks iterated");
284        for (int iter = 1; ; ++iter) { // forever
285            size_t thisCount = callallcallbacks(mode&~8); // call all in wanted order
286            aw_message(GBS_global_string("%zu callbacks were called (iteration %i)", thisCount, iter));
287            if (!thisCount) {
288                aw_message("No uncalled callbacks left");
289                break;
290            }
291
292            callCount += thisCount;
293        }
294    }
295    else if (mode == -1) {
296        forgetCalledCallbacks();
297    }
298    else {
299        CallbackArray callbacks;
300        switch (mode) {
301            case 0:
302            case 1:
303                GBS_hash_do_const_sorted_loop(prvt->action_hash, add_wanted_callbacks, GBS_HCF_sortedByKey, &callbacks);
304                break;
305            case 2:
306            case 3:
307                GBS_hash_do_const_sorted_loop(prvt->action_hash, add_wanted_callbacks, sortedByCallbackLocation, &callbacks);
308                break;
309            case -2:
310                aw_message("Marking all callbacks as \"called\"");
311                FALLTHROUGH;
312            case 4:
313                GBS_hash_do_const_loop(prvt->action_hash, add_wanted_callbacks, &callbacks);
314                break;
315            default:
316                aw_assert(0);
317                break;
318        }
319
320        switch (mode) {
321            case -2:
322            case 0:
323            case 2: break;                          // use this order
324            case 1:
325            case 3: reverse(callbacks.begin(), callbacks.end()); break; // use reverse order
326            case 4: random_shuffle(callbacks.begin(), callbacks.end()); break; // use random order
327            default: aw_assert(0); break;           // unknown mode
328        }
329
330        count = callbacks.size();
331        aw_message(GBS_global_string("%zu callbacks were not called yet", count));
332
333        CallbackIter end = callbacks.end();
334
335        for (int pass = 1; pass <= 2; ++pass) {
336            size_t       curr = 1;
337            CallbackIter cb   = callbacks.begin();
338
339            for (; cb != end; ++cb) {
340                const char *remote_command      = cb->c_str();
341                const char *remote_command_name = remote_command;
342                {
343                    const char *slash = strrchr(remote_command, '/');
344                    if (slash) remote_command_name = slash+1;
345                }
346
347                char firstNameChar = remote_command_name[0];
348                bool this_pass     = firstNameChar == '-' ? (pass == 2) : (pass == 1);
349
350                if (this_pass) {
351                    GBS_write_hash(alreadyCalledHash, remote_command, 1); // don't call twice
352
353                    if (mode != -2) { // -2 means "only mark as called"
354                        AW_cb *cbs    = (AW_cb *)GBS_read_hash(prvt->action_hash, remote_command);
355                        bool   skipcb = firstNameChar == '!' || GBS_read_hash(dontCallHash, remote_command);
356
357                        if (!skipcb) {
358                            if (cbs->contains(AnyWinCB(AW_help_entry_pressed))) skipcb = true;
359                        }
360
361                        if (skipcb) {
362                            fprintf(stderr, "Skipped callback %zu/%zu (%s)\n", curr, count, remote_command);
363                        }
364                        else {
365                            fprintf(stderr, "Calling back %zu/%zu (%s)\n", curr, count, remote_command);
366
367                            GB_clear_error();
368
369                            cbs->run_callbacks();
370                            callCount++;
371                            process_pending_events();
372
373                            if (GB_have_error()) {
374                                fprintf(stderr, "Unhandled error in '%s': %s\n", remote_command, GB_await_error());
375                            }
376                        }
377                    }
378                }
379                else {
380                    if (pass == 1) {
381                        fprintf(stderr, "Delayed callback %zu/%zu (%s)\n", curr, count, remote_command);
382                    }
383                }
384
385                curr++;
386            }
387
388            if (pass == 1) fprintf(stderr, "Executing delayed callbacks:\n");
389        }
390
391        aw_message(GBS_global_string("%zu callbacks are marked as called now", GBS_hash_elements(alreadyCalledHash)));
392    }
393
394    return callCount;
395}
396
397// --------------------------------------------------------------------------------
398#endif // DEBUG
399
Note: See TracBrowser for help on using the repository browser.