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