source: tags/ms_r16q2/WINDOW/AW_root_debug.cxx

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