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