source: tags/cvs_2_svn/MERGE/MG_checkfield.cxx

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