source: trunk/third/scrollkeeper/libs/merge.c @ 20861

Revision 20861, 5.5 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20860, which included commits to RCS files with non-trunk default branches.
Line 
1/* copyright (C) 2001 Sun Microsystems, Inc.*/
2
3/*   
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19#include <config.h>
20#include <libxml/tree.h>
21#include <libxml/parser.h>
22#include <stdlib.h>
23#include <scrollkeeper.h>
24#include <string.h>
25
26/* the returned value must not be modified outside this routine
27*/
28static xmlChar *get_doc_uid(xmlNodePtr doc_node)
29{
30        xmlNodePtr node;
31       
32        for(node = doc_node->children; node != NULL; node = node->next) {
33                if (!xmlStrcmp(node->name, (xmlChar *)"docseriesid") &&
34                    node->children != NULL &&
35                    node->children->type == XML_TEXT_NODE &&
36                    node->children->content != NULL) {
37                    return node->children->content;
38                }
39        }
40       
41        return NULL;
42}
43
44static int find_uid_in_sect(xmlNodePtr sect_node, xmlChar *orig_uid)
45{
46        xmlNodePtr node;
47        xmlChar *uid;
48       
49        for(node = sect_node->children; node != NULL; node = node->next) {
50                if (xmlStrcmp(node->name, (xmlChar *)"doc")) {
51                        continue;
52                }
53       
54                uid = get_doc_uid(node);
55                if (uid != NULL) {
56                        if (!xmlStrcmp(orig_uid, uid)) {
57                                return 1;
58                        }
59                }
60        }
61       
62        return 0;
63}
64
65static void merge_two_sections(xmlNodePtr sect_node, xmlNodePtr other_sect_node)
66{
67        xmlNodePtr node, new_node;
68        xmlChar *uid;
69       
70        for(node = other_sect_node->children; node != NULL; node = node->next) {
71                if (xmlStrcmp(node->name, (xmlChar *)"doc")) {
72                        continue;
73                }
74       
75                uid = get_doc_uid(node);
76                if (uid != NULL) {
77                        if (!find_uid_in_sect(sect_node, uid)) {
78                                new_node = xmlCopyNode(node, 1);
79                                check_ptr(new_node, "");
80                                xmlAddChild(sect_node, new_node);
81                        }
82                }
83        }
84}
85
86static int find_sect_with_code(xmlNodePtr tree, xmlChar *sect_code,
87                                xmlNodePtr *sect_return)
88{
89        xmlNodePtr sect_node;
90        xmlChar *code;
91       
92        for(sect_node = tree; sect_node != NULL; sect_node = sect_node->next) {
93                if (!xmlStrcmp(sect_node->name, (xmlChar *)"sect")) {
94                        code = xmlGetProp(sect_node, (xmlChar *)"categorycode");
95                        if (code != NULL) {
96                                if (!xmlStrcmp(sect_code, code)) {
97                                        *sect_return = sect_node;
98                                        xmlFree(code);
99                                        return 1;
100                                }
101                                xmlFree(code);
102                        }
103                       
104                        if (find_sect_with_code(sect_node->children,
105                                                sect_code, sect_return)) {
106                                return 1;
107                        }
108                }
109        }
110
111        return 0;
112}
113
114static void merge_sections(xmlNodePtr sect_node, xmlChar *code,
115                                xmlDocPtr *tree_tab, int tree_num)
116{
117        int i;
118        xmlNodePtr other_sect_node;
119       
120        for(i = 0; i < tree_num; i++) {
121                if (tree_tab[i] == NULL) {
122                        continue;
123                }
124       
125                if (find_sect_with_code(tree_tab[i]->children->children,
126                                        code, &other_sect_node)) {
127                        merge_two_sections(sect_node, other_sect_node);
128                }
129        }
130}
131
132static void merge_trees(xmlNodePtr tree, xmlDocPtr *tree_tab, int tree_num)
133{
134        xmlNodePtr sect_node;
135        xmlChar *code;
136   
137        for(sect_node = tree; sect_node != NULL; sect_node = sect_node->next) {
138                if (!xmlStrcmp(sect_node->name, (xmlChar *)"sect"))
139                {
140                        code = xmlGetProp(sect_node, (xmlChar *)"categorycode");
141                        if (code != NULL) {
142                                merge_sections(sect_node, code, tree_tab, tree_num);
143                                xmlFree(code);
144                        }
145                       
146                        merge_trees(sect_node->children, tree_tab, tree_num);
147                }
148        }
149}
150
151static xmlDocPtr merge_locale_trees_in_first(xmlDocPtr *tree_tab, int tree_num)
152{
153        xmlDocPtr new_tree;
154        int i;
155
156        if (tree_tab == NULL || tree_num == 0)
157                return NULL;
158               
159        for(i = 0; i < tree_num; i++) {
160                if (tree_tab[i] != NULL) {
161                        break;
162                }
163        }
164       
165        if (i == tree_num) {
166                return NULL;
167        }
168               
169        new_tree = xmlCopyDoc(tree_tab[i], 1);
170        check_ptr(new_tree, "");
171       
172        if (tree_num > 0) {
173                merge_trees(new_tree->children->children, &(tree_tab[i+1]), tree_num-i-1);
174        }
175
176        return new_tree;
177}
178
179static char *create_content_list_file_path(char *scrollkeeper_dir, char *locale,
180                                                char *base)
181{
182        char *str;
183               
184        str = malloc(sizeof(char)*
185                        (strlen(scrollkeeper_dir)+1+strlen(locale)+1+strlen(base)+1)); 
186        check_ptr(str, "");
187       
188        sprintf(str, "%s/%s/%s", scrollkeeper_dir, locale, base);
189       
190        return str;
191}
192
193xmlDocPtr merge_locale_trees(char *scrollkeeper_dir, char *base_locale, char *basename)
194{
195        char **lang_tab, *path;
196        int i, lang_num, count;
197        xmlDocPtr merged_tree, *tree_tab;
198       
199        lang_tab = sk_get_language_list();
200       
201        if (lang_tab == NULL) {
202                return NULL;
203        }
204       
205        for(i = 0, lang_num = 0; lang_tab[i] != NULL; i++) {
206                lang_num++;
207        }
208       
209        tree_tab = (xmlDocPtr *)malloc(sizeof(xmlDocPtr)*(lang_num+1));
210       
211        path = create_content_list_file_path(scrollkeeper_dir,
212                                base_locale, basename);
213        tree_tab[0] = xmlParseFile(path);
214        free(path);
215       
216        for(i = 0, count = 1; i < lang_num; i++) {
217                if (!strcmp(base_locale, lang_tab[i])) {
218                        continue;
219                }
220               
221                path = create_content_list_file_path(scrollkeeper_dir,
222                                lang_tab[i], basename);
223                tree_tab[count] = xmlParseFile(path);
224                free(path);
225                count++;
226        }
227 
228        merged_tree = merge_locale_trees_in_first(tree_tab, count);
229       
230        for(i = 0; lang_tab[i] != NULL; i++) {
231                free(lang_tab[i]);
232        }
233       
234        for(i = 0; i < count; i++) {
235                if (tree_tab[i] != NULL) {
236                        xmlFreeDoc(tree_tab[i]);
237                }
238        }
239       
240        free(lang_tab);
241        free(tree_tab);
242       
243        return merged_tree;
244}
Note: See TracBrowser for help on using the repository browser.