source: branches/port5/AWT/AWT_nds.cxx

Last change on this file was 6100, checked in by westram, 16 years ago
  • fix warning "format not a string literal and no format arguments"
    • GB_export_error → GB_export_error/GB_export_errorf
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.1 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <memory.h>
4// #include <malloc.h>
5#include <string.h>
6
7#include <aw_root.hxx>
8#include <aw_device.hxx>
9#include <aw_window.hxx>
10#include <aw_awars.hxx>
11
12#include <arbdbt.h>
13#include <awt.hxx>
14#include "awt_nds.hxx"
15#include "awt_config_manager.hxx"
16#include "awt_sel_boxes.hxx"
17
18#define NDS_PER_PAGE 10         // number of NDS definitions on each config-page
19#define NDS_PAGES     6         // how many config-pages (each has NDS_PER_PAGE definitions)
20
21#define NDS_COUNT (NDS_PER_PAGE*NDS_PAGES)    // overall number of NDS definitions
22
23#define AWAR_NDS_PAGE "tmp/viewkeys/page"
24
25#if defined(DEBUG)
26#define NDS_STRING_SIZE 200
27#else
28#define NDS_STRING_SIZE 4000
29#endif // DEBUG
30
31struct make_node_text_struct {
32    char  buf[NDS_STRING_SIZE]; // buffer used to generate output
33    char *bp;
34    int   space_left;
35
36    long count;
37    int  show_errors;           // how many errors to show
38
39    long  lengths[NDS_COUNT];   // length of generated string
40    char *dkeys[NDS_COUNT];     // database field name (may be empty)
41    bool  rek[NDS_COUNT];       // 1->key is hierarchical (e.g. 'ali_16s/data')
42    char *parsing[NDS_COUNT];   // ACI/SRT program
43    bool  at_group[NDS_COUNT];  // whether string shall appear at group NDS entries
44    bool  at_leaf[NDS_COUNT];   // whether string shall appear at leaf NDS entries
45
46    void init_buffer() {
47        bp         = buf;
48        space_left = NDS_STRING_SIZE-1;
49    }
50    char *get_buffer() {
51        bp[0] = 0;
52        return buf;
53    }
54
55    void insert_overflow_warning() {
56        awt_assert(space_left >= 0); // <0 means 'already warned'
57        while (space_left) {
58            *bp++ = ' ';
59            space_left--;
60        }
61
62        static const char *warning  = "..<truncated>";
63        static int         warn_len = 0;
64        if (!warn_len) warn_len = strlen(warning);
65
66        strcpy(buf+(NDS_STRING_SIZE-warn_len-1), warning);
67        space_left = -1;
68    }
69
70    void append(char c) {
71        if (space_left >= 1) {
72            *bp++ = c;
73            space_left--;
74        }
75        else if (!space_left) {
76            insert_overflow_warning();
77        }
78    }
79    void append(const char *str, int length = -1) {
80        awt_assert(str);
81        if (length == -1) length = strlen(str);
82        awt_assert(int(strlen(str)) == length);
83
84        if (space_left >= length) {
85            strcpy(bp, str);
86            bp         += length;
87            space_left -= length;
88        }
89        else { // space_left < length
90            if (space_left >= 0) {
91                if (space_left>0) {
92                    memcpy(bp, str, space_left);
93                    bp         += space_left;
94                    space_left  = 0;
95                }
96                insert_overflow_warning();
97            }
98        }
99    }
100
101} *awt_nds_ms = 0;
102
103inline const char *viewkeyAwarName(int i, const char *name) {
104    awt_assert(i >= 0 && i < NDS_PER_PAGE);
105    return GBS_global_string("tmp/viewkeys/viewkey_%i/%s", i, name);
106}
107
108inline AW_awar *viewkeyAwar(AW_root *aw_root,AW_default awdef,int i, const char *name, bool string_awar) {
109    const char *awar_name = viewkeyAwarName(i, name);
110    AW_awar    *awar      = 0;
111    if (string_awar) awar = aw_root->awar_string(awar_name, "", awdef);
112    else        awar      = aw_root->awar_int(awar_name, 0, awdef);
113    return awar;
114}
115
116static void map_viewkey(AW_root *aw_root, AW_default awdef, int i, GBDATA *gb_viewkey)  {
117    // maps one NDS key data to one line of the config window
118
119    GBDATA *gb_key_text = GB_entry(gb_viewkey, "key_text");
120    GBDATA *gb_pars     = GB_entry(gb_viewkey, "pars");
121    GBDATA *gb_len1     = GB_entry(gb_viewkey, "len1");
122    GBDATA *gb_group    = GB_entry(gb_viewkey, "group");
123    GBDATA *gb_leaf     = GB_entry(gb_viewkey, "leaf");
124
125    awt_assert(gb_key_text);
126    awt_assert(gb_pars);
127    awt_assert(gb_len1);
128    awt_assert(gb_group);
129    awt_assert(gb_leaf);
130
131    AW_awar *Awar;
132    Awar = viewkeyAwar(aw_root, awdef, i, "key_text", true ); Awar->map(gb_key_text);
133    Awar = viewkeyAwar(aw_root, awdef, i, "pars",     true ); Awar->map(gb_pars    );
134    Awar = viewkeyAwar(aw_root, awdef, i, "len1",     false); Awar->map(gb_len1    );
135    Awar = viewkeyAwar(aw_root, awdef, i, "group",    false); Awar->map(gb_group   );
136    Awar = viewkeyAwar(aw_root, awdef, i, "leaf",     false); Awar->map(gb_leaf    );
137}
138
139static void map_viewkeys(AW_root *aw_root, AW_CL cl_awdef, AW_CL cl_gb_main) {
140    // map visible viewkeys to internal db entries
141    static bool  initialized        = false;
142    AW_default   awdef              = (AW_default)cl_awdef;
143    GBDATA      *gb_main            = (GBDATA*)cl_gb_main;
144    AW_awar     *awar_selected_page = 0;
145
146    if (!initialized) {
147        awar_selected_page = aw_root->awar_int(AWAR_NDS_PAGE, 0);
148        awar_selected_page->add_callback(map_viewkeys, cl_awdef, cl_gb_main); // bind to self
149        initialized        = true;
150    }
151    else {
152        awar_selected_page = aw_root->awar(AWAR_NDS_PAGE);
153    }
154
155    int page = awar_selected_page->read_int();
156#if defined(DEBUG)
157    printf("map_viewkeys to page %i\n", page);
158#endif // DEBUG
159    if (page<NDS_PAGES) {
160        GB_transaction ta(gb_main);
161
162        GBDATA *gb_arb_presets = GB_search(gb_main,"arb_presets",GB_CREATE_CONTAINER);
163        GBDATA *gb_viewkey     = 0;
164       
165        int i1 = page*NDS_PER_PAGE;
166        int i2 = i1+NDS_PER_PAGE-1;
167
168        for (int i = 0; i <= i2; i++) {
169            gb_viewkey = !gb_viewkey ? GB_entry(gb_arb_presets,"viewkey") : GB_nextEntry(gb_viewkey);
170            awt_assert(i<NDS_COUNT);
171            awt_assert(gb_viewkey);
172            if (i >= i1) map_viewkey(aw_root, awdef, i-i1, gb_viewkey);
173        }
174    }
175}
176
177void create_nds_vars(AW_root *aw_root, AW_default awdef, GBDATA *gb_main) {
178    GB_push_transaction(gb_main);
179
180    GBDATA *gb_viewkey     = 0;
181    GBDATA *gb_arb_presets = GB_search(gb_main,"arb_presets",GB_CREATE_CONTAINER);
182
183    for (int i = 0; i<NDS_COUNT; ++i) {
184        gb_viewkey = !gb_viewkey ? GB_entry(gb_arb_presets,"viewkey") : GB_nextEntry(gb_viewkey);
185
186        if (!gb_viewkey) gb_viewkey = GB_create_container(gb_arb_presets,"viewkey");
187
188        {
189            int  group             = 0;
190            int  leaf              = 0;
191            bool was_group_name    = false;
192            int  default_len       = 30;
193
194            GBDATA *gb_key_text = GB_entry(gb_viewkey, "key_text");
195            if (!gb_key_text) {
196                gb_key_text        = GB_create(gb_viewkey,"key_text",GB_STRING);
197                const char *wanted = "";
198                switch(i){
199                    case 0: wanted = "name"; default_len = 12; leaf = 1; break;
200                    case 1: wanted = "full_name"; leaf = 1; break;
201                    case 2: wanted = ""; was_group_name = true; break;
202                    case 3: wanted = "acc"; default_len = 20; leaf = 1; break;
203                    case 4: wanted = "date"; break;
204                }
205                GB_write_string(gb_key_text, wanted);
206            }
207
208            if (strcmp(GB_read_char_pntr(gb_key_text), "group_name") == 0) {
209                GB_write_string(gb_key_text, "");
210                was_group_name = true; // means: change group/leaf + add 'taxonomy(1)' to ACI
211            }
212
213            GB_searchOrCreate_int(gb_viewkey, "len1", default_len); 
214            GBDATA *gb_pars = GB_searchOrCreate_string(gb_viewkey, "pars", "");
215
216            if (was_group_name) {
217                group = 1;
218                leaf  = 0;
219
220                const char *pars = GB_read_char_pntr(gb_pars);
221
222                if (pars[0] == 0) pars        = "taxonomy(1)"; // empty ACI/SRT
223                else if (pars[0] == ':') pars = GBS_global_string("taxonomy(1)|%s", pars); // was an SRT -> unsure what to do
224                else if (pars[0] == '|') pars = GBS_global_string("taxonomy(1)%s", pars); // was an ACI -> prefix taxonomy
225                else pars                     = GBS_global_string("taxonomy(1)|%s", pars); // other ACIs -> same
226
227                GB_write_string(gb_pars, pars);
228            }
229
230            {
231                GBDATA *gb_flag1 = GB_entry(gb_viewkey, "flag1");
232                if (gb_flag1) {
233                    if (GB_read_int(gb_flag1)) { // obsolete
234                        leaf = 1;
235                    }
236                    GB_ERROR error = GB_delete(gb_flag1);
237                    if (error) aw_message(error);
238                }
239            }
240
241            {
242                GBDATA *gb_inherit = GB_entry(gb_viewkey, "inherit");
243                if (gb_inherit) { // 'inherit' is old NDS style -> convert & delete
244                    if (was_group_name && GB_read_int(gb_inherit)) leaf = 1;
245                    GB_ERROR error = GB_delete(gb_inherit);
246                    if (error) aw_message(error);
247                }
248            }
249
250            GB_searchOrCreate_int(gb_viewkey, "group", group);
251            GB_searchOrCreate_int(gb_viewkey, "leaf", leaf);
252        }
253    }
254
255    aw_root->awar_string("tmp/viewkeys/key_text_select","",awdef);
256    GB_pop_transaction(gb_main);
257
258    map_viewkeys(aw_root, (AW_CL)awdef, (AW_CL)gb_main); // call once
259}
260
261void awt_pre_to_view(AW_root *aw_root){
262    char *str = aw_root->awar(AWAR_SELECT_ACISRT_PRE)->read_string();
263    char *brk = strchr(str,'#');
264    if (brk) {
265        *(brk++) = 0;
266        aw_root->awar(AWAR_SELECT_ACISRT)->write_string(brk);
267    }else{
268        aw_root->awar(AWAR_SELECT_ACISRT)->write_string(str);
269    }
270    free(str);
271}
272void AWT_create_select_srtaci_window(AW_window *aww,AW_CL awar_acisrt,AW_CL awar_short)
273{
274    AWUSE(awar_short);
275    static AW_window *win = 0;
276
277    if (!win) {
278        AW_root *aw_root = aww->get_root();
279        aw_root->awar_string(AWAR_SELECT_ACISRT);
280        aw_root->awar_string(AWAR_SELECT_ACISRT_PRE);
281        aw_root->awar(AWAR_SELECT_ACISRT)->map((char *)awar_acisrt);
282       
283        AW_window_simple *aws = new AW_window_simple;
284        aws->init( aw_root, "SRT_ACI_SELECT", "SRT_ACI_SELECT");
285        aws->load_xfig("awt/srt_select.fig");
286        aws->button_length(13);
287
288        aws->callback( AW_POPDOWN);
289        aws->at("close");
290        aws->create_button("CLOSE", "CLOSE","C");
291
292        aws->callback( AW_POPUP_HELP,(AW_CL)"acisrt.hlp");
293        aws->at("help");
294        aws->create_button("HELP", "HELP","H");
295
296        aws->at("box");
297        AW_selection_list*  id = aws->create_selection_list(AWAR_SELECT_ACISRT_PRE);
298        char *filename = AWT_unfold_path("lib/sellists/srt_aci*.sellst","ARBHOME");
299        GB_ERROR error = aws->load_selection_list(id,filename);
300        free(filename);
301        if (error) aw_message(error);
302
303        aws->at("field");
304        aws->create_text_field(AWAR_SELECT_ACISRT);
305
306        aw_root->awar(AWAR_SELECT_ACISRT_PRE)->add_callback(awt_pre_to_view);
307        awt_pre_to_view(aw_root);
308        win =  (AW_window*)aws;
309    }
310    win->activate();
311}
312
313static void nds_init_config(AWT_config_definition& cdef) {
314    for (int i = 0; i<NDS_PER_PAGE; ++i) {
315        cdef.add(viewkeyAwarName(i, "leaf"), "leaf", i);
316        cdef.add(viewkeyAwarName(i, "group"), "group", i);
317        cdef.add(viewkeyAwarName(i, "key_text"), "key_text", i);
318        cdef.add(viewkeyAwarName(i, "len1"), "len1", i);
319        cdef.add(viewkeyAwarName(i, "pars"), "pars", i);
320    }
321}
322
323static char *nds_store_config(AW_window *aww, AW_CL, AW_CL) {
324    AWT_config_definition cdef(aww->get_root());
325    nds_init_config(cdef);
326    return cdef.read();
327}
328
329static void nds_restore_config(AW_window *aww, const char *stored, AW_CL, AW_CL) {
330    AWT_config_definition cdef(aww->get_root());
331    nds_init_config(cdef);
332
333    AWT_config parsedCfg(stored);
334    if (parsedCfg.has_entry("inherit0")) {
335        aw_message("Converting stored config to new NDS format -- consider saving it again.");
336        // Note: The conversion applied here is also done in create_nds_vars()
337
338        GB_ERROR error = 0;
339
340        for (int i = 0; !error && i<NDS_COUNT; ++i) {
341            bool was_group_name = false;
342            {
343                const char *key_text_key = GBS_global_string("key_text%i", i);
344                const char *key_text     = parsedCfg.get_entry(key_text_key);
345                if (strcmp(key_text, "group_name") == 0) {
346                    was_group_name = true;
347                    parsedCfg.set_entry(key_text_key, "");
348                }
349            }
350
351            bool leaf    = false;
352            bool group   = false;
353            int  inherit = 0;
354
355            {
356                const char *inherit_key   = GBS_global_string("inherit%i", i);
357                const char *inherit_value = parsedCfg.get_entry(inherit_key);
358
359                if (inherit_value) {
360                    inherit = atoi(inherit_value);
361                    parsedCfg.delete_entry(inherit_key);
362                }
363                else {
364                    error = GB_export_errorf("Expected entry '%s' in saved config", inherit_key);
365                }
366            }
367
368            if (was_group_name) {
369                if (!error) {
370                    leaf  = inherit;
371                    group = true;
372
373                    char       *aci_key = GBS_global_string_copy("pars%i", i);
374                    const char *aci     = parsedCfg.get_entry(aci_key);
375                    char       *new_aci = 0;
376
377                    if      (aci[0] == 0)   { new_aci = strdup("taxonomy(1)"); }
378                    else if (aci[0] == '|') { new_aci = GBS_global_string_copy("taxonomy(1)%s", aci); }
379                    else                    { new_aci = GBS_global_string_copy("taxonomy(1)|%s", aci); }
380
381                    parsedCfg.set_entry(aci_key, new_aci);
382
383                    free(new_aci);
384                    free(aci_key);
385                }
386            }
387            else {
388                leaf = true;
389            }
390
391            if (!error) {
392                const char *flag1_key   = GBS_global_string("active%i", i);
393                const char *flag1_value = parsedCfg.get_entry(flag1_key);
394                if (flag1_value) {
395                    int flag1 = atoi(flag1_value);
396                    if (flag1 == 0) { leaf = group = false; }
397                    parsedCfg.delete_entry(flag1_key);
398                }
399                else {
400                    error = GB_export_errorf("Expected entry '%s' in saved config", flag1_key);
401                }
402            }
403
404            if (!error) {
405                const char *leaf_key  = GBS_global_string("leaf%i", i);
406                parsedCfg.set_entry(leaf_key, GBS_global_string("%i", int(leaf)));
407                const char *group_key = GBS_global_string("group%i", i);
408                parsedCfg.set_entry(group_key, GBS_global_string("%i", int(group)));
409            }
410        }
411
412        if (!error) {
413            char *converted_cfg_str = parsedCfg.config_string();
414            cdef.write(converted_cfg_str);
415            free(converted_cfg_str);
416        }
417        else {
418            aw_message(error);
419        }
420    }
421    else {
422        cdef.write(stored);
423    }
424}
425
426AW_window *AWT_create_nds_window(AW_root *aw_root,AW_CL cgb_main) {
427    static AW_window_simple *aws = 0;
428    if (!aws) {
429        aws = new AW_window_simple;
430        aws->init( aw_root, "NDS_PROPS", "NDS");
431        aws->load_xfig("awt/nds.fig");
432        aws->auto_space(10,5);
433
434        aws->callback( AW_POPDOWN);
435        aws->at("close");
436        aws->create_button("CLOSE", "CLOSE","C");
437
438        aws->at("help");
439        aws->callback(AW_POPUP_HELP,(AW_CL)"props_nds.hlp");
440        aws->create_button("HELP", "HELP","H");
441
442        aws->at("page");
443        aws->create_option_menu(AWAR_NDS_PAGE, "", "");
444        for (int p = 0; p < NDS_PAGES; p++) {
445            const char *text = GBS_global_string("Entries %i - %i", p*NDS_PER_PAGE+1, (p+1)*NDS_PER_PAGE);
446            aws->insert_option(text, "", p);
447        }
448        aws->update_option_menu();
449
450        AWT_insert_config_manager(aws, AW_ROOT_DEFAULT, "nds", nds_store_config, nds_restore_config, 0, 0);
451
452        // --------------------
453
454        aws->button_length(13);
455        int dummy,closey;
456        aws->at_newline();
457        aws->get_at_position( &dummy,&closey );
458
459        aws->create_button(0,"K");
460
461        aws->at_newline();
462
463        int leafx, groupx, fieldselectx, fieldx, columnx, srtx, srtux;
464
465        aws->auto_space(10,0);
466
467        int i;
468        // for (i=0;i<NDS_COUNT; i++) {
469        for (i=0;i<NDS_PER_PAGE; i++) {
470            aws->get_at_position( &leafx,&dummy );
471            aws->create_toggle(viewkeyAwarName(i, "leaf"));
472
473            aws->get_at_position( &groupx,&dummy );
474            aws->create_toggle(viewkeyAwarName(i, "group"));
475
476            {
477                char *awar_name = strdup(viewkeyAwarName(i, "key_text"));
478
479                aws->button_length(20);
480                aws->get_at_position( &fieldx,&dummy );
481                aws->create_input_field(awar_name,15);
482
483                aws->button_length(0);
484                aws->callback(AWT_popup_select_species_field_window, (AW_CL)awar_name, cgb_main); // awar_name belongs to cbs now
485                aws->get_at_position( &fieldselectx,&dummy );
486
487                char *button_id = GBS_global_string_copy("SELECT_NDS_%i", i+1);
488                aws->create_button(button_id, "N");
489                free(button_id);
490            }
491
492            aws->get_at_position( &columnx,&dummy );
493            aws->create_input_field(viewkeyAwarName(i, "len1"),4);
494
495            {
496                char *awar_name = strdup(viewkeyAwarName(i, "pars"));
497
498                aws->get_at_position( &srtx,&dummy );
499                aws->button_length(0);
500                aws->callback(AWT_create_select_srtaci_window,(AW_CL)awar_name,0); // awar_name belongs to cbs now
501                {
502                    char *button_id = GBS_global_string_copy("SELECT_SRTACI_%i", i+1);
503                    aws->create_button(button_id, "S");
504                    free(button_id);
505                }
506
507                aws->get_at_position( &srtux,&dummy );
508                aws->at_set_to(true, false, -7, 30);
509                aws->create_input_field(awar_name,40);
510            }
511
512            aws->at_unset_to();
513            aws->at_newline();
514        }
515
516        aws->at(leafx,closey);
517
518        aws->at_x(leafx);
519        aws->create_button(0,"LEAF");
520        aws->at_x(groupx);
521        aws->create_button(0,"GRP.");
522
523        aws->at_x(fieldx);
524        aws->create_button(0,"FIELD");
525
526        aws->at_x(fieldselectx);
527        aws->create_button(0,"SEL");
528
529        aws->at_x(columnx);
530        aws->create_button(0,"WIDTH");
531
532        aws->at_x(srtx);
533        aws->create_button(0,"SRT");
534
535        aws->at_x(srtux);
536        aws->create_button(0,"ACI/SRT PROGRAM");
537    }
538
539    return aws;
540}
541
542
543
544void make_node_text_init(GBDATA *gb_main){
545    GBDATA *gbz,*gbe;
546    int     count;
547
548    if (!awt_nds_ms) awt_nds_ms = (struct make_node_text_struct *) GB_calloc(sizeof(struct make_node_text_struct),1);
549
550    GBDATA *gb_arb_presets = GB_search(gb_main,"arb_presets",GB_CREATE_CONTAINER);
551    count                  = 0;
552
553    for (gbz = GB_entry(gb_arb_presets, "viewkey"); gbz; gbz  = GB_nextEntry(gbz)) {
554        /* toggle set ? */
555        bool at_leaf  = *GBT_read_int(gbz, "leaf");
556        bool at_group = *GBT_read_int(gbz, "group");
557
558
559        if (at_leaf || at_group) {
560            freeset(awt_nds_ms->dkeys[count], GB_read_string(GB_entry(gbz, "key_text")));
561
562            awt_nds_ms->rek[count]      = (GB_first_non_key_char(awt_nds_ms->dkeys[count]) != 0);
563            awt_nds_ms->lengths[count]  = *GBT_read_int(gbz, "len1");
564            awt_nds_ms->at_leaf[count]  = at_leaf;
565            awt_nds_ms->at_group[count] = at_group;
566
567            gbe = GB_entry(gbz, "pars");
568            freeset(awt_nds_ms->parsing[count], 0);
569            if (gbe && GB_read_string_count(gbe)>1 ) awt_nds_ms->parsing[count] = GB_read_string(gbe);
570            count++;
571        }
572    }
573    awt_nds_ms->show_errors = 10;
574    awt_nds_ms->count       = count;
575}
576
577enum { MNTN_COMPRESSED = 0, MNTN_SPACED = 1, MNTN_TABBED = 2 };
578
579#if defined(DEBUG)
580// #define QUOTE_NDS_STRING
581#endif // DEBUG
582
583const char *make_node_text_nds(GBDATA *gb_main, GBDATA * gbd, int mode, GBT_TREE *species, const char *tree_name)
584{
585    // mode == MNTN_COMPRESSED      compress info (no tabbing, seperate single fields by komma)
586    // mode == MNTN_SPACED          format info (using spaces)
587    // mode == MNTN_TABBED          format info (using 1 tab per column - for easy import into star-calc, excel, etc. )
588
589    awt_nds_ms->init_buffer();
590
591    if (!gbd) {
592        if (!species) return "<internal error: no tree-node, no db-entry>";
593        if (!species->name) return "<internal error: node w/o name>";
594        sprintf(awt_nds_ms->buf,"<%s>",species->name); // zombie
595        return awt_nds_ms->buf;
596    }
597
598#if defined(QUOTE_NDS_STRING)
599    awt_nds_ms->append('\'');
600#endif // QUOTE_NDS_STRING
601
602    bool    field_was_printed = false;
603    GB_BOOL is_leaf           = species ? species->is_leaf : GB_TRUE;
604
605    for (int i = 0; i < awt_nds_ms->count; i++) {
606        if (is_leaf) { if (!awt_nds_ms->at_leaf[i]) continue; }
607        else         { if (!awt_nds_ms->at_group[i]) continue; }
608
609        char *str        = 0;   // the generated string
610        bool  apply_aci  = false; // whether aci shall be applied
611        bool  align_left = true; // otherwise align right
612
613        {
614            const char *field_output = "";
615            const char *field_name   = awt_nds_ms->dkeys[i];
616
617            if (field_name[0] == 0) { // empty field_name -> only do ACI/SRT
618                apply_aci = true;
619            }
620            else { // non-empty field_name
621                GBDATA *gbe;
622                if (awt_nds_ms->rek[i]) {       /* hierarchical key */
623                    gbe = GB_search(gbd,awt_nds_ms->dkeys[i],0);
624                }
625                else {              /* flat entry */
626                    gbe = GB_entry(gbd, awt_nds_ms->dkeys[i]);
627                }
628                // silently ignore missing fields (and leave apply_aci false!)
629                if (gbe) {
630                    apply_aci = true;
631                    switch (GB_read_type(gbe)) {
632                        case GB_INT: field_output  = GBS_global_string("%li", GB_read_int(gbe)); align_left = false; break;
633                        case GB_BYTE: field_output = GBS_global_string("%i", GB_read_byte(gbe)); align_left = false; break;
634
635                        case GB_FLOAT: {
636                            const char *format = "%5.4f";
637                            if (mode == MNTN_TABBED) { // '.' -> ','
638                                char *dotted  = GBS_global_string_copy(format, GB_read_float(gbe));
639                                char *dot     = strchr(dotted, '.');
640                                if (dot) *dot = ',';
641                                field_output  = GBS_global_string("%s", dotted);
642                                free(dotted);
643                            }
644                            else {
645                                field_output = GBS_global_string(format, GB_read_float(gbe));
646                            }
647                            align_left = false;
648                            break;
649                        }
650                        case GB_STRING:
651                            field_output = GB_read_char_pntr(gbe);
652                            break;
653
654                        default : {
655                            char *as_string = GB_read_as_string(gbe);
656                            field_output    = GBS_global_string("%s", as_string);
657                            free(as_string);
658                        }
659                    }
660                }
661            }
662            str = strdup(field_output);
663        }
664
665        // apply ACI/SRT program
666
667        GB_ERROR error = 0;
668        if (apply_aci) {
669            const char *aci_srt = awt_nds_ms->parsing[i];
670            if (aci_srt) {
671                char *aci_result = GB_command_interpreter(gb_main, str, aci_srt, gbd, tree_name);
672                freeset(str, aci_result ? aci_result : GBS_global_string_copy("<error: %s>", GB_await_error()));
673            }
674        }
675
676        bool skip_display = (mode == MNTN_COMPRESSED && str[0] == 0);
677        if (!skip_display) {
678            switch (mode) {
679                case MNTN_COMPRESSED:
680                    if (!field_was_printed) break; // no komma no space if nothing printed yet
681                    awt_nds_ms->append(','); // seperate single fields by komma in compressed mode
682                    // fall-through
683                case MNTN_SPACED:
684                    awt_nds_ms->append(' '); // print at least one space if not using tabs
685                    break;
686                   
687                case MNTN_TABBED:
688                    if (i != 0) awt_nds_ms->append('\t'); // tabbed output for star-calc/excel/...
689                    break;
690                   
691                default :
692                    awt_assert(0);
693                    break;
694            }
695
696            field_was_printed = true;
697
698            int str_len = strlen(str);
699            int nds_len = awt_nds_ms->lengths[i];
700            if (str_len>nds_len) { // string is too long -> shorten
701                str[nds_len] = 0;
702                str_len      = nds_len;
703            }
704
705            if (mode == MNTN_SPACED) { // may need alignment
706                const char *spaced = GBS_global_string((align_left ? "%-*s" : "%*s"), nds_len, str);
707                awt_nds_ms->append(spaced, nds_len);
708            }
709            else {
710                awt_nds_ms->append(str, str_len);
711            }
712        }
713
714        // show first XXX errors
715        if (error && awt_nds_ms->show_errors>0) {
716            awt_nds_ms->show_errors--;
717            aw_message(error);
718        }
719
720        free(str);
721    }
722
723#if defined(QUOTE_NDS_STRING)
724    awt_nds_ms->append('\'');
725#endif // QUOTE_NDS_STRING
726
727    return awt_nds_ms->get_buffer();
728}
729
730char *make_node_text_list(GBDATA * gbd, FILE *fp)
731{
732    /* if mode==0 screen else file */
733    char       *bp;
734    const char *p;
735    GBDATA     *gbe;
736    long        i;
737    long        cp;
738    char        c = 0;
739    char        fieldname[50];
740
741    bp = awt_nds_ms->buf;
742    if (!gbd) {
743        *bp = 0;
744        return awt_nds_ms->buf;
745    }
746
747    fprintf(fp, "\n------------------- %s\n", GBT_read_name(gbd));
748
749    for (i = 0; i < awt_nds_ms->count; i++) {
750        if (awt_nds_ms->rek[i]) {       /* hierarchical key */
751            gbe = GB_search(gbd,awt_nds_ms->dkeys[i],0);
752        }else{              /* flat entry */
753            gbe = GB_entry(gbd, awt_nds_ms->dkeys[i]);
754        }
755        if (!gbe) continue;
756        /*** get field info ***/
757        switch (GB_read_type(gbe)) {
758            case GB_INT:
759                sprintf(bp, "%li", GB_read_int(gbe));
760                break;
761            case GB_STRING:
762                p = GB_read_char_pntr(gbe);
763                sprintf(bp,"%s", p);
764                break;
765            case GB_FLOAT:
766                sprintf(bp, "%4.4f", GB_read_float(gbe));
767                break;
768            default:
769                sprintf(bp,"'default:' make_node_text_list!");
770                                 break;
771        }/*switch*/
772
773        /*** get fieldname ***/
774        strcpy(fieldname, awt_nds_ms->dkeys[i]);
775
776        /*** print fieldname+begin of line ***/
777        cp = strlen (bp);
778        if (cp>=60) {
779            c = bp[60];
780            bp[60] = 0;
781        }
782        fprintf(fp,"%18s: %s\n",fieldname+1, bp);
783        if (cp>=60) bp[60] = c;
784
785        while(cp > 60) {
786            cp -= 60;
787            bp += 60;
788            if (cp>=60) {
789                c = bp[60];
790                bp[60] = 0;
791            }
792            fprintf(fp,"%18s  %s\n","", bp);
793            if (cp>=60) bp[60] = c;
794        }
795    }
796    *bp = 0;
797    return awt_nds_ms->buf;
798}
Note: See TracBrowser for help on using the repository browser.