source: branches/profile/WINDOW/AW_root_debug.cxx

Last change on this file was 12145, checked in by westram, 10 years ago
  • reduce gtk≠motif differences
    • move check into is_wanted_callback()
File size: 17.2 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#endif
170
171    // do not open 2nd ARB_NT window (to buggy)
172    GBS_write_hash(dontCallHash, "new_window", 4);
173
174#if 1
175#if defined(WARN_TODO)
176#warning test callbacks asking questions again later
177#endif
178    GBS_write_hash(dontCallHash, "ARB_NT/tree_scale_lengths",                            5);
179    GBS_write_hash(dontCallHash, "CREATE_USER_MASK/CREATE",                              5);
180    GBS_write_hash(dontCallHash, "GDE__Import__Import_sequences_using_Readseq_slow_/GO", 5);
181    GBS_write_hash(dontCallHash, "INFO_OF_ALIGNMENT/DELETE",                             5);
182    GBS_write_hash(dontCallHash, "LOAD_SELECTION_BOX/LOAD",                              5);
183    GBS_write_hash(dontCallHash, "MULTI_PROBE/CREATE_NEW_SEQUENCE",                      5);
184    GBS_write_hash(dontCallHash, "PT_SERVER_ADMIN/KILL_ALL_SERVERS",                     5);
185    GBS_write_hash(dontCallHash, "PT_SERVER_ADMIN/KILL_SERVER",                          5);
186    GBS_write_hash(dontCallHash, "PT_SERVER_ADMIN/UPDATE_SERVER",                        5);
187    GBS_write_hash(dontCallHash, "REALIGN_DNA/REALIGN",                                  5);
188    // GBS_write_hash(dontCallHash, "SPECIES_QUERY/DELETE_LISTED",                          5);
189    GBS_write_hash(dontCallHash, "SPECIES_QUERY/DELETE_LISTED_spec",                     5);
190    GBS_write_hash(dontCallHash, "SPECIES_QUERY/SAVELOAD_CONFIG_spec",                   5);
191    GBS_write_hash(dontCallHash, "SPECIES_SELECTIONS/RENAME",                            5);
192    GBS_write_hash(dontCallHash, "SPECIES_SELECTIONS/STORE_0",                           5);
193    GBS_write_hash(dontCallHash, "del_marked",                                           5);
194    GBS_write_hash(dontCallHash, "create_group",                                         5);
195    GBS_write_hash(dontCallHash, "dcs_threshold",                                        5);
196    GBS_write_hash(dontCallHash, "NAME_SERVER_ADMIN/DELETE_OLD_NAMES_FILE",              5);
197    GBS_write_hash(dontCallHash, "detail_col_stat",                                      5);
198#endif
199
200    // don't call some close-callbacks
201    // (needed when they perform cleanup that makes other callbacks from the same window fail)
202    GBS_write_hash(dontCallHash, "ARB_IMPORT/CLOSE", 6);
203
204    GB_HASH *autodontCallHash = GBS_create_hash(100, GB_MIND_CASE);
205    GBS_hash_do_loop(dontCallHash, auto_dontcall1, autodontCallHash);
206    GBS_hash_do_loop(autodontCallHash, auto_dontcall2, dontCallHash);
207    GBS_free_hash(autodontCallHash);
208}
209
210class StringVectorArray : public ConstStrArray {
211    CallbackArray array;
212public:
213    StringVectorArray(const CallbackArray& a)
214        : array(a)
215    {
216        reserve(a.size());
217        for (CallbackArray::iterator id = array.begin(); id != array.end(); ++id) {
218            put(id->c_str());
219        }
220    }
221};
222
223inline bool exclude_key(const char *key) {
224    if (strncmp(key, "FILTER_SELECT_", 14) == 0) {
225        if (strstr(key, "/2filter/2filter/2filter/") != 0) {
226            return true;
227        }
228    }
229    else {
230        if (strstr(key, "SAVELOAD_CONFIG") != 0) return true;
231    }
232    return false;
233}
234
235inline bool is_wanted_callback(const char *key) {
236    return
237        GBS_read_hash(alreadyCalledHash, key) == 0 && // dont call twice
238        !exclude_key(key); // skip some problematic  callbacks
239}
240
241static int sortedByCallbackLocation(const char *k0, long v0, const char *k1, long v1) {
242    AW_cb *cbs0 = reinterpret_cast<AW_cb*>(v0);
243    AW_cb *cbs1 = reinterpret_cast<AW_cb*>(v1);
244
245    int cmp       = cbs0->compare(*cbs1);
246    if (!cmp) cmp = strcmp(k0, k1);
247
248    return cmp;
249}
250
251// ------------------------
252//      get_action_ids
253
254static long add_wanted_callbacks(const char *key, long value, void *cl_callbacks) {
255    if (is_wanted_callback(key)) {
256        CallbackArray *callbacks = reinterpret_cast<CallbackArray*>(cl_callbacks);
257        callbacks->push_back(string(key));
258    }
259    return value;
260}
261
262ConstStrArray *AW_root::get_action_ids() {
263    if (!dontCallHash) build_dontCallHash();
264    CallbackArray callbacks;
265    GBS_hash_do_sorted_loop(prvt->action_hash, add_wanted_callbacks, GBS_HCF_sortedByKey, &callbacks);
266    return new StringVectorArray(callbacks);
267}
268
269// --------------------------
270//      callallcallbacks
271
272size_t AW_root::callallcallbacks(int mode) {
273    // mode == -2 -> mark all as called
274    // mode == -1 -> forget called
275    // mode == 0 -> call all in alpha-order
276    // mode == 1 -> call all in reverse alpha-order
277    // mode == 2 -> call all in code-order
278    // mode == 3 -> call all in reverse code-order
279    // mode == 4 -> call all in random order
280    // mode & 8 -> repeat until no uncalled callbacks left
281
282    size_t count     = GBS_hash_count_elems(prvt->action_hash);
283    size_t callCount = 0;
284
285    aw_message(GBS_global_string("Found %zi callbacks", count));
286
287    if (!dontCallHash) build_dontCallHash();
288
289    if (mode>0 && (mode&8)) {
290        aw_message("Calling callbacks iterated");
291        for (int iter = 1; ; ++iter) { // forever
292            size_t thisCount = callallcallbacks(mode&~8); // call all in wanted order
293            aw_message(GBS_global_string("%zu callbacks were called (iteration %i)", thisCount, iter));
294            if (!thisCount) {
295                aw_message("No uncalled callbacks left");
296                break;
297            }
298
299            callCount += thisCount;
300        }
301    }
302    else if (mode == -1) {
303        forgetCalledCallbacks();
304    }
305    else {
306        CallbackArray callbacks;
307        switch (mode) {
308            case 0:
309            case 1:
310                GBS_hash_do_sorted_loop(prvt->action_hash, add_wanted_callbacks, GBS_HCF_sortedByKey, &callbacks);
311                break;
312            case 2:
313            case 3:
314                GBS_hash_do_sorted_loop(prvt->action_hash, add_wanted_callbacks, sortedByCallbackLocation, &callbacks);
315                break;
316            case -2:
317                aw_message("Marking all callbacks as \"called\"");
318            case 4:
319                GBS_hash_do_loop(prvt->action_hash, add_wanted_callbacks, &callbacks);
320                break;
321            default:
322                aw_assert(0);
323                break;
324        }
325
326        switch (mode) {
327            case -2:
328            case 0:
329            case 2: break;                          // use this order
330            case 1:
331            case 3: reverse(callbacks.begin(), callbacks.end()); break; // use reverse order
332            case 4: random_shuffle(callbacks.begin(), callbacks.end()); break; // use random order
333            default: aw_assert(0); break;           // unknown mode
334        }
335
336        count = callbacks.size();
337        aw_message(GBS_global_string("%zu callbacks were not called yet", count));
338
339        CallbackIter end = callbacks.end();
340
341        for (int pass = 1; pass <= 2; ++pass) {
342            size_t       curr = 1;
343            CallbackIter cb   = callbacks.begin();
344
345            for (; cb != end; ++cb) {
346                const char *remote_command = cb->c_str();
347                bool        this_pass      = remote_command[0] == '-' ? (pass == 2) : (pass == 1);
348
349                if (this_pass) {
350                    GBS_write_hash(alreadyCalledHash, remote_command, 1); // don't call twice
351
352                    if (mode != -2) { // -2 means "only mark as called"
353                        AW_cb *cbs    = (AW_cb *)GBS_read_hash(prvt->action_hash, remote_command);
354                        bool   skipcb = remote_command[0] == '!' || GBS_read_hash(dontCallHash, remote_command);
355
356                        if (!skipcb) {
357                            if (cbs->contains(AW_CB(AW_help_entry_pressed))) skipcb = true;
358                        }
359
360                        if (skipcb) {
361                            fprintf(stderr, "Skipped callback %zu/%zu (%s)\n", curr, count, remote_command);
362                        }
363                        else {
364                            fprintf(stderr, "Calling back %zu/%zu (%s)\n", curr, count, remote_command);
365
366                            GB_clear_error();
367
368                            cbs->run_callbacks();
369                            callCount++;
370                            process_pending_events();
371
372                            if (GB_have_error()) {
373                                fprintf(stderr, "Unhandled error in '%s': %s\n", remote_command, GB_await_error());
374                            }
375
376                            if (cbs->contains(AW_POPUP)) {
377                                fputs("Popping down windows not supported atm\n", stderr);
378                            }
379                        }
380                    }
381                }
382                else {
383                    if (pass == 1) {
384                        fprintf(stderr, "Delayed callback %zu/%zu (%s)\n", curr, count, remote_command);
385                    }
386                }
387
388                curr++;
389            }
390
391            if (pass == 1) fprintf(stderr, "Executing delayed callbacks:\n");
392        }
393
394        aw_message(GBS_global_string("%zu callbacks are marked as called now", GBS_hash_count_elems(alreadyCalledHash)));
395    }
396
397    return callCount;
398}
399
400// --------------------------------------------------------------------------------
401#endif // DEBUG
402
Note: See TracBrowser for help on using the repository browser.