source: tags/arb-6.0/ARBDB/adTest.cxx

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