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