source: tags/svn.1.5.4/MERGE/MG_checkfield.cxx

Last change on this file was 8309, checked in by westram, 14 years ago
  • moved much code into static scope

(partly reverted by [8310])

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.9 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : MG_checkfield.cxx                                 //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "merge.hxx"
12
13#include <item_sel_list.h>
14#include <awt_sel_boxes.hxx>
15
16#include <aw_awar.hxx>
17#include <aw_root.hxx>
18#include <aw_msg.hxx>
19#include <arb_progress.h>
20
21#include <arbdbt.h>
22#include <arb_strbuf.h>
23
24#include <cctype>
25
26#define AWAR_SOURCE_FIELD "/tmp/merge1/chk/source"
27#define AWAR_DEST_FIELD   "/tmp/merge1/chk/dest"
28#define AWAR_TOUPPER      "/tmp/merge1/chk/ToUpper"
29#define AWAR_EXCLUDE      "/tmp/merge1/chk/exclude"
30#define AWAR_CORRECT      "/tmp/merge1/chk/correct"
31#define AWAR_ETAG         "/tmp/merge1/chk/tag"
32
33
34static int gbs_cmp_strings(char *str1, char *str2, int *tab) { // returns 0 if strings are equal
35    char *s1, *s2;
36    int c1, c2;
37    s1 = str1;
38    s2 = str2;
39    int count = 10;
40    do {
41        do { c1 = *(s1++); } while (tab[c1] < 0);
42        do { c2 = *(s2++); } while (tab[c2] < 0);
43        if (tab[c1] != tab[c2]) {   // difference found
44            return 1;
45        }
46        count --;
47    } while (count && c1 && c2);
48    return 0;
49}
50
51
52static char *GBS_diff_strings(char *str1, char * &str2, char *exclude, long ToUpper, long correct,
53                       char **res1, char **res2, long *corrrected) {
54
55    char  buffer1[256];
56    char  buffer2[256];
57    char *dest1 = buffer1;
58    char *dest2 = buffer2;
59    char *s1, *s2;
60    int   c1, c2;
61    int   count = 3;
62    int   tab[256];
63    int   i;
64
65    s1 = str1;
66    s2 = str2;
67    *dest1 = 0;
68    *dest2 = 0;
69    tab[0] = 0;
70    char gapchar = '#';
71    if (strlen(exclude)) gapchar = exclude[0];
72    else    exclude = 0;
73
74    for (i=1; i<256; i++) {
75        tab[i] = i;
76        if (exclude && strchr(exclude, i)) {
77            tab[i] = -1;
78            continue;
79        }
80        if (ToUpper && i >= 'a' && i <= 'z') {
81            tab[i] = i-'a'+'A';
82        }
83    }
84
85    do {
86        do { c1 = *(s1++); } while (tab[c1] < 0);
87        do { c2 = *(s2++); } while (tab[c2] < 0);
88        if (tab[c1] != tab[c2]) {   // difference found
89            if (correct) {
90                // check substitution
91                {
92                    int c = s2[-1];
93                    s2[-1] = s1[-1];
94                    if (toupper(c1) == toupper(c2) ||
95                        !gbs_cmp_strings(s1, s2, &tab[0])) {
96                        *corrrected = 1;
97                        continue;
98                    }
99                    s2[-1] = c;
100                }
101
102                // check insertion in s2
103                if (!gbs_cmp_strings(s1-1, s2, &tab[0])) {
104                    s2[-1] = gapchar;
105                    do { c2 = *(s2++); } while (tab[c2] < 0); // eat s2
106                    *corrrected = 1;
107                    continue;
108                }
109                // check deletion in s2
110                if (!gbs_cmp_strings(s1, s2-1, &tab[0])) {
111                    int toins = c1;
112                    char *toinspos = s2-1;
113                    if (toinspos > str2) toinspos--;
114                    if (tab[(unsigned char)toinspos[0]]> 0) { // real insertion
115                        GBS_strstruct *str = GBS_stropen(strlen(str2+10));
116                        int pos = s2-str2-1;
117                        GBS_strncat(str, str2, pos);
118                        GBS_chrcat(str, toins);
119                        GBS_strcat(str, str2+pos);
120                        delete str2;
121                        str2 = GBS_strclose(str);
122                        s2 = str2+pos+1;
123                        *corrrected = 1;
124                        continue;
125                    }
126                    int side=1; // 0 = left   1= right
127                    if (tab[(unsigned char)s1[0]]<0) side = 0;
128                    if (! side) {
129                        while (toinspos > str2 &&
130                                tab[(unsigned char)toinspos[-1]] < 0) toinspos--;
131                    }
132                    toinspos[0] = toins;
133                    *corrrected = 1;
134                    do { c1 = *(s1++); } while (tab[c1] < 0); // eat s1
135                    continue;
136                }
137            }
138            if (count >= 0) {
139                sprintf(dest1, "%ti ", s1-str1-1);
140                sprintf(dest2, "%ti ", s2-str2-1);
141                dest1 += strlen(dest1);
142                dest2 += strlen(dest2);
143            }
144            count --;
145        }
146    } while (c1 && c2);
147
148    if (c1 || c2) {
149        sprintf(dest1, "... %ti ", s1-str1-1);
150        sprintf(dest2, "... %ti ", s2-str2-1);
151        dest1 += strlen(dest1);
152        dest2 += strlen(dest2);
153    }
154    if (count<0) {
155        sprintf(dest1, "and %i more", 1-count);
156        sprintf(dest2, "and %i more", 1-count);
157        dest1 += strlen(dest1);
158        dest2 += strlen(dest2);
159    }
160    if (strlen(buffer1)) {
161        *res1 = strdup(buffer1);
162        *res2 = strdup(buffer2);
163    }
164    else {
165        *res1 = 0;
166        *res2 = 0;
167    }
168    return 0;
169}
170
171int mg_count_queried(GBDATA *gb_main) {
172    int queried  = 0;
173    for (GBDATA *gb_spec = GBT_first_species(gb_main);
174         gb_spec;
175         gb_spec = GBT_next_species(gb_spec))
176    {
177        if (IS_QUERIED_SPECIES(gb_spec)) queried++;
178    }
179    return queried;
180}
181
182static void mg_check_field_cb(AW_window *aww) {
183    AW_root  *root    = aww->get_root();
184    GB_ERROR  error   = 0;
185    char     *source  = root->awar(AWAR_SOURCE_FIELD)->read_string();
186    char     *dest    = root->awar(AWAR_DEST_FIELD)->read_string();
187    char     *exclude = root->awar(AWAR_EXCLUDE)->read_string();
188    long      ToUpper = root->awar(AWAR_TOUPPER)->read_int();
189    long      correct = root->awar(AWAR_CORRECT)->read_int();
190    char     *tag     = root->awar(AWAR_ETAG)->read_string();
191
192    if (source[0] == 0) {
193        error = "Please select a source field";
194    }
195    else if (dest[0] == 0) {
196        error = "Please select a dest field";
197    }
198    else {
199        error = GB_begin_transaction(GLOBAL_gb_merge);
200
201        if (!error) {
202            error = GB_begin_transaction(GLOBAL_gb_dest);
203
204            GBDATA *gb_species_data1 = GB_search(GLOBAL_gb_merge, "species_data", GB_CREATE_CONTAINER);
205            GBDATA *gb_species_data2 = GB_search(GLOBAL_gb_dest,  "species_data", GB_CREATE_CONTAINER);
206
207            GBDATA *gb_species1;
208            GBDATA *gb_species2;
209
210            // First step: count selected species
211            arb_progress progress("Checking fields", mg_count_queried(GLOBAL_gb_merge));
212
213            // Delete all 'dest' fields in gb_database 2
214            for (gb_species2 = GBT_first_species_rel_species_data(gb_species_data2);
215                 gb_species2 && !error;
216                 gb_species2 = GBT_next_species(gb_species2))
217            {
218                GBDATA *gbd    = GB_search(gb_species2, dest, GB_FIND);
219                if (gbd) error = GB_delete(gbd);
220            }
221
222            for (gb_species1 = GBT_first_species_rel_species_data(gb_species_data1);
223                 gb_species1 && !error;
224                 gb_species1 = GBT_next_species(gb_species1))
225            {
226                {
227                    GBDATA *gbd    = GB_search(gb_species1, dest, GB_FIND);
228                    if (gbd) error = GB_delete(gbd);
229                }
230
231                if (!error) {
232                    if (IS_QUERIED_SPECIES(gb_species1)) {
233                        const char *name1 = GBT_read_name(gb_species1);
234                        gb_species2       = GB_find_string(gb_species_data2, "name", name1, GB_IGNORE_CASE, SEARCH_GRANDCHILD);
235                        if (!gb_species2) {
236                            aw_message(GBS_global_string("WARNING: Species %s not found in DB II", name1));
237                        }
238                        else {
239                            gb_species2 = GB_get_father(gb_species2);
240
241                            GBDATA *gb_field1 = GB_search(gb_species1, source, GB_FIND);
242                            GBDATA *gb_field2 = GB_search(gb_species2, source, GB_FIND);
243                            char   *s1        = gb_field1 ? GB_read_as_tagged_string(gb_field1, tag) : 0;
244                            char   *s2        = gb_field2 ? GB_read_as_tagged_string(gb_field2, tag) : 0;
245
246                            if (s1 || s2) {
247                                char *positions1 = 0;
248                                char *positions2 = 0;
249
250                                if (s1 && s2) {
251                                    long corrected = 0;
252                                    GBS_diff_strings(s1, s2, exclude, ToUpper, correct, &positions1, &positions2, &corrected);
253                                    if (corrected) {
254                                        error = GB_write_as_string(gb_field2, s2);
255                                        if (!error) GB_write_flag(gb_species2, 1);
256                                    }
257                                }
258                                else {
259                                    positions1 = GBS_global_string_copy("field missing in %s DB", s1 ? "other" : "this");
260                                    positions2 = GBS_global_string_copy("field missing in %s DB", s2 ? "other" : "this");
261                                }
262
263                                if (positions1 && !error) {
264                                    error             = GBT_write_string(gb_species2, dest, positions2);
265                                    if (!error) error = GBT_write_string(gb_species1, dest, positions1);
266                                }
267
268                                free(positions2);
269                                free(positions1);
270                            }
271
272                            free(s2);
273                            free(s1);
274                        }
275                        progress.inc_and_check_user_abort(error);
276                    }
277                }
278            }
279
280            error = GB_end_transaction(GLOBAL_gb_merge, error);
281            error = GB_end_transaction(GLOBAL_gb_dest, error);
282        }
283    }
284    if (error) aw_message(error);
285
286    free(tag);
287    free(exclude);
288    free(dest);
289    free(source);
290}
291
292
293AW_window *create_mg_check_fields(AW_root *aw_root) {
294    AW_window_simple *aws = 0;
295
296    aw_root->awar_string(AWAR_SOURCE_FIELD);
297    aw_root->awar_string(AWAR_DEST_FIELD, "tmp", AW_ROOT_DEFAULT);
298    aw_root->awar_string(AWAR_EXCLUDE, ".-", AW_ROOT_DEFAULT);
299    aw_root->awar_string(AWAR_ETAG, "");
300    aw_root->awar_int(AWAR_TOUPPER);
301    aw_root->awar_int(AWAR_CORRECT);
302
303    aws = new AW_window_simple;
304    aws->init(aw_root, "MERGE_COMPARE_FIELDS", "COMPARE DATABASE FIELDS");
305    aws->load_xfig("merge/seqcheck.fig");
306
307    aws->callback((AW_CB0)AW_POPDOWN);
308    aws->create_button("CLOSE", "CLOSE", "C");
309
310    aws->at("help");
311    aws->callback(AW_POPUP_HELP, (AW_CL)"checkfield.hlp");
312    aws->create_button("HELP", "HELP", "H");
313
314
315    aws->at("exclude");
316    aws->create_input_field(AWAR_EXCLUDE);
317
318    aws->at("toupper");
319    aws->create_toggle(AWAR_TOUPPER);
320
321    aws->at("correct");
322    aws->create_toggle(AWAR_CORRECT);
323
324    aws->at("tag");
325    aws->create_input_field(AWAR_ETAG, 6);
326
327    create_selection_list_on_itemfields(GLOBAL_gb_dest, aws, AWAR_SOURCE_FIELD,
328                                            FIELD_FILTER_STRING, "source", 0, SPECIES_get_selector(), 20, 10);
329
330    create_selection_list_on_itemfields(GLOBAL_gb_dest, aws, AWAR_DEST_FIELD,
331                                            (1<<GB_STRING)|(1<<GB_INT), "dest", 0, SPECIES_get_selector(), 20, 10);
332
333#if defined(WARN_TODO)
334#warning check code above. Maybe one call has to get GLOBAL_gb_merge ?
335#endif
336
337
338    aws->at("go");
339    aws->highlight();
340    aws->callback(mg_check_field_cb);
341    aws->create_button("GO", "GO");
342
343    return (AW_window *)aws;
344}
Note: See TracBrowser for help on using the repository browser.