source: tags/ms_r16q2/ARBDB/adTest.cxx

Last change on this file was 14682, checked in by westram, 9 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : adTest.cxx                                        //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "gb_key.h"
12#include <arb_misc.h>
13
14const char *GB_get_db_path(GBDATA *gbd) {
15    GBDATA *gb_father = GB_FATHER(gbd);
16
17    if (gb_father) {
18        const char *father_path = GB_get_db_path(gb_father);
19        const char *key         = GB_KEY(gbd);
20        RETURN_LOCAL_ALLOC(GBS_global_string_copy("%s/%s", father_path, key ? key : "<gbmain>"));
21    }
22    return "";
23}
24
25void GB_dump_db_path(GBDATA *gbd) {
26    printf("Path to GBDATA %p (type=%s) is '%s'\n", gbd, GB_get_type_name(gbd), GB_get_db_path(gbd));
27}
28
29static void dump_internal(GBDATA *gbd, int *lines_allowed) {
30    static int     indent            = 0;
31    const char    *type_name         = GB_get_type_name(gbd);
32    const char    *key_name          = 0;
33    const char    *content           = 0;
34    unsigned long  content_len       = 0;
35    GBCONTAINER   *father            = GB_FATHER(gbd);
36    GBDATA        *gb_show_later     = 0;
37    char          *whatto_show_later = 0;
38    bool           showChildren      = true;
39
40    if (father) {
41        int             index_pos = (int)gbd->index; // my index position in father
42        gb_header_list *hls       = &(GB_DATA_LIST_HEADER(father->d)[index_pos]);
43
44        if (!hls) {
45            key_name = GBS_global_string("<no gb_header_list found for index_pos=%i>", index_pos);
46            father   = 0;                           // otherwise crash below
47        }
48        else {
49            GBDATA *gb_self = GB_HEADER_LIST_GBD(*hls);
50            if (gb_self != gbd) {
51                key_name = GBS_global_string("<element not linked in parent>");
52                if (gb_self) {
53                    gb_show_later     = gb_self;
54                    whatto_show_later = GBS_global_string_copy("Element linked at index pos of %p", gbd);
55                }
56                father = 0;                         // otherwise crash below
57            }
58            // otherwise father looks fine
59        }
60    }
61
62    if (father) {
63        bool is_db_server = GB_is_server(gbd);
64
65        if (is_db_server && gbd->server_id != GBTUM_MAGIC_NUMBER) {
66            key_name = GBS_global_string("<element with illegal server-id %p>", (void*)gbd->server_id);
67        }
68        else if (is_db_server && father->server_id != GBTUM_MAGIC_NUMBER) {
69            key_name = GBS_global_string("<elements parent has illegal server-id %p>", (void*)father->server_id);
70            father   = 0;                           // avoids crashes below
71        }
72        else {
73            key_name = GB_KEY_QUARK(gbd) ? GB_KEY(gbd) : "<illegal quark=0>";
74        }
75    }
76
77    if (!father && !key_name) {
78        key_name     = "<unknown quark - element w/o father>";
79        showChildren = false;
80    }
81    else {                                          // test if we need a transaction
82        if (GB_MAIN(gbd)->get_transaction_level() == 0) {
83            GB_push_transaction(gbd);
84            dump_internal(gbd, lines_allowed);
85            GB_pop_transaction(gbd);
86            return;
87        }
88    }
89
90    if (indent == 0) {
91        printf("\nGB_dump of '%s':\n", father ? GB_get_db_path(gbd) : "<no DB-path - father missing or not inspected>");
92        if (lines_allowed) (*lines_allowed)--;
93    }
94
95    if (father) {
96        if (GB_ARRAY_FLAGS(gbd).changed == GB_DELETED) {
97            content = "<can't examine - entry is deleted>";
98        }
99        else {
100            switch (gbd->type()) {
101                case GB_INT:    { content = GBS_global_string("%li", GB_read_int(gbd)); break; }
102                case GB_FLOAT:  { content = ARB_float_2_ascii(GB_read_float(gbd)); break; }
103                case GB_BYTE:   { content = GBS_global_string("%i", GB_read_byte(gbd)); break; }
104                case GB_STRING: { content = GB_read_char_pntr(gbd); content_len = GB_read_count(gbd); break; }
105                case GB_LINK:   { content = GBS_global_string("link to %p", GB_follow_link(gbd)); break; }
106                case GB_BITS:   { break; }
107                case GB_BYTES:  { break; }
108                case GB_INTS:   { break; }
109                case GB_FLOATS: { break; }
110                case GB_DB:     { content = "see below"; break; }
111                default:        { content = ""; break; }
112            }
113        }
114    }
115
116    if (content==0) {
117        if (GB_have_error()) {
118            content = GBS_global_string("<failed to read content (error is '%s')>", GB_await_error());
119        }
120        else {
121            content = "<illegal zero content, but no error - severe bug?!>";
122        }
123    }
124    if (content_len == 0) content_len = strlen(content);
125
126    {
127        char     *prefix  = GBS_global_string_copy("%*s %-15s gbd=%p type=%s content=", indent, "", key_name, gbd, type_name);
128        unsigned  wrappos = 500;
129        char     *toFree  = 0;
130
131        if (content_len > wrappos) {
132            toFree      = strdup(content);
133            content     = toFree;
134            content_len = GBS_shorten_repeated_data(toFree);
135        }
136
137        if (content_len <= wrappos) {
138            printf("%s'%s'\n", prefix, content);
139            if (lines_allowed) (*lines_allowed)--;
140        }
141        else {
142            char          *buffer  = (char*)malloc(wrappos+1);
143            unsigned long  rest    = content_len;
144            const char    *from    = content;
145            int            cleared = 0;
146
147            buffer[wrappos] = 0;
148            while (rest) {
149                memcpy(buffer, from, wrappos);
150                rest  = rest>wrappos ? rest-wrappos : 0;
151                from += wrappos;
152                printf("%s'%s'\n", prefix, buffer);
153                if (lines_allowed && --(*lines_allowed) <= 0) break;
154                if (!cleared) { memset(prefix, ' ', strlen(prefix)); cleared = 1; }
155            }
156            free(buffer);
157        }
158        free(prefix);
159        free(toFree);
160    }
161
162    if (gbd->is_container() && showChildren) {
163        GBCONTAINER *gbc = gbd->as_container();
164
165        if (gbd->flags2.folded_container) gb_unfold(gbc, -1, -1);
166        for (GBDATA *gbp = GB_child(gbd); gbp; gbp = GB_nextChild(gbp)) {
167            ++indent;
168            dump_internal(gbp, lines_allowed);
169            --indent;
170            if (lines_allowed && (*lines_allowed)<0) break;
171        }
172    }
173
174    if (gb_show_later) {
175        if (!lines_allowed || (*lines_allowed)>0) {
176            printf("%*s Showing %s:\n", indent, "", whatto_show_later);
177            freenull(whatto_show_later);
178            ++indent;
179            dump_internal(gb_show_later, lines_allowed);
180            --indent;
181        }
182    }
183}
184
185NOT4PERL void GB_dump(GBDATA *gbd) { // used for debugging
186    int max_lines = 2500;
187    dump_internal(gbd, &max_lines);
188    if (max_lines <= 0) {
189        printf("Warning: Dump has been aborted (too many lines)\n"
190               "[use GB_dump_no_limit() if you really want to dump all]\n");
191    }
192}
193
194NOT4PERL void GB_dump_no_limit(GBDATA *gbd) { // used for debugging
195    dump_internal(gbd, 0);
196}
197
198// ---------------------
199//      Fix database
200
201static GB_ERROR gb_fix_recursive(GBDATA *gbd) {
202    if (gbd->is_container()) {
203        for (GBDATA *gbp = GB_child(gbd); gbp; gbp = GB_nextChild(gbp)) {
204            gb_fix_recursive(gbp);
205        }
206    }
207    else {
208        GBQUARK key_quark = GB_KEY_QUARK(gbd);
209        if (key_quark == 0) {
210            GB_MAIN_TYPE *Main         = GB_MAIN(gbd);
211            const char   *new_key_try  = GBS_global_string("illegal_zero_key_%s", GB_get_type_name(gbd));
212            char         *new_key_name = GBS_string_2_key(new_key_try);
213            GBQUARK       keyq         = gb_find_or_create_quark(Main, new_key_name);
214
215            printf("new_key_name='%s'\n", new_key_name);
216
217            gb_assert(keyq != 0);
218            {
219                long gbm_index    = quark2gbmindex(Main, keyq);
220                GB_GBM_INDEX(gbd) = gbm_index;      // set new index
221
222                // @@@ FIXME: above command has no effect
223
224                printf("Fixed zero key_quark of GBDATA at %p\n", gbd);
225                GB_dump_db_path(gbd);
226            }
227
228            free(new_key_name);
229        }
230    }
231
232    return 0;
233}
234
235GB_ERROR GB_fix_database(GBDATA *gb_main) {
236    GB_ERROR err  = GB_begin_transaction(gb_main);
237    if (!err) err = gb_fix_recursive(gb_main);
238    return GB_end_transaction(gb_main, err);
239}
240
Note: See TracBrowser for help on using the repository browser.