source: tags/svn.1.5.4/ARBDB/adTest.cxx

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