xref: /haiku/src/bin/locale/linkcatkeys.cpp (revision 1026b0a1a76dc88927bb8175c470f638dc5464ee)
1 /*
2 ** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
3 ** Distributed under the terms of the OpenBeOS License.
4 */
5 
6 #include <cstdio>
7 #include <cstdlib>
8 #include <vector>
9 
10 #include <Entry.h>
11 #include <File.h>
12 #include <String.h>
13 
14 #include <EditableCatalog.h>
15 #include <DefaultCatalog.h>
16 #include <HashMapCatalog.h>
17 
18 
19 using BPrivate::CatKey;
20 using BPrivate::DefaultCatalog;
21 using BPrivate::EditableCatalog;
22 using BPrivate::HashMapCatalog;
23 using std::vector;
24 
25 
26 void
27 usage()
28 {
29 	fprintf(stderr,
30 		"usage: linkcatkeys [-v] [-t(a|f|r)] [-o <outfile>] [-l <catalogLang>]\n"
31 		"                   -s <catalogSig> <catalogFiles>\n"
32 		"options:\n"
33 		"  -l <catalogLang>\tlanguage of the target-catalog (default is English)\n"
34 		"  -o <outfile>\t\texplicitly specifies the name of the output-file\n"
35 		"  -s <catalogSig>\tsignature of the target-catalog\n"
36 		"  -t(a|f|r)\t\tspecifies target of resulting catalog (-tf is default)\n"
37 		"           \t\ta => write catalog as an attribute (to output-file)\n"
38 		"           \t\tf => write catalog into the output-file\n"
39 		"           \t\tr => write catalog as a resource (to output-file)\n"
40 		"  -v\t\t\tbe verbose, show summary\n");
41 	exit(-1);
42 }
43 
44 
45 int
46 main(int argc, char **argv)
47 {
48 	bool showSummary = false;
49 	bool showWarnings = false;
50 	vector<const char *> inputFiles;
51 	BString outputFile("default.catalog");
52 	enum TargetType {
53 		TARGET_ATTRIBUTE,
54 		TARGET_FILE,
55 		TARGET_RESOURCE
56 	};
57 	TargetType outputTarget = TARGET_FILE;
58 	const char *catalogSig = NULL;
59 	BString catalogLang("English");
60 	status_t res;
61 	while ((++argv)[0]) {
62 		if (argv[0][0] == '-' && argv[0][1] != '-') {
63 			char *arg = argv[0] + 1;
64 			char c;
65 			while ((c = *arg++) != '\0') {
66 				if (c == 's')
67 					catalogSig = (++argv)[0];
68 				else if (c == 'l')
69 					catalogLang = (++argv)[0];
70 				else if (c == 'v')
71 					showSummary = true;
72 				else if (c == 'w')
73 					showWarnings = true;
74 				else if (c == 'o') {
75 					outputFile = (++argv)[0];
76 					break;
77 				}
78 				else if (c == 't') {
79 					switch(*arg) {
80 						case 'a': outputTarget = TARGET_ATTRIBUTE; break;
81 						case 'f': outputTarget = TARGET_FILE; break;
82 						case 'r': outputTarget = TARGET_RESOURCE; break;
83 						default: usage();
84 					}
85 				}
86 			}
87 		} else if (!strcmp(argv[0], "--help")) {
88 			usage();
89 		} else {
90 			inputFiles.push_back(argv[0]);
91 		}
92 	}
93 	if (inputFiles.empty() || !catalogSig || !outputFile.Length())
94 		usage();
95 
96 	EditableCatalog targetCatalog("Default", catalogSig, catalogLang.String());
97 	if ((res = targetCatalog.InitCheck()) != B_OK) {
98 		fprintf(stderr, "couldn't construct target-catalog %s - error: %s\n",
99 			outputFile.String(), strerror(res));
100 		exit(-1);
101 	}
102 	DefaultCatalog* targetCatImpl
103 		= dynamic_cast<DefaultCatalog*>(targetCatalog.CatalogData());
104 	if (!targetCatImpl) {
105 		fprintf(stderr, "couldn't access impl of target-catalog %s\n",
106 			outputFile.String());
107 		exit(-1);
108 	}
109 
110 	uint32 count = inputFiles.size();
111 	for( uint32 i=0; i<count; ++i) {
112 		EditableCatalog inputCatalog("plaintext", catalogSig, "native");
113 		if ((res = inputCatalog.ReadFromFile(inputFiles[i])) != B_OK) {
114 			fprintf(stderr, "couldn't load source-catalog %s - error: %s\n",
115 				inputFiles[i], strerror(res));
116 			exit(-1);
117 		}
118 		HashMapCatalog* inputCatImpl
119 			= dynamic_cast<HashMapCatalog*>(inputCatalog.CatalogData());
120 		if (!inputCatImpl) {
121 			fprintf(stderr, "couldn't access impl of input-catalog %s\n",
122 				inputFiles[i]);
123 			exit(-1);
124 		}
125 
126 		// now walk over all entries in input-catalog and add them to
127 		// target catalog, unless they already exist there.
128 		HashMapCatalog::CatWalker walker(inputCatImpl);
129 		while (!walker.AtEnd()) {
130 			const CatKey &plainTextKey(walker.GetKey());
131 			BString keyString, keyComment, keyContext;
132 			plainTextKey.GetStringParts(&keyString,&keyComment,&keyContext);
133 			const CatKey fixedCatKey(keyString.String(), keyComment.String(),
134 					keyContext.String());
135 
136 			if (!targetCatImpl->GetString(fixedCatKey))
137 				targetCatImpl->SetRawString(fixedCatKey, walker.GetValue());
138 			walker.Next();
139 		}
140 	}
141 
142 	switch(outputTarget) {
143 		case TARGET_ATTRIBUTE: {
144 			BEntry entry(outputFile.String());
145 			entry_ref eref;
146 			entry.GetRef(&eref);
147 			res = targetCatalog.WriteToAttribute(eref);
148 			if (res != B_OK) {
149 				fprintf(stderr,
150 					"couldn't write target-attribute to %s - error: %s\n",
151 					outputFile.String(), strerror(res));
152 				exit(-1);
153 			}
154 			break;
155 		}
156 		case TARGET_RESOURCE: {
157 			BEntry entry(outputFile.String());
158 			entry_ref eref;
159 			entry.GetRef(&eref);
160 			res = targetCatalog.WriteToResource(eref);
161 			if (res != B_OK) {
162 				fprintf(stderr,
163 					"couldn't write target-resource to %s - error: %s\n",
164 					outputFile.String(), strerror(res));
165 				exit(-1);
166 			}
167 			break;
168 		}
169 		default: {
170 			res = targetCatalog.WriteToFile(outputFile.String());
171 			if (res != B_OK) {
172 				fprintf(stderr,
173 					"couldn't write target-catalog to %s - error: %s\n",
174 					outputFile.String(), strerror(res));
175 				exit(-1);
176 			}
177 			break;
178 		}
179 	}
180 	if (showSummary) {
181 		int32 count = targetCatalog.CountItems();
182 		if (count) {
183 			fprintf(stderr, "%ld key%s found and written to %s\n",
184 				count, (count==1 ? "": "s"), outputFile.String());
185 		} else
186 			fprintf(stderr, "no keys found\n");
187 	}
188 
189 	return res;
190 }
191