source: branches/port5/ARBDB/adTest.c

Last change on this file was 6204, checked in by westram, 15 years ago
  • GB_dump
    • if content read from DB is NULL, check for exported error
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/types.h>
5#include <sys/mman.h>
6
7/*#include "arbdb.h"*/
8#include "adlocal.h"
9#include "admap.h"
10
11#define VERBOSE 0
12
13static const char *actType = "none";
14static void *actData = NULL;
15static int  actQuark = 0;
16
17void err_hook() {
18    int x=2;
19    x=x;
20}
21
22#define err(gbd,quark,type,mess) \
23    do { \
24        fprintf(stderr, "(%s*)0x%p(=%s) %s (in (%s*)0x%p(=%s))\n",\
25            type,gbd,Main->keys[quark].key,mess,\
26            actType,actData,Main->keys[actQuark].key); \
27        err=1; \
28        err_hook();\
29    } while (0)
30
31#define errGBD(gbd,quark,mess) err(gbd,quark,"GBDATA",mess)
32#define errGBC(gbc,quark,mess) err(gbc,quark,"GBCONTAINER",mess)
33
34void testData(GB_MAIN_TYPE *Main, GBDATA *gbd, long server_id, int key_quark)
35{
36    int err = 0;
37
38#if (VERBOSE>=2)
39    printf("Teste (GBDATA*)0x%p (=%s)\n", gbd, Main->keys[key_quark].key);
40#endif
41
42    if (gbd->server_id != server_id) errGBD(gbd, key_quark, "illegal server id");
43}
44
45void testContainer(GB_MAIN_TYPE *Main,GBCONTAINER *gbc, long server_id, int key_quark)
46{
47    struct gb_header_list_struct *header;
48    int     item,
49        err=0;
50    const char  *oldType   = actType;
51    void    *oldData  = actData;
52    int     oldQuark  = actQuark;
53
54#if (VERBOSE>=1)
55    printf("Teste (GBCONTAINER*)0x%p (=%s)\n", gbc, Main->keys[key_quark].key);
56#endif
57    actType  = "GBCONTAINER";
58    actData  = gbc;
59    actQuark = key_quark;
60
61    if (gbc->server_id != server_id) {
62        errGBC(gbc, actQuark, "illegal server id");
63    }
64
65    header = GB_DATA_LIST_HEADER(gbc->d);
66    for (item=0; item<gbc->d.nheader; item++) {
67        GBDATA *gbd = GB_HEADER_LIST_GBD(header[item]);
68        GBCONTAINER *father;
69        int     type, quark = header[item].flags.key_quark;
70
71        if (!gbd) continue;
72
73        if (quark>=Main->sizeofkeys) {
74            fprintf(stderr, "Illegal quark %i\n", quark);
75            continue;
76        }
77
78
79        if (!gbd) errGBC(gbc,key_quark,"NULL-GBDATA in header-list");
80
81        type = GB_TYPE(gbd);
82
83        if (type==GB_DB) testContainer(Main,(GBCONTAINER*)gbd, server_id, quark);
84        else         testData(Main,gbd,server_id,quark);
85
86        father = GB_FATHER(gbd);
87        if (!father) {
88            errGBD(gbd, quark, "has no father.");
89        }
90        else if (father!=gbc) {
91            errGBD(gbd, quark,"is not son of..");
92        }
93        else if (gbd->index!=item) {
94            errGBD(gbd, quark,"index mismatch..");
95        }
96        else if (err) {
97            errGBD(gbd, quark,"is correct connected to..");
98        }
99    }
100
101    actType = oldType;
102    actData = oldData;
103    actQuark = oldQuark;
104}
105
106void gb_testDB(GBDATA *gbd)
107{
108    GB_MAIN_TYPE    *Main = 0;
109    GBCONTAINER     *gbc;
110    long        server_id;
111    int         err=0;
112
113    actType = "GB_MAIN_TYPE";
114    actData = gbd;
115    actQuark = 0;
116
117    gbc = GB_FATHER(gbd);
118    Main = GBCONTAINER_MAIN(gbc);
119
120    if (!gbc) {
121        fprintf(stderr, "(GBDATA*)0x%p has no father\n", gbd);
122        err_hook();
123    }
124    if (!Main) {
125        fprintf(stderr, "(GBCONTAINER*)0x%p has no main-entry\n", gbc);
126        err_hook();
127    }
128
129    gbc = Main->data;
130    if (!gbc) {
131        err(Main, actQuark, "GB_MAIN_TYPE","has no data");
132    }
133
134    server_id = gbc->server_id;
135
136    if (GB_FATHER(gbc)!=Main->dummy_father) {
137        errGBC(gbc, actQuark, "mainContainer's father != dummy_father");
138    }
139    if (Main->dummy_father->server_id != server_id) {
140        errGBC(Main->dummy_father, actQuark, "illegal server id");
141    }
142
143    if (!err) testContainer(Main,gbc,server_id,0);
144
145    printf("testDB passed.\n");
146}
147
148const char *GB_get_type_name(GBDATA *gbd) {
149    int         type = GB_TYPE(gbd);
150    const char *type_name;
151
152    switch (type) {
153        case GB_INT:    { type_name = "GB_INT"; break; }
154        case GB_FLOAT:  { type_name = "GB_FLOAT"; break; }
155        case GB_BYTE:   { type_name = "GB_BYTE"; break; }
156        case GB_STRING: { type_name = "GB_STRING"; break; }
157        case GB_LINK:   { type_name = "GB_LINK"; break; }
158        case GB_BITS:   { type_name = "GB_BITS"; break; }
159        case GB_BYTES:  { type_name = "GB_BYTES"; break; }
160        case GB_INTS:   { type_name = "GB_INTS"; break; }
161        case GB_FLOATS: { type_name = "GB_FLOATS"; break; }
162        case GB_DB:     { type_name = "GB_DB"; break; }
163        default: {
164            static char *unknownType = 0;
165            freeset(unknownType, GBS_global_string_copy("<unknown GB_TYPE=%i>", type));
166            type_name = unknownType;
167            break;
168        }
169    }
170
171    return type_name;
172}
173
174const char *GB_get_db_path(GBDATA *gbd) {
175    GBDATA *gb_father = (GBDATA*)GB_FATHER(gbd);
176
177    if (gb_father) {
178        char *father_path = strdup(GB_get_db_path(gb_father));
179
180        static char *result; // careful! used recursively
181        freeset(result, GBS_global_string_copy("%s/%s", father_path, GB_KEY(gbd)));
182        free(father_path);
183       
184        return result;
185    }
186    return "";
187}
188
189void GB_dump_db_path(GBDATA *gbd) {
190    printf("Path to GBDATA %p (type=%s) is '%s'\n", gbd, GB_get_type_name(gbd), GB_get_db_path(gbd));
191}
192
193static void GB_dump_internal(GBDATA *gbd, int *lines_allowed) {
194    static int     indent            = 0;
195    int            type              = GB_TYPE(gbd);
196    const char    *type_name         = GB_get_type_name(gbd);
197    const char    *key_name          = 0;
198    const char    *content           = 0;
199    unsigned long  content_len       = 0;
200    GBCONTAINER   *father            = GB_FATHER(gbd);
201    GBDATA        *gb_show_later     = 0;
202    char          *whatto_show_later = 0;
203    GB_BOOL        showChilds        = GB_TRUE;
204
205    if (father) {
206        int index_pos = (int)gbd->index; /* my index position in father */
207        struct gb_header_list_struct *hls = &(GB_DATA_LIST_HEADER(father->d)[index_pos]);
208
209        if (!hls) {
210            key_name = GBS_global_string("<no gb_header_list_struct found for index_pos=%i>", index_pos);
211            father = 0; // otherwise crash below
212        }
213        else {
214            GBDATA *gb_self = GB_HEADER_LIST_GBD(*hls);
215            if (gb_self != gbd) {
216                key_name = GBS_global_string("<element not linked in parent>");
217                if (gb_self) {
218                    gb_show_later     = gb_self;
219                    whatto_show_later = GBS_global_string_copy("Element linked at index pos of %p", gbd);
220                }
221                father = 0; // otherwise crash below
222            }
223            // otherwise father looks fine
224        }
225    }
226
227    if (father) {
228        GB_BOOL is_db_server = GB_is_server(gbd);
229
230        if (is_db_server && gbd->server_id != GBTUM_MAGIC_NUMBER) {
231            key_name = GBS_global_string("<element with illegal server-id %p>", (void*)gbd->server_id);
232        }
233        else if (is_db_server && father->server_id != GBTUM_MAGIC_NUMBER) {
234            key_name = GBS_global_string("<elements parent has illegal server-id %p>", (void*)father->server_id);
235            father   = 0; /* avoids crashes below */
236        }
237        else {
238            key_name = GB_KEY_QUARK(gbd) ? GB_KEY(gbd) : "<illegal quark=0>";
239        }
240    }
241
242    if (!father && !key_name) {
243        key_name   = "<unknown quark - element w/o father>";
244        showChilds = GB_FALSE;
245    }
246    else { // test if we need a transaction
247        if (!GB_MAIN(gbd)->transaction) {
248            GB_push_transaction(gbd);
249            GB_dump_internal(gbd, lines_allowed);
250            GB_pop_transaction(gbd);
251            return;
252        }
253    }
254
255    if (indent == 0) {
256        printf("\nGB_dump of '%s':\n", father ? GB_get_db_path(gbd) : "<no DB-path - father missing or not inspected>");
257        if (lines_allowed) (*lines_allowed)--;
258    }
259
260    if (father) {
261        if (GB_ARRAY_FLAGS(gbd).changed == gb_deleted) {
262            content = "<can't examine - entry is deleted>";
263        }
264        else {
265            switch (type) {
266                case GB_INT:    { content = GBS_global_string("%li", GB_read_int(gbd)); break; }
267                case GB_FLOAT:  { content = GBS_global_string("%f", (float)GB_read_float(gbd)); break; }
268                case GB_BYTE:   { content = GBS_global_string("%i", GB_read_byte(gbd)); break; }
269                case GB_STRING: { content = GB_read_char_pntr(gbd); content_len = GB_read_count(gbd); break; }
270                case GB_LINK:   { content = GBS_global_string("link to %p", GB_follow_link(gbd)); break; }
271                case GB_BITS:   { break; }
272                case GB_BYTES:  { break; }
273                case GB_INTS:   { break; }
274                case GB_FLOATS: { break; }
275                case GB_DB:     { content = "see below"; break; }
276                default:        { content = ""; break; }
277            }
278        }
279    }
280
281    if (content==0) {
282        if (GB_have_error()) {
283            content = GBS_global_string("<failed to read content (error is '%s')>", GB_await_error());
284        }
285        else {
286            content = "<illegal zero content, but no error - severe bug?!>";
287        }
288    }
289    if (content_len == 0) content_len = strlen(content);
290
291    {
292        char     *prefix  = GBS_global_string_copy("%*s %-15s gbd=%p type=%s content=", indent, "", key_name, gbd, type_name);
293        unsigned  wrappos = 500;
294        char     *toFree  = 0;
295
296        if (content_len > wrappos) {
297            toFree      = strdup(content);
298            content     = toFree;
299            content_len = GBS_shorten_repeated_data(toFree);
300        }
301
302        if (content_len <= wrappos) {
303            printf("%s'%s'\n", prefix, content);
304            if (lines_allowed) (*lines_allowed)--;
305        }
306        else {
307            char          *buffer  = malloc(wrappos+1);
308            unsigned long  rest    = content_len;
309            const char    *from    = content;
310            int            cleared = 0;
311
312            buffer[wrappos] = 0;
313            while (rest) {
314                memcpy(buffer, from, wrappos);
315                rest  = rest>wrappos ? rest-wrappos : 0;
316                from += wrappos;
317                printf("%s'%s'\n", prefix, buffer);
318                if (lines_allowed && --(*lines_allowed) <= 0) break;
319                if (!cleared) { memset(prefix, ' ', strlen(prefix)); cleared = 1; }
320            }
321            free(buffer);
322        }
323        free(prefix);
324        free(toFree);
325    }
326
327    if (type==GB_DB && showChilds == GB_TRUE) {
328        GBCONTAINER *gbc = (GBCONTAINER*)gbd;
329        GBDATA *gbp;
330
331        if (gbd->flags2.folded_container) gb_unfold(gbc, -1, -1);
332        for (gbp = GB_child(gbd); gbp; gbp = GB_nextChild(gbp)) {
333            ++indent;
334            GB_dump_internal(gbp, lines_allowed);
335            --indent;
336            if (lines_allowed && (*lines_allowed)<0) break;
337        }
338    }
339
340    if (gb_show_later) {
341        if (!lines_allowed || (*lines_allowed)>0) {
342            printf("%*s Showing %s:\n", indent, "", whatto_show_later);
343            freeset(whatto_show_later, NULL); 
344            ++indent;
345            GB_dump_internal(gb_show_later, lines_allowed);
346            --indent;
347        }
348    }
349}
350
351void GB_dump(GBDATA *gbd) {
352    int max_lines = 2500;
353    GB_dump_internal(gbd, &max_lines);
354    if (max_lines <= 0) {
355        printf("Warning: Dump has been aborted (too many lines)\n"
356               "[use GB_dump_no_limit() if you really want to dump all]\n");
357    }
358}
359
360void GB_dump_no_limit(GBDATA *gbd) {
361    GB_dump_internal(gbd, 0);
362}
363
364/* -------------------------------------------------------------------------------- */
365/* Fix database                                                                     */
366/* -------------------------------------------------------------------------------- */
367
368static GB_ERROR gb_fix_recursive(GBDATA *gbd) {
369    GBDATA *gbp;
370    int     type = GB_TYPE(gbd);
371
372    if (type == GB_DB) {
373        for (gbp = GB_child(gbd); gbp; gbp = GB_nextChild(gbp)) {
374            gb_fix_recursive(gbp);
375        }
376    }
377    else {
378        int key_quark = GB_KEY_QUARK(gbd);
379        if (key_quark == 0) {
380            GB_MAIN_TYPE *Main         = GB_MAIN(gbd);
381            const char   *new_key_try  = GBS_global_string("illegal_zero_key_%s", GB_get_type_name(gbd));
382            char         *new_key_name = GBS_string_2_key(new_key_try);
383            GBQUARK       keyq         = gb_key_2_quark(Main, new_key_name);
384
385            printf("new_key_name='%s'\n", new_key_name);
386
387            ad_assert(keyq != 0);
388            {
389                long gbm_index    = GB_QUARK_2_GBMINDEX(Main, keyq);
390                GB_GBM_INDEX(gbd) = gbm_index; // set new index
391
392                /* @@@ FIXME: above command has no effect  */
393
394                printf("Fixed zero key_quark of GBDATA at %p\n", gbd);
395                GB_dump_db_path(gbd);
396            }
397
398            free(new_key_name);
399        }
400    }
401
402    return 0;
403}
404
405GB_ERROR GB_fix_database(GBDATA *gb_main) {
406    GB_ERROR err  = GB_begin_transaction(gb_main);
407    if (!err) err = gb_fix_recursive(gb_main);
408    return GB_end_transaction(gb_main, err);
409}
410
411
Note: See TracBrowser for help on using the repository browser.