source: branches/port5/PHYLO/PH_main.cxx

Last change on this file was 6072, checked in by westram, 16 years ago
  • added missing and fixed broken hotkeys
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.5 KB
Line 
1#include "phylo.hxx"
2#include "phwin.hxx"
3#include "PH_display.hxx"
4
5#include <awt_sel_boxes.hxx>
6#include <aw_preset.hxx>
7
8#include <awt.hxx>
9
10#include <cstdlib>
11#include <cstring>
12#include <iostream>
13
14using namespace std;
15
16extern void ph_view_matrix_cb(AW_window *);
17extern void ph_view_species_cb(AW_window *,AW_CL,AW_CL);
18extern void ph_view_filter_cb(AW_window *,AW_CL,AW_CL);
19extern void ph_calculate_matrix_cb(AW_window *,AW_CL,AW_CL);
20extern void PH_create_save_matrix_window(AW_root *,char *);
21extern void display_status(AW_window *,AW_CL,AW_CL);
22
23AW_HEADER_MAIN
24AW_window *create_tree_window(AW_root *aw_root);
25
26GBDATA *GLOBAL_gb_main; // global gb_main for arb_phylo
27char **filter_text;
28
29GB_ERROR ph_check_initialized() {
30    if (!PHDATA::ROOT) return "Please select alignment and press DONE";
31    return 0;
32}
33
34void create_filter_text()
35{
36    filter_text = (char **) calloc(FILTER_MODES,sizeof (char *));
37    for(int i=0;i<FILTER_MODES;i++) filter_text[i] = new char[100];
38   
39    strcpy(filter_text[DONT_COUNT],           "don't count (ignore)                              ");
40    strcpy(filter_text[SKIP_COLUMN_IF_MAX],   "if occurs most often => forget whole column       ");
41    strcpy(filter_text[SKIP_COLUMN_IF_OCCUR], "if occurs => forget whole column                  ");
42    strcpy(filter_text[COUNT_DONT_USE_MAX],   "count, but do NOT use as maximum                  ");
43    strcpy(filter_text[TREAT_AS_UPPERCASE],   "treat as uppercase character                      ");
44    strcpy(filter_text[TREAT_AS_REGULAR],     "treat as regular character                        ");
45}
46
47void startup_sequence_cb(AW_window *aww,AW_CL cd1, AW_CL cl_aww)
48{
49    PHDATA *phd;
50    char *use,*load_what;
51    AW_root *aw_root;
52
53    if(aww) aww->hide();
54    aw_root=(AW_root *) cd1;
55    // loading database
56    GB_push_transaction(GLOBAL_gb_main);
57    if(GBT_get_alignment_len(GLOBAL_gb_main,aw_root->awar("phyl/alignment")->read_string())<1) {
58        aw_root->awar("phyl/alignment")->write_string(GBT_get_default_alignment(GLOBAL_gb_main));
59    }
60    GB_pop_transaction(GLOBAL_gb_main);
61
62    use = aw_root->awar("phyl/alignment")->read_string();
63    load_what = aw_root->awar("phyl/which_species")->read_string();   // all, marked ...
64    phd=new PHDATA(aw_root);
65    GB_set_cache_size(GLOBAL_gb_main, PH_DB_CACHE_SIZE);
66    phd->load(use);
67    phd->ROOT = phd;
68    long len = PHDATA::ROOT->get_seq_len();
69    aw_root->awar("phyl/filter/stopcol")->write_int(len );
70    aw_root->awar("phyl/filter/startcol")->set_minmax(0,len);
71    aw_root->awar("phyl/filter/stopcol")->set_minmax(0,len);
72
73    ((AW_window*)cl_aww)->activate(); // pop up main window
74    ph_view_species_cb(0,0,0);
75}
76
77ATTRIBUTED(__ATTR__NORETURN, static void ph_exit(AW_window *aw_window, PH_root *ph_root))
78{
79    AWUSE(aw_window);
80    GBDATA *gb_main = ph_root->gb_main;
81    if (gb_main) {
82        aw_window->get_root()->unlink_awars_from_DB(gb_main);
83#if defined(DEBUG)
84        AWT_browser_forget_db(gb_main);
85#endif // DEBUG
86        GB_close(gb_main);
87    }
88    exit(0);
89}
90
91
92void expose_callb(AW_window *aw,AW_CL cd1,AW_CL cd2)
93{
94    AWUSE(aw);AWUSE(cd1);AWUSE(cd2);
95
96    if(PH_display::ph_display->displayed()!=NONE)
97    {
98        PH_display::ph_display->clear_window();
99        PH_display::ph_display->display();
100    }
101    else    // startup
102    {
103        //startup_sequence_cb(0,aw->get_root());
104    }
105} // expose_callb
106
107
108void resize_callb(AW_window *aw,AW_CL cd1,AW_CL cd2)
109{
110    AWUSE(aw);AWUSE(cd1);AWUSE(cd2);
111    if(PH_display::ph_display)
112    {
113        PH_display::ph_display->resized();
114        PH_display::ph_display->display();
115    }
116}
117//                           total_cells_horiz=PHDATA::ROOT->get_seq_len();
118//                            { if(PHDATA::ROOT->markerline[x]>=0.0)
119
120static GB_ERROR PH_create_ml_multiline_SAI(GB_CSTR sai_name, int nr, GBDATA **gb_sai_ptr) {
121    GBDATA   *gb_sai = GBT_find_or_create_SAI(GLOBAL_gb_main, sai_name);
122    GBDATA   *gbd, *gb2;
123    GB_ERROR  error  = ph_check_initialized();
124
125    if (!error) {
126        for (gbd = GB_child(gb_sai); gbd; gbd = gb2) {
127            gb2 = GB_nextChild(gbd);
128
129            const char *key = GB_read_key_pntr(gbd);
130            if (!strcmp(key,"name")) continue;
131            if (!strncmp(key,"ali_",4)) continue;
132           
133            error = GB_delete(gbd);
134            if (error) break;
135        }
136    }
137
138    if (!error) {
139        GBDATA *gb_ali = GB_search(gb_sai,PHDATA::ROOT->use,GB_FIND);
140        if (gb_ali) {
141            for (gbd = GB_child(gb_ali); gbd; gbd = gb2) {
142                gb2 = GB_nextChild(gbd);
143
144                const char *key = GB_read_key_pntr(gbd);
145                if (!strcmp(key,"data")) continue;
146                if (!strcmp(key,"_TYPE")) continue;
147               
148                error = GB_delete(gbd);
149                if (error) break;
150            }
151        }
152    }
153
154    GBDATA *gb_data = 0, *gb_TYPE = 0;
155
156    if (!error) {
157        gb_data             = GBT_add_data(gb_sai,PHDATA::ROOT->use,"data",GB_STRING);
158        if (!gb_data) error = GB_await_error();
159    }
160
161    if (!error) {
162        gb_TYPE             = GBT_add_data(gb_sai,PHDATA::ROOT->use,"_TYPE",GB_STRING);
163        if (!gb_TYPE) error = GB_await_error();
164    }
165
166    if (!error && !PHDATA::ROOT->markerline) {
167        error = "Nothing calculated yet";
168    }
169
170    if (!error) {
171        char *full_save_name = 0;
172        FILE *saveResults    = 0;
173        if (nr == 2) {
174            char *save_name = GB_unique_filename("conservationProfile", "gnu");
175            saveResults     = GB_fopen_tempfile(save_name, "w+", &full_save_name);
176            GB_remove_on_exit(full_save_name);
177            free(save_name);
178
179            if (!saveResults) error = GB_await_error();
180        }
181
182        if (!error) {
183            AW_window *main_win   = PH_used_windows::windowList->phylo_main_window;
184            long       minhom     = main_win->get_root()->awar("phyl/filter/minhom")->read_int();
185            long       maxhom     = main_win->get_root()->awar("phyl/filter/maxhom")->read_int();
186            long       startcol   = main_win->get_root()->awar("phyl/filter/startcol")->read_int();
187            long       stopcol    = main_win->get_root()->awar("phyl/filter/stopcol")->read_int();
188            float     *markerline = PHDATA::ROOT->markerline;
189            long       len        = PHDATA::ROOT->get_seq_len();
190
191            char *data = (char *)calloc(sizeof(char),(int)len+1);
192            int   cnt  = 0;
193
194
195            for (int x=0;x<len;x++) {
196                char c;
197
198                if (x<startcol || x>stopcol) {
199                    c = '.';
200                }
201                else  {
202                    float ml = markerline[x];
203                    if (nr==2 && ml>0.0) {
204                        ph_assert(saveResults);
205                        fprintf(saveResults, "%i\t%.2f\n", cnt, ml);
206                        cnt++;
207                    }
208
209                    if (ml>=0.0 && ml>=minhom && ml<=maxhom) {
210                        int digit = -1;
211                        switch (nr) {
212                            case 0: // hundred
213                                if (ml>=100.0) digit = 1;
214                                break;
215                            case 1: // ten
216                                if (ml>=10.0) digit = int(ml/10);
217                                break;
218                            case 2: // one
219                                digit = int(ml);
220                                break;
221                            default:
222                                gb_assert(0);
223                                break;
224                        }
225                       
226                        if (digit<0) c = '-';
227                        else         c = '0' + digit%10;
228                    }
229                    else {
230                        c = '-';
231                    }
232                }
233
234                data[x] = c;
235            }
236            data[len] = 0;
237
238            if (saveResults) {
239                fclose(saveResults);
240                fprintf(stderr, "Note: Frequencies as well saved to '%s'\n", full_save_name);
241            }
242
243            error = GB_write_string(gb_data, data);
244            if (!error) {
245                const char *buffer = GBS_global_string("FMX: Filter by Maximum Frequency: "
246                                                       "Start %li; Stop %li; Minhom %li%%; Maxhom %li%%",
247                                                       startcol, stopcol, minhom, maxhom);
248                error = GB_write_string(gb_TYPE, buffer);
249            }
250            free(data);
251        }
252        free(full_save_name);
253    }
254
255    if (!error) *gb_sai_ptr = gb_sai;
256    return error;
257}
258
259void PH_save_ml_multiline_cb(AW_window *aww) {
260    GB_begin_transaction(GLOBAL_gb_main);
261    GB_ERROR error = 0;
262    char *fname = aww->get_root()->awar("tmp/phylo/markerlinename")->read_string();
263    int fname_len = strlen(fname);
264    {
265        char *digit_appended = (char*)malloc(fname_len+2);
266        memcpy(digit_appended, fname, fname_len);
267        strcpy(digit_appended+fname_len, "0");
268
269        freeset(fname, digit_appended);
270    }
271    GBDATA *gb_sai[3];
272    int i;
273    for (i=0; !error && i<3; i++) {
274        fname[fname_len] = '0'+i;
275        error = PH_create_ml_multiline_SAI(fname, i, &gb_sai[i]);
276    }
277
278    delete fname;
279
280    if (error) {
281        GB_abort_transaction(GLOBAL_gb_main);
282        aw_message(error);
283    }else{
284        GB_commit_transaction(GLOBAL_gb_main);
285    }
286}
287
288void PH_save_ml_cb(AW_window *aww) {
289    GB_begin_transaction(GLOBAL_gb_main);
290    GB_ERROR error = 0;
291
292    char   *fname  = aww->get_root()->awar("tmp/phylo/markerlinename")->read_string();
293    GBDATA *gb_sai = GBT_find_or_create_SAI(GLOBAL_gb_main,fname);
294    GBDATA *gbd,*gb2;
295
296    error = ph_check_initialized();
297
298    if (!error) {
299        for (gbd = GB_child(gb_sai); gbd; gbd = gb2) {
300            gb2 = GB_nextChild(gbd);
301
302            const char *key = GB_read_key_pntr(gbd);
303            if (!strcmp(key,"name")) continue;
304            if (!strncmp(key,"ali_",4)) continue;
305           
306            error = GB_delete(gbd);
307            if (error) break;
308        }
309    }
310
311    if (!error) {
312        GBDATA *gb_ali = GB_search(gb_sai,PHDATA::ROOT->use,GB_FIND);
313        if (gb_ali) {
314            for (gbd = GB_child(gb_ali); gbd; gbd = gb2) {
315                gb2 = GB_nextChild(gbd);
316
317                const char *key = GB_read_key_pntr(gbd);
318                if (!strcmp(key,"bits")) continue;
319                if (!strcmp(key,"_TYPE")) continue;
320               
321                error = GB_delete(gbd);
322                if (error) break;
323            }
324        }
325    }
326
327    GBDATA *gb_bits = 0, *gb_TYPE = 0;
328
329    if (!error) {
330        gb_bits             = GBT_add_data(gb_sai,PHDATA::ROOT->use,"bits",GB_BITS);
331        if (!gb_bits) error = GB_await_error();
332    }
333
334    if (!error) {
335        gb_TYPE             = GBT_add_data(gb_sai,PHDATA::ROOT->use,"_TYPE",GB_STRING);
336        if (!gb_TYPE) error = GB_await_error();
337    }
338
339    if (!error && !PHDATA::ROOT->markerline) {
340        error = "Nothing calculated yet";
341    }
342
343    if (!error) {
344        AW_window *main_win   = PH_used_windows::windowList->phylo_main_window;
345        long       minhom     = main_win->get_root()->awar("phyl/filter/minhom")->read_int();
346        long       maxhom     = main_win->get_root()->awar("phyl/filter/maxhom")->read_int();
347        long       startcol   = main_win->get_root()->awar("phyl/filter/startcol")->read_int();
348        long       stopcol    = main_win->get_root()->awar("phyl/filter/stopcol")->read_int();
349        long       len        = PHDATA::ROOT->get_seq_len();
350        char      *bits       = (char *)calloc(sizeof(char),(int)len+1);
351        int        x;
352        float     *markerline = PHDATA::ROOT->markerline;
353
354        for (x=0;x<len;x++) {
355            int bit;
356
357            if (x < startcol || x>stopcol) {
358                bit = 0;
359            }
360            else {
361                float ml = markerline[x];
362
363                if (ml>=0.0 && ml>=minhom && ml<=maxhom) bit = 1;
364                else                     bit = 0;
365
366            }
367            bits[x] = '0'+bit;
368        }
369
370        GB_write_bits(gb_bits,bits,len, "0");
371        char buffer[1024];
372        sprintf(buffer,"FMX: Filter by Maximum Frequency: "
373                "Start %li; Stop %li; Minhom %li%%; Maxhom %li%%",
374                startcol, stopcol, minhom, maxhom);
375
376        GB_write_string(gb_TYPE,buffer);
377
378        free(bits);
379    }
380    free(fname);
381
382    if (error) {
383        GB_abort_transaction(GLOBAL_gb_main);
384        aw_message(error);
385    }else{
386        GB_commit_transaction(GLOBAL_gb_main);
387    }
388}
389
390
391AW_window *PH_save_markerline(AW_root *root, AW_CL cl_multi_line)
392{
393    int multi_line = int(cl_multi_line); // ==1 -> save three SAI's usable as column percentage
394
395    root->awar_string("tmp/phylo/markerlinename","markerline",AW_ROOT_DEFAULT);
396
397    AW_window_simple *aws = new AW_window_simple;
398
399    if (multi_line) {
400        aws->init( root, "EXPORT_FREQUENCY_LINES", "Export Frequency Lines");
401    }
402    else {
403        aws->init( root, "EXPORT_MARKER_LINE", "Export Marker Line");
404    }
405
406    aws->load_xfig("phylo/save_markerline.fig");
407
408    aws->callback( AW_POPDOWN);
409    aws->at("close");
410    aws->create_button("CLOSE","CLOSE","C");
411
412    aws->callback( AW_POPUP_HELP,(AW_CL)"ph_export_markerline.hlp");
413    aws->at("help");
414    aws->create_button("HELP","HELP","H");
415
416    aws->at("name");
417    aws->create_input_field("tmp/phylo/markerlinename");
418
419    aws->at("box");
420    awt_create_selection_list_on_extendeds(GLOBAL_gb_main,aws,"tmp/phylo/markerlinename");
421
422    aws->at("save");
423    if (multi_line)     aws->callback(PH_save_ml_multiline_cb);
424    else        aws->callback(PH_save_ml_cb);
425    aws->create_button("EXPORT","EXPORT","E");
426
427    return aws;
428}
429
430AW_window *create_phyl_main_window(AW_root *aw_root,PH_root *ph_root,AWT_graphic * awd)
431{
432    AWUSE(awd);
433    AW_window_menu_modes *awm = new AW_window_menu_modes();
434    awm->init(aw_root,"ARB_PHYLO", "ARB_PHYLO", 830,630);
435
436    // create menues and menu inserts with callbacks
437    //
438
439    AW_gc_manager gcmiddle = AW_manage_GC( awm,
440                                           awm->get_device (AW_MIDDLE_AREA),
441                                           PH_GC_0, PH_GC_0_DRAG, AW_GCM_DATA_AREA,
442                                           resize_callb, 0,0,
443                                           false, // no color groups
444                                           "#CC9AF8",
445                                           "#SEQUENCE$#000000",
446                                           "#MARKER$#FF0000",
447                                           "NOT_MARKER$#A270C0",
448                                           NULL);
449    AW_gc_manager gcbottom = AW_manage_GC( awm,
450                                           awm->get_device (AW_BOTTOM_AREA),
451                                           PH_GC_0, PH_GC_0_DRAG, AW_GCM_WINDOW_AREA,
452                                           resize_callb, 0,0,
453                                           false, // no color groups
454                                           "pink",
455                                           "#FOOTER",NULL);
456
457    GBUSE(gcbottom);
458
459#if defined(DEBUG)
460    AWT_create_debug_menu(awm);
461#endif // DEBUG
462   
463    // File menu
464    awm->create_menu("File","F");
465    awm->insert_menu_topic("export_filter", "Export Filter",      "E", "ph_export_markerline.hlp", AWM_ALL, (AW_CB)AW_POPUP, (AW_CL)PH_save_markerline, 0);
466    awm->insert_menu_topic("export_freq",   "Export Frequencies", "F", "ph_export_markerline.hlp", AWM_ALL, (AW_CB)AW_POPUP, (AW_CL)PH_save_markerline, 1);
467    awm->insert_menu_topic("quit",          "Quit",               "Q", "quit.hlp",                 AWM_ALL, (AW_CB)ph_exit,  (AW_CL)ph_root,            0);
468
469    // Calculate menu
470    awm->create_menu("Calculate","C" );
471    awm->insert_menu_topic("calc_column_filter", "Column Filter", "F", "no help", AWM_ALL, (AW_CB2)ph_view_filter_cb, (AW_CL)0, (AW_CL)0);
472
473    // Config menu
474    awm->create_menu("Config","o");
475    awm->insert_menu_topic("config_column_filter", "Column Filter", "F", "no help", AWM_ALL, AW_POPUP, (AW_CL)PH_create_filter_window, 0);
476
477    // Properties menu
478    awm->create_menu("Properties","P");
479    awm->insert_menu_topic("props_menu", "Menu: Colors and Fonts ...",                 "M", "props_frame.hlp",   AWM_ALL, AW_POPUP,(AW_CL)AW_preset_window,    0)     ;
480    awm->insert_menu_topic("props_data", "Data: Colors and Fonts ...",                 "D", "ph_props_data.hlp", AWM_ALL, AW_POPUP,(AW_CL)AW_create_gc_window, (AW_CL)gcmiddle );
481    awm->insert_menu_topic("save_props", "Save Properties (in ~/.arb_prop/phylo.arb)", "S", "savedef.hlp",       AWM_ALL,          (AW_CB)AW_save_defaults,    0, 0)  ;
482
483
484    // set window areas
485    awm->set_info_area_height( 30 );
486    awm->at(5,2);
487    awm->auto_space(5,-2);
488
489    awm->callback( (AW_CB1)ph_exit ,(AW_CL)ph_root);
490    awm->button_length(0);
491    awm->help_text("quit.hlp");
492    awm->create_button("QUIT","QUIT");
493
494    awm->callback(AW_POPUP_HELP,(AW_CL)"phylo.hlp");
495    awm->button_length(0);
496    awm->create_button("HELP","HELP","H");
497
498
499    awm->set_bottom_area_height( 120 );
500
501    awm->set_expose_callback(AW_MIDDLE_AREA, expose_callb,   (AW_CL)awm,     0);
502    awm->set_resize_callback(AW_MIDDLE_AREA, resize_callb,   (AW_CL)awm,     0);
503    awm->set_expose_callback(AW_BOTTOM_AREA, display_status, (AW_CL)aw_root, 0);
504    awm->set_resize_callback(AW_BOTTOM_AREA, display_status, (AW_CL)aw_root, 0);
505
506    return (AW_window *)awm;
507}
508
509
510AW_window *create_select_alignment_window(AW_root *aw_root, AW_CL cl_aww)
511{
512    AW_window_simple *aws = new AW_window_simple;
513
514    aws->init( aw_root,"SELECT_ALIGNMENT", "SELECT ALIGNMENT");
515    aws->load_xfig("phylo/select_ali.fig");
516    aws->button_length(10);
517
518    aws->at("done");
519    aws->callback(startup_sequence_cb,(AW_CL) aw_root, cl_aww);
520    aws->create_button("DONE","DONE","D");
521
522    aws->at("which_alignment");
523    awt_create_selection_list_on_ad(GLOBAL_gb_main,(AW_window *)aws,"phyl/alignment","*=");
524    return (AW_window *) aws;
525}
526
527
528
529PH_used_windows::PH_used_windows(void)
530{
531    memset((char *) this,0,sizeof(PH_used_windows));
532}
533
534// initialize 'globals'
535PH_used_windows *PH_used_windows::windowList = 0;
536PH_display *PH_display::ph_display=0;
537PHDATA *PHDATA::ROOT = 0;
538
539
540int
541main(int argc, char **argv)
542{
543    if (argc > 2 || (argc == 2 && strcmp(argv[1], "--help") == 0)) {
544        fprintf(stderr, "Usage: arb_phylo [database]\n");
545        return EXIT_FAILURE;
546    }
547
548    PH_root          *ph_root;
549    AW_root          *aw_root;
550    char            **alignment_names;
551    GB_ERROR          error     = 0;
552    AW_default        aw_default;
553    PH_used_windows  *puw       = new PH_used_windows;
554    PH_display       *phd       = new PH_display;
555    int               num_alignments;
556    const char       *db_server = (argc == 2 ? argv[1] : ":");
557
558    aw_initstatus();
559    aw_root = new AW_root;
560    aw_default = aw_root->open_default(".arb_prop/phylo.arb");
561    aw_root->init_variables(aw_default);
562    aw_root->init_root("ARB_PHYLO", false);
563
564    if (argc == 2) {
565        db_server = argv[1];
566    }
567    ph_root = new PH_root;
568    if ((error = ph_root->open(db_server))) { // initializes global 'GLOBAL_gb_main'
569        aw_message(error);
570        exit(-1);
571    }
572
573    // create arb_phylo awars :
574    PH_create_filter_variables(aw_root, aw_default);
575    PH_create_matrix_variables(aw_root, aw_default);
576    ARB_init_global_awars(aw_root, aw_default, GLOBAL_gb_main);
577#if defined(DEBUG)
578    AWT_create_db_browser_awars(aw_root, aw_default);
579#endif // DEBUG
580
581#if defined(DEBUG)
582    AWT_announce_db_to_browser(GLOBAL_gb_main, GBS_global_string("ARB-database (%s)", db_server));
583#endif // DEBUG
584
585    create_filter_text();
586
587    // create main window :
588
589    puw->phylo_main_window = create_phyl_main_window(aw_root, ph_root, 0);
590    puw->windowList        = puw;
591
592    // exposing the main window is now done from inside startup_sequence_cb()
593    // (otherwise it crashes during resize because the resize callback gets
594    // called before startup_sequence_cb initialized the necessary data)
595    //
596    // puw->phylo_main_window->show();
597
598    phd->ph_display = phd;
599
600    //loading database
601    GB_push_transaction(GLOBAL_gb_main);
602    alignment_names = GBT_get_alignment_names(GLOBAL_gb_main);
603
604    for (num_alignments = 0; alignment_names[num_alignments] != 0; num_alignments++) ;
605    if (num_alignments > 1) {
606        AW_window *sel_ali_aww = create_select_alignment_window(aw_root, (AW_CL)puw->phylo_main_window);
607        sel_ali_aww->show();
608    }
609    else {
610        aw_root->awar("phyl/alignment")->write_string( alignment_names[0]);
611        startup_sequence_cb(0, (AW_CL)aw_root, (AW_CL)puw->phylo_main_window);
612    }
613    GBT_free_names(alignment_names);
614    GB_pop_transaction(GLOBAL_gb_main);
615
616    aw_root->main_loop();
617    return EXIT_SUCCESS;
618}
619
620
621
622void AD_map_viewer(GBDATA *dummy,AD_MAP_VIEWER_TYPE)
623    {
624    AWUSE(dummy);
625}
Note: See TracBrowser for help on using the repository browser.